从 malloc 到页表:一次用户态内存访问背后的全流程

从 malloc 到页表:一次用户态内存访问背后的全流程

📘 支持作者新书:《Yocto项目实战教程:高效定制嵌入式Linux系统》


本文以 32 位 ARMv7 架构为例,拆解一次最简单的 malloc(8) 动作在 Linux 内核下引发的虚拟内存分配与页表构建全过程。


1. 用户空间 malloc 背后的流程总览

以用户代码为例:

char *p = malloc(8);
*p = 'A';

这个过程涉及多个阶段:

  1. 用户调用 malloc(),进入 glibc 分配器
  2. 若无可用缓存,则通过 brk()mmap() 系统调用请求内存
  3. 内核分配虚拟地址空间(创建 VMA)
  4. 用户首次访问 *p 触发缺页异常
  5. 内核页异常处理分配物理页并建立页表

2. 第一步:glibc 调用 brk 或 mmap

  • malloc(8) 触发 ptmalloc2,若已有堆缓存则直接分配,否则通过 brk() 扩展堆;
  • 若分配较大(一般 >128KB),glibc 选择 mmap() 分配独立区域;
brk(0x0804a000);  // 小内存扩展堆顶

3. 第二步:内核创建 VMA 区域

系统调用 sys_brk()sys_mmap() 后,进入内核态:

  • 找到 current->mm(即进程的内存描述符)
  • 为虚拟地址区域创建 vm_area_struct
  • 插入到 VMA 链表或红黑树中
// 进程虚拟内存结构
mm_struct
├── mmap → vm_area_struct → vm_area_struct → ...
├── pgd → 页目录

此时还 没有分配物理页帧,页表也尚未建立!


4. 第三步:首次访问触发 Page Fault

程序执行 *p = 'A' 时:

  • CPU 发现虚拟地址未建立映射 → 触发异常中断
  • 内核进入 do_page_fault() 进行缺页处理

流程如下:

do_page_fault()find_vma() // 查找是否是合法地址handle_mm_fault()do_anonymous_page()alloc_page()

5. 第四步:内核分配页帧,建立页表

do_anonymous_page() 中:

  • 分配物理页帧(来自伙伴系统)
  • 使用 set_pte() 更新页表项,建立虚拟 → 物理映射
  • 同时更新 TLB

页表层次回顾(ARM32)

ARMv7 使用二级页表:

  • PGD(页目录):4096 项,每项映射 1MB;共 4KB
  • PTE(页表项):每项映射 4KB;按需分配
// 示例地址 0x0804a000(用户态地址)
pgd_index = 0x0804a000 >> 20; // PGD index
pte_index = (0x0804a000 >> 12) & 0xFF; // PTE index

内核会为缺失页表页分配内存,并建立对应页表项。


在这里插入图片描述

6. 最终效果:完成映射

至此:

  • 0x0804a000 映射到物理页帧(如 0x1f305000)
  • *p = 'A' 的访问命中 TLB,内存访问成功
用户空间:0x0804a000 → 页表 → 页帧 0x1f305000 → DRAM

此后访问同一页均不再触发异常。


7. 总结流程图

malloc()
 → brk()/mmap()
   → 内核创建 VMA
     → 首次访问触发 Page Fault
       → 分配物理页 → 更新页表 → 恢复执行

8. 小结与内核视角

步骤内核结构/函数说明
系统调用sys_brk / sys_mmap分配虚拟地址
虚拟地址注册insert_vm_struct添加到 mm_struct 中
缺页处理do_page_fault()异常处理入口
分配页帧alloc_page()来自伙伴系统
映射页表set_pte()更新页表结构

📘 推荐阅读:

  • 第一篇:《Arm32 Memory Model:内核空间与用户空间的真相解析》
  • 支持作者新书:《Yocto项目实战教程》
    👉 京东购买链接:https://item.jd.com/15020438.html

📌 作者:嵌入式 Jerry | 视频教程请关注 B 站:“嵌入式 Jerry”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值