2.2 规划物理内存格局,设置缓冲区、虚拟盘、主内存
接下来设置缓冲区、虚拟盘、主内存。主机中的运算需要CPU、内存相互配合工作才能实现,内存也是参与运算的重要部件。对内存中缓冲区、主内存的设置、规划,从根本上决定了所有进程使用内存的数量和方式,必然会影响到进程在主机中的运算速度。
具体规划如下:除内核代码和数据所占的内存空间之外,其余物理内存主要分为三部分,分别是主内存区、缓冲区和虚拟盘。主内存区是进程代码运行的空间,也包括内核管理进程的数据结构;缓冲区主要作为主机与外设进行数据交互的中转站;“虚拟盘区”是一个可选的区域,如果选择使用虚拟盘,就可以将外设上的数据先复制进虚拟盘区,然后加以使用。由于从内存中操作数据的速度远高于外设,因此这样可以提高系统执行效率。
这里,系统要对主内存中的这三种不同性质的区域,在大小、位置以及管理方式方面进行规划。
先根据内存大小对缓冲区和主内存区的位置和大小进行如图2-2所示的初步设置。
具体执行代码如下:
- //代码路径:init/main.c:
- …
- #define EXT_MEM_K (*(unsigned short *)0x90002) //从1 MB开始的扩展内存(KB)数
- …
- void main(void)
- {
- …
- memory_end= (1<<20) + (EXT_MEM_K<<10); //1 MB + 扩展内存(MB)数,即内存总数
- memory_end &= 0xfffff000; //按页的倍数取整,忽略内存末端不足一页的部分
- if (memory_end > 16*1024*1024)
- memory_end= 16*1024*1024;
- if (memory_end > 12*1024*1024)
- buffer_memory_end= 4*1024*1024;
- else if (memory_end > 6*1024*1024)
- buffer_memory_end= 2*1024*1024;
- else
- buffer_memory_end= 1*1024*1024;
- main_memory_start= buffer_memory_end; //缓冲区之后就是主内存
- …
- }
其中memory_end为系统有效内存末端位置。超过这个位置的内存部分,在操作系统中不可见。main_memory_start为主内存区起始位置。buffer_memory_end为缓冲区末端位置。对于缓冲区的起始位置,我们将在2.10节中详细介绍。
小贴士
有几个常用的左移、右移的数据关系需要记住:
<<20或>>20相当于乘或除以1 MB,
<<12或>>12相当于乘或除以4 KB(联想到页),
<<10或>>10相当于乘或除以1 KB。
所以,1<<20就是1 MB,EXT_MEM_K<<10就是EXT_MEM_K(扩展内存的KB数)的字节数。