linux新打开界面置顶,[置顶] Linux启动过程详解

启动linux kernel过程:

PC/AT机内存使用区域图:

|-----------------------------------------------------| 0xffffffff(=4GB)

|           jmp ROM_BIOS_LOCACTION

|-----------------------------------------------------| 0xfffffff0(=4GB-16B)

|                   ROM BIOS                          |

|-----------------------------------------------------| 0xfffeffff(=4GB - 64KB)

|

|-----------------------------------------------------| 16MB

|

|-----------------------------------------------------| 0x100000(=1MB)

|                 ROM BIOS Map                        |

|-----------------------------------------------------| 0xf0000

|                 Other BIOS Map                      |

|-----------------------------------------------------| 0xe0000

|                Other Card ROM BIOS                  |

|-----------------------------------------------------| 0xc7fff

|                    VGA ROM BIOS                     |

|-----------------------------------------------------| 0xc0000(=768KB)

|                  Video buffer                       |

|-----------------------------------------------------| 0xa0000(=640KB)(=640 * 1024B)

|

|-----------------------------------------------------| 0x00500

|                   BIOS  Data                        |

|-----------------------------------------------------| 0x00400

|                Interrupt Vector                     |

|-----------------------------------------------------| 0x00000

Note!!!

1) 为保持计算机在软件上的兼容,PC/AT在1MB以下物理内存使用分配上依然与8086兼容,因为

8086只有20根地址线,只能寻址1MB,只是原来系统ROM中BIOS一直处于CPU所能寻址的内存最

高端位置处,而BIOS原来所在位置(指BIOS在8086机器所能寻址的位置)被用作现在机器BIOS的

Shadow区域,即:把BIOS复制到此位置处.

2) 除了0xA0000~0xFFFFF(total=384KB): 用于I/O设备

0xfffe0000~0xffffffff(total=128KB): 用于BIOS

其余部分都可以作为系统内存

1.当计算机系统上电或者按下复位按钮时:

CPU: cs = 0xF000,ip=0xFFF0, 故,段基地址=0xFFFF0000,段长度=64KB,CPU代码指针指向

0xFFFFFFF0,即:4GB空间最后一个64KB的最后一个16字节处,这里存放一条跳转指令,主机将

该跳转指令安排为BIOS的初始化程序的入口地址.

Note!!!(author: bogdan)

Bochs在BIOS程序的第一条指令处中断

[0xfffffff0]f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0

查看CS寄存器的值

cs:s=0xf000, dl=0x0000ffff, dh=0xff0093ff, valid=1

查看ip的值:

rip: 0x00000000:0000fff0

intel处理器,实模式下地址的计算为"段地址*16+偏移地址"即是f000*10+fff0=ffff0 即物理地址为[0x000ffff0];那么为什么会是[0xfffffff0]呢?

解释:

这时因为intel 286后,实模式下地址的计算根本就不是"段地址*16+偏移地址"

而是采用跟保护模式一样的地址计算方式,即采用描述符。也就是说,实模式下

段寄存器的缓冲区也是有用的,段寄存器的缓冲区是“不可见的”,它有8个字节。

cs:s=0xf000, dl=0x0000ffff, dh=0xff0093ff, valid=1,其中dl,dh就是它的缓冲寄存器。

段寄存器缓冲区的值就是描述符的值,我们知道,当寄存器的值不变时(valid=1,描述符有效,

这时,段寄存器的值无关紧要,是什么值应该都可以)是从段寄存器的缓冲区中取基地址的,

从dl=0x0000ffff, dh=0xff0093ff(描述符), 可以看出,段界限=0ffff,基地址=ffff0000,

G=1(段界限粒度为字节,段大小限制为64k),d=0,avl=0,P=1(段已在内存中),DPL=0(ring0,特权级为0),

s=1(存储段描述符),type=3(这里为什么不是大于等于8,我就不清楚了)所以物理地址是ffff0000+0000fff0=fffffff0,

即第一条指令的地址为[0xfffffff0]。接下来,实模式下,当段寄存器的地址发生变化的时候,就会把段寄存器的值左移4位,

放入段寄存器的缓冲器中的基地址部分,这应该是实模式转移指令做的事情。这样,在实模式下看起来,地址的计算方式就是"段地址*16+偏移地址"。

intel 为什么要这样做呢?完全是为了向上兼容处理器惹的祸!我们知道实模式下的地址都是物理地址,我们的内存根本就不能达到[0xfffffff0],

那么这个地址在哪里呢?其实,cpu启动的时候,这个地址应该是采取某种机制把它映射到rom中的(bios),在rom中执行到适当的时候,

会rombois拷贝到内存的1m后64k,并采用某种机制切换到内存中执行,以加快启动的速度。

基于这样的地址计算方式,其实在实模式下,完全可以访问到大于1M的空间,

这样做:合适地初始化各个描述符,做好必要的工作,暂时切换到保护模式,注意要开启A20地址线,然后再切换回实模式,

不要关闭a20,这样地址应该就不会回滚了。注意,进入保护模式不要开启分页,或者开启分页后保证线性地址是和物理地址一样的,

为了防止找不到你的指令,回保护模式的时候也不要改变段寄存器的值,因为改变段寄存器的值就改变段寄存器的缓冲寄存器的值了,

这样就访问不到大于1M的内存了,当然,访问不存在的地址可能会出现问题。

2.BIOS初始化过程包含两部分工作: 系统加电自检和系统自举(OS的装入和引导)

1)检测电脑系统中的内存,显卡等关键设备是否能够正常工作.

2)查找显卡的BIOS,然后调用显卡BIOS的初始化代码,用它完成显卡的初始化工作.

3)查找其他设备的BIOS程序,找到之后同样要调用这些BIOS的内部初始化代码来初始化设备。

4)显示BIOS自己的启动代码.

5)检测CPU的类型和工作频率,并将检测结果显示在屏幕上。

6)开始检测系统中安装的一些标准硬件设备(硬盘, CD-ROM等)

7)标准设备检测完成后开始检测一些即插即用设备

Note!!!

上述步骤是在打开电源开关或按Reset按钮进行冷启动时所要完成的各种初始化工作,如果

按Ctrl+Alt+Del键进行热启动时直接从第三步开始,同时会跳过第五步

8)BIOS在执行了一系列硬件检测和初始化工作之后,就会把与原来PC机兼容的64KB BIOS代码和

数据复制到低端1MB末端64KB处,然后跳转到这个地方并且让CPU进入真正的实模式模式工作.

9)加电自检完成后,按照指定的启动顺序从软盘,硬盘和光驱中寻找启动设备。

Note!!

若硬盘是启动设备:即硬盘的第一个扇区(0磁头,0磁道,1扇区),硬盘最开始的512B,其最后两个字节是0x55AA

这是引导扇区的标志,512个字节不能多一个字节也不能少一个字节.

10)找到启动设备后,将启动设备上的512个字节的OS引导程序加载到内存0x7c00处,并跳转到这个地方继续

执行引导操作.

3.到此开始执行Linux的引导程序boot

Path: boot/bootsect.s.

Func: 其被BIOS读入到内存物理地址0x7c00(31KB)处,当它被执行时就会吧自己移动到内存

物理地址0x90000(576KB)处,并把启动设备后2KB(= 4 sector)字节代码(boot/setup.s)读入到内存0x90200出,而

kernel的其他部分(system模块)则被读入到内存地址0x10000(64KB)开始处

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值