
内存映射 : 物理内存和虚拟内存之间、 文件中的内容映射到虚拟内存空间。
申请小块内存用 brk; 申请大块内存或文件映射用 mmap
mmap:映射文件, 由 fd 得到 struct file
内存管理不直接分配内存, 在使用时才分配
用户态缺页异常, 触发缺页中断, 调用 do_page_default
__do_page_fault 判断中断是否发生在内核
四级页表

全局页目录项 pgd 在创建进程 task_struct 时创建并初始化, 会调用 pgd_ctor 拷贝内核页表到进程的页表
进程被调度运行时, 通过 switch_mm_irqs_off->load_new_mm_cr3 切换内存上下文
cr3 是 cpu 寄存器, 存储进程 pgd 的物理地址(load_new_mm_cr3 加载时通过直接内存映射进行转换)
cpu 访问进程虚拟内存时, 从 cr3 得到 pgd 页表, 最后得到进程访问的物理地址
进程地址转换发生在用户态, 缺页时才进入内核态(调用__handle_mm_fault)
__handle_mm_fault 调用 pud_alloc, pmd_alloc, handle_pte_fault 分配页表项
swap
swap 有没有缓存页swap 文件(也是调用 readpage)
避免每次都需要经过页表(存再内存中)访问内存

用户态内存映射函数 mmap,包括用它来做匿名映射和文件映射。
用户态的页表结构,存储位置在 mm_struct 中。
在用户态访问没有映射的内存会引发缺页异常,分配物理页表、补齐页表。如果是匿名映射则分配物理内存;如果是 swap,则将 swap 文件读入;如果是文件映射,则将文件读入。
- 内存映射函数 vmalloc, kmap_atomic
- 内核态页表存放位置和工作流程
- 内核态缺页异常处理

swapper_pg_dir 指向内核顶级页目录 pgd
xxx_ident/kernel/fixmap_pgt 分别是直接映射/内核代码/固定映射的xxx级页表目录 swapper_pg_dir 指向 init_top_pgt, 是 ELF 文件的全局变量, 因此再内存管理初始化之间就存在
init_top_pgt 先初始化了三项
level3_ident_pgt (内核代码段的某个虚拟地址) 减去 __START_KERNEL_MAP (内核代码起始虚拟地址) 得到实际物理地址level3_ident_pgtlevel3_kernel_pgt 内核代码区512MB, 直接映射区 1GBmm_struct 指向 swapper_pg_dir start_kernel→ setup_arch
load_cr3(swapper_pg_dir) 并刷新 TLBinit_mem_mapping→kernel_physical_mapping_init, 用 __va 将物理地址映射到虚拟地址, 再创建映射页表项CPU 在保护模式下访问虚拟地址都必须通过 cr3, 系统只能照做load_cr3 之前, 通过 early_top_pgt 完成映射vmalloc 区域用于内存映射- kmap_atomic 直接创建页表进行映射
- vmalloc 只分配内核虚拟地址, 访问时触发缺页中断, 调用 do_page_fault→vmalloc_fault 用于关联内核页表项
