精灵巫婆 发表于 2015-1-16 11:58:27

linux教程之Linux内核中罕见内存分派函数先容

安装和登录命令:login、shutdown、halt、reboot、mount、umount、chsh
1.道理申明
  Linux内核中采用了一种同时合用于32位和64位体系的内存分页模子,关于32位体系来讲,两级页表充足用了,而在x86_64系统中,用到了四级页表,如-1所示。四级页表分离为:
  *页全局目次(PageGlobalDirectory)
  *页下级目次(PageUpperDirectory)
  *页两头目次(PageMiddleDirectory)
  *页表(PageTable)
  页全局目次包括多少页下级目次的地点,页下级目次又顺次包括多少页两头目次的地点,而页两头目次又包括多少页表的地点,每个页表项指向一个页框。Linux中接纳4KB巨细的页框作为尺度的内存分派单位。
  多级分页目次布局
  1.1.同伴体系算法
  在实践使用中,常常必要分派一组一连的页框,而频仍地请求和开释分歧巨细的一连页框,一定招致在已分派页框的内存块平分散了很多小块的余暇页框。如许,即便这些页框是余暇的,其他必要分派一连页框的使用也很可贵到满意。
  为了不呈现这类情形,Linux内核中引进了同伴体系算法(buddysystem)。把一切的余暇页框分组为11个块链表,每一个块链表分离包括巨细为1,2,4,8,16,32,64,128,256,512和1024个一连页框的页框块。最年夜能够请求1024个连续页框,对应4MB巨细的一连内存。每一个页框块的第一个页框的物理地点是该块巨细的整数倍。
  假定要请求一个256个页框的块,先从256个页框的链表中查找余暇块,假如没有,就往512个页框的链表中找,找到了则将页框块分为2个256个页框的块,一个分派给使用,别的一个移到256个页框的链表中。假如512个页框的链表中仍没有余暇块,持续向1024个页框的链表查找,假如仍旧没有,则前往毛病。
  页框块在开释时,会自动将两个一连的页框块兼并为一个较年夜的页框块。
  1.2.slab分配器
  slab分派器源于Solaris2.4的分派算法,事情于物理内存页框分派器之上,办理特定巨细工具的缓存,举行疾速而高效的内存分派。
  slab分派器为每种利用的内查对象创建独自的缓冲区。Linux内核已接纳了同伴体系办理物理内存页框,因而slab分派器间接事情于同伴系统之上。每种缓冲区由多个slab构成,每一个slab就是一组一连的物理内存页框,被分别成了流动数量的工具。依据工具巨细的分歧,缺省情形下一个slab最多能够由1024个页框组成。出于对齐等别的方面的请求,slab平分配给工具的内存大概年夜于用户请求的工具实践巨细,这会形成必定的内存华侈。
  2.经常使用内存分派函数
  2.1.__get_free_pages
  unsignedlong__get_free_pages(gfp_tgfp_mask,unsignedintorder)
  __get_free_pages函数是最原始的内存分派体例,间接从同伴体系中猎取原始页框,前往值为第一个页框的肇端地点。__get_free_pages在完成上只是封装了alloc_pages函数,从代码剖析,alloc_pages函数会分派长度为1<<order的一连页框块。order参数的最年夜值由include/Linux/Mmzone.h文件中的MAX_ORDER宏决意,在默许的2.6.18内核版本中,该宏界说为10。也就是说在实际上__get_free_pages函数一次最多能请求1<<10*4KB也就是4MB的一连物理内存。可是在实践使用中,极可能由于不存在这么大批的一连余暇页框而招致分派失利。在测试中,order为10时分派乐成,order为11则前往毛病。
  2.2.kmem_cache_alloc
  structkmem_cache*kmem_cache_create(constchar*name,size_tsize,
  size_talign,unsignedlongflags,
  void(*ctor)(void*,structkmem_cache*,unsignedlong),
  void(*dtor)(void*,structkmem_cache*,unsignedlong))
  void*kmem_cache_alloc(structkmem_cache*c,gfp_tflags)
  kmem_cache_create/kmem_cache_alloc是基于slab分派器的一种内存分派体例,合用于重复分派开释统一巨细内存块的场所。起首用kmem_cache_create创立一个高速缓存地区,然后用kmem_cache_alloc从该高速缓存地区中猎取新的内存块。kmem_cache_alloc一次能分派的最年夜内存由mm/slab.c文件中的MAX_OBJ_ORDER宏界说,在默许的2.6.18内核版本中,该宏界说为5,因而一次最多能请求1<<5*4KB也就是128KB的一连物理内存。剖析内核源码发明,kmem_cache_create函数的size参数年夜于128KB时会挪用BUG()。测试了局考证了剖析了局,用kmem_cache_create分配凌驾128KB的内存时使内核溃散。
  2.3.kmalloc
  void*kmalloc(size_tsize,gfp_tflags)
  kmalloc是内核中最经常使用的一种内存分派体例,它经由过程挪用kmem_cache_alloc函数来完成。kmalloc一次最多能请求的内存巨细由include/Linux/Kmalloc_size.h的内容来决意,在默许的2.6.18内核版本中,kmalloc一次最多能请求巨细为131702B也就是128KB字节的一连物理内存。测试了局标明,假如试图用kmalloc函数分派年夜于128KB的内存,编译不克不及经由过程。
  2.4.vmalloc
  void*vmalloc(unsignedlongsize)
  后面几种内存分派体例都是物理一连的,能包管较低的均匀会见工夫。可是在某些场所中,对内存区的哀求不是很频仍,较高的内存会见工夫也能够承受,这是就能够分派一段线性一连,物理不一连的地点,带来的优点是一次能够分派较年夜块的内存。-1表示的是vmalloc分派的内存利用的地点局限。vmalloc对一次能分派的内存巨细没有明白限定。出于功能思索,应审慎利用vmalloc函数。在测试过程当中,最年夜能一次分派1GB的空间。
  Linux内核部份内存散布
  2.5.dma_alloc_coherent
  void*dma_alloc_coherent(structdevice*dev,size_tsize,
  ma_addr_t*dma_handle,gfp_tgfp)
  DMA是一种硬件机制,同意核心设备和主存之间间接传输IO数据,而不必要CPU的介入,利用DMA机制能年夜幅进步与设备通讯的吞吐量。DMA操纵中,触及到CPU高速缓存和对应的内存数据分歧性的成绩,必需包管二者的数据分歧,在x86_64系统布局中,硬件已很好的办理了这个成绩,dma_alloc_coherent和__get_free_pages函数完成不同不年夜,前者实践是挪用__alloc_pages函数来分派内存,因而一次分派内存的巨细限定和后者一样。__get_free_pages分派的内存一样能够用于DMA操纵。测试了局证实,dma_alloc_coherent函数一次能分派的最年夜内存也为4M。
  2.6.ioremap
  void*ioremap(unsignedlongoffset,unsignedlongsize)
  ioremap是一种更间接的内存“分派”体例,利用时间接指定物理肇端地点和必要分派内存的巨细,然后将该段物理地点映照到内核地点空间。ioremap用到的物理地点空间都是事前断定的,和下面的几种内存分派体例其实不太一样,并非分派一段新的物理内存。ioremap多用于设备驱动,可让CPU间接会见内部设备的IO空间。ioremap能映照的内存由原本的物理内存空间决意,以是没有举行测试。
  2.7.BootMemory
  假如要分派大批的一连物理内存,上述的分派函数都不克不及满意,就只能用对照特别的体例,在Linux内核引诱阶段来预留部份内存。
  2.7.1.在内核引诱时分派内存
  void*alloc_bootmem(unsignedlongsize)
  能够在Linux内核引诱过程当中绕过同伴体系来分派年夜块内存。利用办法是在Linux内核引诱时,挪用mem_init函数之前用alloc_bootmem函数请求指定巨细的内存。假如必要在其他中央挪用这块内存,能够将alloc_bootmem前往的内存首地点经由过程EXPORT_SYMBOL导出,然后就能够利用这块内存了。这类内存分派体例的弱点是,请求内存的代码必需在链接到内核中的代码里才干利用,因而必需从头编译内核,并且内存办理体系看不到这部份内存,必要用户自行办理。测试了局标明,从头编译内核后重启,可以会见引诱时分派的内存块。
  2.7.2.经由过程内核引诱参数预留顶部内存
  在Linux内核引诱时,传进参数“mem=size”保存顶部的内存区间。好比体系有256MB内存,参数“mem=248M”会预留顶部的8MB内存,进进体系后能够挪用ioremap(0xF800000,0x800000)来请求这段内存。
