当前: 首页 - 图书专区 - Linux内核编程
Linux内核编程


  在线购买
Claudia Salzberg Rodriguez, Gordon Fischer, Steven Smolski
7-111-19217-6
49.00
386
2006年07月20日
陈莉君 贺炎 刘霞林
计算机 > 操作系统 > Linux
Prentice Hall
6425
简体中文
16开
The Linux Kernel Primer:A Top-Down Approach For X86 and PowerPc Architectures
教材
其他(华章科技)







本书是一本Linux内核编程的权威指南,其独特的由表及里学习途径使得内核编程更易于理解。本书从用户空间到内核,把内核的实现原理与用户级编程的基本原则相联系,系统地跟踪了实现功能。这种途径有助于在你所了解的Linux知识基础上,加深对内核组成及工作机理的理解。
  为了理解内核代码并掌控其行为,作者逐步引入所有的工具和汇编语言编程技术,并一一比较x86和PowerPC的实现,揭示了含糊不清的实现功能。另外,书中对源代码例子和实际项目都加有适当注释。本书是第一本全面涵盖快速增长的PowerPC Linux开发平台的书,也是惟一一本用Linux构建系统彻底讨论内核配置的书。

本书主要内容
● 数据结构
● x86和PPC汇编语言
● 查看内核内部状态
● Linux进程模型
● 用户空间和内核空间
● 中断和异常
● 内存分配和跟踪
● 跟踪子系统行为
● I/O交互
● 文件系统和文件操作
● 调度和同步
● 内核启动过程
● 内核构建过程
● 配置选项
● 设备驱动程序
  本书介绍了Linux内核编程需要的所有技巧和技术,无论对于系统程序员、软件工程师、系统分析员、测试人员还是Linux的热衷者来说,都是不可或缺的参考书。
无论是一般的技术还是专业性很强的计算机,对于试图了解它们的人们来说都同样具有不可思议的魔力。技术的发展推动着对已确立的框架和曾经模糊的陈旧概念的重新评估。Linux操作系统已经对促进工业变革和商业营销方式做出了巨大贡献。GNU公共许可证的采用,以及与GNU软件的互动,使围绕开源的各种争论有了共同的标准。开源操作系统如此强大,Linux无疑是一个极其成功的典范,它以无法想像的魔力吸引着世界各地的程序员。
  对于数量庞大的计算机用户来说,越来越多的人使用了Linux。有了各种各样的发布版,社团的支持,以及工业后盾,Linux的应用也找到了安全的港湾,它的身影出现在大学、工业应用以及数以千万计的家庭用户中。
  使用大潮促进了技术支持和新功能需求的日益增长。这样一来,愈来愈多的程序员发现自己对Linux内核的内幕感兴趣,因为大量现有的(还有快速增长的)军工企业需要支持不同的体系结构和种类繁多的新设备。
  Linux操作系统的繁荣和发展归功于把内核移植到了Power体系结构,它覆盖了从高端的服务器到低端的嵌入式系统。随着各公司倾向于购买基于Power PC的系统来运行Linux,想知道Linux在该体系结构上运行机理的愿望就显得日益强烈。
  适合的读者
  本书可供不同级别的系统程序员、Linux爱好者以及应用程序开发者阅读,这些开发者渴望更好地理解自己的程序到底是如何工作的。只要有C知识,熟悉基本的Linux使用基础,还想知道Linux是如何工作的,那么你就会发现这本书提供了进行这种理解基本而必要的概念,可以说,本书是理解Linux内核如何工作的初级读本。
  不管你是编写过在Linux上运行的小程序,还是已开发过系统但正在寻求对某个子系统特性的理解,本书所编写的内容都是你所期待的。
  内容组织
  本书分为三部分,每部分都提供必要的知识,让读者能顺畅地钻研Linux内幕。
  第一部分提供必要的工具,并理解对Linux内幕所进行的探索。
  第1章“概述”,叙述Linux和UNIX的历史,罗列很多发布版,并从用户空间的观点简述各种内核子系统。
  第2章“内核探索工具集”,描述Linux内核中常用的数据结构和语言的用法,介绍x86和PowerPC体系结构的汇编语言,并简述一些工具和实用程序,从而可以获取理解内核内幕所需的信息。
  第二部分介绍了在每个内核子系统中所涉及的基本概念,并分析了执行子系统功能的必要代码。
  第3章“进程:程序执行的基本模型”,涵盖了进程模型的实现。解释了为何引入进程,并讨论了用户空间到内核空间的控制流,也讨论了内核空间到用户空间的控制流。我们还讨论了进程在内核中是如何实现的,并描述了所有与进程执行相关的数据结构。本章还涵盖了中断和异常,描述了这些硬件机制在每种体系结构中是如何发生的,它们与Linux内核又是如何交互的。
  第4章“内存管理”,描述了Linux内核如何追踪和管理用户空间进程的可用内存和内核的可用内存。本章描述了内核对内存分类的方式,以及如何决定分配和释放内存,也详细描述了缺页机制以及它是怎样在硬件上执行的。
  第5章“输入/输出”,描述了处理器是如何与其他设备进行交互的,内核又是如何响应和控制这些交互的。本章还涵盖了各种设备及其在内核中的实现。
  第6章“文件系统”,概述文件和目录如何在内核中实现。本章引入了虚拟文件系统,它是用于支持多文件系统的抽象层。本章还跟踪了文件相关操作的执行,如打开和关闭文件。
  第7章“调度和内核同步”,描述调度程序的操作,调度程序让多个进程运行起来就像只有一个进程在系统中运行一样。本章详细描述了内核如何选择一个任务运行,进程切换时如何与硬件进行交互。本章还叙述了什么是内核抢占,它又是怎样执行的。最后,描述了系统时钟的工作原理,内核怎样使用它计时。
  第8章“内核引导”,描述电源开和关时都发生些什么。本章对各种处理器装入内核的方式进行了跟踪,包括对BIOS、Open Firmware和bootloaders的描述。然后,考察了内核启动和初始化时的线性顺序,涵盖了前面章节中讨论的所有子系统。
  第三部分,描述如何构建内核并与内核进行交互的多种途径。
  第9章“构建Linux内核”,涵盖了编译内核所必需的工具和执行的目标文件的格式。还详细描述了内核源代码编译(Kernel Source Build)系统是如何操作的,怎样把配置选项加到内核编译系统中。
  第10章“向内核添加代码”,描述了/dev/random操作,这在所有的Linux系统中都可以看到。就像对熟悉的设备进行描述一样,本章还从更实战的观点触及了曾经描述过的概念。最后,还描述了如何给自己的设备编写代码。
  探索方法
   本书向读者介绍了理解内核的必要概念。我们遵循自顶向下的方式来组织内容,具体体现在以下两个方面:
  首先,我们把内核的工作和用户空间所执行的操作关联起来,因为读者对后者更熟悉,并渴望以这样的方式理解内核的工作原理。在可能的情况下,我们会从用户空间的例子说起,并跟踪代码的执行到内核。但有时,这种跟踪方式并不总是可行,因为子系统的数据类型和底层结构必须在解释其工作原理之前引入。在这些情况下,我们把对内核子系统的解释和它与用户空间程序如何联系的具体例子结合起来。有双重意图:其一,当内核一方面与用户空间打交道,另一方面与硬件打交道时突出了在内核看到的层面;其二,通过跟踪代码和事件发生的顺序来解释子系统的工作原理。我们相信,这将有助于读者把内核的工作原理与自己所知道的知识相关联,也有利于让读者看到,一个特定的功能是怎样与操作系统的其他部分相
