1.1 UNIX发展史 1
第1章 概述 1
1.2 标准和通用接口 2
1.3 自由软件和开放源码 3
1.4 Linux发布版的快速浏览 3
1.4.1 Debian 4
1.4.2 Red Hat/Fedora 4
1.4.3 Mandriva 4
1.4.4 SUSE 4
1.4.5 Gentooo 4
1.4.6 Yellow Dog 4
1.4.7 其他发布版 5
1.5 内核版本信息 5
1.6 基于Power的Linux 5
1.7 操作系统的概念 6
1.9.1 用户接口 7
1.8 内核组织 7
1.9 Linux内核概述 7
1.9.2 用户身份鉴别 8
1.9.3 文件和文件系统 8
1.9.4 进程 12
1.9.5 系统调用 15
1.9.6 Linux调度程序 15
1.9.7 Linux设备驱动程序 16
1.10 可移植性和体系结构相关性 16
小结 17
习题 17
第2章 内核探索工具集 18
2.1 内核中常见的数据类型 18
2.1.1 链表 18
2.1.2 查找 21
2.1.3 树 21
2.2 汇编 23
2.2.1 PowerPC 24
2.2.2 x86 26
2.3 汇编语言示例 28
2.3.1 x86中的汇编示例 29
2.3.2 PowerPC中的汇编示例 31
2.4 内联汇编 33
2.4.1 输出操作数 33
2.4.2 输入操作数 33
2.4.3 修改过的寄存器(或者已修改元素列表) 33
2.4.4 参数的编号方式 34
2.4.5 约束条件 34
2.4.6 asm 34
2.4.7 _volatile_ 34
2.5 特殊的C语言用法 37
2.5.1 asmlinkage 37
2.5.4 const和volatile 38
2.5.3 inline 38
2.5.2 UL 38
2.6 内核探测工具一览 39
2.6.1 objdump/readelf 39
2.6.2 hexdump 40
2.6.3 nm 41
2.6.4 objcopy 41
2.6.5 ar 41
2.7 内核发言:倾听来自内核的消息 41
2.7.1 printk() 41
2.7.2 dmesg 41
2.7.3 /var/log/messages 42
2.8 其他 42
2.8.1 _init 42
2.8.2 likely()和unlikely() 42
2.8.3 IS_ERR和PTR_ERR 43
小结 44
项目:Hellomode 44
2.8.4 通告程序链 44
习题 47
第3章 进程:程序执行的基本模型 48
3.1 引入程序 49
3.2 进程描述符 51
3.2.1 与进程属性相关的域 53
3.2.2 与调度相关的域 54
3.2.3 涉及进程间相互关系的域 56
3.2.4 进程信任度相关的域 58
3.2.5 进程权能相关的域 59
3.2.6 进程限制相关的域 60
3.2.7 文件系统和地址空间相关的域 61
3.3 进程的创建:fork()、vfork和clone()系统调用 62
3.3.1 fork()函数 64
3.3.2 vfork()函数 64
3.3.3 clone()函数 65
3.3.4 do_fork()函数 66
3.4 进程生命周期 68
3.4.1 进程的状态 68
3.4.2 进程状态转换 69
3.5 进程的终止 72
3.5.1 sys_exit()函数 73
3.5.2 do_exit()函数 73
3.5.3 父进程通知和sys_wait4() 75
3.6 了解进程的动态:调度程序的基本构架 77
3.6.1 基本结构 78
3.6.2 从等待中醒来或者激活 79
3.7 等待队列 83
3.7.1 添加到等待队列 85
3.7.2 等待事件 86
3.7.3 唤醒进程 88
3.8 异步执行流程 90
3.8.1 异常 90
3.8.2 中断 92
小结 109
项目:current系统变量 110
习题 112
第4章 内存管理 113
4.1 页 115
4.1.1 标志 116
4.2 内存区 117
4.2.1 内存区描述符 117
4.2.2 内存区操作辅助函数组 119
4.3.1 请求页面函数族 120
4.3 页面 120
4.3.2 释放页面的函数族 121
4.3.3 伙伴系统 122
4.4 Slab分配器 126
4.4.1 缓存描述符 127
4.4.2 通用目的缓存描述符 131
4.4.3 slab描述符 131
4.5.1 slab分配器有关的全局变量 133
4.5 slab分配器的生命周期 133
4.5.2 创建缓存 134
4.5.3 slab创建与cache_grow() 139
4.5.4 Slab的销毁:退还内存与kmem_cache_destroy() 141
4.6 内存请求路径 142
4.6.1 kmalloc() 142
4.6.2 kmem_cache_alloc() 143
4.7 进程内存结构 144
4.7.1 mm_struct 144
4.7.2 vm_area_struct 146
4.8 进程映像分布于线性地址空间 147
4.9 页表 150
4.10 缺页 150
4.10.1 x86缺页异常 151
4.10.2 缺页处理程序 151
4.10.3 PowerPC缺页异常 158
小结 158
项目:进程内存映射 159
习题 160
第5章 输入/输出 161
5.1 硬件如何实现总线、桥、端口和接口 161
5.2 设备 165
5.2.1 块设备概述 165
5.2.2 请求队列和I/O调度 166
5.2.3 示例:“通用”块设备驱动程序 174
5.2.4 设备操作 176
5.2.7 时钟设备 177
5.2.5 字符设备概述 177
5.2.6 网络设备 177
5.2.8 终端设备 178
5.2.9 直接存储器存取 178
小结 178
项目:创建并口驱动程序 178
习题 186
6.1.1 文件和文件名 187
第6章 文件系统 187
6.1 文件系统的一般概念 187
6.1.2 文件类型 188
6.1.3 附加文件属性 188
6.1.4 目录和路径名 189
6.1.5 文件的操作 189
6.1.6 文件描述符 189
6.1.7 磁盘块,磁盘分区及其实现 190
6.1.8 性能 191
6.2 Linux的虚拟文件系统 191
6.2.1 VFS的数据结构 193
6.2.2 全局链表和局部链表的引用 203
6.3 与VFS相关的结构 204
6.3.1 fs_struct结构 205
6.3.2 files_struct结构 205
6.4 页缓冲 208
6.4.1 address_space结构 209
6.4.2 buffer_head结构 210
6.5 VFS的系统调用和文件系统层 212
6.5.1 open() 213
6.5.2 close() 217
6.5.3 read() 220
6.5.4 write() 235
小结 236
习题 237
第7章 调度和内核同步 238
7.1 Linux调度程序 239
7.1.1 选择下一个进程 239
7.1.2 上下文切换 244
7.1.3 让出CPU 251
7.2 抢占 259
7.2.1 显式内核抢占 259
7.2.2 隐式用户抢占 259
7.2.3 隐式内核抢占 260
7.3 自旋锁和信号量 262
7.4 系统时钟:关于时间和定时器 264
7.4.1 实时时钟:现在几点了? 264
7.4.2 读取PPC实时时钟 266
7.4.3 读取x86的实时时钟 268
小结 269
习题 270
第8章 内核引导 271
8.1 BIOS和Open Firmware 272
8.2 引导装入程序(Boot Loaders) 272
8.2.1 GRUB 273
8.2.2 LILO 275
8.2.3 PowerPC和Yaboot 276
8.3 体系结构相关的内存初始化 277
8.3.1 PowerPC的硬件内存管理 277
8.3.2 基于Intel x86体系结构的硬件内存管理 286
8.4 原始的RAM盘 294
8.3.3 PowerPC和x86的代码汇集 294
8.5 开始:start_kernel() 295
8.5.1 调用lock_kernel() 296
8.5.2 调用page_address_init() 298
8.5.3 调用printk(linux_banner) 300
8.5.4 调用setup_arch 300
8.5.5 调用setup_per_cpu_areas() 303
8.5.6 调用smp_prepare_boot_cpu() 304
8.5.7 调用sched_init() 305
8.5.8 调用build_all_zonelists() 307
8.5.9 调用page_alloc_init 307
8.5.10 调用parse_args() 308
8.5.11 调用trap_init() 310
8.5.12 调用rcu_init() 310
8.5.13 调用init_IRQ() 311
8.5.15 调用time_init() 312
8.5.14 调用softirq_init() 312
8.5.16 调用console_init() 313
8.5.17 调用profile_init() 314
8.5.18 调用local_irq_enable() 314
8.5.19 配置initrd 315
8.5.20 调用mem_init() 315
8.5.21 调用late_time_init() 320
8.5.22 调用calibrate_delay() 320
8.5.23 调用pgtable_cache_init() 321
8.5.24 调用buffer_init() 322
8.5.25 调用security_scaffolding_startup() 323
8.5.26 调用vfs_caches_init() 323
8.5.27 调用radix_tree_init() 329
8.5.28 调用signal_init() 330
8.5.29 调用page_writeback_init() 330
8.5.30 调用proc_root_init() 332
8.5.31 调用init_idle() 334
8.5.32 调用rest_init() 334
8.6 init线程(或进程1) 335
小结 339
习题 339
第9章 构建Linux内核 340
9.1 工具链 340
9.1.1 编译程序 341
9.1.2 跨编译程序 341
9.1.3 链接程序 342
9.1.4 ELF二进制目标文件 342
9.2 编译内核源代码 346
9.2.1 解释源代码 346
9.2.2 编译内核映像 349
小结 355
习题 355
第10章 向内核添加代码 356
10.1 浏览源代码 356
10.1.1 熟悉文件系统 356
10.1.2 Filps和Fops 357
10.1.3 用户空间和内核空间 359
10.1.4 等待队列 360
10.1.5 工作队列和中断 363
10.1.6 系统调用 365
10.1.7 其他类型的驱动程序 365
10.1.8 设备模型和sysfs系统文件 368
10.2 编写源代码 370
10.2.1 设备基础 370
10.2.2 符号输出 372
10.2.3 IOCTL 373
10.2.4 轮询与中断 375
10.2.5 工作队列和Tasklets 379
10.2.6 增加系统调用的代码 380
10.3 编译和调试 382
小结 383
习题 384
参考文献 385