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

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

unix.superglobalmegacorp.com

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