内存分配是Linux比较复杂也是比较重要的部分,这个和ssd驱动很类似:物理地址和虚拟地址的映射关系。下面总结下最近看到的有关内存分配的内容和自己的理解;

1、一致内存访问和非一致内存访问



上图来自《深入linux设备驱动程序内核机制》

简单的说明下,UMA(一致内存访问 uniform memory access)可以很好的看到所有cpu访问内存的距离都是一样的(其实就是通过总线到内存的速度和距离都是一样的)所以就叫一致内存访问;

很显然右边的NUMA就是非一致内存访问,内存节点0是CPU0的本地内存(虽然其他CPU也可以访问,但是没有CPU0的速度高),所以这样各个CPU访问内存节点都会首先选择本地内存节点,然后再考虑其他内存节点;

2、物理内存和虚拟地址

上图来自《深入linux设备驱动程序内核机制》

首先大概的可以看出左边的mem_map数组中存放的是page结构体元素,中间的是实际的物理内存,右边的是虚拟的地址范围;

他们之间的关系大概是这样的,mem_map数组中的元素和物理内存页联系,page指针指向中间的物理内存中的某个物理页,这个关系是为了系统方便管理内存;

而物理内存页和右边的虚拟地址范围映射,这个是为了操作物理内存,一般右边的虚拟地址由cpu使用(软件上使用的也是虚拟地址,不过该地址最终还是CPU使用)。CPU和MMU之间使用的都是虚拟地址,出了MMU后就转换为实际的物理内存地址,一般有两个地方使用:1、总线上;2、物理内存(可以理解为内存条上);

这里类比下SSD驱动的原理:FTL数组中存放的是pba(lun、block、page、offset),而数组下标为lba,pba是SSD上的实际物理地址,lba则是上层软件使用的逻辑地址;他们通过FTL数组来映射,这样就可以通过修改数组中的pba来实现SSD像硬盘那样覆盖写等硬盘的特有性能;

回到内存分配上,从上面的图中应该可以看出物理内存分为三大区域:ZONE_DMA、ZONE_NORMAL、ZONE_HIGHMEM;mem_map数组和物理内存页全部一一映射,也会形成三大区域;而在系统初始化期间,会把物理内存区域中ZONE_DMA和ZONE_NORMAL分别和右边的虚拟地址“物理页面直接映射区”(这个虚拟地址区域名称有点怪,其实就是内核地址的0~896M地址范围)建立线性映射,这样就会建立相应的页目录和页表;如果对右边这个虚拟地址范围分配有疑问的可以看看:http://blog.csdn.net/yuzhihui_no1/article/details/46982231,不过这些都是在32位的系统中的,在64位系统中可以说完全不一样,不过有这个概念会好点;

这时候,如果在内核内存ZONE_DMA和ZONE_NORMAL区域分配,则可以直接返回虚拟地址(0~896M)这个虚拟地址的界限不是固定的;如果需要在物理内存ZONE_HIGHMEM分配时,则要复杂些了;简单的步骤为:1、在物理内存ZONE_HIGHMEM中查找一个空闲页;2、在右边的虚拟地址中的动态映射区或固定映射区分配一个虚拟地址;3、建立页目录和页表,使物理页和虚拟地址映射起来;

3、物理页分配接口函数

    首先是:alloc_pages(gfp_mask, order)宏,(是不是很奇怪没有先写kmalloc、vmalloc,那是因为他们俩比较复杂,也比较重要,当然最主要的是他们不是分配物理页。后面要用很大的篇幅来分析他们俩);参数 gfp_mask是一个掩码参数,用来控制分配行为(哪个区域分配、是否阻塞分配等);order是表示分配2的order次方个物理页面;
alloc_pages(gfp_mask, order); 调用 alloc_pages_node(); 调用 __alloc_pages();说到底最后工作的还是__alloc_pages(),alloc_pages()和__alloc_pages()都可以分配来自ZONE_HIGHMEM区域的物理页,主要看gfp_mask指定的分配区域; 注意alloc_pages()是宏不是函数;
__get_free_pages(gfp_mask, order);这个分配函数首先是判断gfp_mask,如果指定为ZONE_HIGHMEM分配区域,则失败退出;否则,就调用alloc_pages()函数;由此看出__get_free_pages()函数只能分配ZONE_DMA和ZONE_NORMAL区域的物理页,也就是说不需要修改页表;

简单的分配物理页接口函数就这两个,其他的都是些变种,根据gfp_mask,和order来实现的变种函数;

