辽源市住房和城乡建设局网站,网站开发要用多少钱,优书网下载,专业做网站建设公司内核态的内存映射机制#xff0c;主要包含以下几个部分#xff1a;
内核态内存映射函数 vmalloc、kmap_atomic 是如何工作的#xff1b;内核态页表是放在哪里的#xff0c;如何工作的#xff1f;swapper_pg_dir 是怎么回事#xff1b;出现了内核态缺页异常应该怎么办主要包含以下几个部分
内核态内存映射函数 vmalloc、kmap_atomic 是如何工作的内核态页表是放在哪里的如何工作的swapper_pg_dir 是怎么回事出现了内核态缺页异常应该怎么办
内核页表的顶级目录 init_top_pgt定义在 __INITDATA 里面。它们都有代码段还有一些初始化了的全局变量放在.init 区域。这些说的就是这个区域。可以看到页表的根其实是全局变量这就使得我们初始化的时候甚至内存管理还没有初始化的时候很容易就可以定位到。
因为 level3_ident_pgt 是在虚拟地址的内核代码段里的而 __START_KERNEL_map 正是虚拟地址空间的内核代码段的起始地址。这样level3_ident_pgt 减去 __START_KERNEL_map 才是物理地址。
第一项定义完了以后接下来跳到 PGD_PAGE_OFFSET 的位置再定义一项。从定义可以看出这一项就应该是 __PAGE_OFFSET_BASE 对应的。__PAGE_OFFSET_BASE 是虚拟地址空间里面内核的起始地址。第二项也指向 level3_ident_pgt直接映射区。
第二项定义完了以后接下来跳到 PGD_START_KERNEL 的位置再定义一项。从定义可以看出这一项应该是 __START_KERNEL_map 对应的项__START_KERNEL_map 是虚拟地址空间里面内核代码段的起始地址。第三项指向 level3_kernel_pgt内核代码区。
接下来的代码就很类似了就是初始化个表项然后指向下一级目录最终形成下面这张图。 内核页表定义完了一开始这里面的页表能够覆盖的内存范围比较小。例如内核代码区 512M直接映射区 1G。这个时候其实只要能够映射基本的内核代码和数据结构就可以了。可以看出里面还空着很多项可以用于将来映射巨大的内核虚拟地址空间等用到的时候再进行映射。
如果是用户态进程页表会有 mm_struct 指向进程顶级目录 pgd对于内核来讲也定义了一个 mm_struct指向 swapper_pg_dir。
在用户态可以通过 malloc 函数分配内存当然 malloc 在分配比较大的内存的时候底层调用的是 mmap当然也可以直接通过 mmap 做内存映射在内核里面也有相应的函数。
在虚拟地址空间里面有个 vmalloc 区域从 VMALLOC_START 开始到 VMALLOC_END可以用于映射一段物理内存。
kmap_atomic 和 vmalloc 不同。kmap_atomic 发现没有页表的时候就直接创建页表进行映射了。而 vmalloc 没有它只分配了内核的虚拟地址。所以访问它的时候会产生缺页异常。
内核态的缺页异常还是会调用 do_page_fault但是会走到咱们上面用户态缺页异常中没有解析的那部分 vmalloc_fault。这个函数并不复杂主要用于关联内核页表项。
对于用户态的内存分配或者直接调用 mmap 系统调用分配或者调用 malloc。调用 malloc 的时候如果分配小的内存就用 sys_brk 系统调用如果分配大的内存还是用 sys_mmap 系统调用。正常情况下用户态的内存都是可以换出的因而一旦发现内存中不存在就会调用 do_page_fault。 此文章为11月Day06学习笔记内容来源于极客时间《趣谈Linux操作系统》推荐该课程。