?? setup.s
字號:
!! setup.s (C) 1991 Linus Torvalds!! setup.s is responsible for getting the system data from the BIOS,! and putting them into the appropriate places in system memory.! both setup.s and system has been loaded by the bootblock.!! This code asks the bios for memory/disk/other parameters, and! puts them in a "safe" place: 0x90000-0x901FF, ie where the! boot-block used to be. It is then up to the protected mode! system to read them from there before the area is overwritten! for buffer-blocks.!! NOTE! These had better be the same as in bootsect.s!INITSEG = 0x9000 ! we move boot here - out of the waySYSSEG = 0x1000 ! system loaded at 0x10000 (65536).SETUPSEG = 0x9020 ! this is the current segment.globl begtext, begdata, begbss, endtext, enddata, endbss.textbegtext:.databegdata:.bssbegbss:.textentry startstart:! ok, the read went well so we get current cursor position and save it for! posterity. mov ax,#INITSEG ! this is done in bootsect already, but... mov ds,ax mov ah,#0x03 xor bh,bh int 0x10 mov ax,cs mov es,ax mov cx,#25 ! 字符串長度 mov bx,#0x000B ! page 0, attribute B mov bp,#msg2 mov ax,#0x1301 ! write string, move cursor int 0x10 mov ah,#0x03 ! read cursor pos xor bh,bh int 0x10 ! save it in known place, con_init fetches mov [0],dx ! it from 0x90000.! Get memory size (extended mem, kB)內存大小位置 mov ah,#0x88 int 0x15 mov [2],ax
mov ah,#0x03
xor bh,bh
int 0x10
mov ax,cs
mov es,ax
mov cx,#12 ! 字符串長度 mov bx,#0x0006 ! page 0, attribute 8
mov bp,#msg3
mov ax,#0x1301 ! write string, move cursor
int 0x10 call print_bx
mov ah,#0x03
xor bh,bh
int 0x10
mov ax,cs
mov es,ax
mov cx,#4 ! 字符串長度 mov bx,#0x0009 ! page 0, attribute 9
mov bp,#msg4
mov ax,#0x1301 ! write string, move cursor
int 0x10
call print_nl! Get video-card data: mov ah,#0x0f int 0x10 mov [4],bx ! bh = display page mov [6],ax ! al = video mode, ah = window width! check for EGA/VGA and some config parameters mov ah,#0x12 mov bl,#0x10 int 0x10 mov [8],ax mov [10],bx mov [12],cx! Get hd0 data 從0x41處拷貝16個字節(磁盤參數表) mov ax,#0x0000 mov ds,ax lds si,[4*0x41] mov ax,#INITSEG mov es,ax mov di,#0x0080 mov cx,#0x10 rep !重復16次 movsb! Get hd1 data mov ax,#0x0000 mov ds,ax lds si,[4*0x46] mov ax,#INITSEG mov es,ax mov di,#0x0090 mov cx,#0x10 rep movsb! Check that there IS a hd1 :-) mov ax,#0x01500 mov dl,#0x81 int 0x13 jc no_disk1 cmp ah,#3 je is_disk1no_disk1: mov ax,#INITSEG mov es,ax mov di,#0x0090 mov cx,#0x10 mov ax,#0x00 rep stosbis_disk1:! now we want to move to protected mode ... cli ! no interrupts allowed !! first we move the system to it's rightful place mov ax,#0x0000 cld ! 'direction'=0, movs moves forwarddo_move: mov es,ax ! destination segment add ax,#0x1000 cmp ax,#0x9000 jz end_move mov ds,ax ! source segment sub di,di sub si,si mov cx,#0x8000 rep movsw jmp do_move! then we load the segment descriptorsend_move: mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-) mov ds,ax lidt idt_48 ! load idt with 0,0 lgdt gdt_48 ! load gdt with whatever appropriate! that was painless, now we enable A20 call empty_8042 mov al,#0xD1 ! command write out #0x64,al call empty_8042 mov al,#0xDF ! A20 on out #0x60,al call empty_8042! well, that went ok, I hope. Now we have to reprogram the interrupts :-(! we put them right after the intel-reserved hardware interrupts, at! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really! messed this up with the original PC, and they haven't been able to! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,! which is used for the internal hardware interrupts as well. We just! have to reprogram the 8259's, and it isn't fun. mov al,#0x11 ! initialization sequence out #0x20,al ! send it to 8259A-1 .word 0x00eb,0x00eb ! jmp $+2, jmp $+2 out #0xA0,al ! and to 8259A-2 .word 0x00eb,0x00eb mov al,#0x20 ! start of hardware int's (0x20) out #0x21,al .word 0x00eb,0x00eb mov al,#0x28 ! start of hardware int's 2 (0x28) out #0xA1,al .word 0x00eb,0x00eb mov al,#0x04 ! 8259-1 is master out #0x21,al .word 0x00eb,0x00eb mov al,#0x02 ! 8259-2 is slave out #0xA1,al .word 0x00eb,0x00eb mov al,#0x01 ! 8086 mode for both out #0x21,al .word 0x00eb,0x00eb out #0xA1,al .word 0x00eb,0x00eb mov al,#0xFF ! mask off all interrupts for now out #0x21,al .word 0x00eb,0x00eb out #0xA1,al! well, that certainly wasn't fun :-(. Hopefully it works, and we don't! need no steenking BIOS anyway (except for the initial loading :-).! The BIOS-routine wants lots of unnecessary data, and it's less! "interesting" anyway. This is how REAL programmers do it.!! Well, now's the time to actually move into protected mode. To make! things as simple as possible, we do no register set-up or anything,! we let the gnu-compiled 32-bit programs do that. We just jump to! absolute address 0x00000, in 32-bit protected mode. mov ax,#0x0001 ! protected mode (PE) bit lmsw ax ! This is it!die: jmp die
jmpi 0,8 ! jmp offset 0 of segment 8 (cs)! This routine checks that the keyboard command queue is empty! No timeout is used - if this hangs there is something wrong with! the machine, and we probably couldn't proceed anyway.empty_8042: .word 0x00eb,0x00eb in al,#0x64 ! 8042 status port test al,#2 ! is input buffer full? jnz empty_8042 ! yes - loop retprint_bx:
!以16進制方式打印棧頂的16位數
push ax
push cx
push dx
print_hex:
mov cx,#4 ! 4個十六進制數字 mov dx,[2] ! 將(bp)所指的值放入dx中,如果bp是指向棧頂的話print_digit:
rol dx,#4 ! 循環以使低4比特用上 !! 取dx的高4比特移到低4比特處。 mov ax,#0xe0f ! ah = 請求的功能值,al = 半字節(4個比特)掩碼。 and al,dl ! 取dl的低4比特值。 add al,#0x30 ! 給al數字加上十六進制0x30
cmp al,#0x3a
jl outp !是一個不大于十的數字
add al,#0x07 !是a~f,要多加7
outp:
int 0x10
loop print_digit
pop dx
pop cx
pop ax
ret
!打印回車換行
print_nl:
push ax
mov ax,#0xe0d ! CR
int 0x10
mov al,#0xa ! LF
int 0x10
pop ax
ret
gdt: .word 0,0,0,0 ! dummy .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb) .word 0x0000 ! base address=0 .word 0x9A00 ! code read/exec .word 0x00C0 ! granularity=4096, 386 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb) .word 0x0000 ! base address=0 .word 0x9200 ! data read/write .word 0x00C0 ! granularity=4096, 386idt_48: .word 0 ! idt limit=0 .word 0,0 ! idt base=0Lgdt_48: .word 0x800 ! gdt limit=2048, 256 GDT entries .word 512+gdt,0x9 ! gdt base = 0X9xxxxmsg2: .byte 13,10 .ascii "Now we are in SETUP" .byte 13,10,13,10
msg3:
.ascii "Memory SIZE:"
msg4:
.ascii "KB"
.byte 13,10 .textendtext:.dataenddata:.bssendbss:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -