【Linux内核】计算机从加电自启到加载内核

总结:主板上电->BIOS->引导程序->内核。

详述:
我们一打开电脑,首先通电,主板上电,向CPU的reset引脚发送电信号,设置cs:ip寄存器,该寄存器内容指向0xffff0(该位置在1M地址尾部)。
在0xffff0处,是一条ljmp长跳转指令,跳转到BIOS的起始位置。

为什么先跳转到0xffff0处?由于不同的BIOS具有不同的长度,准确定位到 BIOS 的起始地址是很困难的。因此规定在0xffff0处放一条跳转指令,跳转到BIOS的起始处。

BIOS主要做了一些初始化的工作,包括:

  • 加电自检,查看设备是否正常工作;
  • 创建中断描述符表;
  • 搜索引导程序(bootloader)并将其从磁盘读入内存

对于xv6来说,BIOS从磁盘起始扇区(0号扇区)加载512字节到物理地址0x7c00处,随后BIOS会跳转到该地址,从而进入bootloader的控制。这里bootloader是如何编译得到的?是由文件编译链接后得到的。为什么其长度正好就是512B,最后两个字节正好就是0x55aa呢?这也是由文件确定的,该文件由perl语言编写而成。0x55aa是魔数,最后两个字节是0x55aa的扇区会被认为是bootloader所在扇区。

接下来控制权交给bootloader,干了四件事:

  • 关中断,在初始化阶段,禁用中断可以确保在初始化完成之前不会被其他中断打断。
  • 打开A20地址线(有三种方式打开,linux三种都实现且打开完均有检验,xv6属于简单版本,只用了第一种方法也就是8042键盘控制法,简单来说就是往键盘的两个端口写数据,数据写完了,A20地址线也就打开了,8042 控制器负责接收来自计算机键盘的按键信息);
  • 设置GDTR并开启保护模式。将 48位 的数据加载到GDTR中,低16位是GDT的界限值,高32位是GDT的基地址。这 48位 的数据是我们设置好的。通过将CR0寄存器的第0位设为1,将cpu从实模式切换到保护模式。GDT是全局描述符表,GDTR是全局描述符表寄存器。在该文件中有专门的符号描述GDT,包含三个段:空段,代码段,数据段,并设置后两个段的段基址为0,段大小为4G。
  • 加载内核代码。先从1号扇区开始读取4KB一页的内容到指定物理地址0x10000处,这包含了ELF header和Program header table。从ELF头可以获取程序头表起始位置,程序表项个数。循环遍历程序头表项,根据 表项属性 将内核数据依次从磁盘加载到内存。将内核文件从磁盘全部读取到内存后,跳转到ELFHDR->e_entry指向的指令处,即跳转到内核代码。

linux下二进制可执行文件有着严格的格式,这个格式就叫做ELF,全称Executeable and Linkable> Format,可执行可链接格式。
内核其实就是一个可执行程序,格式是ELF。它被固定的放在bootloader所在扇区的后一个扇区,也就是1号扇区。

好啦,至此这一套流程简单讲述完毕。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值