linux-0.12/boot/setup.S`
来源:互联网 发布:淘宝如何申请分销 编辑:程序博客网 时间:2024/05/22 17:14
setup.S 在进入system前执行,它首先调用bios获得各种硬件参数,然后进入保护模式。
。。代码看起来有点无聊
!! 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!#include <linux/config.h>;#define DEF_INITSEG 0x9000;#define DEF_SYSSEG 0x1000;#define DEF_SETUPSEG 0x9020;#define DEF_SYSSIZE 0x3000INITSEG = 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 ;0x9000! Get memory size (extended mem, kB) mov ah,#0x88 int 0x15 mov [2],ax;取系统所含扩展内存的大小,保存在0x90002! check for EGA/VGA and some config parameters mov ah,#0x12 mov bl,#0x10 int 0x10 mov [8],ax mov [10],bx ;0x9000a 安装的显示内存 0x9000b 显示状态(彩色/单色) mov [12],cx ;0x9000c 显示卡特性参数 mov ax,#0x5019 ;检查屏幕是否是80*25的 cmp bl,#0x10 je novga ;如果中断 返回bl=0x10 表示不是vga显卡 跳 novga call chsvga 检测显示卡厂家和类型 修改显示的行列值novga: mov [14],ax 保存当前的行列值 ;取屏幕当前光标位置 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 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 取第一个硬盘的信息 mov ax,#0x0000 mov ds,ax lds si,[4*0x41] mov ax,#INITSEG mov es,ax mov di,#0x0080 mov cx,#0x10 rep 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 ... 进入保护模式咯ing cli ! no interrupts allowed !! first we move the system to it's rightful place mov ax,#0x0000 cld ! 'direction'=0, movs moves forward ;移动systemdo_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 ;等待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.;重新对8259进行编程 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8259 get done! 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! 设置cr0 进入到保护模式 jmpi 0,8 ! jmp offset 0 of segment 8 (cs) ;8 =0b 0000 0000 0000 1-000 ;所以这里是使用 GDT中的第二个全局描述符 ;至此就会跳转执行system中的代码! 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 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 pop ds mov ax,#0xc000 mov es,ax lea si,msg1 call prtstrnokey: in al,#0x60 cmp al,#0x82 jb nokey cmp al,#0xe0 ja nokey cmp al,#0x9c je svga mov ax,#0x5019 pop ds retsvga: lea si,idati ! Check ATI 'clues' mov di,#0x31 mov cx,#0x09 repe cmpsb jne noati lea si,dscati lea di,moati lea cx,selmod jmp cxnoati: mov ax,#0x200f ! Check Ahead 'clues' mov dx,#0x3ce out dx,ax inc dx in al,dx cmp al,#0x20 je isahed cmp al,#0x21 jne noahedisahed: lea si,dscahead lea di,moahead lea cx,selmod jmp cxnoahed: mov dx,#0x3c3 ! Check Chips & Tech. 'clues' in al,dx or al,#0x10 out dx,al mov dx,#0x104 in al,dx mov bl,al mov dx,#0x3c3 in al,dx and al,#0xef out dx,al cmp bl,[idcandt] jne nocant lea si,dsccandt lea di,mocandt lea cx,selmod jmp cxnocant: mov dx,#0x3d4 ! Check Cirrus 'clues' mov al,#0x0c out dx,al inc dx in al,dx mov bl,al xor al,al out dx,al dec dx mov al,#0x1f out dx,al inc dx in al,dx mov bh,al xor ah,ah shl al,#4 mov cx,ax mov al,bh shr al,#4 add cx,ax shl cx,#8 add cx,#6 mov ax,cx mov dx,#0x3c4 out dx,ax inc dx in al,dx and al,al jnz nocirr mov al,bh out dx,al in al,dx cmp al,#0x01 jne nocirr call rst3d4 lea si,dsccirrus lea di,mocirrus lea cx,selmod jmp cxrst3d4: mov dx,#0x3d4 mov al,bl xor ah,ah shl ax,#8 add ax,#0x0c out dx,ax ret nocirr: call rst3d4 ! Check Everex 'clues' mov ax,#0x7000 xor bx,bx int 0x10 cmp al,#0x70 jne noevrx shr dx,#4 cmp dx,#0x678 je istrid cmp dx,#0x236 je istrid lea si,dsceverex lea di,moeverex lea cx,selmod jmp cxistrid: lea cx,ev2tri jmp cxnoevrx: lea si,idgenoa ! Check Genoa 'clues' xor ax,ax seg es mov al,[0x37] mov di,ax mov cx,#0x04 dec si dec dil1: inc si inc di mov al,(si) seg es and al,(di) cmp al,(si) loope l1 cmp cx,#0x00 jne nogen lea si,dscgenoa lea di,mogenoa lea cx,selmod jmp cxnogen: lea si,idparadise ! Check Paradise 'clues' mov di,#0x7d mov cx,#0x04 repe cmpsb jne nopara lea si,dscparadise lea di,moparadise lea cx,selmod jmp cxnopara: mov dx,#0x3c4 ! Check Trident 'clues' mov al,#0x0e out dx,al inc dx in al,dx xchg ah,al mov al,#0x00 out dx,al in al,dx xchg al,ah mov bl,al ! Strange thing ... in the book this wasn't and bl,#0x02 ! necessary but it worked on my card which jz setb2 ! is a trident. Without it the screen goes and al,#0xfd ! blurred ... jmp clrb2 !setb2: or al,#0x02 !clrb2: out dx,al and ah,#0x0f cmp ah,#0x02 jne notridev2tri: lea si,dsctrident lea di,motrident lea cx,selmod jmp cxnotrid: mov dx,#0x3cd ! Check Tseng 'clues' in al,dx ! Could things be this simple ! :-) mov bl,al mov al,#0x55 out dx,al in al,dx mov ah,al mov al,bl out dx,al cmp ah,#0x55 jne notsen lea si,dsctseng lea di,motseng lea cx,selmod jmp cxnotsen: mov dx,#0x3cc ! Check Video7 'clues' in al,dx mov dx,#0x3b4 and al,#0x01 jz even7 mov dx,#0x3d4even7: mov al,#0x0c out dx,al inc dx in al,dx mov bl,al mov al,#0x55 out dx,al in al,dx dec dx mov al,#0x1f out dx,al inc dx in al,dx mov bh,al dec dx mov al,#0x0c out dx,al inc dx mov al,bl out dx,al mov al,#0x55 xor al,#0xea cmp al,bh jne novid7 lea si,dscvideo7 lea di,movideo7selmod: push si lea si,msg2 call prtstr xor cx,cx mov cl,(di) pop si push si push cxtbl: pop bx push bx mov al,bl sub al,cl call dprnt call spcing lodsw xchg al,ah call dprnt xchg ah,al push ax mov al,#0x78 call prnt1 pop ax call dprnt call docr loop tbl pop cx call docr lea si,msg3 call prtstr pop si add cl,#0x80nonum: in al,#0x60 ! Quick and dirty... cmp al,#0x82 jb nonum cmp al,#0x8b je zero cmp al,cl ja nonum jmp nozerozero: sub al,#0x0anozero: sub al,#0x80 dec al xor ah,ah add di,ax inc di push ax mov al,(di) int 0x10 pop ax shl ax,#1 add si,ax lodsw pop ds retnovid7: pop ds ! Here could be code to support standard 80x50,80x30 mov ax,#0x5019 ret! Routine that 'tabs' to next col.spcing: mov al,#0x2e call prnt1 mov al,#0x20 call prnt1 mov al,#0x20 call prnt1 mov al,#0x20 call prnt1 mov al,#0x20 call prnt1 ret ! Routine to print asciiz-string at DS:SIprtstr: lodsb and al,al jz fin call prnt1 jmp prtstrfin: ret! Routine to print a decimal value on screen, the value to be! printed is put in al (i.e 0-255). dprnt: push ax push cx mov ah,#0x00 mov cl,#0x0a idiv cl cmp al,#0x09 jbe lt100 call dprnt jmp skip10lt100: add al,#0x30 call prnt1skip10: mov al,ah add al,#0x30 call prnt1 pop cx pop ax ret! Part of above routine, this one just prints ascii alprnt1: push ax push cx mov bh,#0x00 mov cx,#0x01 mov ah,#0x0e int 0x10 pop cx pop ax ret! Prints <CR> + <LF>docr: push ax push cx mov bh,#0x00 mov ah,#0x0e mov al,#0x0a mov cx,#0x01 int 0x10 mov al,#0x0d int 0x10 pop cx 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 = 0X9xxxxmsg1: .ascii "Press <RETURN> to see SVGA-modes available or any other key to continue." db 0x0d, 0x0a, 0x0a, 0x00msg2: .ascii "Mode: COLSxROWS:" db 0x0d, 0x0a, 0x0a, 0x00msg3: .ascii "Choose mode by pressing the corresponding number." db 0x0d, 0x0a, 0x00idati: .ascii "761295520"idcandt: .byte 0xa5idgenoa: .byte 0x77, 0x00, 0x66, 0x99idparadise: .ascii "VGA="! Manufacturer: Numofmodes: Mode:moati: .byte 0x02, 0x23, 0x33 moahead: .byte 0x05, 0x22, 0x23, 0x24, 0x2f, 0x34mocandt: .byte 0x02, 0x60, 0x61mocirrus: .byte 0x04, 0x1f, 0x20, 0x22, 0x31moeverex: .byte 0x0a, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40mogenoa: .byte 0x0a, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78moparadise: .byte 0x02, 0x55, 0x54motrident: .byte 0x07, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5amotseng: .byte 0x05, 0x26, 0x2a, 0x23, 0x24, 0x22movideo7: .byte 0x06, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45! msb = Cols lsb = Rows:dscati: .word 0x8419, 0x842cdscahead: .word 0x842c, 0x8419, 0x841c, 0xa032, 0x5042dsccandt: .word 0x8419, 0x8432dsccirrus: .word 0x8419, 0x842c, 0x841e, 0x6425dsceverex: .word 0x5022, 0x503c, 0x642b, 0x644b, 0x8419, 0x842c, 0x501e, 0x641b, 0xa040, 0x841edscgenoa: .word 0x5020, 0x642a, 0x8419, 0x841d, 0x8420, 0x842c, 0x843c, 0x503c, 0x5042, 0x644bdscparadise: .word 0x8419, 0x842bdsctrident: .word 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843cdsctseng: .word 0x503c, 0x6428, 0x8419, 0x841c, 0x842cdscvideo7: .word 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c.textendtext:.dataenddata:.bssendbss:
当setup执行后,system模块被移动到0x0000开始处,而从0x90000开始存放了内核会使用的系统基本参数。
此时临时全局描述表中有三个描述符:第一个是NULL不使用,另外两个是代码段描述符和数据段描述符,他们都指向系统模块的起始处,0x0000,最后一句jmpi 0,8 会跳转到system模块的开始部分,也就是head.s 继续执行下去;
0 0
- linux-0.12/boot/setup.S`
- Linux/boot/setup.S
- /linux/boot/setup.s
- Linux 0.11/boot/setup.s
- Linux-setup.S
- linux-0.12/boot/head.s
- linux-0.12/boot/bootsect.S源代码阅读
- Linux 内核解读之Boot-- -setup
- Linux/boot/bootsect.S
- Linux/boot/head.S
- linux boot.s
- /linux/boot/bootsect.s
- linux-boot-arch_x86_kernel_head_32.S
- 浅析Linux源码:bootsect.s,setup.s,head.s
- linux 0.11 内核学习 -- setup.s
- Linux 1.0 Setup.S 学习日记
- linux kernel Setup.S代码完全注释
- linux 0.11 内核学习 -- setup.s
- C# word 操作页脚书签
- HDOJ 2578 Dating with girls(1)
- 升级python之后,yum下载东西时出现File "/usr/bin/yum", line 30
- What is Docker and why is it so darn popular?
- 下一轮WiFi革命来临:详解高通MU-MIMO技术(Multi-User Multiple-Input Multiple-Output多用户多入多出技术)
- linux-0.12/boot/setup.S`
- 安卓加载外部数据库
- 返回类的内部数据带来的问题
- TencentApiInterfaceDelegate 是这个找不到的原因
- 唯品会峰值系统架构演变
- 冒泡排序
- JSON和XML:不可同日而语
- 带引用计数智能指针
- 计数排序Counting sort