📄 setup.s
字号:
!! setup.S Copyright (C) 1991, 1992 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.!! Move PS/2 aux init code to psaux.c! (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92!! some changes and additional features by Christoph Niemann, March 1993! (niemann@rubdv15.ETDV.Ruhr-Uni-Bochum.De)!! NOTE! These had better be the same as in bootsect.s!#include <linux/config.h>#include <linux/segment.h>#ifndef SVGA_MODE#define SVGA_MODE ASK_VGA#endifINITSEG = DEF_INITSEG ! we move boot here - out of the waySYSSEG = DEF_SYSSEG ! system loaded at 0x10000 (65536).SETUPSEG = DEF_SETUPSEG ! 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! Get memory size (extended mem, kB) mov ah,#0x88 int 0x15 mov [2],ax! set the keyboard repeat rate to the max mov ax,#0x0305 xor bx,bx ! clear bx int 0x16! 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 mov ax,#0x5019 cmp bl,#0x10 je novga mov ax,#0x1a00 ! Added check for EGA/VGA discrimination int 0x10 mov bx,ax mov ax,#0x5019 cmp bl,#0x1a ! 1a means VGA, anything else EGA or lower jne novga call chsvganovga: mov [14],ax mov ah,#0x03 ! read cursor pos xor bh,bh ! clear bh int 0x10 ! save it in known place, con_init fetches mov [0],dx ! it from 0x90000. ! Get video-card data: mov ah,#0x0f int 0x10 mov [4],bx ! bh = display page mov [6],ax ! al = video mode, ah = window width! Get hd0 data xor ax,ax ! clear ax mov ds,ax lds si,[4*0x41] mov ax,#INITSEG mov es,ax mov di,#0x0080 mov cx,#0x10 cld rep movsb! Get hd1 data xor ax,ax ! clear ax mov ds,ax lds si,[4*0x46] mov ax,#INITSEG mov es,ax mov di,#0x0090 mov cx,#0x10 cld 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 xor ax,ax ! clear ax cld rep stosbis_disk1:! check for PS/2 pointing device mov ax,#INITSEG mov ds,ax mov [0x1ff],#0 ! default is no pointing device int 0x11 ! int 0x11: equipment determination test al,#0x04 ! check if pointing device installed jz no_psmouse mov [0x1ff],#0xaa ! device presentno_psmouse:! now we want to move to protected mode ... cli ! no interrupts allowed ! mov al,#0x80 ! disable NMI for the bootup sequence out #0x70,al! first we move the system to its rightful place mov ax,#0x100 ! start of destination segment mov bx,#0x1000 ! start of source segment cld ! 'direction'=0, movs moves forwarddo_move: mov es,ax ! destination segment add ax,#0x100 cmp ax,#0x9000 jz end_move mov ds,bx ! source segment add bx,#0x100 sub di,di sub si,si mov cx,#0x800 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! make sure any possible coprocessor is properly reset.. xor ax,ax out #0xf0,al call delay out #0xf1,al call delay! 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 call delay out #0xA0,al ! and to 8259A-2 call delay mov al,#0x20 ! start of hardware int's (0x20) out #0x21,al call delay mov al,#0x28 ! start of hardware int's 2 (0x28) out #0xA1,al call delay mov al,#0x04 ! 8259-1 is master out #0x21,al call delay mov al,#0x02 ! 8259-2 is slave out #0xA1,al call delay mov al,#0x01 ! 8086 mode for both out #0x21,al call delay out #0xA1,al call delay mov al,#0xFF ! mask off all interrupts for now out #0xA1,al call delay mov al,#0xFB ! mask all irq's but irq2 which out #0x21,al ! is cascaded! 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.!! Note that the short jump isn't strictly needed, althought there are! reasons why it might be a good idea. It won't hurt in any case.! mov ax,#0x0001 ! protected mode (PE) bit lmsw ax ! This is it! jmp flush_instrflush_instr: jmpi 0x1000,KERNEL_CS ! jmp offset 1000 of segment 0x10 (cs)! This routine checks that the keyboard command queue is empty! (after emptying the output buffers)!! No timeout is used - if this hangs there is something wrong with! the machine, and we probably couldn't proceed anyway.empty_8042: call delay in al,#0x64 ! 8042 status port test al,#1 ! output buffer? jz no_output call delay in al,#0x60 ! read it jmp empty_8042no_output: test al,#2 ! is input buffer full? jnz empty_8042 ! yes - loop ret!! Read a key and return the (US-)ascii code in al, scan code in ah!getkey: xor ah,ah int 0x16 ret!! Read a key with a timeout of 30 seconds. The cmos clock is used to get! the time.!getkt: call gettime add al,#30 ! wait 30 seconds cmp al,#60 jl lminute sub al,#60lminute: mov cl,alagain: mov ah,#0x01 int 0x16 jnz getkey ! key pressed, so get it call gettime cmp al,cl jne again mov al,#0x20 ! timeout, return default char `space' ret!! Flush the keyboard buffer!flush: mov ah,#0x01 int 0x16 jz empty xor ah,ah int 0x16 jmp flushempty: ret!! Read the cmos clock. Return the seconds in al!gettime: push cx mov ah,#0x02 int 0x1a mov al,dh ! dh contains the seconds and al,#0x0f mov ah,dh mov cl,#0x04 shr ah,cl aad pop cx ret!! Delay is needed after doing i/o!delay: .word 0x00eb ! jmp $+2 ret! Routine trying to recognize type of SVGA-board present (if any)! and if it recognize one gives the choices of resolution it offers.! If one is found the resolution chosen is given by al,ah (rows,cols).chsvga: cld push ds push cs mov ax,[0x01fa] pop ds mov modesave,ax mov ax,#0xc000 mov es,ax mov ax,modesave cmp ax,#NORMAL_VGA je defvga cmp ax,#EXTENDED_VGA je vga50 cmp ax,#ASK_VGA jne svga lea si,msg1 call prtstr call flushnokey: call getkt cmp al,#0x0d ! enter ? je svga ! yes - svga selection cmp al,#0x20 ! space ? je defvga ! no - repeat call beep jmp nokeydefvga: mov ax,#0x5019 pop ds ret/* extended vga mode: 80x50 */vga50: mov ax,#0x1112 xor bl,bl int 0x10 ! use 8x8 font set (50 lines on VGA) mov ax,#0x1200 mov bl,#0x20 int 0x10 ! use alternate print screen mov ax,#0x1201 mov bl,#0x34 int 0x10 ! turn off cursor emulation mov ah,#0x01 mov cx,#0x0607 int 0x10 ! turn on cursor (scan lines 6 to 7) pop ds mov ax,#0x5032 ! return 80x50 ret/* extended vga mode: 80x28 */vga28: pop ax ! clean the stack mov ax,#0x1111 xor bl,bl int 0x10 ! use 9x14 fontset (28 lines on VGA) mov ah, #0x01 mov cx,#0x0b0c int 0x10 ! turn on cursor (scan lines 11 to 12) pop ds mov ax,#0x501c ! return 80x28 ret/* svga modes */svga: cld lea si,id9GXE ! Check for the #9GXE (jyanowit@orixa.mtholyoke.edu,thanks dlm40629@uxa.cso.uiuc.edu) mov di,#0x49 ! id string is at c000:049 mov cx,#0x11 ! length of "Graphics Power By" repe cmpsb jne of1280is9GXE: lea si,dsc9GXE ! table of descriptions of video modes for BIOS lea di,mo9GXE ! table of sizes of video modes for my BIOS br selmod ! go ask for video modeof1280: cld lea si,idf1280 ! Check for Orchid F1280 (dingbat@diku.dk) mov di,#0x10a ! id string is at c000:010a mov cx,#0x21 ! length repe cmpsb jne nf1280 isVRAM: lea si,dscf1280 lea di,mof1280 br selmodnf1280: lea si,idVRAM mov di,#0x10a mov cx,#0x0c repe cmpsb je isVRAM cld lea si,idati ! Check ATI 'clues' mov di,#0x31 mov cx,#0x09 repe cmpsb jne noati lea si,dscati lea di,moati br selmodnoati: mov ax,#0x200f ! Check Ahead 'clues' mov dx,#0x3ce out dx,ax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -