linux0.11系统启动

本文介绍了Linux 0.11内核启动过程,包括BIOS初始化硬件并加载bootsect.s,bootsect.s移动引导扇区、读取setup和system模块;setup.s读取系统参数、移动system模块、设置GDT和IDT等进入32位保护模式;head.s重新设置中断和全局描述符表、检测硬件、设置分页机制后运行main程序,还提及gdb调试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写自定义目录标题

bios

初始化硬件,加载bootsect.s,第一个磁盘的512字节

bootsect.s

bootsect.s完成的工作首先是将引导扇区从内存地址0x07C00移动到0x90000处,然后读取共占四个扇区的setup模块,显示加载系统的信息,然后将system模块读入到内存地址0x10000处

setup.s

setup.s首先读取包括光标位置,扩展内存(超过1MB大小以外的物理内存)大小,显示模式,硬盘参数等系统参数,并将这些参数写入到空间地址0x90000~0x90200这512个字节的空间中,然后将system模块从地址0x10000处移动到地址0x00000处,覆盖掉了BIOS用到的数据和中断向量表,这也说明了此后Linux系统确实不再使用BIOS提供的服务了。然后加载已经提前设置好的全局描述符表GDT到GDTR寄存器,中断描述符表IDT到IDTR寄存器,开启A20地址线,重新设置两个中断控制芯片,最后设置CPU的控制寄存器CR0(也称机器状态字),从而进入32位保护模式,并跳转到物理内存0x00000地址处执行,这里是system模块最前面的head.s程序。

setup执行后内存分布图:
系统引导及启动过程内存分布

head.s

head.s程序在被编译生成目标文件后会与内核其他程序一起被链接成system模块,位于system模块的最前面开始部分,这也就是为什么称其为头部(head)程序的原因。system模块将被放置在磁盘上setup模块之后开始的扇区中,即从磁盘上第6个扇区开始放置。一般情况下Linux 0.11内核的system模块大约有120KB左右,因此在磁盘上大约占240个扇区。
如head.s执行中的内存使用情况图所示,head.s首先重新设置中断描述符表idt,共256项,并使各个表项均指向一个只报错误的哑中断子程序ignore_int,加载idt表到idtr寄存器。然后设置全局描述符表gdt,实际上新设置的GDT表最开始的3个表项与原来在setup.s程序中设置的GDT表除了在段限长上有些区别以外(原为8MB,现为16MB),其他内容完全一样。不同的是,setup.s中设置的GDT表是临时的,只设置了3个表项,而head.s中设置的GDT表在后面一直使用,这里除了设置最开始的3个表项外,还把其他表项全部请零,加载gdt表到gdtr寄存器。接着检测A20地址线是否真的开启,以及测试PC机是否含有数字协处理器芯片(80287,80387或其他兼容芯片),并在控制寄存器CR0中设置相应的标志位。接着将main函数地址压栈,并设置管理内存的分页处理机制,将页目录表放在绝对物理地址0开始处(也是本程序所处的物理内存位置,因此这段程序将被覆盖掉),紧随后面放置共可寻址16MB内存的4个页表,并分别设置它们的表项,设置好页目录表和4个页表后,开启分页机制。最后,利用返回指令将之前预先放置在栈顶的/init/main.c程序的入口地址弹出,去运行*main()*程序。

注意:32位启动代码是从绝对地址 0x00000000 开始的,这里也是也目录将存在的地方,因此这里的启动代码将被也目录完整覆盖掉,head.s执行过程中内存分配如下:

在这里插入图片描述

寻址方式区别
实模式:
寻址方式为:

segment<<4+offset

保护模式:
段寄存器是选择子,结构如下

15                          3 2 1     0
+----------------------------+--+--+--+
|        描述符索引           |TI| RPL |		段寄存器/选择子
+----------------------------+--+--+--+
  1. RPL(Requestor’s Privilege Level),请求者特权级
  2. TI(Table Indicator),表指示器,用于指定选择符所引用的描述符表。TI=0,指定GDT表;TI=1,指定当前的LDT表
  3. 描述符索引用于选择指定描述符表中的其中一个。处理器将该索引值乘上8,并加上描述符表的基地址即可访问表中指定的段描述符。

