《30天自制操作系统》笔记(06)——CPU的32位模式

news/2024/7/20 15:46:13 标签: 操作系统, 内存管理, c/c++

《30天自制操作系统》笔记(06)——CPU的32位模式

进度回顾

上一篇中实现了启用鼠标、键盘的功能。屏幕上会显示出用户按键、点击鼠标的情况。这是通过设置硬件的中断函数实现的,可以说硬件本身的设计就具有事件驱动的性质,所以软件层面上才有基于事件的消息机制。

但上一篇没有说明中断的来龙去脉,本篇就从头到尾描述一下CPU与此相关的设置问题。

Segment

32位的CPU使用32条地址线,能区分232=4G个内存地址。每个内存地址都有1Byte的内容。

分段,就是将4GB的内存分成很多块(block),每一块的起始地址都看作0来处理。有了这个功能,任何程序都可以先写上一句"ORG 0",一个应用程序就不会占用别人的内存空间,这样就可以同时运行多个程序。像这样分割出来的块,就称为(segment)。还有一种"分页"的技术,这里不讨论。

为了表示一个段,需要记录以下信息:

  • 段的起始地址
  • 段的大小
  • 段的管理属性(禁止写入,执行,系统专用等)

这些信息需要用8个字节保存。使用段的方式是和调色板神似的:DS是16位,理论上能够表示216=65536个段。但由于CPU设计上的原因,低3位不能用,因此DS只能表示213=8192个段(即第0个~第8191个)。

在16位模式下,如果写"MOV AL, [DS:EBX]",那么要计算的地址是DS*16+EBX。在32位模式下,则应该是DS表示的段(segment)的起始地址+EBX。

另外,如果写成"MOV AL, [EBX]",则汇编器认为这等同于"MOV AL, [DS:EBX]"。这一点在16位和32位模式下是一致的。

要存储8192个段,就需要占用8192*8=65536Byte=64KB的内存空间。这64KB的数据就称为GDT (Global segment Descriptor Table)即"全局段号记录表"。

将这64K的GDT整齐地排列在内存某处,再将其起始地址和有效设定个数放在CPU内被称作GDTR的48bit寄存器中,GDT的设定就完成了。

段的起始地址、大小、管理属性这些信息是按bit保存的,十分复杂,暂时不要理会。

IDT

当CPU遇到外部情况变化,或是内部发生某些错误时,会临时切换过去处理这种突发事件。这就是中断功能。键盘按键、鼠标按键、鼠标移动、除0等都会引发中断。有了中断机制,CPU就不需要一直查询这些低速设备的状态,将时间用在处理任务上。

因此,要使用鼠标键盘,就必须使用中断机制,即设置IDT

IDT(Interrupt Descriptor Table)即"中断记录表"。IDT记录了0~255的中断号与调用函数之间的对应关系。当发生了123号中断,就会调用对应的函数。其设置方式与GDT是相似的,IDT的每一项也需要8Byte保存,这8Byte里包括中断处理函数名(即C语言中的函数指针)。

另外,必须先设置GDT后设置IDT。原因不详。

PIC

PIC(Programmable Interrupt Controller)即"可编程中断控制器"。它是一个硬件芯片

PIC控制器

当键盘鼠标发生按键、移动时,PIC就会向CPU发送电信号,然后CPU要求PIC发送2个Byte来(其内容为"0xcd 0x??",实际上是机器语言的INT指令),CPU还真就把PIC送来的这2个Byte看作一条指令执行。其结果是调用IDT中对应的函数。

PIC的设定基本上都是固定死的几行代码,暂时不用理会。

进入32位模式

进入32位模式实际上很简单,按照一定的步骤将某些寄存器(CR0等)设置为特定的值就行了。也有点繁琐,暂时不理会。

