关于Linux 0.00的理解

boot.s:

首先,PC机上电后,80x86结构的CPU进入实模式,并从地址0xFFFF0开始执行代码,该部分代码为BIOS程序,他会从物理地址0开始初始化中断向量,此后他将引导扇区读入内存绝对地址0x7C00地址处,并跳转到这个地方,然后控制权限就移交给boot.s汇编程序,程序执行权限从start进入,jmpi指令后,会更新CS:EIP;此时CS为0x07C0,eip为0x0000;然后设置ds,ss段寄存器为cs段;

接着进入load_system段:该段中首先利用BIOS中断int 0x13(ah=0x02)进行磁盘数据读取,读取范围为0柱面,0磁头,2扇区(从1开始计数)位置开始,读取17个扇区(8K == 0x2200)到es:bx == 0x1000:0x0000,读取成功CF标志为0;

成功加载后,先关闭中断,然后将刚读取进来的数据(0x1000:0x0000区间的0x4000 byte数据)搬运到0x0000:0x0000位置;然后加载了idt表(0x0000:0x0000)和gdt表(0x7c00 + gdt:0x7FF),之后使用lmsw加载CR0机器状态字,这里设置了PE标志位,也就是切换进入保护模式;之后跳转0x0008:0x0000代码位置进行执行,需要注意的是,该位置0x0008:0x0000寻址时,是保护模式状态下的寻址,因此0x0008是一个段描述符,其基地址可以通过gdt表查到为0,也就是加载到的head程序;

head.s:

该文件需要注意的是,此时已经进入了保护模式,也就是段寄存器中存储的是段选择符,因此此处startup_32一开始就使ds、es指向0x10,该段是个数据段,段基址为0x0000;然后加载了栈地址到esp中;接着重新设置了idt和gdt并重新加载了ds、es、fd和gs段寄存器;然后设置时钟控制器:通过端口0x43对8254芯片控制寄存器进行控制,首先设置为0x36(选择通道0,先读写低字节再读写高字节,通道工作方式选择方式3,16比特二进制计数),然后设置通道0的初始计数值11930;BIOS初始设置将时钟中断的向量号设定为了8(关于向量号是在中断控制器中进行设置的),这里是直接设置保护模式下的idt中断描述符表的8号中断为时钟中断,是个中断门描述符,调用程序就是timer_interrupt子程序,然后设置了系统中断int 0x80的中断门调用system_intrerupt子程序(其余中断门都在setup_idt子程序中设置为ignore_int子程序);然后控制中断控制器允许时钟中断(由于此时还没有sli开启系统中断,因此时钟中断目前还是不能被触发);接着切换到用户模式:加载预先设置好的任务0的TSS段和LDT段,接着设置当前任务号为任务0,然后设置中断返回状态(CS:EIP,FLAGS;SS:ESP),最后使用iret切换回任务0的用户模式,任务0就是一直循环调用int 0x80中断输出A,而任务切换是在时钟中断中进行的(这里有个点,就是任务切换并不是在替换掉TSS段后,返回系统调用后进行的切换,而是在ljmp TSS段的时候就已经完成了TR寄存器与执行环境的替换,而剩余的内核程序是在又切换回来执行的)。实现程序的交替执行;

makefile:

对于这个makefile,比较有意思,他是通过dd来对boot和system进行组装,且去除了文件头,由于boot使用as86进行编译,最终他的执行文件头为32 byte,而system由gas和gld进行编译链接,对应文件的执行文件头为1K,因此会有不同的skip,另外dd system会seek掉1,该操作是为了跨过引导扇区;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值