Annotation of linux/boot/bootsect.s, revision 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.