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

1.1.1.2 ! root        1: !
        !             2: !      setup.s         (C) 1991 Linus Torvalds
        !             3: !
        !             4: ! setup.s is responsible for getting the system data from the BIOS,
        !             5: ! and putting them into the appropriate places in system memory.
        !             6: ! both setup.s and system has been loaded by the bootblock.
        !             7: !
        !             8: ! This code asks the bios for memory/disk/other parameters, and
        !             9: ! puts them in a "safe" place: 0x90000-0x901FF, ie where the
        !            10: ! boot-block used to be. It is then up to the protected mode
        !            11: ! system to read them from there before the area is overwritten
        !            12: ! for buffer-blocks.
        !            13: !
        !            14: 
        !            15: ! NOTE! These had better be the same as in bootsect.s!
        !            16: 
        !            17: INITSEG  = 0x9000      ! we move boot here - out of the way
        !            18: SYSSEG   = 0x1000      ! system loaded at 0x10000 (65536).
        !            19: SETUPSEG = 0x9020      ! this is the current segment
1.1       root       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: entry start
                     31: start:
                     32: 
1.1.1.2 ! root       33: ! ok, the read went well so we get current cursor position and save it for
        !            34: ! posterity.
1.1       root       35: 
1.1.1.2 ! root       36:        mov     ax,#INITSEG     ! this is done in bootsect already, but...
1.1       root       37:        mov     ds,ax
1.1.1.2 ! root       38:        mov     ah,#0x03        ! read cursor pos
1.1       root       39:        xor     bh,bh
1.1.1.2 ! root       40:        int     0x10            ! save it in known place, con_init fetches
        !            41:        mov     [0],dx          ! it from 0x90000.
1.1       root       42: 
1.1.1.2 ! root       43: ! Get memory size (extended mem, kB)
1.1       root       44: 
                     45:        mov     ah,#0x88
                     46:        int     0x15
                     47:        mov     [2],ax
                     48: 
1.1.1.2 ! root       49: ! Get video-card data:
        !            50: 
        !            51:        mov     ah,#0x0f
        !            52:        int     0x10
        !            53:        mov     [4],bx          ! bh = display page
        !            54:        mov     [6],ax          ! al = video mode, ah = window width
        !            55: 
        !            56: ! check for EGA/VGA and some config parameters
        !            57: 
        !            58:        mov     ah,#0x12
        !            59:        mov     bl,#0x10
        !            60:        int     0x10
        !            61:        mov     [8],ax
        !            62:        mov     [10],bx
        !            63:        mov     [12],cx
        !            64: 
        !            65: ! Get hd0 data
1.1       root       66: 
                     67:        mov     ax,#0x0000
                     68:        mov     ds,ax
                     69:        lds     si,[4*0x41]
                     70:        mov     ax,#INITSEG
                     71:        mov     es,ax
                     72:        mov     di,#0x0080
                     73:        mov     cx,#0x10
                     74:        rep
                     75:        movsb
                     76: 
1.1.1.2 ! root       77: ! Get hd1 data
1.1       root       78: 
                     79:        mov     ax,#0x0000
                     80:        mov     ds,ax
                     81:        lds     si,[4*0x46]
                     82:        mov     ax,#INITSEG
                     83:        mov     es,ax
                     84:        mov     di,#0x0090
                     85:        mov     cx,#0x10
                     86:        rep
                     87:        movsb
                     88: 
1.1.1.2 ! root       89: ! Check that there IS a hd1 :-)
1.1       root       90: 
                     91:        mov     ax,#0x01500
                     92:        mov     dl,#0x81
                     93:        int     0x13
                     94:        jc      no_disk1
                     95:        cmp     ah,#3
                     96:        je      is_disk1
                     97: no_disk1:
                     98:        mov     ax,#INITSEG
                     99:        mov     es,ax
                    100:        mov     di,#0x0090
                    101:        mov     cx,#0x10
                    102:        mov     ax,#0x00
                    103:        rep
                    104:        stosb
                    105: is_disk1:
                    106: 
1.1.1.2 ! root      107: ! now we want to move to protected mode ...
1.1       root      108: 
1.1.1.2 ! root      109:        cli                     ! no interrupts allowed !
1.1       root      110: 
1.1.1.2 ! root      111: ! first we move the system to it's rightful place
1.1       root      112: 
                    113:        mov     ax,#0x0000
1.1.1.2 ! root      114:        cld                     ! 'direction'=0, movs moves forward
1.1       root      115: do_move:
1.1.1.2 ! root      116:        mov     es,ax           ! destination segment
1.1       root      117:        add     ax,#0x1000
                    118:        cmp     ax,#0x9000
                    119:        jz      end_move
1.1.1.2 ! root      120:        mov     ds,ax           ! source segment
1.1       root      121:        sub     di,di
                    122:        sub     si,si
                    123:        mov     cx,#0x8000
                    124:        rep
                    125:        movsw
                    126:        jmp     do_move
                    127: 
1.1.1.2 ! root      128: ! then we load the segment descriptors
1.1       root      129: 
                    130: end_move:
1.1.1.2 ! root      131:        mov     ax,#SETUPSEG    ! right, forgot this at first. didn't work :-)
1.1       root      132:        mov     ds,ax
1.1.1.2 ! root      133:        lidt    idt_48          ! load idt with 0,0
        !           134:        lgdt    gdt_48          ! load gdt with whatever appropriate
