Annotation of linux/boot/bootsect.s, revision 1.1.1.1

1.1       root        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:

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.