Linux0.11 源码阅读笔记
一,前期的准备
1,bootsect.s
通过阅读Makefile和build.c可知,bootsect.s 编译后的bootsect 是整个系统的第一段程序,它占用软盘的前512字节。
question: 系统为什么认为软盘是一个启动盘,并从bootsect开始执行?
ans: 先来说说系统为什么它被认为是启动盘?考虑一个极端情况,使用命令dd if='/dev/zero' of='floppy.img bs=512 count=1
制作一个软盘镜像(所有内容均为0),使用Bochs启动。此时会提示它不是启动盘。
实际上,计算机判断启动盘的方式很简单:使用魔数,第510和511字节(最后两字节)为 ** 55aa 。
question:如何保证目标文件大小是512字节?
ans:在汇编程序中使用 .org ** 指令。
所以,为了保证软盘是启动盘,在bootsect.s 中使用了这样的代码:
.org 508 root_dev: .word ROOT_DEV boot_flag: .word 0xAA55
那么,如果要如何自己制作一个启动盘呢?知道了魔数的概念后,很容易写一个C语言程序制作一个启动盘(只是Bochs不再提示没有启动盘了)。在Linux中,有一些比较方便的工具可以完成这个任务:使用刚才提到的dd制作一个镜像,在使用hexedit工具把魔数改好就可以了!
___
接下来,具体看看bootsect的程序。
从 _start 开始,这里是程序入口。第一个关键动作是:rep movw
,其中,rep的作用是执行下面这个指令cx次,movw是复制一个字(两个字节)ds:si处内容到es:di处。再看看前面几行对寄存器的赋值,容易理解,这段代码就是:将0x7c00处代码复制512字节到0x9c00处。
接下来,使用Bios中断int 0x13
从软盘读取setup模块和system模块,其中,读取Sysetm模块时,由于该模块比较大,所以同时容int 0x10
在屏幕打印提示内。当一切准备就绪,一行jmpi 0,SETUPSEG
跳转到Setup模块,至此,完成自己的使命。
总结一下,bootsect.s有以下几行关键代码:rep movw
,int 0x13
,int 0x10
,jmpi 0,SETUPLEN
,.org 508
,.word 0xAA55
,分别完成了这样几个任务 : 复制自身到0x9c00,读取Setup和System模块,跳转到Setup,保证启动区大小,插入魔数制成启动盘。