9)内存划分
内存划分
1 |
|
ROOT_DEV 为系统的根文件设备号,drive_info 为之前 setup.s 程序获取并存储在内存 0x90000 处的设备信息,我们先不管这俩变量,等之后用到了再说。
1 |
|
这一坨代码虽然很乱,但仔细看,就会发现它只是为了计算出三个变量罢了。main_memory_startmemory_endbuffer_memory_end我们继续观察最后一行代码还会发现,其实有两个变量是相等的。main_memory_start = buffer_memory_end;
这部分是针对不同的内存大小,设置不同的边界值,假设总内存一共就 8M 大小:
memory_end 就是:8 * 1024 * 1024
buffer_memory_end 就为:2 * 1024 * 1024
那么 main_memory_start 和它相等,也为:2 * 1024 * 1024
具体主内存区是如何管理的,要看 mem_init 方法。
1 |
|
缓冲区是如何管理的,要看 buffer_init 方法。
1 |
|
主内存管理
mem_init 函数,代码:
1 |
|
这个函数就是给一个 mem_map 数组的各个位置上赋了值,先是全部赋值为 USED 也就是 100,然后对其中一部分又赋值为了 0。
宏定义和全局变量
#define LOW_MEM 0x100000
- 定义了低内存的起始地址为 1MB(0x100000)。
#define PAGING_MEMORY (15*1024*1024)
- 定义分页内存的总大小为 15MB。
#define PAGING_PAGES (PAGING_MEMORY>>12)
- 计算分页页数(每页4KB),即
PAGING_MEMORY
右移12位,相当于除以4096。
- 计算分页页数(每页4KB),即
#define MAP_NR(addr) (((addr)-LOW_MEM)>>12)
- 计算地址
addr
对应的页号,即地址减去低内存起始地址后右移12位。
- 计算地址
#define USED 100
- 定义表示页面已使用的值为 100。
static long HIGH_MEMORY = 0;
- 定义高内存的变量,初始化为0。
static unsigned char mem_map[PAGING_PAGES] = { 0, };
- 定义一个内存映射数组,长度为
PAGING_PAGES
,用于标记内存页的使用情况,初始值全为0。
- 定义一个内存映射数组,长度为
代码作用
- 将
mem_map
数组初始化,全部设置为USED
代表全部使用。 - 将从2M开始的页全部标记为未使用,即
mem_map
数组对应的位置零。
- 1M 以下的内存这个数组干脆没有记录,这里的内存是无需管理的,或者换个说法是无权管理的,也就是没有权利申请和释放,因为这个区域是内核代码所在的地方,不能被“污染”。
- 1M 到 2M 这个区间是缓冲区,2M 是缓冲区的末端,缓冲区的开始在哪里我们之后再说,这些地方不是主内存区域,因此直接标记为 USED,产生的效果就是无法再被分配了。
- 2M 以上的空间是主内存区域,而主内存目前没有任何程序申请,所以初始化时统统都是零,未来等着应用程序去申请和释放这里的内存资源。
总结
这部分的工作是把内存分为了三部分,内核程序、缓冲区和主内存。并创建了表mem_map 用来管理内存使用情况
9)内存划分
https://carl-5535.github.io/2024/08/05/Linux0.11/9)内存划分/