__pmd_populate(pmdp, __pa(ptep), _PAGE_KERNEL_TABLE);//调用 __pmd_populate,将页表项的物理地址和内核页表的保护标志 _PAGE_KERNEL_TABLE 传递给它。 } static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)//填充用户空间的 PMD。 { extern pmdval_t user_p...
"Page flags" are simple bit flags describing the state of a page of physical memory. They are defined in <linux/page-flags.h>. Flags exist to mark "reserved" pages (kernel memory, I/O memory, or simply nonexistent), locked pages, those under writeback I/O, those which are part of ...
GFP_KERNEL:用于内核空间的内存分配,可能休眠; GFP_ATOMIC:用于原子性的内存分配,不会休眠;典型原子性场景有中断处理程序,软中断,tasklet等 kmalloc内存分配最终总是调用__get_free_pages 来进行实际的分配,故前缀都是GFP_开头。 kmalloc分最多只能分配32个page大小的内存,每个page=4k,也就是128K大小,其中16个字节...
PAGE_KERNEL, node, area->caller); }else{// 直接调用 kmalloc 分配数组所需内存pages = kmalloc_node(array_size, nested_gfp, node); }// 初始化 vm_structarea->pages = pages; area->nr_pages = nr_pages;// 依次为 vmalloc 区中包含的所有虚拟内存页分配物理内存for(i =0; i < area->nr_p...
pte_offset_kernel():输入一个PMD(找到页框地址)和一个线性地址(找到页内偏移): #define pte_offset_kernel(pmd, address) ((pte_t *) pmd_page_kernel(*(pmd)) + pte_index(address)) #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) ...
GFP_KERNEL参数是gfp_mask标志的一个例子 调用_get_free_pages(*)之后要注意进行错误检查。内核分配可能失败,因此你的代码必须进行检查并做相应的处理。这意味在此之前,你所做的所有工作可能前功尽弃,甚至还需要回归到原来的状态。正因为如此,在程序开始时就先进行内存分配时很有意义的,这能让错误处理得到容易一点...
initial_page_table + KERNEL_PGD_BOUNDARY, KERNEL_PGD_PTRS); // 将内核顶级页表起始地址...
因为现代 CPU 的寻址不能绕过 MMU。不过内核空间和用户空间不同,它一般不做 swap,也就没有 page ...
GFP_KERNEL: 内核内存分配的常用标志。 GFP_HIGHMEM: 从HIGH_MEM区域请求内存。 GFP_ATOMIC: 以不能休眠的原子方式分配内存。当需要从中断上下文分配内存时使用。 使用GFP_HIGHMEM时需要注意,不应该与__get_free_pages() (或者 __get_free_page())一起使用,因为HIGHMEM内存不能保证是连续的,所以不能返回从该区...
上图展示了vmemmap、mem_section、page与物理地址及kernel线性地址之间的关系。在启动时,page_ext分配并存储在mm_section->page_ext中。使用时,我们通过page_ext_get获取页对应的page_ext信息,然后使用函数get_page_owner提取struct page_owner信息。检查内存泄漏的过程本质上是扫描所有page的page_ext...