Linux内核深度解析:虚拟内存与内存管理系统详解

5星 · 超过95%的资源 需积分: 26 510 下载量 93 浏览量 更新于2024-07-31 7 收藏 4.52MB PDF 举报
《疯狂内核之——Linux虚拟内存》是一本深入探讨Linux操作系统底层内存管理和虚拟内存机制的指南。该书详细讲解了Linux在x86架构上的分段和分页机制,重点围绕页全局目录、页表、线性地址转换以及物理地址映射等关键概念展开。章节一首先介绍了Linux的基本分段和分页原理,包括线性地址到物理地址的转换过程,以及如何处理不同类型的地址字段。 接着,作者详细剖析了Linux内存布局,区分了内核空间和用户空间,并展示了内核是如何初始化和管理这两种空间的,如临时内核页表的初始化和第一次用户空间的进入。书中还涉及了固定映射和高端内存的内核映射策略,包括永久和临时内存映射的区分。 第二章深入到了内核级内存管理系统,涵盖了Linux页面管理、NUMA架构、伙伴系统算法、页面级内存分配与释放、每CPU页面高速缓存、slab分配器等复杂概念。这里重点阐述了内存管理的高效算法,如slab分配器的运作机制,以及内存池和非连续内存区的管理。 第三章探讨了进程的地址空间,包括用户态内存分配、mm_struct数据结构,以及线性区的管理,如红黑树算法用于查找和维护地址空间的访问权限。此外,书中还介绍了如何动态分配和释放线性地址区间,以及创建和删除进程地址空间的过程。 磁盘文件内存映射是本书的另一个关键部分,它解释了内存映射数据结构、创建和请求调页过程,以及如何刷新脏页以保持数据一致性。非线性内存映射和页面回收策略也在这一章中得到详尽讨论。 最后,书中介绍了交换机制,包括交换区的结构、激活和禁用交换区的方法,以及页面的换入换出操作。同时,书中还详细解释了缺页异常处理程序的流程,特别是如何处理页错误和进行页面请求。 《疯狂内核之——Linux虚拟内存》是一本深入到Linux内核核心的实操手册,适合对操作系统内存管理感兴趣的开发者和研究者,它提供了全面且深入的理解,帮助读者掌握Linux虚拟内存管理的精髓。
2011-05-30 上传
目录 1 进程的组织 5 1.1 进程相关数据结构 5 1.1.1 进程的基本信息 6 1.1.2 进程状态 10 1.1.3 TASK_RUNNING状态的进程链表 11 1.1.4 进程间关系 12 1.2 Linux的线程——轻量级进程 15 1.3 进程的创建——do_fork()函数详解 19 1.4 执行进程间切换 33 1.4.1 进程切换之前的工作 33 1.4.2 进程切换实务 —— switch_to宏 37 1.4.3 __switch_to函数 39 1.5 fork与vfock系统调用的区别 42 1.6 内核线程 46 1.7 挂起状态进程的组织 49 1.7.1 等待队列头 49 1.7.2 等待队列的操作 50 1.7.3 进程资源限制 55 1.8 系统调用execve() 56 1.8.1 拷贝用户态参数 57 1.8.2 重要的数据结构 61 1.8.3 search_binary_handler函数 66 1.8.4 目标文件的装载和投入运行 69 1.8.5 库函数 92 2 中断控制 94 2.1 中断的分类 94 2.2 中断的硬件环境 95 2.2.1 外部中断请求IRQ 95 2.2.2 中断描述符表 96 2.2.3 中断和异常的硬件处理 97 2.3 中断描述符表 99 2.3.1 中断门、陷阱门及系统门 99 2.3.2 IDT的初步初始化 100 2.4 异常处理 101 2.5 中断处理 106 2.5.1 中断向量 107 2.5.2 IRQ数据结构 108 2.5.3 do_IRQ()函数 113 2.5.4 中断服务例程 115 2.5.5 IRQ线的动态分配 116 2.6 下半部分 117 2.6.1 软中断 118 2.6.2 tasklet 121 2.6.3 工作队列 122 2.7定时器中断 124 2.7.1 时钟与定时器 124 2.7.2 定时器中断相关的数据结构 127 2.7.3 定时器中断的上半部分 129 3 进程调度 138 3.1 进程调度的概念 138 3.2 进程调度的数据结构和优先级 141 3.2.1 进程的优先级 141 3.2.2 数据结构 145 3.3 调度程序所使用的函数 151 3.3.1 scheduler_tick函数 151 3.3.2 try_to_wake_up函数 156 3.3.3 recalc_task_prio函数 160 3.4 schedule()函数 163 3.4.1 直接调用 163 3.4.2 延迟调用 164 3.4.3 进程切换之前所做的工作 168 3.4.4 完成进程切换时所执行的操作 171 3.4.5 进程切换后所执行的操作 173 3.5 多处理器运行队列的平衡 175 3.5.1 调度域 176 3.5.2 rebalance_tick()函数 178 3.5.3 load_balance()函数 180 3.5.4 move_tasks()函数 183 3.6 进程退出 187 3.6.1 进程终止 187 3.6.2 进程删除 189 4 进程的并发性体现 191 4.1 内核抢占 193 4.1.1 内核抢占概念 193 4.1.2 同步技术总揽 196 4.2 每CPU变量 197 4.3 原子操作 199 4.4 优化屏障和内存壁垒 203 4.4.1 优化屏障 204 4.4.2 内存壁垒 204 4.5 自旋锁 206 4.6 读写自旋锁 211 4.6.1 为读获取和释放一个锁 213 4.6.2 为写获取或释放一个锁 214 4.7 顺序锁 215 4.8 RCU机制 217 4.9 信号量 219 4.9.1 获取和释放信号量 221 4.9.2 读/写信号量 224 4.9.3 补充信号量 225 4.10 禁止本地中断 226 4.10.1 禁止本地中断 227 4.10.2 禁止下半部(可延迟函数) 229 4.11 一些避免竞争条件的实例 231 4.11.1 引用计数器 231 4.11.2 大内核锁 231 4.11.3 内存描述符读/写信号量 232 4.11.4 slab高速缓存链表的信号量 233 4.11.5 索引节点的信号量 233 4.12 内核同步与互斥的总结 233
2011-05-30 上传
目录 1 引子 2 1.1 上电 2 1.2 BIOS时代 3 1.3 内核引导程序 5 2 内核映像的形成 8 2.1 MakeFile预备知识 9 2.1.1 Makefile书写规则 9 2.1.2 Makefile变量 10 2.1.3 条件判断 14 2.1.4 函数 17 2.1.5 隐含规则 17 2.1.6 定义模式规则 19 2.1 KBuild体系 23 2.1.1 内核目标 24 2.1.2 主机程序 26 2.1.3 编译标志 27 2.2 内核编译分析 28 2.2.1 编译配置 29 2.2.2 寻找第一个目标 32 2.2.3 prepare和scripts目标 38 2.2.4 递归编译各对象 41 2.2.5 链接vmlinux 44 2.2.6 制作bzImage 50 3 实模式下的内核代码 57 3.1 内核映像内存布局 58 3.2 实模式汇编代码header.S 60 3.2.1 无用的bootsect代码 60 3.2.2 初始化头变量hdr 63 3.2.3 准备实模式下C语言环境 64 3.3 实模式代码main函数 69 3.3.1 复制初始化头变量 71 3.3.2 初始化堆 74 3.3.3 确保支持当前运行的CPU 75 3.3.4 设置BIOS的x86模式 76 3.3.5 内存的检测 78 3.3.6 设置键盘属性 81 3.3.7 填充系统环境配置表 82 3.3.8 填充IST信息 83 3.3.9 设置Video模式 83 3.4 实模式代码go_to_proteced_mode函数 91 3.4.1 禁止可屏蔽和不可屏蔽中断 92 3.4.2 打开A20地址线 93 3.4.3 安装临时全局描述符表 99 3.4.4 第一次启动保护模式 101 4 保护模式下的内核代码 107 4.1 32位x86保护模式代码 107 4.1.1 内核解压缩的前期工作 108 4.1.2 解压缩内核 111 4.1.3 第二次启动保护模式 121 4.1.4 第一次启动分页管理 124 4.1.5 初始化0号进程 128 4.2 向start_kernel进发 131 4.2.1 初始化中断描述符表 132 4.2.2 第三次启动保护模式 137 4.2.3 启动x86虚拟机 141 5 走向现代:start_kernel函数 144 5.1 初始化同步与互斥环境 148 5.1.1 屏蔽中断 148 5.1.2 启动大内核锁 152 5.1.3 注册时钟通知链 153 5.1.4 激活第一个CPU 155 5.1.5 初始化地址散列表 160 5.1.6 打印版本信息 161 5.2 执行setup_arch()函数 166 5.2.1 拷贝可用内存区信息 171 5.2.2 获得总页面数 175 5.2.3 着手建立永久内核页表 177 5.2.4 第二次启动分页管理 181 5.2.5 建立内存管理架构 186 5.2.6 添砖加瓦 192 5.3 设置每CPU环境 206 5.4 初始化内存管理区列表 211 5.5 利用early_res分配内存 214 5.6 触碰虚拟文件系统 223 5.7 初始化异常服务 224 5.8 初始化内存管理 230 5.8.1 启用伙伴算法 230 5.8.2 初始化slab分配器 241 5.8.3 初始化非连续内存区 250 5.9 初始化调度程序 251 5.10 初始化中断处理系统 256 5.10.1 设置APIC中断服务 256 5.10.2 初始化本地软时钟 264 5.10.3 软中断初始化 268 5.10.4 初始化定时器中断 271 5.11 走进start_kernel尾声 273 5.11.1 初始化slab的后续工作 273 5.11.2 启动console 275 5.11.3 一些简单的函数 276 5.11.4 校准CPU时钟速度 279 5.11.5 创建一些slab缓存 282 5.12 安装根文件系统 287 5.12.1 创建VFS相关slab缓存 288 5.12.2 安装rootfs 291 5.12.3 安装proc文件系统 296 6 后start_kernel时代 298 6.1 创建1号进程 298 6.2 子系统的初始化 306 6.3 启动shell环境 309