Intel386与Linux0.11的关联

386主推保护模式与多任务:
保护模式,不仅是采用分段与分页的内存区域的保护;还有对特殊操作权限的保护,即将操作分等级进行隔离保护;
多任务,则通过硬件进行现场的切换(保存与还原)。
在读Linux0.11中深切感受到操作系统底层实现与芯片的关联度,下面一一道来,
0.11版本,还没有实现对每个进程或任务的内存平坦到4GB虚拟空间,即每个任务一个独立的页目录表,而是64个任务共用一个页目录表。

1、分段机制:
分段机制由如下构件完成:GDTR、LDTR、GDT、LDT、cs、ds、es、fs
GDTR负责GDT表的索引,LTDR负责LDT表的索引。在0.11中只有一个全局的GDT,而每个任务(进程)有自己的LDT。
GDT中有两个项(数据与代码段)用来为内核态执行流提供分段服务,然后每个任务(进程)在GDT有两个项:LDT描述子与TSS描述子。
其中内核态的这两个GDT项可以理解成内核执行流自己的"LDT"项,由CS或DS找到它们其中一个,然后与EIP一起生成线性地址。
其中LDT描述子,存放任务(进程)自己LDT的基址与访问保护信息
其中每个任务(进程)的LDT有两个有效项:代码段与数据段描述符项,内含有段基址。完成 线性地址=相应段基址+EIP

2、分页机制:
分页机制由如下构件完成:CR2、CR3、页表目录、页表
其中CR2计录发生缺页或页保护出错时的线性地址,CR3则作为当前任务(进程)的页表目录基址
页表目录可索引1024个页表,页表可索引1024个页
分页机制的cpu支持主要在线性地址到物理地址的映射上,即MMU完成的工作。
再有就是缺页中断与页保护出错异常的触发支持

3、多任务:
多任务机制由如下构件完成:GDT、TSS、TR
在分段机制中说到的TSS描述子,其存放各个任务(进程)的TSS基址,TSS就是那个实现多任务切换时的快照存放地(各种寄存器)
其中TR0寄存器存放当前任务(进程)的TSS基址,也就是GDT中的TSS描述子中的TSS基址。(用硬件换时间呗)
当然多任务切换并不是仅仅切换一下CPU里那几个寄存器那么简单,由于不同任务其代码段、数据段、运行时栈及页目录都不同,那么在任务切换时,同样需要CPU对上述构件进行切换的硬件支撑。
0.11通过ljmp一个TSS描述子,来实现切换到该描述子对应的任务(进程)。当然在这个切换中CPU可干了不少事:
1、保存现在的CPU状态到当前任务的TSS中(TR)
2、结合GDT,通过新任务的TSS获取到新任务的CPU快照,dump到CPU中,更新TR。完成内核态与用户态的运行时栈的切换(SS0:ESP0,SS1:ESP1),页目录切换(CR3)
3、通过TSS中的ldt找到GDT中ldt选择子,更新LDTR。完成代码段与数据段的切换

4、系统调用及中断处理保护:
系统调用及中断处理保护由如下构件完成:IDT、GDT、CS、ES、FS
IDT为中断描述符表,其中存放类似于实模式中的中断向量(记录中断序号对应的中断处理程序)。
386系列的保护模式除了对每个任务的内在区域进行分隔保护外,还有一点就是对操作系统的行为集提供硬件级的分隔保护。在0.11中,就是将系统调用与中断处理定义为0特权级,进程的用户级操作定义为3特权级,其中前者简称内核态、后者简称用户态。
当然,CPU只有一个,分离也就意味需要通过一个渠道来转换CPU的特权使用状态。0.11通过386的中断门与陷阱门完成了用户态到内核态的。下面为系统调用中断过程,其它类型中断过程相同。
通过“Int 80”指令,即触发一个系统调用中断,然后CPU根据eax传入的中断号到IDT中寻找到对应的中断描述符,内含有代码段选择子、中断处理入口等信息。
这之后386完成了如下工作:
1、将中断前的SS、ESP、EFLAGS、CS、EIP压入内核态栈
2、将中断描述符中的代码段选择子加载到CS中
3、保护性检查,主要比较中断描述符与CS中的请求级别
3、跳转到中断处理入口
在完成中断处理后,需要手工使用iret返回到中断前的状态,iret指令完成如下动作:
将之前压入栈中的寄存器弹出并更新相应寄存器

Intel386与Linux0.11的关联》上有2条评论

  1. yangxiaowei 文章作者

    可以看出单机的指令控制,是靠严格的芯片设计和指令集设计来实现容错的,但在分布式体统中,没有也不可能有如此紧凑严密的硬件机制来保证控制指令准确无误地送到指定位置或不丢失,因此就需要容错算法来辅助完成分布式系统中的各种指令交换与传递

发表评论