3.几种分派函数的对照
分派道理
最年夜内存
其他
__get_free_pages
间接对页框举行操纵
4MB
合用于分派较大批的一连物理内存
kmem_cache_alloc
基于slab机制完成
128KB
合适必要频仍请求开释不异巨细内存块时利用
kmalloc
基于kmem_cache_alloc完成
128KB
最多见的分派体例,必要小于页框巨细的内存时可使用
vmalloc
创建非一连物理内存到假造地点的映照
物理不一连,合适必要年夜内存,可是对地点一连性没有请求的场所
dma_alloc_coherent
基于__alloc_pages完成
4MB
合用于DMA操作
ioremap
完成已知物理地点到假造地点的映照
合用于物理地点已知的场所,如设备驱动
alloc_bootmem
在启动kernel时,预留一段内存,内核看不见
小于物理内存巨细,内存办理请求较高

</p>
不同版本的Linux命令数量不一样,这里笔者把它们中比较重要的和使用频率最多的命令。

活着的死人 发表于 2015-1-16 21:20:23

linux教程之Linux内核中罕见内存分派函数先容

在学习linux的工程中,linux学习方法有很多种,这里是小编的学习心得,给大家拿出来分享一下。

山那边是海 发表于 2015-1-19 06:14:19

再次,Linux是用C语言编写的,我们有学习C语言的基础,读程序和编写代码方面存在的困难小一点,也是我们能较快掌握的原因之一。?

