读书笔记一
一、Linux内核简介
1.1 Unix 的历史
Unix 虽然已经使用了 40 年,但计算机科学家仍然认为它是现存操作系统中最强大和最优秀 的系统。
1.2 追寻 Linus 足迹: Linux 简介
Linux 是一个非商业化的产品,这是它最让人感兴趣的特征。 实际上 Linux是一个互联网上 的协作开发项目。
Linux 用途广泛,包含的东西也名目繁多。 Linux 系统的基础是内核、 C库、工具集和系统 的基本工具
一般情况下, Linux这个词汇主要还是指内核.
1.3 操作系统和内核简介
由于一些现行商业操作系统日趋庞杂及其设计上的缺陆,操作系统的精确定义并没有一个统 一的标准。 许多用户把他们在显示器屏幕上看到的东西理所当然地认为就是操作系统。 通常,当然,操作系统是指在整个系统中负责完成最基本功能和系统管理的那些部 分。这些部分应该包括内核、设备驱动程序、启动引导程序、命令行 Shell 或者其他种类的用户 界面、基本的文件管理工具和系统工具。这些都是必不可少的东西一一别以为只要有浏览器和播 放器就行了。系统这个词其实包含了操作系统和所有运行在它之上的应用程序。 当然,主题是内核。用户界面是操作系统的外在表象,内核才是操作系统的内在核 心。系统其他部分必须依靠内接这部分软件提供的服务,像管理硬件设备、分配系统资源等。 内核有时候被称作是管理者或者是操作系统核心。通常一个内核由负责响应中断的中断服务程 序,负责管理多个进程从而分享处理器时间的调度程序,负责管理进程地址空间的内存管理程 序和网络、进程间通信等系统服务程序共同组成。
当一个应用程 序执行一条系统调用,我们说内核正在代其执行。如果进一步解释,在这种情况下,应用程序被 称为通过系统调用在内核空间运行,而内核被称为运行于进程上下文中。这种交互关系一一-应用 程序通过系统调用界面陷入内核一一是应用程序完成其工作的基本行为方式。
1.4Linux内核和传统Unix内核的比较
Linux 内核与传统的Unix系统之间存在-些显著的差异:
•Linux支持动态加载内核模块。尽管Linux内核也是单内棋,可是允许在需要的时候动态 地卸除和加载部分内核代码.
•Linux支持对称多处理(SMP)机制,尽管许多Unix的变体也支持SMP,但传统的Unix并不支持这种机制。
•Linux内核可以抢占(preemptive)的。与传统的 Unix 变体不同, Linux 内核具有允许在内核 运行的任务优先执行的能力。在其他各种 Unix 产品中,只有 Solaris 和皿IX 支持抢占, 但是大多数 Unix 内核不支持抢占。
•Linux对钱程支持的实现比较有意思:内核并不区分线程和其他的一般进程。对于内核来 说,所有的进程都一样一一只不过是其中的一些共享资源而已。
•Linux提供具有设备类的面向对象的设备模型、热插拔事件,以及用户空阔的设备文件系统(sysfs)。
•Linux忽略了一些被认为是设计得很拙劣的 Unix 特性,像 STREAMS,它还忽略了那些难 以实现的过时标准。
•Linux体现了自由这个词的精髓。现有的 Linux特性集就是 Linux 公开开发模型自由发展 的结果。
不管 Linux 和 Unix有多大的不同,它身上都深深地打上了 Unix 烙印。
1.5 Linux内核版本
第二章 从内核出发
2.1 获取内核源码
登录 Linux 内核官方网站 http://www.kemel.org,可以随时在取当前版本的 Linux源代码,可以是完整的压缩形式(使用 tar 命令创建的一个压缩文件),也可以是增量补丁形式。
2.1.1 使用 Git
在过去的几年中, Linus和他领导的内核开发者们开始使用一个新版本的控制系统来管理Linux内核源代码。 Linus创造的这个系统称为Git.
2.1 .2 安装内核露代码
内核压缩以 GNU zip(gzip)和bzip2 两种形式发布。bzip2是默认和首选形式,因为它在压缩上比gzip 更有优势。以bzip2形式发布的Linux内核叫做linux-x.y.z.tar.bz2, 这里 x.y.z是内核源码的具体版本。
2.1.3 使用补丁
在Linux内核社区中,补丁是通用语。你可以以补丁的形式发布对代码的修改,也可以以补丁的形式接收其他人所做的修改。
2.2 内核源码树
内核源码树由很多目录组成,而大多数目录叉包含更多的子目录。
2.3 编译内核
2.3.1 配置内核
因为Linux源码随手可得,那就意味着在编译它之前可以配置和定制。的确,你可以把自己 需要的特定功能和驱动程序编译进内核。在编译内核之前,首先你必须配置它。
这些配置项要么是二选一,要么是三选一。 二选一就是 yes 或no. 比如 CONFIG PREEMPT 就是二选一,表示内核抢占功能是否开启。三选一可以是 yes、 no 或module. module 意味着该配置项被选定了,但编译的时候这部分功能的实现代码是以模块(一种可以动态安装的独立代码段)的形式生成。在三选一的情况下,显然 yes 选项表示把代码编译进主内核映像中, 而不是作为一个模块. 驱动程序一般都用三选一的配置项。
配置选项也可以是字符串或整数。
这些配置项会被存放在内核代码树根目录下的 .config 文件中。
2.3.2 减少编译的垃圾信息
如果你想尽量少地看到垃圾信息,却又不希望错过错误报告与警告信息的话,你可以用以下命令来对输出进行重定向 :
$ make > ../detritus
一旦你需要查看编译的输出信息,你可以查看这个文件。不过,因为错误和警告都会在屏幕 上显示,所以你需要看这个文件的可能性不大.事实上,我只不过输入如下命令:
$ make > /dev/null
就可把无用的输出信息重定向到永无返回值的黑洞 /dev/null.
2.3.3 衍生多个编译作业
make程序能把编译过程拆分成多个并行的作业。其中的每个作业独立并发地运行,这有助 于极大地加快多处理器系统上的编译过程,也有利于改善处理器的利用率,因为编译大型源代码树也包括 I/0 等待所花费的时间(也就是处理器空下来等待I/0请求完成所花费的时间)。
2.3.4 安装新内核
在内核编译好之后,你还需要安装它.怎么安装就和体系结构以及启动引导工具(bootloader)息息相关了一一查阅启动引导工具的说明,按照它的指导将内核映像拷贝到合适的位置, 并且按照启动要求安装它。一定要保证随时有一个或两个可以启动的内核,以防新编译的内核出现问题。
2.4 内核开发的特点
最重要的差异包括以下几种:
- 内核编程时既不能访问 C库也不能访问标准的 C头文件。
- 内核编程时必须使用 GNU C。 ·内核编程时缺乏像用户空间那样的内存保护机制。
- 内核编程时难以执行浮点运算。 ·内核给每个进程只有一个很小的定长堆钱。
- 由于内核支持异步中断、抢占和 SMP,因此必须时刻注意同步和并发。
- 要考虑可移植性的重要性。
2.4.1 无libc库抑或无标准头文件
与用户空间的应用程序不同,内核不能链接使用标准 C 函数库一一或者其他的那些库也不 行。造成这种情况的原因有许多,其中就包括先有鸡还是先有蛋这个悖论。不过最主要的原因还 是速度和大小。对内核来说, 完整的 C库一一哪怕是它的一个子集,都太大且太低效了。
2.4.2 GNU C ,
像所有自视清高的 Unix 内核一样,Linux内核是用 C语言编写的。让人略感惊讶的是,内核并不完全符合ANSI C标准。实际上,只要有可能,内核开发者总是要用到gcc提供的许多语言的扩展部分。(gcc是多种 GNU 编译器的集合,它包含的C编译器既可以编译内核,也可以编译Linux系统上用C语言写的其他代码。)
- 1. 内联(inline)函数 C99 和 GNU C均支持内联函数。 inline这个名称就可以反映出它的工作方式,函数会在它 所调用的位置上展开。这么做可以消除函数调用和返回所带来的开销(寄存器存储和恢复)。
- 2. 内联汇统 gee 编译器支持在 C 函数中嵌入汇编指令.当然,在内核编程的时候,只有知道对应的体系 结构,才能使用这个功能。 我们通常使用 asm()指令嵌入汇编代码
- 3. 分支卢明 对于条件选择语句, gcc内建了一条指令用于优化,在一个条件经常出现,或者该条件很少 出现的时候,编译器可以根据这条指令对条件分支选择进行优化.内核把这条指令封装成了宏,比如likely()和unlikely(),这样使用起来比较方便。
2.4.3 没有内存保护机制
2.4.4 不要轻易在内核中使用浮点数
2.4.5 容积小而固定的栈
2.4.6 同步和并发
内核很容易产生竞争条件。和单线程的用户空间程序不间,内核的许多特性都要求能够井发 地访问共享数据,这就要求有同步机制以保证不出现竞争条件,特别是:
- Linux 是抢占多任务操作系统。内核的进程调度程序即兴对进程进行调度和重新调度.内 核必须和这些任务同步。
- Linux 内核支持对称多处理器系统 (SMP)。所以,如果没有适当的保护,同时在两个或两 个以上的处理器上执行的内核代码很可能会同时访问共享的同一个资源。
- 中断是异步到来的,完全不顾及当前正在执行的代码。也就是说,如果不加以适当的保 护,中断完全有可能在代码访问资源的时候到来,这样,中段处理程序就有可能访问同一资源。
- Linux 内核可以抢占。所以,如果不加以适当的保护,内核中一段正在执行的代码可能会 被另外一段代码抢占,从而有可能导致几段代码同时访问相同的资摞。
- 常用的解决竞争的办单是自旋锁和信号量
2.4.7 可移植性的重要性
小结:
第 一章将带我们从 Unix 的历史视角来认识 Linux 内核与 Linux 操作系统的前世今生。今天Unix 系统业已愤化成一个具有相似应用程序编程接口(API),并且基于相似设计理念的操作 系统家族。但它又是一个别具特色的操作系统,从萌芽到现在已经有 40余年的历史。若要了解 Linux,我们必须首先认识 Unix 系统。
第二章主要介绍Linux内核的一些基本常识:从何处在取源码,如何编译它,又如何 安装新内核。那么,让我们考察一下内核程序与用户空间程序的差异,以及内核中所使用的通 用编程结构。虽然内核在很多方面有其独特性,但从现在来看,它和其他大型软件项目并无多大差别。