联系的。
  其次,我们采用自顶向下的方法,考察针对子系统操作的主要数据结构,并观察其怎样与系统管理的执行行为相联系。我们尽力描述针对子系统操作的结构,并像追踪子系统的操作一样持续关注这些数据结构。
第1章 概述
1.1 UNIX发展史 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 Gentoo 4
1.4.6 Yellow Dog 4
1.4.7 其他发布版 5
1.5 内核版本信息 5
1.6 基于Power的Linux 5
1.7 操作系统的概念 6
1.8 内核组织 7
1.9 Linux内核概述 7
1.9.1 用户接口 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.2 UL 38
2.5.3 inline 38
2.5.4 const和volatile 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
2.8.4 通告程序链 44
小结 44
项目:Hellomode 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 页面 120
4.3.1 请求页面函数族 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 slab分配器的生命周期 133
4.5.1 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.5 字符设备概述 177
5.2.6 网络设备 177
5.2.7 时钟设备 177
5.2.8 终端设备 178
5.2.9 直接存储器存取 178
小结 178
项目:创建并口驱动程序 178
习题 186
第6章 文件系统 187
6.1 文件系统的一般概念 187
6.1.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.3.3 PowerPC和x86的代码汇集 294
8.4 原始的RAM盘 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.14 调用softirq init() 312
8.5.15 调用time 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
“有龙在此”,中世纪地图绘制者碰到未知和危险的地方就如此标记,可能你首次敲入如下命令也有这样的感觉:
  cd/usr/asc/linux;ls
  你可能也发出“从何开始?”的感叹。“我到底想知道什么?这是怎样放在一起的?本质上又如何工作?”
  现代功能俱全的操作系统庞大而复杂。子系统为数不少,它们之间的交互更错综复杂而且微妙。不错,你的确拥有Linux内核源代码(稍后还会详述),但是,从何处开始,着眼于什么,该以怎样的顺序,远非易事。
  本书的编写目的正在于此。一步一步,你会了解到内核的各个部分,它们如何工作,互相之间怎样关联。本书的作者熟知内核,这些知识贯穿于本书的始终,你和内核之间至少会成为好朋友,乃至产生深厚的情意。
  Linux内核是“自由的”软件。Richard Stallman对自由软件给出了定义,所谓自由(freeˉdom)就是让软件是自由的(Free,第一个字母F大写)。有两层含义,一方面,运行软件是自由的,这是最基本的自由。另一方面,探究程序如何编写也是自由的。这种自由往往被忽略,实际上,这才是最重要的,因为学习如何做事的最好方式之一就是观察别人如何做事。在软件世界中,那就意味着阅读别人的程序,并了解到他们在哪些地方做得较好,哪些地方做得较差。至少在我看来,在现代计算领域里,GNU/Linux之所以能变成一股强大的力量,其最根本原因之一就是GPL的自由。这些自由,在你使用GNU/Linux的每时每刻都会感到其
