-
Notifications
You must be signed in to change notification settings - Fork 0
aboutos
##操作系统知识框架
- 启动过程
- 函数调用过程
- gdt
- 中断
- 内存和页机制
- 线程
启动过程,网上资料比较多了,大框架也有了,我就讲讲我之前不知道的几个问题,第一个是地址的计算,计算机上电之后执行的第一条命令是由 cs:ip 给出的,而这两个寄存器被初始化为FFFFF:0,按照段寻址的访址的方式得出线性地址在 FFFFF0 . 然后BIOS进行硬件自检,然后BIOS加载找到的第一个扇区512字节,放进内存 0x7c00 中,跳转该处. 512字节的前476字节被我们称为 bootloader 承担加载内核的功能,所以需要有识别功能,正常来讲应该知道文件系统和内核文件的格式.这样才知道硬盘的何处加载,以及加载到何处,和接下来跳到哪里去执行内核. bootloader 还要需要切换到保护模式,这就需要设置好 gdt(全局地址描述表)
gdt 是 Global Descriptor Table 的简称,用来处理保护模式下的寻址. 保护模式之所以能够实现就是因为迁移到了这种寻址方式,实模式(8086那种)是直接通过 cs 和 ip 来寻址,没有办法限制 cs 的值,也就没有办法限制一个程序访问的地址. 而保护模式就不一样了, 段寄存的值不是直接的地址,而是一个描述项的索引,描述项不仅可以给出地址,他还可以给出描述信息,规定谁可以用这段内存,cpu 在通过段寄存拿到描述信息之后,通过硬件比较描述信息,然后在计算访问内存,这就从根本上为多个程序同是运行提供了保障. 但是在操作系统的实现上, linux 绕过了这种机制(通过设置 gdt 为平坦模式,既只有一个段),改而通过页机制实现内存的分配.其实作用没差多少.
中断是系统最重要的一环,同样是通过一张表 + 一个寄存器记录基地址来实现的. 从我的角度中断有 cpu 在执行过程发现中断, 硬件发出的中断, 我们自己写的软件发出的中断. 中断描述表(idt)主要就是绑定 中断号:中断处理函数, 当一个中断发生之后, cpu , 通过中断寄存器找到描述表地址,通过中断号找到处理函数地址,然后跳转到处理函数,处理函数保存好当前环境 -- 处理 -- 还原环境.
首先,这两种机制都是需要cpu和硬件MMU支持的,通过制定的格式来完成逻辑地址到物理地址的转换. 其次,所谓逻辑地址就是程序中出现的地址,比如jump far或者mov [123123], %eax,这些地址位数都是一样的,但是逻辑地址有其自身的含义,前几位是段/页,后几位是偏移.而物理地址就是内存的真是地址,该是多少就是多少,可以物理地址和内存就是一个线程映射的关系.
段机制
逻辑地址被划分成了两个部分,段号和偏移地址,通过段表段号::段基址,找到段基址之后 加上偏移地址得到物理地址.
需要说明的是,这个段机制和汇编中用cs:dx来访问内存是是两个概念.cs*16+dx
得到的地址其实是逻辑地址,要再次段机制映射来寻址找到物理地址.
页机制
页机制的计算流程和段机制有相似的地方,但是出发点是不一样的,段机制认为一个程序可以划分为多个段,从而使得内存分配不连续.而页机制根本不在乎.他是将内存划分为固定大小的页,然后映射,实现逻辑连续,实际内存不连续,减少内存碎片.
此时,逻辑地址的含义是页号(p)+偏移(o),通过页号找到帧号(f),然后算出来物理地址.整个过程就是完成(p,o) -> (f,o)的映射.
这两种机制都需要指明"映射表"的位置,即页表基址和段基址.