006-继续编写操作系统

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fl2011sx/article/details/59627023

       上次我们完成了ipl的阶段性目标,现在主要开始着手写操作系统内核。由于在实模式下能够使用的内存实在太少,而且对硬件也而是一种浪费,因此,我们要写一个32位内核的操作系统,所以,就要先进入保护模式。但是,由于在保护模式下不能调用BIOS,因此,要在引入保护模式之前,把可能需要用到的信息保存在内存中。我们指定了一些位置来存放相对应的信息,主要是关于屏幕的信息以及键盘指示灯的信息,代码如下:

CYLS  EQU 0x0ff0
LEDS  EQU 0x0ff1
VMODE EQU 0x0ff2
SCRNX EQU 0x0ff4
SCRNY EQU 0x0ff6
VRAM  EQU 0x0ff8

	org 0xc200		; 这里的org并不是真的可以决定在内存中的加载位置(由ipl决定),而是为了让编译器可以算出正确的标签所代表的内存位置
	
	mov al, 0x13	; 320×200×8位色
	mov ah, 0x00
	int 0x10		; 0x10号中断,ah=0时为VGA显卡图形模式
	mov byte[VMODE], 8
	mov word[SCRNX], 320
	mov word[SCRNY], 200
	mov dword[VRAM], 0x000a0000
	
	mov ah, 0x02
	int 0x16		; ah=0x02时获取键盘led灯状态,保存在al中
	mov [LEDS], al

       接下来就可以向保护模式努力了,不过在此之前,还要先明白很多原理才可以继续接下来的工作。

       下面来介绍一下分段,在实模式下,段的设置其实应该是16字节为一段的,因为DS寄存器存储的数据表示段,DS:BX就会把DS的值乘上16再加上BX的值,所以DS的最小单位就是16字节,而在保护模式下,寻址空间为4GB,仅仅利用这样一个16位寄存器是无法表示出来的,所以,将内存划分为了8192个段(用到的是段寄存器的高13位,第14位为0时访问GDT,为1是访问LDT,后两位则是特权选择器),每个段有512个字节,而DS中表示的值,就对应每个段的段号,每一个段号对应一个32位的内存地址,并且还需要4字节来存储其他信息,那这样一个对应关系就需要一张表来储存,所以我们就需要8192×8B=64KB的内存空间来存储这张表,这部分数据就被称为GDT(global descriptor table),而CPU中会有一个专门的寄存器来存放GDT的地址,这个寄存器就是GDTR,CPU通过GDTR找到GDT,就可以确认当前DS中所表示段号的具体地址,再与其他实际的偏移地址相加,便可以计算出物理地址。

       下一个概念是IDT(interrupt descriptor table),和GDT类似,它是用来记录中断的,由于x86结构的CPU最多支持256种中断,因此,IDT的大小也应该是256×8B=2KB。当发生了中断时,CPU将根据IDTR的值找到IDT,然后再根据中断号找到对应的中断处理函数,执行对应的指令。

     GDTR是一个48位寄存器,给它赋值时必须从一个内存地址开始的连续6个字节给其赋值,指令是LGDT,其低16位是段上限,高32位表示GDT开始地址。在GDT中,每一个单元需要32位地址、20位段上限、12位段属性。20位上限表示页,每页是4KB,所以一共可以表示4KB×1M=4GB。段属性高4位是拓展访问权,低8位是原始访问权(286就有的)。具体的排布如下图:

IDT与其类似,以下是排布图:


        下一个概念是PIC(Programmable Interrupt Controller),即可编程中断控制器。这是用来处理中断的,CPU在高速运转中为了不使低速设备拖后腿,所以使用了中断机制,让它不用自己去持续监听,但总是需要一个设备来做这件事情,这就PIC,它原本是一个独立的芯片,后来被集成在CPU中,通常情况下CPU中会有2个PIC,每个PIC有8个控制端和一个输出端,一个PIC直接连接CPU,另外一个将输出端接入刚才PIC的2号输入口,这样CPU就可以接受15个中断消息了。IMR是中断屏蔽寄存器,这是一个8位寄存器,某位为1表示PIC对应引脚的中断被屏蔽。ICW是初始化控制数据,一共有4个,ICW1~ICW4,1和4是与主板的电器性质相关的(比如说保险丝之类的),所以一般是固定数据。ICW3与主从连接性质有关,而由于硬件线路固定,所以这里一般也是固定值。值得注意的就是ICW2,这个寄存器用来设置中断号,它会给CPU发送消息,而这部分消息会被CPU当做一个int指令来执行,所以也就间接出发了BIOS中断。0x00~0x1f这些中断被保留,作为CPU系统保护通知调用的中断,因此IRQ端口只能设置0x20~0x2f这16个中断。

       下次将讲解如何进入保护模式。

展开阅读全文

没有更多推荐了,返回首页