益处,偶尔停下来,试想一下是不是这回事。
   有了本书,我们充分利用自由之二,让你有机会深入研究Linux内核源代码。你会看到,有些事的确做得不错;同时,你也会看到,有些事也并不尽人意。但是,因为自由之二,你会看到全貌,更重要的是,你会从中学到很多知识。
  况且,这也使我走入了Prentice Hall开源软件开发系列丛书,本书是首批成员之一。开发这一系列丛书的念头源于阅读程序是学习的最好方式之一。如今,这个世界幸运地享有丰富而自由开放的源代码软件,这些源代码正期待着(或许热切渴望着)被阅读、理解,甚至赞许。这一系列丛书会成为你软件开发学习曲线的领路人,也可以说,通过尽可能多地展示真实的代码,有助于你学到货真价实的东西。
  我真诚地希望你会欣赏本书,并从中学到东西。我也期望你会从中得到灵感,从而在自由软件和开源世界开创你自己的事业,参与进来,那无疑是最令人愉快的方式了。
  玩得开心!
  Arnold Robbins系列丛书编辑

  http://www.gnu.org/philosophy/freeˉsw.html。
追本溯源,从本书开始!
  Linux最为人称道的莫过于它的自由精神,所有源代码唾手可得。打开Linux内核源代码,我们可以看到熟悉的C语言函数和一些陌生的汇编代码。但是,Linux内核入门很不容易,它之所以难学,在于庞大的规模和涉及的层面。规模一大,就不易现出本来面目,浑然一体,自然不容易找到着手之处;层面一多,就会让人眼花缭乱,盘根错节,怎能让人提纲挈领?
  就我们的经验,内核初学者(不是编程初学者)可以从这本书着手。本书三位作者有多年的行业经验。Claudia Salzberg Rodriguez就职于IBM Linux技术中心,进行内核及相关编程工具的开发。Gordon Fischer为很多设备开发了Linux和UNIX设备驱动程序。Steve Smolski在半导体行业已经有26年,进行过各种驱动程序和嵌入式系统的开发。他们合作奉献给大家的这本内核入门,是对Linux内核编程的有效指导。作者独特的由表及里学习途径使得内核编程更易于理解,从用户空间到内核,把内核内在的实现原理与用户级编程的基本原则相联系,系统地追踪了实现功能。这种途径有助于扩大你所了解的Linux知识,加深对内核组成及工作机理的理解深度。
  在本书的翻译过程中,更是感到作者软硬件知识的全面、对内容独到的组织方式和娴熟的开发经验。在我们熟知的x86平台之外,作者对PowerPC的深入讲解,不仅让基于PowerPC平台的开发者找到了知音,更为x86的开发者打开了一扇新窗户。
  为了让本书尽快与读者见面,本书翻译组陈莉君、贺炎、刘霞林、康华和石莉放弃了春节的休息时间,夜以继日。书中不妥之处和错误难免,希读者谅解。
  在这消化这本书的基础上,如果你侧重于内核的全面了解,可以进一步研究《Understand Linux Kernel》和源代码本身;如果你侧重于了解内核设计思想,则阅读《Linux Kernel Developˉment》;如果你侧重于实际编程,可以研读《Linux Device Driver》,直接开始动手工作;如果你想有一个轻松的内核学习和实践环节,请访问我们的网站www.kerneltravel.net。
  译 者
  2006年3月
读者书评
发表评论



高级搜索
高性能Linux服务器构建实战:运维监控、性能调优与集群应用
构建高可用Linux服务器
Linux内核设计的艺术:图解Linux操作系统架构设计与实现原理


版权所有© 2008 北京华章图文信息有限公司 京ICP备08102525号 京公网安备110102004606号
通信地址:北京市百万庄南街1号 邮编:100037
电话:(010)68318309, 88378998 传真:(010)68311602, 68995260