段描述符放在描述符表(gdt)中。每一个段描述符占8个字节。
下面是代码段描述符的字节分布:

   63          54 53 52 51 50       48 47 46  44  43    40 39             32
   +-------------+--+--+--+--+--------+--+----+--+--------+----------------+
   | BaseAddress |G |B |0 |A |Segment |P | D  |S |  TYPE  | BaseAddress    | 
   |   31...24   |  |  |  |V | Limit  |  | P  |  |        |   23...16      |
   |             |  |  |  |L | 19...16|  | L  |1 | 1|C|R|A|                |
   +-------------+--+--+--+--+--------+--+----+--+--------+----------------+
   31                               17 16                                  0
   +----------------------------------+------------------------------------+
   |            BaseAddress           |                Segment             |                 
   |             15...0               |                 Limit              |
   |                                  |                 15...0             |
   +----------------------------------+------------------------------------+

段式寻址过程图
虚拟基址经过段式寻址方式转化为线性地址,转换过程如下:
在这里插入图片描述

#gdb 调试
通过 gdb 调试读取gdt 表和 idt 表在内存中的位置,可以得到相应的值
在这里插入图片描述

带中文注释可成功编译运行的Linux0.11+Bochs2.62实验环境说明 此注释以网上获得的“linux带中文注释的0.11版本”为基础,对照赵炯博士《Linux内核完全注释(0.11) 》V3.0版(http://oldlinux.org/download/clk011c-3.0.pdf)编辑而成。作为对赵博士感谢,以及对Linux初学者的回馈,特发布在优快云上。 此注释可以在http://oldlinux.org/Linux.old/bochs/提供的Linux-0.11-devel-XXXXXX实验环境下正确编译成功,使用:"make disk"命令重启Bochs虚拟机后,新编译源码直接生效,便于学习者直接阅读源码,直接进行实验。 注意事项: 1、为了使注释版与实验环境上的Linux0.11内核保持一致,达到对应文件可以互换的目的,与Linux0.11原始版本相比,加入了15个系统调用函数(参见include/Linux/sys.h第78-92行。赵博士原书没有这部分注释,我不敢班门弄斧),其它相关的文件加入了相应的定义。新加入的代码只有函数体定义,没有具体实现,对其它原始代码没有改变、没有影响。 2、键盘定义改成了美式键盘(原始代码中是芬兰键盘,会导致个别键出问题,调试的候我曾被迷糊了好久,以为自己把程序搞乱了)。 3、把网上VC版的注释统一改成了 “/* */” 格式的注释。经测试,在Linux0.11实验环境中(gcc1.40),只有标准C注释语法可以正常编译。 4、由于《Linux内核完全注释(0.11) 》原书版本更新的原因,注释中提到的图、表可能与V3.0版书中不一致。 5、由于代码中加入注释,代码行号发生变化,注释中提到的代码行号会出现不一致,建议对照3.0版查询对应内容。 6、实验方法:请先安装附带的Bochs2.62版安装包,双击Test.bxrc即可启动实验系统,执行命令:sh t,即可完成对linuxcn的编译。 7、linux目录中是此实验系统中/usr/src/linux提取出来的不含中文注释的linux0.11源码(此版本比原始的0.11版多15个系统调用函数),linuxcn是加入了中文注释的源码。 8、diskb.img是实验系统与Windows环境下进行文件交换的1.44M软盘映像,执行脚本命令"sh t"会自动从此映像中读取linux.tar、linuxcn.tar包,解包并编译,编译结果在:/usr/root/zw/linuxcn目录下。为了方便文件交换,建议使用7zip为压缩/解压缩工具(7zip可以直接生成tar包),用WinImage实现Windows环境与软件映像交换文件。 9、实验系统下 .profile中加入了几个命令,请读者注意。 10、若实验环境的启动盘被破坏,请用压缩包中的bootimage-0.11-hd覆盖对应文件即可。 11、若实验环境的要命文件系统被破坏,请用压缩包中的hdc-0.11-new.img覆盖对应文件即可。 2014-5-4 cyfx2288
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值