操作系统程序被加载到内存中的什么地方才行?这个没有特别的规定,根据自己的偏好分给OS一些内存空间就行了。不过有些内存空间放着BIOS等程序,而且大部分高地址的内存是要给应用程序使用的。因此OS程序的空间分配也不要太随意了。下图是HariboteOS设计的内存分布图。

HariboteOS的内存分布图

总结

本文以轻量从简的态度简单说明了OS启动时要初始化的大部分东西,即GDT、IDT、PIC、32位模式。我个人认为这些都是细节,应该进行封装。后续的内存管理、多任务才是OS设计的核心内容。

 

请查看下一篇《《30天自制操作系统》笔记(07)——内存管理

转载于:https://www.cnblogs.com/bitzhuwei/p/OS-in-30-days-06-GDT-IDT-PIC-32Mode.html


http://www.niftyadmin.cn/n/1079545.html

相关文章

深入解析C#编程中的事件开发者在线 Builder.com.cn 更新时间:2008-07-19作者: 来源:...

深入解析C#编程中的事件开发者在线 Builder.com.cn更新时间:2008-07-19作者:来源:本文关键词:精品文章C#事件一个事件是一个使对象或类可以提供公告的成员。用户可以通过提供事件句柄来为事件添加可执行代码。事件使用事件声明来声明:一个事件…

ChatGPT面世具有何意义?ChatGPT会不会取代程序员?

本篇文章给大家谈谈ChatGPT面世具有何意义一个有趣的事情,以及ChatGPT会不会取代程序员一个有趣的事情,希望对各位有所帮助,不要忘了收藏本站喔。1、chatgpt是什么?chatgpt介绍如下:ChatGPT是由人工智能研究实验室OpenAI在2022年…

vim+ctags用法

vim用法 在VIM编辑器的环境下用“:make”就可以编译程序,如果程序中有错误,就会显示出来。下列命令可以快速定位,并修改错误错误“:cl”列出错误 “:cn”让光标指向下一个错误 “:cp”让光标指向上一个错误 “:cnew”从…

在c#中实现3层架构开发者在线 Builder.com.cn 更新时间:2008-07-19作者: 来源:

在c#中实现3层架构开发者在线 Builder.com.cn更新时间:2008-07-19作者:来源:本文关键词:精品文章C#架构这篇文章讨论如何在c#中实现3层架构,使用MS Access数据库存储数据。在此,我在3层架构中实现一个小型的可复用的组…

[JAVA]在Eclipse中使用JUnit4进行单元测试-3

通过前 2 篇文章,您一定对 JUnit 有了一个基本的了解,下面我们来探讨一下JUnit4 中一些高级特性。 一、 高级 Fixture 上一篇文章中我们介绍了两个 Fixture 标注,分别是 Before 和 After ,我们来看看他们是否适合完成如下功能…

Visual C# 2005中如何产生与比较哈希值开发者在线 Builder.com.cn 更新时间:2008-07-20作者: 来源:...

Visual C# 2005中如何产生与比较哈希值开发者在线 Builder.com.cn更新时间:2008-07-20作者:来源:本文关键词:如何产生C#应用C#《Visual C# 2005文件IO与数据存取秘诀》节选条款33Visual C# 2005如何实现比较两个文件的内容是否完全相同条款55Visual C# 2…

浅谈《剑指offer》原题:不使用条件、循环语句求1+2+……+n

转载自:浅谈《剑指offer》原题:求12……n 如侵犯您的版权,请联系:windeal12qq.com 《剑指offer》上的一道原题,求12……n,要求不能使用乘除法,for、while、if、else、switch、case等关键字以及…

在dotnet下用c#编写下载器开发者在线 Builder.com.cn 更新时间:2008-07-20作者: 来源:...

在dotnet下用c#编写下载器开发者在线 Builder.com.cn更新时间:2008-07-20作者:来源:本文关键词:下载器C#实例C#System.Net.WebClient clientnew WebClient();byte[] pageclient.DownloadData("http://www.google.com");string contentSystem.T…