Linux-0.11学习总结——引导启动程序部分
来源:互联网 发布:cms二次开发网站建设 编辑:程序博客网 时间:2024/05/22 08:22
Linux-0.11学习总结——引导启动程序部分
1. BIOS启动
Intel设计CPU开机加电即进入16位的实模式下运行,CS的值预设为0xFFFF,IP的值预设为0x0000,这样CS:IP指向了0xFFFF0的地址位置。BIOS程序地址只有8KB,范围为0xFE000~0xFFFFF。
BIOS程序主要实现了以下功能:
a) 构建中断向量表(0x00000~0x003FF)1KB内存空间;
b) BIOS数据区(0x00400~0x004FF)256字节
c) 在大约56KB以后的位置(0x0E2CE)构建中断向量服务程序(8KB)
其中,中断向量表中有256个中断向量,每个中断向量占4个字节,前两个字节为CS,后两个字节为IP。注意,此时的中断与后面保护模式下的中断不一样。
最后,BIOS程序通过int 0x19中断将软驱中第一扇区(512B)程序bootsect内容拷贝至0x07C00处。
2. Bootsect引导
在内存0x07C00处保存的bootsect程序主要完成的功能有三点:1将自身程序复制到0x90000;2加载软驱4个扇区内容setup到0x90200处;3加载软驱240个扇区system模块到0x10000(此时时间较长,故需要在屏幕上显示:Loading System…)
该部分有一个地方非常值得我学习:
jmpi go, INITSEGgo: mov ax, cs…
这两行代码虽然简短,但非常精妙。Bootsect代码是在一边执行的过程中一边复制到0x90000,增加go一个偏移,使得跳转之后的程序可以在新的位置接着继续往下执行,而不是进入了一个不断复制的死循环。
Bootsect借助BIOS中断int 0x13,将setup.s与system模块分别加载到内存0x90200与0x00000中。最后,程序通过jmpi 0, SETUPSEG完成跳转。
3. Setup程序
该模块程序开始提取内核运行所需要的机器系统数据加载到0x90000~0x901FC位置,覆盖了原来的bootsect部分,这对后面的main函数执行发挥重要的作用!
接下来,setup将system模块的程序从0x10000复制到0x00000位置。然后再设置中断描述符表与全局描述符表。具体代码如下:
lidt [idt_48] ;load idt with 0,0lgdt [gdt_48] ; load gdt with whateverappropriate…gdt:dw 0,0,0,0 ; dummy dw 0x07FF ; 8Mb - limit=2047 (2048*4096=8Mb)dw 0x0000 ; base address=0dw 0x9A00 ; code read/execdw 0x00C0 ; granularity=4096, 386 DATA_DESCRIPTOR:dw 0x07FF ; 8Mb - limit=2047 (2048*4096=8Mb)dw 0x0000 ; base address=0dw 0x9200 ; data read/writedw 0x00C0 ; granularity=4096, 386 idt_48:dw 0 ; idt limit=0dw 0,0 ; idt base=0L gdt_48:dw 0x800 ; gdt limit=2048, 256 GDTentriesdw 512+gdt,0x9 ; gdt base = 0X9xxxx
仔细阅读该部分代码,可以很好地理解Intel对中断描述符与全局描述符的数据结构控制。首先,我们要知道IDT共占六个字节,前两个字节为段长度,后四个字节为段基地址;GDT共占八个字节,两个字节为段限长,四个字节为段基地址,其他分别为特权级、段读写权等,如下图:
全局描述符表指向的是可共享的全局段描述符,可以为数据段描述符,也可以为系统段描述符。总共有256个GDT,共256*8=2048个长度,故上述代码0x800代表的就是段限长。而gdt定义的第一个段描述符为0,0,0,0;第二个为0x00C09200000007FF代入上图的描述符即可换算出段基址、段限长等信息。
mov ax,0x0001 ;protected mode (PE) bitlmsw ax ;This is it;jmpi 0, 8 ;jmp offset 0 of segment 8 (cs)
lmsw是将0x0001赋值给CR0,其中控制寄存器CR0的最低位PE置高,设定处理器的工作方式为保护模式。Jmpi一句,0为段内便宜,8为保护模式下的段选择符,即1000,低两位为特权级0,第三位0为GDT,若为1即LDT,1代表选择GDT中的第一项,即上述所述的0x00C09200000007FF,可以看出段基址为0,故程序在此跳转到0x00000处执行head.s的程序代码。
4. head.s程序执行
与前面不同的是,从head.s开始程序的汇编变成了AT&T汇编,而之前的汇编均为intel汇编。其中system模块(共120KB,240个扇区)包括head.s的25KB+184B以及剩下的main函数部分。Head程序主要完成的功能在于分页机制以及打开CR0的最高位PG。
最值得一提的是head.s程序最后对main函数的调用。由于这个main函数是操作系统的,调用后没有返回,此处Linux采用的一种巧妙的方法是利用RET调用main函数。
after_page_tables: pushl $0 #These are the parameters to main :-) pushl $0 pushl $0 pushl $L6 #return address for main, if it decides to. pushl $__main jmp setup_paging setup_paging: movl $1024*5,%ecx /* 5 pages - pg_dir+4 page tables */ xorl %eax,%eax xorl %edi,%edi /* pg_dir is at 0x000 */ cld;rep;stosl movl $pg0+7,_pg_dir /* set present bit/user r/w */ movl $pg1+7,_pg_dir+4 /* --------- " " --------- */ movl $pg2+7,_pg_dir+8 /* --------- " " --------- */ movl $pg3+7,_pg_dir+12 /* --------- " " --------- */ movl $pg3+4092,%edi movl $0xfff007,%eax /* 16Mb - 4096 + 7 (r/w user,p) */ std1: stosl /*fill pages backwards - more efficient :-) */ subl $0x1000,%eax jge 1b xorl %eax,%eax /* pg_dir is at 0x0000 */ movl %eax,%cr3 /* cr3 - page directory start */ movl %cr0,%eax orl $0x80000000,%eax movl %eax,%cr0 /* set paging (PG) bit */ ret /*this also flushes prefetch-queue */
可以看出在after_page_tables中事先将main函数的入口地址eip手动地压到堆栈中,当下次进行RET返回时,程序将返回该指针地址到eip,从而实现了main函数的跳转。
- Linux-0.11学习总结——引导启动程序部分
- linux启动引导程序配置文件
- Linux的引导启动程序
- linux启动引导程序配置文件
- linux启动引导程序配置文件
- linux启动引导程序配置文件
- linux内核完全注释---学习札记--引导启动程序boot
- 学习 Linux,101: 引导程序
- Linux 引导启动程序(boot)
- linux内核--引导启动程序(boot)
- Linux 引导启动程序(boot)
- Linux 引导启动程序(boot)
- 【Linux】启动引导程序--grub及其配置文件
- [Linux内核完全剖析]第六章 引导启动程序(boot)总结
- Linux内核学习篇一:引导启动
- Linux系统程序启动引导过程详细剖析
- linux启动引导程序lilo与grub区别
- Linux的启动和关机的流程、引导加载程序
- 织梦CMS实现软件及分类信息采集的方法
- 创建自定义控件3-可交互性
- 创建自定义控件4-优化
- 华为信息机开发
- 关于字节对齐和继承的关系
- Linux-0.11学习总结——引导启动程序部分
- linux删除netbeans
- C++知识点
- zju-Gift?!-dfs
- OGG-01028:Object with object number 124750 is compressed. Table compression is not supported.
- Hadoop安全模式的理解
- C语言编译全过程
- Uva 10222 - Decode the Mad man
- EXP中参数compress=y是否导致imp时initial值的变化