为了让操作系统能够统一的管理内存,所以需要让操作系统知道每一个内存地址的使用情况,是可用的,还是不可用的,并采用分页的形式将其管理起来。具体来说就是将4GB的内存(在32位保护模式下CPU只能识别4GB内存)按一定的大小分为多个页面,这里所说的大小不是唯一的,可根据多方面的条件来权衡,在这里我们将页面大小定义为4KB,也就是4096B。并定义一个map位图来存放各个内存页面的使用情况,这个map的大小为1024 * 1024 = 1048576 = 0x100000。也就是说这个map本身占用1MB的内存空间,它的每一个字节代表内存中对应的每一个内存页的使用情况。
另外,操作系统内核程序占用1MB的内存空间,内核在跳转到保护模式时,栈底已经指定为内存地址0x400000。所以map要从0x400000开始到0x4ffffff正好1MB的内存空间,如下图:
对于内核程序、内核堆栈和map所占用的空间,均为固定内存使用空间,也就是说,这部分内存不能再被其它程序所申请,所以从0x0到0x4fffff这部分内存空间默认均为已使用状态。
首先新建alloc.h和alloc.c分别放入include/kernel和mm文件夹中,并在alloc.h中定义3个位图使用状态和内存分配情况:
//未使用 #define MM_FREE (0) //已使用 #define MM_USED (1) //动态分配 #define MM_DYNAMIC (2) //内存页大小4096B #define MM_PAGE_SIZE (4 * 1024) //内存总页数 #define MAP_SIZE (1024 * 1024) //内核程序大小256页 256 * 4096 = 1MB #define KERNEL_SIZE (0x100) //MMAP所在内存地址为0x400000 - 0x4fffff //从0x500000以下为0x500个内存页 #define MMAP_USED_SIZE (0x500)
安装alloc内存申请模块,为map指定相关内存和使用状态:
//位图所在的固定内存区域为0x400000 ~ 0x4fffff mmap = (u8 *) 0x400000; for (int i = 0; i < MAP_SIZE; i++) { //mmap所占用的0x500000以下均为已使用 if (i < MMAP_USED_SIZE) { //设定内核所占用的1MB内存为已使用 mmap[i] = MM_USED; } //剩下的内存为未使用 else { mmap[i] = MM_FREE; } }
Copyright © 2015-2023 问渠网 辽ICP备15013245号