到了十分乏味而又至关重要的部分了,想要一个操作系统运行起来,同时处理不同的程序,就要使用内存管理。
在开始之前,我们给Makefile中所有的gcc命令增加一个-fno-stack-protector,意思是不进行栈溢出检查,这是linux内核程序的一种防止栈溢出漏洞的机制,如果不加这一条指令,在使用栈的时候会发生__stack_chk_fail错误,具体详情百度 linux canary,这次我们做的东西跟linux半点关系都没有,所以就不赘述了。
更正一下内存分布图
把GDT放在0x80000处,这样GDT就一定够用了。GDT最大为64KB
gdt_size: .word 31
gdt_base: .long 0x80000 #定义GDT位置
一、内存管理的原理
为了让操作系统能够统一的管理内存,所以需要让操作系统知道每一个内存地址的使用情况,是可用的,还是不可用的,并采用分页的形式将其管理起来。具体来说就是将内存按一定的大小分为多个页面,这里所说的大小不是唯一的,可根据多方面的条件来权衡,在这里我们将页面大小定义为4KB,也就是4096B(通常情况下也是这样的)。我们假设最大内存为4GB(实际可以更大),采用一个byte来记录4KB的内存是否已经分配出,于是我们需要
0xffffffff÷0x1000=1048576 Bytes = 1024KB = 1MB,我们用0x100000~0x200000来存储这个表格。
一个Byte记录了4KB的内存空间,当第0位置1时,说明内存被使用了,置0说明尚未使用。
我们先把系统的框架完成,以后再来改进这些模块。
二、具体实现
新建memmory文件夹,新建memmory.c和memmory.h,添加进入makefile文件。
InitMMap()函数用于初始化系统内核所占用的内存,这部分内存永远为被使用,将InitMMap()加入main.c
void AllocatePages(int pages,app_memmory_struct *app_memmory)这是内存分配函数,实现原理是遍历内存表,找到连续的pages页内存,然后分配给结构体app_memmory_struct,将内存分配情况输出到屏幕左上角,结构体定义和声明位于下方。
void DeletePages(app_memmory_struct *app_memmory)//删除