加入收藏 | 设为首页 | 会员中心 | 我要投稿 佛山站长网 (https://www.0757zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux操作系统内存管理的源码实现

发布时间:2016-04-22 01:18:23 所属栏目:Linux 来源:网络整理
导读:最近一段时间在阅读Linux的源代码,想把看到的东西写出来,觉得内存这一部分最简单,就先写了出 来。请指正! 内存最低4K的地址是一张页目录(page_dir),页目录

可以看到,数组项数是除去最低1M内存后可以分成的页面数,也就是可以用的物理内存页面。系统在 初始化的时候把还没有被使用的内存物理页面对应的项置为了0,初始代码如下:

399 void mem_init(long start_mem, long end_mem)
400 {
401     int i;
402
403     HIGH_MEMORY = end_mem;
404     for (i=0 ; i405         mem_map[i] = USED;
406     i = MAP_NR(start_mem);
407     end_mem -= start_mem;
408     end_mem >>= 12;
409     while (end_mem-->0)
410         mem_map[i++]=0;
411 }

其实前面所有的申请内存的程序里都最终使用了一个函数get_free_page(),不管申请多少的内存,最 终还是要按页面来申请:

63 unsigned long get_free_page(void)
 64 {
 65 register unsigned long __res asm("ax");
 66
 67 __asm__("std ; repne ; scasbnt"
 68         "jne 1fnt"
 69         "movb ,1(%%edi)nt"
 70         "sall ,%%ecxnt"
 71         "addl %2,%%ecxnt"
 72         "movl %%ecx,%%edxnt"
 73         "movl 24,%%ecxnt"
 74         "leal 4092(%%edx),%%edint"
 75         "rep ; stoslnt"
 76         "movl %%edx,%%eaxn"
 77         "1:"
 78         :"=a" (__res)
 79         :"" (0),"i" (LOW_MEM),"c" (PAGING_PAGES),
 80         "D" (mem_map+PAGING_PAGES-1)
 81         :"di","cx","dx");
 82 return __res;
 83 }

这个函数就是在物理内存中找一张没有使用的页面并返回其物理地址。这是一段gcc内联汇编,它在 mem_map数组中的最后一项一直向前找,只要找一项的值不为0,则用这个数组下标计算出物理地址返回, 并把那一项的值设为1。用下标计算物理地址的方法我想是这样的:index*4096+LOW_MEN (std;repne;scasb,这三句是依次检查mem_map里的每一项的值,如果全部不为0,也即没有物理内存可以 用,立即返回0。movb ,1(%%edi)这句就是把mem_map数组里找到的可用的一项的标志设为1。此时ecx里的 值就是数组下标,因此sall ,%%ecx就是index*4096,addl %2,%%ecx即把刚才的index*4096+LOW_MEM。 73,74,5三句是把相应的物理内存空间内容全部清0。movl %%edx,%%eax显然是返回值了)。

(编辑:佛山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读