kmalloc vmalloc_第1页
kmalloc vmalloc_第2页
kmalloc vmalloc_第3页
kmalloc vmalloc_第4页
kmalloc vmalloc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

kmalloc vmalloc 在设备驱动程序中动态开辟内存 不是用 malloc 而是 kmalloc 或者用 get free pages 直接申请页 释放内存用的是 kfree 或 free pages 对于提供了 MMU 存储管理器 辅助操作系统进行内存管理 提供虚实地址转换等硬件支 持 的处理器而言 Linux 提供了复杂的存储管理系统 使得进程所能访问的内存达到 4GB 进程的 4GB 内存空间被人为的分为两个部分 用户空间与内核空间 用户空间地址分布从 0 到 3GB PAGE OFFSET 在 0 x86 中它等于 0 xC0000000 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 PAGE 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 的实现 kmalloc 函数的实现是在 do kmalloc 中 可以看到在 do kmalloc 代码里最终调用了 cache alloc 来分配一个 slab 其实 kmem cache alloc 等函数的实现也是调用了这个函数来分配新的 slab 我们按照 cache alloc 函数的调用路径一直跟踪下去会发现在 cache grow 函数中使用了 kmem getpages 函数来分配一个物理页面 kmem getpages 函数中调用的 alloc pages node 最终是使用 alloc pages 来返回一个 struct page 结构 而这 个结构正是系统用来描述物理页面的 这样也就证实了上面所说的 slab 是在物理页面基础上 实现的 kmalloc 分配的是物理地址 get free page 是页面分配器提供给调用者的最底层的内存分配函数 它分配连续 的物理内存 get free page 函数本身是基于 buddy 实现的 在使用 buddy 实现的 物理内存管理中最小分配粒度是以页为单位的 关于以上论述 我们可以查看 get free page 的实现 可以看到 get free page 函数只是一个非常简单的封状 它的整个函数实现就是无条件的调用 alloc pages 函数来分配物理内存 上面记录 kmalloc 实现时也提到过是在调用 alloc pages 函数来分配物理页面的前提下进行的 slab 管理 那么这个函数是如何分配到物理页面又是在什么区域中进行分配的 回答这个问题 只能看下相关的实现 可以看到在 alloc pages 函数中 多次尝试调用 get page from freelist 函数从 zonelist 中取得相关 zone 并从其中返回一个可用的 struct page 页面 这里的有些调用分支是因为标志不同 至此 可以知道一个物理页面的 分配是从 zonelist 一个 zone 的结构数组 中的 zone 返回的 那么 zonelist zone 是 如何与物理页面关联 又是如何初始化的呢 继续来看 free area init nodes 函数 此 函数在系统初始化时由 zone sizes init 函数间接调用的 zone sizes init 函数填充了 三个区域 ZONE DMA ZONE NORMAL ZONE HIGHMEM 并把他们作为参数调用 free area init nodes 在这个函数中会分配一个 pglist data 结构 此结构中包含了 zonelist zone 结构和一个 struct page 的物理页结构 在函数最后用此结构作为参数调用 了 free area init node 函数 在这个函数中首先使用 calculate node totalpages 函数标记 pglist data 相关区域 然后调用 alloc node mem map 函数初始化 pglist data 结构中的 struct page 物理页 最后使用 free area init core 函数关联 pglist data 与 zonelist 现在通以上分析已经明确了 get free page 函数分配物理内 存的流程 但这里又引出了几个新问题 那就是此函数分配的物理页面是如何映射的 映射到 了什么位置 到这里不得不去看下与 VMM 相关的引导代码 在看 VMM 相关的引导代码前 先来看一下 virt to phys 与 phys to virt 这两个 函数 顾名思义 即是虚拟地址到物理地址和物理地址到虚拟地址的转换 函数实现十分简单 前者调用了 pa address 转换虚拟地址到物理地址 后者调用 va addrress 将物 理地址转换为虚拟地址 再看下 pa va 这两个宏到底做了什么 define pa x unsigned long x PAGE OFFSET define va x void unsigned long x PAGE OFFSET 通过上面可以看到仅仅是把地址加上或减去 PAGE OFFSET 而 PAGE OFFSET 在 x86 下定义为 0 xC0000000 这里又引出了疑问 在 linux 下写过 driver 的人都知道 在使用 kmalloc 与 get free page 分配完物理地址后 如果想得到正确的物理地址需要使用 virt to phys 进行转换 那么为什么要有这一步呢 我们不分配的不就是物理地址么 怎 么分配完成还需要转换 如果返回的是虚拟地址 那么根据如上对 virt to phys 的分析 为什么仅仅对 PAGE OFFSET 操作就能实现地址转换呢 虚拟地址与物理地址之间的转换不 需要查页表么 代着以上诸多疑问来看 VMM 相关的引导代码 直接从 start kernel 内核引导部分来查找 VMM 相关内容 可以看到第一个应该关注 的函数是 setup arch 在这个函数当中使用 paging init 函数来初始化和映射硬件页表 在初始化前已有 8M 内存被映射 在这里不做记录 而 paging init 则是调用的 pagetable init 来完成内核物理地址的映射以及相关内存的初始化 在 pagetable init 函数中 首先是一些 PAE PSE PGE 相关判断与设置 然后使用 kernel physical mapping init 函数来实现内核物理内存的映射 在这个函数中可以很清 楚的看到 pgd idx 是以 PAGE OFFSET 为启始地址进行映射的 也就是说循环初始化所有 物理地址是以 PAGE OFFSET 为起点的 继续观察我们可以看到在 PMD 被初始化后 所有 地址计算均是以 PAGE OFFSET 作为标记来递增的 分析到这里已经很明显的可以看出 物 理地址被映射到以 PAGE OFFSET 开始的虚拟地址空间 这样以上所有疑问就都有了答案 kmalloc 与 get free page 所分配的物理页面被映射到了 PAGE OFFSET 开始的虚 拟地址 也就是说实际物理地址与虚拟地址有一组一一对应的关系 正是因为有了这种映射关系 对内核以 PAGE OFFSET 启始的虚拟地址的分配也就是对 物理地址的分配 当然这有一定的范围 应该在 PAGE OFFSET 与 VMALLOC START 之 间 后者为 vmalloc 函数分配内存的启始地址 这也就解释了为什么 virt to phys 与 phys to virt 函数的实现仅仅是加 减 PAGE OFFSET 即可在虚拟地址与物理地址之 间转换 正是因为了有了这种映射 且固定不变 所以才不用去查页表进行转换 这也同样回 答了开始的问题 即 kmalloc get free page 分配的是物理地址 而返回的则是虚 拟地址 虽然这听上去有些别扭 正是因为有了这种映射关系 所以需要将它们的返回地址 减去 PAGE OFFSET 才可以得到真正的物理地址 另一篇更容易理解的 kmalloc vmalloc 分配的内存结构 zz 2008 01 20 16 05 进程空间 内核空间 原文 对于提供了 MMU 存储管理器 辅助操作系统进行内存管理 提供虚实地址转换等硬件支 持 的处理器而言 Linux 提供了复杂的存储管理系统 使得进程所能访问的内存达到 4GB 进程的 4GB 内存空间被人为的分为两个部分 用户空间与内核空间 用户空间地址分布从 0 到 3GB PAGE OFFSET 在 0 x86 中它等于 0 xC0000000 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 PAGE 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 中 而 vmalloc 申请的内存则位于 vmalloc start vmalloc end 之间 与物理地址没有简单的 转换关系 虽然在逻辑上它们也是连续的 但是在物理上它们不要求连续 我们用下面的程序来演示 kmalloc get free page 和 vmalloc 的区别 include include include MODULE LICENSE GPL unsigned char pagemem unsigned char kmallocmem unsigned c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论