当前在Intel 32位CPU上实现的Hello China版本采用的是最简单的平展模式,即数据段、代码段和堆栈段相互重叠,覆盖CPU的整个线性地址空间。下面的汇编代码,定义了Hello China PC版的实现中,全局描述表(GDT)的结构。全局描述表包含了代码断、数据段和堆栈段,需要注意的是,按照Intel的定义,GDT中的第一个描述符必须为空,即全部填写为0。
这样在初始化GDT寄存器(lgdtr指令)的时候,只需要把gl_sysgdt标号装入GDT寄存器即可。结合IA32 CPU的段描述符的定义,可以看出,目前Hello China实现的各个段的属性见表5-4。
表5-4 Hello China的段属性
这样的实现实际上是一种最简单、最通用的实现,相当于忽略了IA32的段机制。在嵌入式开发中,这种情况最为常见,因此,按照这种模型实现的操作系统,可移植性要高一些。另外,这种模型符合C语言的内存管理模型,因为按照C语言的标准,一个指针应该能够寻址地址空间中的任何对象,若采用不重合的段模型则可能会出现问题。比如有下列两个函数:
在第二个函数中,dwResult的位置实际上是在堆栈段里面的,这样在调用第一个函数(Function1)的时候,传递过去的参数(&dwResult)实际上是堆栈段的一个地址(偏移)。但是在第一个函数中引用lpdwResult时,缺省情况下是按照数据段内的地址来引用的。这样若堆栈段和数据段不重叠,就不会引用到正确的位置,导致执行结果不正确,严重的话还会引起系统崩溃。之所以产生这个问题,是因为一般的编译器在传递指针参数时只传递段偏移部分,而不传递段选择子。(www.xing528.com)
在当前的实现中,Hello China没有实现进程,只实现了线程,而且实现时,所用的线程和操作系统核心代码以及数据共享同一线性空间。这样的实现方式,也是大多数嵌入式操作系统实现的方式。这种实现方式效率会比进程模型高,因为在线程切换的时候,没有必要切换段寄存器(这会引起整个CPU Cache的刷新),只需要完成堆栈、通用寄存器的切换即可。但也有一个弊端,就是保护功能稍微弱一些,一个线程的崩溃可能会导致整个系统的崩溃。
虽然没有充分采用IA32 CPU的分段机制,但目前Hello China的实现却充分采用了CPU的分页机制来完成内存保护功能。通过分页功能可以很容易地把线性地址空间内的内存地址映射到物理内存中,而且还可以实现按需内存分配功能,保证了内存资源的充分利用。
下面首先对操作系统启动后的内存布局进行描述,然后对系统中的下列两个物理内存区域进行描述:
(1)核心内存池,供操作系统和设备驱动程序使用,进一步分成4KB区(以4KB为单位进行分配)和任意尺寸区(以任何尺寸进行分配)。
(2)分页管理区:供应用程序使用,以分页的方式进行管理。
上述两个区域都是物理内存区域,在介绍上面两个区域的管理方式后,将详细介绍Hello China的虚拟内存实现方法。在当前版本中,虚拟内存的实现是建立在CPU的分页机制上的。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。