兰色精灵 发表于 2015-1-28 05:08:56

随着实验课程的结束,理论课也该结束了,说实话教OS的这两位老师是我们遇到过的不错的老师(这话放这可能不太恰当).

小女巫 发表于 2015-2-5 16:53:31

笔者五分钟后就给出了解决方法: “首先备份原文件到其他目录,然后删掉/usr/local/unispim/unispimsp.ksc,编辑 /usr/local/unispim/unispimsp.ini,最后重启动计算机

不帅 发表于 2015-3-3 12:19:35

虽然大家都比较喜欢漂亮的mm,但是在学 linux 的过程中,还是要多和“男人”接触一下:P 遇到问题的时候,出来看说和上网查之外,就是要多用 linux 下的 man 命令找找帮助。

小魔女 发表于 2015-3-11 11:12:34

Linux最大的特点就是其开源性,这一点是十分难得的,这也是它能够存在到现在的原因之一。

柔情似水 发表于 2015-3-18 14:10:20

在学习的过程中,我们用的是VM虚拟机,开始时真的不真的该怎么去做,特别是我的是命令窗口界面,别人的是图形界面,我都不知道怎么调过来。

精灵巫婆 发表于 2015-3-26 08:35:47

为了更好的学习这门课程,我不仅课上认真听讲,课下也努力学习,为此还在自己的电脑上安装了Ubuntu系统。
页: [1]
查看完整版本: linux教程之Linux内核中罕见内存分派函数先容