root/boot/bootsect.s

/* [previous][next][first][last][top][bottom][index][help] */
   1 !
   2 ! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
   3 ! 0x3000 is 0x30000 bytes = 196kB, more than enough for current
   4 ! versions of linux
   5 !
   6 SYSSIZE = 0x3000
   7 !
   8 !       bootsect.s              (C) 1991 Linus Torvalds
   9 !
  10 ! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
  11 ! iself out of the way to address 0x90000, and jumps there.
  12 !
  13 ! It then loads 'setup' directly after itself (0x90200), and the system
  14 ! at 0x10000, using BIOS interrupts. 
  15 !
  16 ! NOTE! currently system is at most 8*65536 bytes long. This should be no
  17 ! problem, even in the future. I want to keep it simple. This 512 kB
  18 ! kernel size should be enough, especially as this doesn't contain the
  19 ! buffer cache as in minix
  20 !
  21 ! The loader has been made as simple as possible, and continuos
  22 ! read errors will result in a unbreakable loop. Reboot by hand. It
  23 ! loads pretty fast by getting whole sectors at a time whenever possible.
  24 
  25 .globl begtext, begdata, begbss, endtext, enddata, endbss
  26 .text
  27 begtext:
  28 .data
  29 begdata:
  30 .bss
  31 begbss:
  32 .text
  33 
  34 SETUPLEN = 4                            ! nr of setup-sectors
  35 BOOTSEG  = 0x07c0                       ! original address of boot-sector
  36 INITSEG  = 0x9000                       ! we move boot here - out of the way
  37 SETUPSEG = 0x9020                       ! setup starts here
  38 SYSSEG   = 0x1000                       ! system loaded at 0x10000 (65536).
  39 ENDSEG   = SYSSEG + SYSSIZE             ! where to stop loading
  40 
  41 ! ROOT_DEV:     0x000 - same type of floppy as boot.
  42 !               0x301 - first partition on first drive etc
  43 ROOT_DEV = 0x306
  44 
  45 entry start
  46 start:
  47         mov     ax,#BOOTSEG
  48         mov     ds,ax
  49         mov     ax,#INITSEG
  50         mov     es,ax
  51         mov     cx,#256
  52         sub     si,si
  53         sub     di,di
  54         rep
  55         movw
  56         jmpi    go,INITSEG
  57 go:     mov     ax,cs
  58         mov     ds,ax
  59         mov     es,ax
  60 ! put stack at 0x9ff00.
  61         mov     ss,ax
  62         mov     sp,#0xFF00              ! arbitrary value >>512
  63 
  64 ! load the setup-sectors directly after the bootblock.
  65 ! Note that 'es' is already set up.
  66 
  67 load_setup:
  68         mov     dx,#0x0000              ! drive 0, head 0
  69         mov     cx,#0x0002              ! sector 2, track 0
  70         mov     bx,#0x0200              ! address = 512, in INITSEG
  71         mov     ax,#0x0200+SETUPLEN     ! service 2, nr of sectors
  72         int     0x13                    ! read it
  73         jnc     ok_load_setup           ! ok - continue
  74         mov     dx,#0x0000
  75         mov     ax,#0x0000              ! reset the diskette
  76         int     0x13
  77         j       load_setup
  78 
  79 ok_load_setup:
  80 
  81 ! Get disk drive parameters, specifically nr of sectors/track
  82 
  83         mov     dl,#0x00
  84         mov     ax,#0x0800              ! AH=8 is get drive parameters
  85         int     0x13
  86         mov     ch,#0x00
  87         seg cs
  88         mov     sectors,cx
  89         mov     ax,#INITSEG
  90         mov     es,ax
  91 
  92 ! Print some inane message
  93 
  94         mov     ah,#0x03                ! read cursor pos
  95         xor     bh,bh
  96         int     0x10
  97         
  98         mov     cx,#24
  99         mov     bx,#0x0007              ! page 0, attribute 7 (normal)
 100         mov     bp,#msg1
 101         mov     ax,#0x1301              ! write string, move cursor
 102         int     0x10
 103 
 104 ! ok, we've written the message, now
 105 ! we want to load the system (at 0x10000)
 106 
 107         mov     ax,#SYSSEG
 108         mov     es,ax           ! segment of 0x010000
 109         call    read_it
 110         call    kill_motor
 111 
 112 ! After that we check which root-device to use. If the device is
 113 ! defined (!= 0), nothing is done and the given device is used.
 114 ! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
 115 ! on the number of sectors that the BIOS reports currently.
 116 
 117         seg cs
 118         mov     ax,root_dev
 119         cmp     ax,#0
 120         jne     root_defined
 121         seg cs
 122         mov     bx,sectors
 123         mov     ax,#0x0208              ! /dev/ps0 - 1.2Mb
 124         cmp     bx,#15
 125         je      root_defined
 126         mov     ax,#0x021c              ! /dev/PS0 - 1.44Mb
 127         cmp     bx,#18
 128         je      root_defined
 129 undef_root:
 130         jmp undef_root
 131 root_defined:
 132         seg cs
 133         mov     root_dev,ax
 134 
 135 ! after that (everyting loaded), we jump to
 136 ! the setup-routine loaded directly after
 137 ! the bootblock:
 138 
 139         jmpi    0,SETUPSEG
 140 
 141 ! This routine loads the system at address 0x10000, making sure
 142 ! no 64kB boundaries are crossed. We try to load it as fast as
 143 ! possible, loading whole tracks whenever we can.
 144 !
 145 ! in:   es - starting address segment (normally 0x1000)
 146 !
 147 sread:  .word 1+SETUPLEN        ! sectors read of current track
 148 head:   .word 0                 ! current head
 149 track:  .word 0                 ! current track
 150 
 151 read_it:
 152         mov ax,es
 153         test ax,#0x0fff
 154 die:    jne die                 ! es must be at 64kB boundary
 155         xor bx,bx               ! bx is starting address within segment
 156 rp_read:
 157         mov ax,es
 158         cmp ax,#ENDSEG          ! have we loaded all yet?
 159         jb ok1_read
 160         ret
 161 ok1_read:
 162         seg cs
 163         mov ax,sectors
 164         sub ax,sread
 165         mov cx,ax
 166         shl cx,#9
 167         add cx,bx
 168         jnc ok2_read
 169         je ok2_read
 170         xor ax,ax
 171         sub ax,bx
 172         shr ax,#9
 173 ok2_read:
 174         call read_track
 175         mov cx,ax
 176         add ax,sread
 177         seg cs
 178         cmp ax,sectors
 179         jne ok3_read
 180         mov ax,#1
 181         sub ax,head
 182         jne ok4_read
 183         inc track
 184 ok4_read:
 185         mov head,ax
 186         xor ax,ax
 187 ok3_read:
 188         mov sread,ax
 189         shl cx,#9
 190         add bx,cx
 191         jnc rp_read
 192         mov ax,es
 193         add ax,#0x1000
 194         mov es,ax
 195         xor bx,bx
 196         jmp rp_read
 197 
 198 read_track:
 199         push ax
 200         push bx
 201         push cx
 202         push dx
 203         mov dx,track
 204         mov cx,sread
 205         inc cx
 206         mov ch,dl
 207         mov dx,head
 208         mov dh,dl
 209         mov dl,#0
 210         and dx,#0x0100
 211         mov ah,#2
 212         int 0x13
 213         jc bad_rt
 214         pop dx
 215         pop cx
 216         pop bx
 217         pop ax
 218         ret
 219 bad_rt: mov ax,#0
 220         mov dx,#0
 221         int 0x13
 222         pop dx
 223         pop cx
 224         pop bx
 225         pop ax
 226         jmp read_track
 227 
 228 /*
 229  * This procedure turns off the floppy drive motor, so
 230  * that we enter the kernel in a known state, and
 231  * don't have to worry about it later.
 232  */
 233 kill_motor:
 234         push dx
 235         mov dx,#0x3f2
 236         mov al,#0
 237         outb
 238         pop dx
 239         ret
 240 
 241 sectors:
 242         .word 0
 243 
 244 msg1:
 245         .byte 13,10
 246         .ascii "Loading system ..."
 247         .byte 13,10,13,10
 248 
 249 .org 508
 250 root_dev:
 251         .word ROOT_DEV
 252 boot_flag:
 253         .word 0xAA55
 254 
 255 .text
 256 endtext:
 257 .data
 258 enddata:
 259 .bss
 260 endbss:

/* [previous][next][first][last][top][bottom][index][help] */