《Linux内核设计与实现》学习记录一
chapter1 Linux内核简介
前言:Unix是一个具有相似应用程序编程接口(API)并且基于相似设计理念的操作系统家族。
1.1 Unix的历史
1.Unix演化版实现了任务管理、换页机制、TCP/IP等新的特性。
2.Unix的特点:
- Unix很简洁,仅仅提供几百个系统调用并且有一个非常明确的设计目的;
- 在Unix中,所有的东西都被当做文件对待。
- Unix的内核和相关的系统工具软件是用C语言编写的,具有强大的移植能力
- Unix的进程创建非常迅速,并且有一个非常独特的fork()系统调用。(ps.关于fork的内容可以参照:链接一、链接二)
- Unix提供了一套非常简单但又很稳定的进程间通信元语,快速简洁的进程创建过程使Unix的程序把目标放在一次执行保质保量地完成一个任务上,简单稳定的进程间通信机制又使其能够方便组合,具备清晰的层次化结构。
3.Unix的现状:成为一种支持抢占式多任务、多线程、虚拟内存、换页、动态链接和TCP/IP的现代化操作系统。
1.2 追寻Linus足迹:Linux简介
(ps.关于这部分历史演进可以参照:链接三)
1.Linux现在广泛移植到Alpha、ARM、PowerPC、SPARC、x86-64等其他体系结构之上。
2.Linux是类Unix系统,但不是Unix。Linux没有直接使用Unix的源代码,它的实现可能和其他各种Unix的实现大相径庭,但它没有抛弃Unix的设计目标并且保证了应用程序编程接口的一致。
3.Linux内核是自由公开软件,是开源的。
4.Linux的基础是内核、C库、工具集和系统的基本工具。Linux这个词汇在本书中主要还是指内核。
1.3 操作系统和内核简介
1.操作系统是指在整个系统中负责完成最基本功能和系统管理的部分。包括内核、设备驱动程序、启动引导程序、命令行shell、其他种类的用户界面、基本的文件管理工具和系统工具。
2.系统其他部分必须依靠内核这部分软件提供的服务,内核有时候被称作管理者或者操作系统核心,负责响应中断的中断服务程序,负责管理多个进程从而分享处理器时间的调度程序,负责管理进程地址空间的内存管理程序和网络和网络、进程间通信等系统服务程序.
3.内核一般处于系统态,拥有受保护的内存空间和访问硬件设备的所有权限,这种系统态和被保护起来的内存空间,统称为内核空间。
4.内核负责管理系统的硬件设备,即提供了中断机制。当硬件设备和系统通信时,先发出一个一部的中断信号去打断处理器的执行,继而打断内核的执行。内核再根据产生的中断号查找相应的中断服务程序,调用这个程序响应和处理中断。
Linux的中断服务程序不在进程上下文中执行,而是在一个与所有进程都无关的、专门的中断上下文中进行,这样可以保证中断服务程序能够在第一时间响应和处理中断请求,然后快速地退出。
上下文表示着内核的活动范围。将每个处理器在任何指定时间点上的活动概括如下:
运行于用户控件,执行用户进程 运行于内核控件,处于进程上下文,代表某个特定的进程执行 运行于内核控件,处于中断上下文,与任何进程无关,处理某个特定的中断。
1.4 Linux内核和传统Unix内核的比较
1.Unix内核是一个不可分割的静态可执行库。必须以巨大、单独的可执行块的形式在一个单独的地址空间中运行。Unix内核通常需要硬件系统提供页机制(MUU)来管理内存。这样可以加强对内存空间的保护保证每个进程都而已运行于不同的虚地址空间上。
2.单内核与微内核设计的比较
操作系统内核可以分为两大阵营:单内核和微内核
1.单内核就是把它从整体上作为一个单独的大过程来实现、同时也运行在一个单独的地址空间上。内核通常以单个静态二进制文件的形式存放在磁盘中。
内核间通信、内核调用函数等与用户空间应用程序无异。
2.微内核的功能被划分为多个独立过程,每个过程称为服务器。微内核通信通过消息传递处理,即采用了进程间通信机制(IPM)。用于互换“服务”。服务器的独立自主有效地避免了一个服务器的失效祸及另一个,同样,模块化得系统允许一个服务器为了另一个服务器而换出。
- (ps.关于进程间通信部分的内容可以参考:链接四)
3.Linux是一个单内核,但也吸收了微内核的精华(模块化设计、抢占式内核、支持内核线程、动态装载内核模块)。即它是模块化的,多线程的以及内核本身可调度的操作系统。
1.5 Linux内核版本
1.Linux通过一个简单的命名机制来区分稳定的和处于开发中的内核。即用三个护着四个用“.”分割的数字来代表不同内核版本。第一个数字是朱版本号,第二个数字是从版本号,第三个数字是修订版本号,第四个可选的数字为稳定版本号。
2.从副版本号可以反映出该内核是一个稳定版本还是一个处于开发中的版本:如果数字为偶数,即是稳定版内核;若是奇数,则是开发版内核。
chapter2 从内核出发
2.1 获取内核源码
- 使用Git
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git git pull # 更新分支到Linux的最新分支
-
安装内核源代码(如果使用git获取就不需要下载压缩文件。)以下两者均可。
tar xvjf linux-x.y.z.tar.bz2 tar xvzf linux-x.y.z.tar.gz
内核源代码一般安装在/usr/src/linux目录下,即使在安装新内核时,/usr/src/linux目录应当保证原封不动。
-
使用补丁
patch -p1 < ../patch-x.y.z
2. 2内核源码树
2.3 编译内核
1.配置内核
配置项的二选一和三选一:
二选一:yes 或者 no
三选一:yes 或者 no 或者 module(module意味着该配置被选定了,以模块生成。驱动程序一般都用三选一的配置项)
字符页面的命令行工具:
make config
图形界面工具:
make menuconfig
基于默认配置为体系结构创建一个配置:
make defconfig
验证和更新配置:
make oldconfig
2.编译内核
编译内核:
make
重定向到该文件中:
make > .. /detritus
把无用的输出信息重定向到永无返回值的黑洞中:
make > /dev/null
3. 安装新内核
将所有已编译的模块安装到正确的主目录/lib/modules下
make modules_install
2.4 内核开发的特点
- 内核开发时既不能访问C库也不能访问标准的C头文件 (解决方法:include/linux文件夹中包含了所需的内核头文件。)
-
内核编程时必须使用GNU C
-
内联函数: 函数会在所调用的位置上展开。 定义时,需要使用static作为关键字,用inline限定它。 内联函数必须在使用之前就定义好,一般在头文件中定义。 内核中优先使用内联函数而不是宏。
-
内联汇编: 通常使用asm()指令嵌入汇编代码,用volatile表示不优化
- 分支声明: unlikely(x) - x很少出现,绝少发生,通常为假 likely(y) - y经常出现,通常为真
-
内核编程时缺乏像用户空间那样的内存保护机制
- 内核编程时难以执行浮点运算
- 内核给每个进程只有一个很小的定长堆栈
- 由于内核支持异步中断、抢占和SMP(对称多处理系统),必须时刻注意同步和并发。(常用的解决竞争的方法:自旋锁和信号量)。
- 要考虑可移植性的重要性(诸如保持字节序,64位对其,不假定字长和页面长度等。)
chapter 3 遇到的问题及解决办法
问题:我重新装了一个Ubuntu的虚拟机。在倒腾的过程中发现根据书中第二章的命令无法同步git中的代码。甚至提示我未安装git。我使用sudo apt-get install git的时候也报错。
解决办法:我认为是代码源不正确。因此百度了更换代码源的方法。将us的代码源改成cn的了。
将方法附在此:
用vi和gedit 打开 /etc/apt/sources.list 。
将其中的us.archive 全部替换为 cn.archive,这样,以后使用apt-get下载就会使用源自http://cn.archive.ubuntu.com 了。
使用vi编辑器的命令为(注意首先切换到root用户):
root@ubuntu :/#vi /etc/apt/sources.list
打开sources.list。
在vi命令模式下(进入后即是命令行模式,按i后才可进入编辑模式,不过这里不需要编辑模式),输入
:%s/us.archive/cn.archive/g
这样,就将apt-get的源更改为国内的源了。
下面必须重起下apt-get,输入命令:
apt-get update
chapter4 总结
这篇博客是对教材《Linux内核设计与分析》的一个阅读记录。比起看视频来说,对照书本的学习我个人比较习惯,因为视频中的部分讲解感觉并没有讲的很清楚,有时候讲师也是含含糊糊就过去了。有时候觉得自己看完了视频没有学到很多,认为是自己的问题又倒回去反反复复看了几遍,这样一来花费了很多时间。而看书的话,我觉得对一些概念性的东西讲的更多。我认为一年多以来娄老师、刘老师的教导方式的磨练下,我已经渐渐明白对于我个人来说,视频更多的是教会我如何时候用计算机操作实践,网上实验楼的平台也非常好用,不用再课下总是倒腾装软件搭平台。虽然说这种操作很实用,但是如果每学一门课,每做一个实验就要花上好多时间来装东西真的很费心费力,特别是在学校的网络下来说特别吃力。因此我非常依赖于实验楼这个平台。
另外,这学期还未开学我就开始跟慕课视频,个人感觉还是比较认真的。但是老师上课的时候有时候会听的云里雾里,感觉视频听懂了上课却又有很多补充的东西没听懂。就像是这一秒钟没听懂之后就都是&……%¥#@的感觉。让我很有挫败感。实验也是做了之后并不知道一些命令是什么意思。课下功夫非常多。还有博客写完之后我会去看看身边大神的笔记然后再来对照自己的笔记。觉得大家记录都差不多,但是体会就差很多。老师的评论也让我有些恍惚。似乎是感觉自己学的和别的同学不是在一个水平上。有一种老师对我的学习比较担忧的感觉?
但是老师给我的问题会让我更重视一些问题的理解,每每老师留了问题我就会倒回去看看我对这部分问题的记录和理解,然后再查点资料再来补充一下。生怕答得有偏差?总之,接下来的学习我觉得会更加重视博客的质量,多和其他同学交流学习一下优秀博客的心得。