Post

引导启动程序(BOOT)

引导启动程序(BOOT)

PC的电源打开后,80x86结构的CPU自动进入实模式,并从地址0xFFFF0开始自动执行程序代码,这个地址通常是ROM-BIOS中的地址。PC机的BIOS将执行某些系统的检测,并在物理地址0处开始初始化中断向量 启动引导时内核在内存中的位置变化

bootsect.s 程序

bootsect.s是磁盘引导块程序,驻留在磁盘的第一个扇区中。在PC机加电ROM BIOS自检后,ROM BIOS会把引导扇区代码bootsect加载到内存地址0x7C00开始处并执行

  • 首先将自己移动到内存绝对地址0x90000开始处并继续执行
  • 把磁盘第2个扇区的连续4个扇区的setup模块加载到内存紧接着bootsect后面位置处(0x90200
  • 利用BIOS中断0x13取磁盘参数表中当前启动引导盘的参数,接着在屏幕上显示”Loading system…“字符串
  • 把磁盘上setup模块后面的system模块加载到内存0x10000开始的地方
  • 确定根文件系统的设备号
  • 最后长跳转到setup程序的开始处(0x90200)执行setup程序

从硬盘启动系统

  • 系统上电后,可启动硬盘的第1个扇区(主引导记录MBR)会被BIOS加载到内存0x7c00处并可开始执行

setup.s 程序

setup.s是一个操作系统加载程序,主要作用是利用ROM BIOS中断读取机器系统数据,并将这些数据保存到0x90000开始的位置(覆盖掉bootsect程序所在的地方)

  • 然后将system模块从0x10000-0x8ffff整块向下移动到内存绝对地址0x00000
  • 然后加载IDTRGDTR
  • 开启A20地址线,重新设置两个中断控制芯片8259A,将硬件中断号重新设置为0x20-0x2f
  • 最后设置CPU的控制器CR0,从而进入32位保护模式,并跳转到位于system模块最前面的head.s程序继续执行

setup执行后的内存映像

head.s 程序

内核在保护模式

  • 首先,加载各个数据段寄存器,重新设置中断描述符表idt(共256项),并使各个表项均指向一个只报错误的哑中断子程序ignore_int
  • 重新设置全局段描述符表gdt
  • 使用物理地址0与1MB开始处的字节内容相比较的方法,检测A20地址线是否已真的开启
  • 设置管理内存的分页处理机制,将页目录表放在绝对物理地址0开始处(也是本程序所处的物理内存位置,因此这段程序将被覆盖掉),紧随后面放置共可寻址16MB内存的4个页表,并分别设置它们的表项。
    • 每个表项的属性标志都被设置成0x07,表示页存在、用户可读写,保证任务0和任务1的代码和数据不仅可以在用户态下执行,而且又不能随意访问内核资源
  • 最后,利用返回指令将预先放置在堆栈中的/init/main.c程序的入口地址弹出,去运行main()程序

head执行后的内存映像

linux内核使用描述符表示意图

This post is licensed under CC BY 4.0 by the author.