博客URL:www.shicoder.top
大家好,终于我们到达了操作系统的装载机部分。装载机也是操作系统中最重要的部分。它采用上面的启动并启用下核。然后让我们开始!!!
在加载程序中,最重要的一点是检测内存,检测某些系统参数并在当时将其用于内核,然后我们将介绍如何在加载器中检测内存。相同,让我们看一下代码检测内存
请注意,我们在这里获得内存的方式是在BIOS中使用INT 0x15 Neutron函数0xE820。LET给出了INT 0x15下3个子功能的具体描述
内存的相关值形成一个结构:ards(地址范围描述符),总计20个字节如下
返回值如下
通过上述代码,可以在ARDS_COUNT中存在ARDS的数量,并且每个ARDS的值都放在Ards_buffer中。
进入保护模式需要三个步骤
在实际模式下,访问地址的方法是
部分地址<< 4 +偏移地址
但是,在进入保护模式后,地址线就足够了,总计32,因此不需要上述方法。地址方法是
部分选择(16 -bit):内部偏移(32-bit)
让我们来谈谈下一段。在选择部分中有16位,3-15位描述性索引(13位可以指示8,192),第二位是Ti bit,ti = 0,这表明从全局出发描述符表,ti = 1,从from表示,表示局部描述符表。0-1是特权级别的RPL(熟悉的特权级别0-3,2位数字),代码如下
上面显示了全局描述符表(GDT)。全局描述符表中的每个项目都是全局描述符。每个全局描述符都指向内存中的位置。
因此,如何描述这一记忆部分特别重要。全局描述符的结构如下。
全局描述符表有8192个项目。每个项目表示内存的全局描述符,表的0项为null。有一个特殊的寄存器GDT寄存器指向它。只要您阅读此寄存器的值,您就可以找到此表,然后您知道哪个是出价。GDT寄存器具有48位,结构如下,0-15位具有总计在16位识别GDT边界中,总共65536字节,每个全局描述符8字节,因此总共65536/8 = 8192一个
相关代码如下
我们专注于关键部分,我们将遵循另一个关键部分 -
我们之前说过,在进入保护模式之前,我们必须加载GDT才能在保护模式之后在其他地方使用它,因此请使用以下命令
然后,我们构建代码段和数据段的选择,并通过选择孩子的结构来构建它
实际上,它是在保护模式下使用较大的地址线。因此,打开A20线很简单,即,端口0x92的第一个位置1可以是:代码如下:
我们需要打开CR0寄存器的0(PE)保护启用。该方法如下
我们可以看到一个非常奇怪的JMP指令
因为我们知道在跳跃是一种真实模式之前,它可能是16位,但是跳到保护模式后,需要在32下执行它,然后尚不清楚CPU指令,并且仍然可以通过16-16分析。分析32位指令的位方法将是错误,因此使用1 JMP模式来执行
在之前的步骤之后,我们最终进入了保护模式。我们在此版本的操作系统中设置的保护模式非常简单,代码如下:
当我们编译时,我们首先编写系统。命令如下
最后,我们可以编写C语言,在撰写汇编之前,这确实很不舒服,哈哈哈。
内核的主要程序是Main.C.
请注意本系列的第二章中的0xB8000,有以下代码
0xb8000超过16位,因此在实际模式下需要使用它,并且在保护模式下有32位,因此您可以直接访问它
原始:https://juejin.cn/post/7096292749883736094