1.1       root      135: 
1.1.1.2 ! root      136: ! that was painless, now we enable A20
1.1       root      137: 
                    138:        call    empty_8042
1.1.1.2 ! root      139:        mov     al,#0xD1                ! command write
1.1       root      140:        out     #0x64,al
                    141:        call    empty_8042
1.1.1.2 ! root      142:        mov     al,#0xDF                ! A20 on
1.1       root      143:        out     #0x60,al
                    144:        call    empty_8042
                    145: 
1.1.1.2 ! root      146: ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
        !           147: ! we put them right after the intel-reserved hardware interrupts, at
        !           148: ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
        !           149: ! messed this up with the original PC, and they haven't been able to
        !           150: ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
        !           151: ! which is used for the internal hardware interrupts as well. We just
        !           152: ! have to reprogram the 8259's, and it isn't fun.
        !           153: 
        !           154:        mov     al,#0x11                ! initialization sequence
        !           155:        out     #0x20,al                ! send it to 8259A-1
        !           156:        .word   0x00eb,0x00eb           ! jmp $+2, jmp $+2
        !           157:        out     #0xA0,al                ! and to 8259A-2
1.1       root      158:        .word   0x00eb,0x00eb
1.1.1.2 ! root      159:        mov     al,#0x20                ! start of hardware int's (0x20)
1.1       root      160:        out     #0x21,al
                    161:        .word   0x00eb,0x00eb
1.1.1.2 ! root      162:        mov     al,#0x28                ! start of hardware int's 2 (0x28)
1.1       root      163:        out     #0xA1,al
                    164:        .word   0x00eb,0x00eb
1.1.1.2 ! root      165:        mov     al,#0x04                ! 8259-1 is master
1.1       root      166:        out     #0x21,al
                    167:        .word   0x00eb,0x00eb
1.1.1.2 ! root      168:        mov     al,#0x02                ! 8259-2 is slave
1.1       root      169:        out     #0xA1,al
                    170:        .word   0x00eb,0x00eb
1.1.1.2 ! root      171:        mov     al,#0x01                ! 8086 mode for both
1.1       root      172:        out     #0x21,al
                    173:        .word   0x00eb,0x00eb
                    174:        out     #0xA1,al
                    175:        .word   0x00eb,0x00eb
1.1.1.2 ! root      176:        mov     al,#0xFF                ! mask off all interrupts for now
1.1       root      177:        out     #0x21,al
                    178:        .word   0x00eb,0x00eb
                    179:        out     #0xA1,al
                    180: 
1.1.1.2 ! root      181: ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
        !           182: ! need no steenking BIOS anyway (except for the initial loading :-).
        !           183: ! The BIOS-routine wants lots of unnecessary data, and it's less
        !           184: ! "interesting" anyway. This is how REAL programmers do it.
        !           185: !
        !           186: ! Well, now's the time to actually move into protected mode. To make
        !           187: ! things as simple as possible, we do no register set-up or anything,
        !           188: ! we let the gnu-compiled 32-bit programs do that. We just jump to
        !           189: ! absolute address 0x00000, in 32-bit protected mode.
        !           190: 
        !           191:        mov     ax,#0x0001      ! protected mode (PE) bit
        !           192:        lmsw    ax              ! This is it!
        !           193:        jmpi    0,8             ! jmp offset 0 of segment 8 (cs)
        !           194: 
        !           195: ! This routine checks that the keyboard command queue is empty
        !           196: ! No timeout is used - if this hangs there is something wrong with
        !           197: ! the machine, and we probably couldn't proceed anyway.
1.1       root      198: empty_8042:
                    199:        .word   0x00eb,0x00eb
1.1.1.2 ! root      200:        in      al,#0x64        ! 8042 status port
        !           201:        test    al,#2           ! is input buffer full?
        !           202:        jnz     empty_8042      ! yes - loop
1.1       root      203:        ret
                    204: 
                    205: gdt:
1.1.1.2 ! root      206:        .word   0,0,0,0         ! dummy
1.1       root      207: 
1.1.1.2 ! root      208:        .word   0x07FF          ! 8Mb - limit=2047 (2048*4096=8Mb)
        !           209:        .word   0x0000          ! base address=0
        !           210:        .word   0x9A00          ! code read/exec
        !           211:        .word   0x00C0          ! granularity=4096, 386
        !           212: 
        !           213:        .word   0x07FF          ! 8Mb - limit=2047 (2048*4096=8Mb)
        !           214:        .word   0x0000          ! base address=0
        !           215:        .word   0x9200          ! data read/write
        !           216:        .word   0x00C0          ! granularity=4096, 386
1.1       root      217: 
                    218: idt_48:
1.1.1.2 ! root      219:        .word   0                       ! idt limit=0
        !           220:        .word   0,0                     ! idt base=0L
1.1       root      221: 
                    222: gdt_48:
1.1.1.2 ! root      223:        .word   0x800           ! gdt limit=2048, 256 GDT entries
        !           224:        .word   512+gdt,0x9     ! gdt base = 0X9xxxx
1.1       root      225:        
                    226: .text
                    227: endtext:
                    228: .data
                    229: enddata:
                    230: .bss
                    231: endbss:

unix.superglobalmegacorp.com

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