From: hyvatti@klaava.Helsinki.FI (Jaakko Hyvatti) Subject: boothard.S - a bootsector for hard disks Date: 21 May 1992 18:08:16 GMT
In article <gunter.706437336@severus> gunter@sci.kun.nl (Gunter Windau) writes:
>You might create a small partition on your harddisk that's just
>big enough to hold the linux bootimage and make this partition
>the 'active' one. I think the bios will load the kernel from this
>partition, just like it does from a floppy.
>I haven't tried it myself so it might not work, although I'd like
>to know if it does...
It does not. What you need is a special bootsector for hard disks
like the one below. Be careful with it, I just got it working..
--
Jaakko Hyv{tti Jaakko.Hyvatti@Helsinki.FI
Lapinrinne 1 B 608 hyvatti@plootu.helsinki.fi
00180 Helsinki, Finland +358-0-6958 5368
==================================================================
#
# Makefile for boothard by Jaakko Hyv{tti 1992-05-21
#
# Boothard.S is a hard disk boot sector designed to
# be used for booting Linux from fixed disks. It does
# the job of bootsect.S from original sources and is
# a direct derivate of it.
#
# What you need is to make a bootable primary partition
# for your kernel and kernel only. 256kB or 512kB
# is enough for the Image file.
#
# Build your conventional linux kernel as usual
#
# Edit this Makefile to get LINUX and ROOT_DEV right
#
# Type 'make' in the directory where this Makefile and boothard.S
# are.
#
# Then copy the resulting Image file to your newly created
# hard disk partition, like 'cp Image /dev/hda4'.
#
# WARNING! Nobody but you is to blame if something breaks!
# I am not reponsible for anything this piece
# of garbage does! If you don't know what you are
# doing do not do it. Back up everything.
#
# BUGS
#
# Somebody is free to document better the procedure of
# getting this thing into use.
#
# Questions to Jaakko.Hyvatti@Helsinki.FI or hyvatti@cc.helsinki.fi
#
# LINUX specifies where to find compiled kernel and include files
#
LINUX = /usr/src/linux
#
# ROOT_DEV specifies the default root-device when making the image.
#
ROOT_DEV = /dev/hdb1
#
AS86 =as86 -0 -a
LD86 =ld86 -0
CPP =/lib/cpp -nostdinc -I$(LINUX)/include
all: Image
Image: boothard $(LINUX)/boot/setup $(LINUX)/tools/system \
$(LINUX)/tools/build
cp $(LINUX)/tools/system system.tmp
strip system.tmp
$(LINUX)/tools/build boothard $(LINUX)/boot/setup \
system.tmp $(ROOT_DEV) > Image
rm system.tmp
sync
boothard.s: boothard.S $(LINUX)/include/linux/config.h
$(CPP) -traditional boothard.S -o boothard.s
boothard.o: boothard.s
$(AS86) -o boothard.o boothard.s
boothard: boothard.o
$(LD86) -s -o boothard boothard.o
clean:
rm -f Image boothard boothard.o boothard.s
install: Image
@echo
@echo To install kernel to a bootable hard disk partition
@echo just copy your Image file to it.
@echo
@echo WARNING! Doing so destroys all data on that partition!
@echo
@echo Example:
@echo
@echo cp Image /dev/hda4
@echo
#
# end of Makefile for boothard
#
=================================================================
!
! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
! 0x4000 is 0x40000 bytes = 256kB, more than enough for current
! versions of linux
!
#include <linux/config.h>
SYSSIZE = DEF_SYSSIZE
!
! bootsect.S (C) 1991 Linus Torvalds
! modified by Drew Eckhardt
! modified by Bruce Evans (bde)
! modified by Jaakko J. Hyv{tti (jjh) to boot from hard disk.
! Original version was from Linux 0.96 sources.
!
! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
! itself out of the way to address 0x90000, and jumps there.
!
! bde - should not jump blindly, there may be systems with only 512K low
! memory. Use int 0x12 to get the top of memory, etc.
!
! It then loads 'setup' directly after itself (0x90200), and the system
! at 0x10000, using BIOS interrupts.
!
! NOTE! currently system is at most 8*65536 bytes long. This should be no
! problem, even in the future. I want to keep it simple. This 512 kB
! kernel size should be enough, especially as this doesn't contain the
! buffer cache as in minix
!
! The loader has been made as simple as possible, and continuos
! read errors will result in a unbreakable loop. Reboot by hand. It
! loads pretty fast by getting whole tracks at a time whenever possible.
.text
SETUPSECS = 4 ! nr of setup-sectors
BOOTSEG = 0x07C0 ! original address of boot-sector
INITSEG = DEF_INITSEG ! we move boot here - out of the way
SETUPSEG = DEF_SETUPSEG ! setup starts here
SYSSEG = DEF_SYSSEG ! system loaded at 0x10000 (65536).
! ROOT_DEV & SWAP_DEV are now written by "build".
ROOT_DEV = 0
SWAP_DEV = 0
! ld86 requires an entry symbol. This may as well be the usual one.
.globl _main
_main:
#if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
int 3
#endif
push es ! jjh - es:bp is the location of the partition
mov ax,#BOOTSEG ! table entry. Save it.
mov ds,ax
mov ax,#INITSEG
mov es,ax
mov cx,#256
sub si,si
sub di,di
cld
rep
movsw
jmpi go,INITSEG
go: mov ax,cs
mov dx,#0x4000 ! 0x4000 is arbitrary value >= length of
! bootsect + length of setup + room for stack
! bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde). We
! wouldn't have to worry about this if we checked the top of memory. Also
! my BIOS can be configured to put the wini drive tables in high memory
! instead of in the vector table. The old stack might have clobbered the
! drive table.
mov es,ax
pop ds ! jjh - ds:bp is the partition table entry
push ax
mov ss,ax ! put stack at INITSEG:0x4000.
mov sp,dx
! Print some inane message
push bp
mov ah,#0x03 ! read cursor pos
xor bh,bh
int 0x10
mov cx,#27
mov bx,#0x0007 ! page 0, attribute 7 (normal)
mov bp,#msg1
mov ax,#0x1301 ! write string, move cursor
int 0x10
pop bp
! ok, we've written the message
mov ah,#8 ! read capacity
mov si,bp
mov dl,(si) ! drive number from partition table
int 0x13
error1:
jc error1 ! Who cares about errors?
and cl,#0x3f
seg cs
mov sectors,cl ! save the drive geometry
inc dh
seg cs
mov heads,dh
mov si,bp ! get info from partition table
mov dx,(si) ! drive and head
mov cx,2(si) ! sector and track
mov al,#1
call add_sectors ! skip the bootsector
mov bx,#0x0200 ! address = 512, in INITSEG
mov ax,#0x0200+SETUPSECS ! service 2, nr of sectors
int 0x13 ! read setup
error2:
jc error2 ! loop on error
! now we want to load the system (at 0x10000)
mov si,bp
mov bp,#SYSSIZE ! maximum number of sectors needed to read
shr bp,#5
cmp 0x0e(si),#0 ! check the size of the partition
jnz load_it
cmp bp,0x0c(si)
jb load_it
mov bp,0x0c(si) ! partition is smaller than SYSSIZE
mov ax,#0xe20 ! tell it by printing a space
int 0x10
load_it:
mov ax,#SYSSEG
mov es,ax ! segment of 0x010000
mov ax,cs
mov ds,ax
xor bx,bx ! loading offset 0
mov al,#SETUPSECS ! skip setup, it was just read
more:
call add_sectors ! increment source sector
mov ax,(sectors)
cmp bp,ax ! is there still more than one track?
jb last_read
sub bp,ax
mov ax,#0xe2e ! yes, print a dot
int 0x10
mov al,(sectors)
mov ah,#2
int 0x13 ! load a track
error3:
jc error3
mov di,(sectors) ! increment destination segment
shl di,#5
mov ax,es
add ax,di
mov es,ax
mov al,(sectors)
jmp more
last_read:
mov ax,#0xe21 ! '!'
int 0x10
mov ax,bp
mov ah,#2
int 0x13 ! the rest of the last track
error4:
jc error4
call kill_motor ! just in case
call print_nl
! After that we check which root-device to use. If the device is
! defined (!= 0), nothing is done and the given device is used.
! Otherwise halt, there is no point in checking out any floppies etc.
seg cs
mov ax,root_dev
or ax,ax
undef_root:
jz undef_root
root_defined:
! after that (everything loaded), we jump to
! the setup-routine loaded directly after
! the bootblock:
jmpi 0,SETUPSEG
/*
* jjh - This routine adds al to the sector-head-track number.
* al must be <= (sectors)
*/
add_sectors:
mov ah,cl
and ah,#0x3f
and cl,#0xc0
add al,ah
cmp al,(sectors)
jbe add1
sub al,(sectors)
inc dh
cmp dh,(heads)
jb add1
sub dh,(heads)
inc ch
jnz add1
add cl,#0x40
add1:
or cl,al
ret
/*
* This procedure turns off the floppy drive motor, so
* that we enter the kernel in a known state, and
* don't have to worry about it later.
*/
kill_motor:
push dx
mov dx,#0x3f2
xor al, al
outb
pop dx
ret
print_nl:
mov ax, #0xe0d ! CR
int 0x10
mov al, #0xa ! LF
int 0x10
ret
sectors:
.word 0
heads:
.word 0
msg1:
.byte 13,10
.ascii "Welcome to the the jungle"
.org 506
swap_dev:
.word SWAP_DEV
root_dev:
.word ROOT_DEV
boot_flag:
.word 0xAA55
! end of boothard.S