内存管理-57-系统零页
基于 msm-5.4
一、简介
匿名页面缺页异常处理 do_anonymous_page() 中使用了系统零页,因为对于 malloc() 来说。分配的内存仅仅是进程地址空间中的虚拟地址。若此时用户程序需要读这个 malloc() 分配的虚拟内存,那么系统会返回全 0 的数据。因此Linux内核不必为这种情况单独分配物理内存,而是使用系统零页。使用系统零页来映射 malloc() 分配的虚拟地址。当程序需要写入这个页面时就会触发一个缺页异常,于是缺页异常就变成了写时复制的缺页异常了。
malloc()分配虚拟内存有以下几种情况:
(1) malloc后直接读
此时内核会进入匿名页面缺页异常,即 do_anonymous_page() 中使用系统零页进行映射。此时映射的PTE属性是只读的。
(2) malloc后先读后写
先读的操作会导致使用系统零页进行映射,此时映射的PTE属性是只读的。当写入时触发另外一个写时复制缺页异常。
(3) malloc后直接写
进入匿名页面缺页异常,调用 alloc_zeroed_user_highpage_movable() 来分配一个新页面,使用该页面来设置PTE,此时这个PTE的属性是可写的。
Arm64建构中 empty_zero_page 被定义成一个全局数组。
//msm-5.4/arch/arm64/mm/mmu.c unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] __page_aligned_bss; EXPORT_SYMBOL(empty_zero_page);
系统提供了一些辅助宏来使用这个系统零页:
//msm-5.4/arch/arm64/include/asm/pgtable.h #define ZERO_PAGE(vaddr) phys_to_page(__pa_symbol(empty_zero_page)) static inline int is_zero_pfn(unsigned long pfn) { return pfn == zero_pfn; } static inline unsigned long my_zero_pfn(unsigned long addr) { return zero_pfn; } //msm-5.4/mm/memory.c unsigned long zero_pfn __read_mostly; EXPORT_SYMBOL(zero_pfn); static int __init init_zero_pfn(void) { zero_pfn = page_to_pfn(ZERO_PAGE(0)); return 0; } early_initcall(init_zero_pfn);
二、使用位置
1. 匿名页读类型缺页异常
见上文简介部分。
posted on 2026-01-13 17:16 Hello-World3 阅读(1) 评论(0) 收藏 举报
浙公网安备 33010602011771号