目录
- entry_start
- load_setup
- print_message
- load_system
- kill_motor
- root_defined
- jmpi 0,SETUPSEG
bootsect.s是操作系统安装好后,操作系统所在磁盘引导扇区中的代码。 开机时CPU处于实模式 CS=0XFFFF;IP=0X0000,先执行烧录在主板ROM中的BIOS程序, BIOS会映射到内存的0XFFFF0处。BIOS会进行硬件检测、 安装BIOS提供的中断例程到中断向量表等工作,最重要的是将磁盘中(最初使用的软盘)0磁头0磁道1扇区的 引导程序bootsect.s加载到内存的0X7C00处,然后设置CS=0X7C0;IP=0X0000,开始执行引导扇区的引导程序bootsect.s。
bootsect.s源码的大致结构如下。最复杂的是 load_system模块,我会单独列出它的流程图。
entry_start
- 功能:将加载到内存0X7C0处的引导扇区内容bootsect.s,整体移动到内存的0X90000处,目的是为了腾出更多的空间,后面的system模块会加载到内存0X10000处。
- 掌握汇编的串传送指令rep movsw、实模式段地址和偏移地址、扇区的大小是512字节就能看懂这段代码。
load_setup
- 功能:将 紧跟在磁盘引导扇区 后面的SETUP模块(4个扇区)加载到内存中,也是紧跟在移动到内存0X90000处的引导扇区(bootsect.s)之后。
- 主要就是使用了磁盘IO的中断例程int 0X13 ah=0X2 读取磁盘中扇区加载到内存指定位置。
- 加载完SETUP模块后,又调用中断例程int 0X13 ah=0X8 获取磁盘的参数,将每磁道的扇区数保存在sector中,最复杂的load_system模块需要这个数据。
print_message
- 功能:在等待计算机启动时显示信息,就好像安装windows系统的电脑开机后,看到的windows的相关logo。
- 通过中断例程 int 0X10 ah=0x13 屏幕显示服务,打印字符串。
load_system
- 功能:system模块是操作系统的核心,这段代码就是加载操作系统的核心模块。阅读这段时,深深理解了,为什么程序员宁愿自己重写,不想维护别人的代码。
- 读懂这段代码的知识点1:实模式下访存方式,内存分为多个段,每段大小为64KB。内存地址分为段地址和偏移地址,对内存写时,如果写入的内容超过了64KB,在写到偏移地址0XFFFF时,要及时对段寄存器修改,加0X1000,指向下一个64KB的边界。如果不修改段寄存器,只会破坏该段开始处写入的内容。
- 知识点2:磁盘的读写方式。现代机械硬盘由多个盘片组成,每个盘片都有一个磁头,盘片上有多个同心的磁道,每个磁道有多个扇区。硬盘所有盘片的同一半径的磁道组成一个柱面。顺序读写磁盘就是按柱面读写,读写完一个柱面再换下一个柱面。采用这个方式是为了加快磁盘IO的速度,因为磁盘读写中通过摇头臂调整磁头指向的磁道最费时,所以按所有盘片同一半径的磁道顺序读取(柱面读取)减少调整磁头臂的次数,加快了磁盘IO。
- load_system部分的代码就是围绕上面两个知识点写的,操作系统的核心模块System肯定远远超过64KB,加载时要注意判断内存段是否写满,写满就要更改段寄存器,指向下个段;通过中断例程int 0X13读磁盘时,判断磁道有没有读完,读完切换磁头到同一个柱面的下一个磁头指向磁道继续读,柱面是否读完,读完磁道加1,换到另一个柱面,从磁头0指向的磁道开始读。
下面是load_system部分的代码流程图:
kill_motor
- 功能:查deepseek得知,这段的功能是通过向端口写入参数关闭软驱。虽然写入端口的参数不是那么懂,软驱早就被淘汰了,也就没纠结。大致就是关闭软驱的功能,毕竟代码执行到此处,软盘中的操作系统都已经加载到内存了。
root_defined
- 功能:查deepseek得知,这段涉及文件系统设备的初始化选择。
- 这段代码能看懂,就是不理解。第一个不理解,就是软盘的相关的东西,软驱已经淘汰,不用在意;第二个不理解是几个16进制的数字,怎么跟设备,文件系统挂钩了?相信继续学习下去应该就懂了。
- ROOT_DEV = 0x306这参数不止在这里bootsect.s定义了,fs/super.c中同样也定义了。fs我猜测应该表示filesystem文件系统,等学习到文件系统部分应该就理解现在的疑问了。
jmpi 0,SETUPSEG
- 功能:执行到这儿,表示引导扇区的代码bootsect.s都执行完了,该执行已加载到内存的SETUP模块了,SETUP模块的段地址就是SETUPSEG = 0x9020