自制 x86-64 内核(46):mmap 文件映射

上一章实现了 TCP 服务端,这章来实现一个经典的内存管理功能:mmap 文件映射。 什么是 mmap 文件映射 mmap 把文件的一段内容映射到进程的虚拟地址空间。映射后可以像读内存一样读文件——不需要 read() 系统调用,直接解引用指针。 int fd = open("/bin/busybox", O_RDONLY); char *p = mmap(NULL, 4096, PROT_READ, MAP_PRIVATE, fd, 0); // p[0..3] 就是文件的前 4 字节(ELF magic: 7f 45 4c 46) 关键设计:VMA 和 Lazy 分配 mmap 不会立刻分配物理内存,而是登记一个 VMA(虚拟内存区域),等到进程真正访问这段地址时,才通过缺页异常按需读取文件内容并建立页表映射。 mmap(fd) → 注册 VMA(vaddr, len, inum, offset) → 返回虚拟地址 ↓ 进程访问该地址 #PF not-present → 找到 VMA → 分配物理页 → ext2_read(inum, offset, page) → 建立页表 → 重试指令 这就是操作系统课上说的"按需分页"(demand paging)。 实现步骤 1. 定义 VMA 结构 在 process_t 中加入 VMA 数组: ...

June 3, 2026 · 2 min · 大飞

自制 x86-64 内核(47):动态链接器基础

这一章实现了对 PIE(Position-Independent Executable)程序的支持,也就是不加 -static 编译出来的"动态"程序。 问题:PIE 和静态 ELF 的区别 用 musl-gcc 编译一个简单的 hello world: # 静态(之前一直用的) musl-gcc -static -O2 -o hello hello.c # 动态(PIE) musl-gcc -O2 -o hello_pie hello.c file 查看: hello: ELF 64-bit LSB executable, x86-64, statically linked hello_pie: ELF 64-bit LSB pie executable, x86-64, dynamically linked 区别在于: 属性 静态 (ET_EXEC) PIE (ET_DYN) e_type 2 3 虚地址 固定(如 0x400000) 从 0 开始,需加载时指定 base 重定位 无 .rela.dyn 表 外部依赖 无 通常有(但 musl PIE 已内嵌 libc) 为什么 musl PIE 没有"真正的"动态链接? musl-gcc 默认把所有 libc 代码静态链接进去,只是编译为 PIE 格式(支持 ASLR)。所以运行时: ...

June 3, 2026 · 1 min · 大飞
京ICP备14031575号-3