码迷,mamicode.com
首页 > 其他好文 > 详细

0.11之路(四):从实模式到保护模式

时间:2015-04-16 23:50:32      阅读:390      评论:0      收藏:0      [点我收藏+]

标签:

(一)关中断并将system移动到内存地址起始位置 0x00000

将CPU的标志寄存器(EFLAGS)中的中断允许标志(IF)置0。这样系统不会再响应中断,直到main函数中能够适应保护模式的中断服务体系重建完毕才会打开,那时候响应中断的服务程序将不再是BIOS提供的中断服务程序,而是系统自身提供的。
就是要完成实模式下的中断向量表和保护模式下的中断描述符表(IDT)的交接工作。借助关中断(cli)和开中断(sti)完成这个过程的创建,即在创建过程中不能去响应中断,否则没有对应的中断程序,系统会crash。

setup程序将位于 0x10000 的内核程序复制到内存地址起始位置 0x00000 处。本来0x00000这个位置存放的是由BIOS建立的中断向量表和BIOS数据区,这样它们都会被覆盖,所以在新的用于保护模式的中断服务体系建立完毕之前,操作系统不再具备响应并处理中断的能力。这就是关中断的意义。

为了建立32位操作系统,引入新的概念:中断描述附表(IDT)和全局描述符表(GDT)。


(二)打开A20,实现32位寻址

本来5个F,打开A20后,就变成了8个F,即4G。
对0.11来说,最大只能支持16MB的物理内存,但其线性地址空间已经是4GB。
实模式下CPU寻址范围为0~0xFFFFF,共1MB寻址空间,需要0~19号共20根地址线。进入保护模式后,将使用32位寻址模式,即采用32根地址线进行寻址,第21根(A20)至第32根地址线的选通控制将意味着寻址模式的切换。


(三)8259A保护模式下的重新编程

为了建立中断机制,就要知道8259A,它是可以用程序控制的中断控制器。单个8259A能管理8级向量优先级中断。

我们需要对8259A进行重新编程,因为CPU在保护模式下,int 0x00~int 0x1F 被Intel保留作为内部(不可屏蔽)中断和异常中断。如果不对8259A进行重新编程,int 0x00 ~ int 0x1F 中断将被覆盖。所以需要通过8259A编程将原来的IRQ0x00~IRQ0x0F对应的中断号重新分布,即在保护模式下,IRQ0x00~IRQ0x0F的中断号是 int 0x20~ int 0x2F。

setup程序通过下面的代码将CPU工作方式设为保护模式,将CR0寄存器第0位(PE)置1,即设定处理器工作方式为保护模式。

mov    ax, #0x0001        ! protected mode(PE) bit
lmsw   ax                 ! This is it!

lmsw: Load Machine Status Word
置处理器状态字。但是只有操作数的低4位被存入CR0,只有PE,MP,EM和TS被改写,CR0其他位不受影响。

CPU工作方式转变为保护模式后,一个重要的特征就是要根据GDT决定后续执行哪里的程序。有了GDT的引导,接下来就会跳转到head程序的开始位置。head.s开始执行。

实际上,我们所说的system程序,就是由head程序和main程序链接而成的,head在前,main紧挨着head。head程序做了个对内核程序在内存中的布局有很重大的意义的事情:创建分页机制,即在0x000000的位置创建了页目录表、页表、缓冲区、GDT、IDT。

再提一下,在实模式下,CS本身就是代码段基址,在保护模式下,CS本身不是代码段基址,而是代码段选择符。也就是说,从实模式转变为保护模式,段基址的使用方法和实模式差别非常大,要使用GDT产生段基址。

接下来要将页目录表和页表放在内存起始位置。它们被放置在从0x00000开始的内存位置。

之后就可以执行用32位编译器编译的main函数了。总之,head.s就是用来从开机时的16位实模式过渡到main函数执行需要的32位保护模式。

0.11之路(四):从实模式到保护模式

标签:

原文地址:http://blog.csdn.net/bluecloudmatrix/article/details/45042947

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!