root/boot/bootsect.s

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

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