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

1.1.1.2 ! root        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.
1.1       root       24: 
                     25: .globl begtext, begdata, begbss, endtext, enddata, endbss
                     26: .text
                     27: begtext:
                     28: .data
                     29: begdata:
                     30: .bss
                     31: begbss:
                     32: .text
                     33: 
1.1.1.2 ! root       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
1.1       root       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
1.1.1.2 ! root       60: ! put stack at 0x9ff00.
1.1       root       61:        mov     ss,ax
1.1.1.2 ! root       62:        mov     sp,#0xFF00              ! arbitrary value >>512
1.1       root       63: 
1.1.1.2 ! root       64: ! load the setup-sectors directly after the bootblock.
        !            65: ! Note that 'es' is already set up.
1.1       root       66: 
                     67: load_setup:
1.1.1.2 ! root       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
1.1       root       74:        mov     dx,#0x0000
1.1.1.2 ! root       75:        mov     ax,#0x0000              ! reset the diskette
1.1       root       76:        int     0x13
                     77:        j       load_setup
                     78: 
                     79: ok_load_setup:
                     80: 
1.1.1.2 ! root       81: ! Get disk drive parameters, specifically nr of sectors/track
1.1       root       82: 
                     83:        mov     dl,#0x00
1.1.1.2 ! root       84:        mov     ax,#0x0800              ! AH=8 is get drive parameters
1.1       root       85:        int     0x13
                     86:        mov     ch,#0x00
                     87:        seg cs
                     88:        mov     sectors,cx
                     89:        mov     ax,#INITSEG
                     90:        mov     es,ax
                     91: 
1.1.1.2 ! root       92: ! Print some inane message
1.1       root       93: 
1.1.1.2 ! root       94:        mov     ah,#0x03                ! read cursor pos
1.1       root       95:        xor     bh,bh
                     96:        int     0x10
                     97:        
                     98:        mov     cx,#24
1.1.1.2 ! root       99:        mov     bx,#0x0007              ! page 0, attribute 7 (normal)
1.1       root      100:        mov     bp,#msg1
1.1.1.2 ! root      101:        mov     ax,#0x1301              ! write string, move cursor
1.1       root      102:        int     0x10
                    103: 
1.1.1.2 ! root      104: ! ok, we've written the message, now
        !           105: ! we want to load the system (at 0x10000)
1.1       root      106: 
                    107:        mov     ax,#SYSSEG
1.1.1.2 ! root      108:        mov     es,ax           ! segment of 0x010000
1.1       root      109:        call    read_it
                    110:        call    kill_motor
                    111: 
1.1.1.2 ! root      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.
1.1       root      116: 
                    117:        seg cs
                    118:        mov     ax,root_dev
                    119:        cmp     ax,#0
                    120:        jne     root_defined
                    121:        seg cs
                    122:        mov     bx,sectors
1.1.1.2 ! root      123:        mov     ax,#0x0208              ! /dev/ps0 - 1.2Mb
1.1       root      124:        cmp     bx,#15
                    125:        je      root_defined
1.1.1.2 ! root      126:        mov     ax,#0x021c              ! /dev/PS0 - 1.44Mb
1.1       root      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: 
1.1.1.2 ! root      135: ! after that (everyting loaded), we jump to
        !           136: ! the setup-routine loaded directly after
        !           137: ! the bootblock:
1.1       root      138: 
                    139:        jmpi    0,SETUPSEG
                    140: 
1.1.1.2 ! root      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
1.1       root      150: 
                    151: read_it:
                    152:        mov ax,es
                    153:        test ax,#0x0fff
1.1.1.2 ! root      154: die:   jne die                 ! es must be at 64kB boundary
        !           155:        xor bx,bx               ! bx is starting address within segment
1.1       root      156: rp_read:
                    157:        mov ax,es
1.1.1.2 ! root      158:        cmp ax,#ENDSEG          ! have we loaded all yet?
1.1       root      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:

unix.superglobalmegacorp.com

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