注意:这是分配多个的连续的物理页的函数接口,kmalloc、vmalloc函数分配的不一定是整个页大小的内存;

转载地址:http://blog.csdn.net/yuzhihui_no1/article/details/47284329

如果讲解的不正确,欢迎指正,谢谢!!

linux内核内存分配(一、基本概念)的更多相关文章

  1. linux内核内存分配(三、虚拟内存管理)

    在分析虚拟内存管理前要先看下linux内核内存的具体分配我開始就是困在这个地方.对内核内存的分类不是非常清晰.我摘录当中的一段: 内核内存地址 ============================ ...

  2. LINUX内核内存屏障

    =================                          LINUX内核内存屏障                          ================= By ...

  3. linux内核--内存管理(二)

    一.进程与内存     所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内 ...

  4. Linux内核-内存回收逻辑和算法(LRU)

    Linux内核内存回收逻辑和算法(LRU) LRU 链表 在 Linux 中,操作系统对 LRU 的实现主要是基于一对双向链表:active 链表和 inactive 链表,这两个链表是 Linux ...

  5. Linux内核内存管理算法Buddy和Slab: /proc/meminfo、/proc/buddyinfo、/proc/slabinfo

    slabtop cat /proc/slabinfo # name <active_objs> <num_objs> <objsize> <objpersla ...

  6. 模拟linux的内存分配与回收

    模拟linux的内存分配与回收 要求 通过深入理解内存分配管理的三种算法,定义相应的数据结构,编写具体代码. 充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣. (1)掌握内存分配FF,BF ...

  7. 【转】Linux内核中分配4M以上大内存的方法

    在Linux内核中, kmalloc能够分配的最大连续内存为2的(MAX_ORDER-1)次方个page(参见alloc_pages函数,     "if (unlikely(order & ...

  8. linux环境内存分配原理 mallocinfo

    Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全 ...

  9. linux内核内存管理(zone_dma zone_normal zone_highmem)

    Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数 ...

随机推荐

  1. windows 2003一个网卡绑定多个IP地址

    1.打开“网络连接”,选中需要添加多个IP的“本地连接”-->右键-->“属性”: 2.从“常规”中找到“Internet 协议(TCP/IP)属性”: 3.选择手动设置IP地址.网关.掩 ...

  2. HDU 5191

    好端端的被HACK掉了...应该是在两端都要补W个0才对,之前只想到要在后面补足0,没想到前面也应该补足,因为前面即便存在0也可能使得移动的积木数最少.. T_T #include <iostr ...

  3. HDU 5176

    这道题以前好像在哪遇到过. 注意树的每一条边都是桥,所以,桥两端的点要到达对方是必须通过这条边的.于是,可以把边由小到大排序,利用并查集,这样,每加一条边就连通了一部分,而随着权值的增大,必定是桥两端 ...

  4. HDU 1515

    简单题,直接用STACK模拟整个过程. 模拟出栈时,应注意保护现场,等到递归完成后返回. #include <iostream> #include <string.h> #in ...

  5. Android解决使用findViewById时须要对返回值进行类型转换问题的辅助类

    在我们的开发工作时,findViewById可能是用得最多的函数之中的一个.但它特别讨厌的地方就是我们常常须要对返回的view进行类型转换,输入麻烦.代码丑陋,比如曾经我们在Activity中找一些子 ...

  6. cocos2dx 自己主动绑定js

    依照教程把全部资源下载好后....... 找到cocos2dx project下的tools/bindings-generator/test 发现里面有test.sh , test.ini , 去掉s ...

  7. luogu1771 方程的解

    题目大意 对于不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整数,g(x)=x^x mod 1000(即x^x除以1000的余数),x,k是给定的数.我们要求的是这个不定 ...

  8. Code Coverage and Unit Test in SonarQube

    概念 https://blog.ndepend.com/guide-code-coverage-tools/ Code Coverage Results Import (C#, VB.NET) Uni ...

  9. AdaBoostClassifier实战

    AdaBoostClassifier实战 部分内容摘自:http://blog.csdn.net/sun_shengyun/article/details/54289955 这里我们用一个具体的例子来 ...

  10. Oracle 10G 中的"回收站"

    在Oracle 10g数据库中,引入了一个回收站(Recycle Bin)的数据库对象. 回收站,从原理上来说就是一个数据字典表,放置用户Drop掉的数据库对象信息.用户进行Drop操作的对象并没有被 ...