《自己动手编写操作系统》笔记

本文记录了学习编写操作系统的笔记,主要涉及描述符和选择子结构、GDT装载、特权级切换规则、LDT加载以及实模式到保护模式的转换。详细解析了在特权级切换中,如CPL、RPL和DPL的作用,以及如何通过调用门进行权限跳转。同时介绍了实模式跳转到保护模式的关键步骤,包括开启A20地址线和设置Cr0寄存器。
摘要由CSDN通过智能技术生成
2013-3-26
这两天在学习编写操作系统,略记于下
1.     描述符和选择子结构细节说明

                                                                                                              
描述符和选择子的结构如上,从描述符结构上看,段基址是4字节32bit,段界限是20bit,但是特别需要注意的是在属性字段中,有一位G是表示段界限的粒度的,为0表示粒度为字节,为1表示粒度为4K(2^12),也就是说段界限表示的范围可以是1M(2^20)或者4G(2^32),由此,在使用jump或者call进行跳转的时候,offset的范围也就被确定了,它不能超过1M或者4G。
由于选择子是要被放入到兼容于8086的16bit寄存器中的,所以他们都是16bit,由于描述符是8字节(2^3),那么用来存放描述符的tab,即GDT,LDT都是8字节对齐的,而且每个描述符的起始位置都是8字节对齐的,那么用来索引描述符的选择字也是8字节对齐的,由此,选择子的低三位对于索引来说就是无用的,intel把它们用做它途,TI表示是从GDT还是LDT中索引,RPL表示请求的特权级
2.     GDT装载
GDT寄存器结构是32位基地址 16位界限,由于是小端模式,所以其结构定义及装在过程如下:
Gdt     dw GdtLen – 1
     dd 0
add eax, LABEL_GDT
add [Gdt + 2], eax
lgdt [Gdt]
由于界限是16bit,每个描述符是8字节,所以至多只能有8192(2^13)个描述符
3.     特权级切换,由高到低,由低到高,一致代码段,CPL,RPL,DPL
特权级由高到低分别是0,1,2,3,
CPL:表示当前程序运行的特权级,一般情况下,CPL等于当前代码段的特权级,当程序在不同特权级跳转的时候,CPL将会被赋值为目标代码段的特权级,但是对于一致代码段比较特殊,如果目标代码段为一致代码段,那么CPL的特权级不会改变,仍然等于原来代码段的特权级
DPL:表示代码段的特权级,根据不同的段类型,DPL的限制如下:
数据段:DPL规定可以访问此段的最低特权级
TSS:DPL规定可以访问此段的最低特权级
调用门:DPL规定了当前程序可以访问此调用门的最低特权级
非一致代码段(不适用调用门访问):DPL规定了访问该段的特权级
一致代码段和通过调用门访问的非一致代码段:DPL规定了访问此段的最高优先级
总结如下:
数据段、TSS和调用门可以被相同或者更高特权级访问
一致代码段可以被相同或者更低特权级访问
非一致代码段只能被同特权级访问,在使用调用门的情况下,可以被低特权级的段访问
使用CallGate需要满足的特权级如下所示:
这里显示了代码段A通过调用门G访问段B的情况,必须满足如下的条件

也就是说,通过调用门,使我们有可能通过一个比当前段特权级低的调用门跳转到一个比当前段特权级高的段
特别需要说明的是,上面所说的都是通过call和jmp进行跳转的限制,如果目标代码段的特权级低的话,通过call和jmp是不能跳转的,但可以使用如下的方式:

如果当前处于高特权级,想跳转到低特权级,可以把目标段的ss,esp,cs,eip入栈,然后调用retf指令,这样这些值就会被依次赋值到相应的寄存器中
如果当前处于低特权级,通过调用门想跳转到高特权级,必须首先加载TSS,指定高特权级的栈,因为进行这样的长跳转,会不同特权级别栈的转移
从目前的代码中看,要在特权级0中加载TSS,原因尚不明了
4.     LDT
LDT首先也是一个描述符表,它构成一个段,这个段在GDT中有一个描述符,并且有一个相应的选择子,LDT的载入过程如下:
mov ax, SelectorLDT
lldt ax
jmp SelectorLDTCode:0
特别注意使用LDT中的选择子的时候,一定要把选择子的TI位置1,表示使用LDT
5.     实模式跳转到保护模式
关中断;保护模式下中断处理机制不同于实模式
打开A20地址线
Cr0寄存器的PE位置1
6.     保护模式跳回实模式
上述过程的反向过程
Cr0寄存器的PE位置0
关闭A20地址线
开中断
7.     调用门结构

对比门描述符和前面的代码段数据段描述符,可以看到byte5是完全相同的,cpu应该是根据此段来区分他们的类型
Jmp的代码跳转流程:
CodeInReal         
CodeInProtect          DPL0
CodeInRing32          DPL3
CodeInCallGate     DPL3
CodeInLDT          DPL0
CodeToReal

2013-3-31
第四章实际上是用来描述如何编写boot的,综述如下:
引导扇区的格式



引导扇区是0磁道0柱面的第一个扇区,即512字节的内容,它首先是一个短跳转指令,跳转到后面的引导代码中,还有一些关于读写磁盘的参数信息,结尾是两个字节,0x55,0xAA
软盘数据存放格式,最后一个图我们还可以知道扇区号在磁盘中是如何定义的,这有助于我们根据磁头号,柱面来计算柱面号,磁头号和起始扇区号,这个图的注释有点问题,BIOS所需要的起始扇区号是从1开始计数的,而我们的输入,扇区号,是从0开始计数的,所以扇区0和1在0柱面的0磁头和1磁头指定的位置
扇区2和3在1柱面的0磁头和1磁头指定的位置
以此类推

这里需要注意的是根目录区,它其中每个条目是32字节,结构如下,条目的个数是引导扇区中指定的,BPB_RootEntCnt,

这里有文件名和开始的簇号,在引导扇区中说明了每簇包含的扇区数,在FAT12中每簇包含一个扇区,簇应该是一种针对数据区的概念,因为根目录区后是数据区,数据区的第一个簇号是2,不是0或者1,这个簇号2,对应的是FAT表中的FAT表项序号
FAT12格式

FAT表使用12bit作为一个表项,来表示当前表项对应簇的下一个簇号,上图给出了他们之间的bit序列的关系,同时使用大于等于FF8作为表项链表的结束标志,FF7作为坏簇的标志。

引导过程
BIOS将引导扇区512字节的内容加载到地址0000:7C00处开始执行,从这里开始就是boot的过程,
从引导扇区的结构我们知道,它通过一个短跳转至引导代码中,引导代码在root目录区中遍历所有的32字节条目,查找指定的loader文件条目,
找到该条目后,得到该文件所在的第一个簇号,读入对应扇区的数据,然后根据FAT表查找该簇号的下一个簇号,继续读取对应扇区的内容,直至把整个文件读入内容中指定的地址处,
跳转至该地址,把控制权交给loader
Boot的工作内容总结,实际上手机上的boot的工作内容也是如此,具有统一性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值