- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
PAGE
PAGE 9
kmalloc 详解
使用 kmalloc() 函数时,可分配的大小为 32 x PAGE_SIZE 。大多数系统中
PAGE_SIZE 的大小为 4096,因此超过 131072 字节就不能分配内存。
flag 参数表示指定分配内存的特性,它的值可为以下几个:
GFP_KERNEL
kmalloc() 函数中使用的代表性参数,请求动态内存总是分配成功。利用该值使用kmalloc() 函数时,若内核中的内存不足 ( 剩余内存小于 min_free_pages ),设备驱动程序调用的进程将被停止运行,直到动态内存可以分配。当其他进程释放内存, 达到可分配动态内存时,才能使程序重新启动。kmalloc() 函数分配到必要的内存, 并返回相应内存的起始地址。因此,在中断服务上使用 kmalloc() 函数不能利用该参数!
GFP_ATOMIC
内核存在可分配的内存时,无条件分配内存,若没有就立即释放 NULL ,因此, 进程不会进入睡眠状态,但是便成时可能无法分配内存。
GFP_DMA
用于分配连续的物理内存。设备驱动程序运行的内存空间不是物理内存而是虚拟地址内存,从进程的角度查看分配的内存,虚拟地址空间是连续的,而实际物理空间是不连续的。DMA 控制器无法使用不连续的物理空间,此时就可以使用 GFP_MDA 标志。
在设备驱动程序中动态开辟内存,不是用 malloc,而是 kmalloc,或者用get_free_pages 直接申请页。释放内存用的是 kfree,或 free_pages.
对于提供了 MMU(存储管理器,辅助操作系统进行内存管理,提供虚实地址转换等硬件支持)的处理器而言,Linux 提供了复杂的存储管理系统,使得进程所能访问的内存达到 4GB。
进程的 4GB 内存空间被人为的分为两个部分--用户空间与内核空间。用户空间地址分布从 0 到 3GB(PAGE_OFFSET,在 0x86 中它等于 0xC0000000),3GB到 4GB 为内核空间。
内核空间中,从3G 到 vmalloc_start 这段地址是物理内存映射区域(该区域中包含了内核镜像、物理页框表 mem_map 等等),比如我们使用的 VMware 虚拟系统内存是 160M,那么 3G~3G+160M 这片内存就应该映射物理内存。在物理内存映射区之后,就是 vmalloc 区域。对于 160M 的系统而言,vmalloc_start位置应在 3G+160M 附近(在物理内存映射区与 vmalloc_start 期间还存在一个
8M 的 gap 来防止跃界),vmalloc_end 的位置接近 4G(最后位置系统会保留一片 128k 大小的区域用于专用页面映射)
kmalloc 和 get_free_page 申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在较简单的转换关系,virt_to_phys()可以实现内核虚拟地址转化为物理地址:
#define pa(x) ((unsigned long)(x)_OFFSET)
extern inline unsigned long virt_to_phys(volatile void * address)
{
return pa(address);
}
上面转换过程是将虚拟地址减去 3G(PAGE_OFFSET=0XC000000)。
与之对应的函数为 phys_to_virt(),将内核物理地址转化为虚拟地址: #define va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) extern inline void * phys_to_virt(unsigned long address)
{
return va(address);
}
virt_to_phys()和 phys_to_virt()都定义在 include\asm-i386\io.h 中。
1、kmalloc() 分配连续的物理地址,用于小内存分配。
2、 get_free_page() 分配连续的物理地址,用于整页分配。
至于为什么说以上函数分配的是连续的物理地址和返回的到底是物理地址还是虚拟地址,下面的记录会做出解释。
kmalloc() 函数本身是基于 slab 实现的。slab 是为分配小内存提供的一种高效机制。但 slab 这种分配机制又不是独立的,它本身也是在页分配器的基础上来划分更细粒度的内存供调用者使用。也就是说系统先用页分配器分配以页为最小单位的连续物理地址,然后 kmalloc() 再在这上面根据调用者的需要进行切分。
关于以上论述,我们可以查看 kmalloc() 的实现,k
您可能关注的文档
最近下载
- 小学数学教学中学生逻辑推理能力的培养策略教学研究课题报告.docx
- [浙江]永康市委统战部编制外工作人员招聘笔试历年参考题库附带答案详解.doc VIP
- 教你三步查看老婆微信聊天记录.docx VIP
- 2022年公务员考试内蒙古行政职业能力测验真题.doc VIP
- 兴澄特钢海洋工程用钢研究与开发现状..ppt VIP
- 运动解剖学课件.pptx VIP
- 2025年气瓶检验员考试题及答案.docx VIP
- 大学藏文四级考试题库及答案.doc VIP
- (2025秋新版)人教版三年级数学上册全册教案.pdf
- 新解读《GB_T 20970-2015石油天然气工业 井下工具 封隔器和桥塞》最新解读.docx VIP
文档评论(0)