第一章 Linux内核简介
一、历史
由于Unix系统设计简洁并且在发布时提供源代码,所以许多其他组织和团体都对它进了进一步的开发。
Unⅸ虽然已经使用了40年,但计算机科学家仍然认为它是现存操作系统中最强大和最优秀的系统。从1969年诞生以来,由Dennis Ritchie和Ken Thompson的灵感火花点亮的这个Unix产物已经成为一种传奇,它历经了时间的考验依然声名不坠。
二、操作系统和内核简介
处理器在任何指定时间点上的活动范围可以概括为下列三者之一:
运行于内核空间,处于进程上下文,代表某个特定的进程执行。
运行于内核空间,处于中断上下文,与任何进程无关,处理某个特定的中断。
运行于用户空间,执行用户进程。
三、Linux内核和传统UNIX内核特点的比较
- Linux支持动态加载内核模块。
- Linux支持对称多处理(SMP)机制
- Linux内核可以抢占。
- Linux内核并不区分线程和其他的一般进程
四、Linux内核版本
命名规则:
五、Linux内核开发者社区
最重要的论坛:Linux kernel mailing list(lkml)
第二章 从内核出发
一、获取内核源码
课本中给出的方式是使用git,代码如下:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
git pull # 更新分支到Linux的最新分支
安装:
tar xvjf linux-x.y.z.tar.bz2 或者 tar xvzf linux-x.y.z.tar.gz
• 如果使用git获取就不需要下载压缩文件。
• /usr/src/linux目录应当保证原封不动。
打补丁:
patch -p1 < ../patch-x.y.z
二、内核源码树
三、编译内核
1.配置内核
字符页面的命令行工具: make config
图形界面工具 make menuconfig
配置项的二选一和三选一:
二选一:yes 或者 no
三选一:yes 或者 no 或者 module(以模块生成)
其他的几种配置:
make defconfig //基于默认配置
make oldconfig //验证和更新配置
2.编译内核:make
• 减少编译的垃圾信息→对输出进行重定向。
make > .. /detritus # 重定向到这个文件里了
make > /dev/null # 把无用的输出信息重定向到永无返回值的黑洞里。
• 衍生多个编译作业→
make jn # n是衍生出的作业数,每个处理器可以衍生出1或2个作业,16核时n可取32.
3.安装新内核
make modules_install
System.map这个文件是一份符号对照表
四、内核开发的特点
1.内核开发时既不能访问C库也不能访问标准的C头文件
应对:include/linux文件夹中包含了所需的内核头文件。
2.内核编程时必须使用GNU C
内联函数: 函数会在所调用的位置上展开。 定义时,需要使用static作为关键字,用inline限定它。 内联函数必须在使用之前就定义好,一般在头文件中定义。 内核中优先使用内联函数而不是宏。
内联汇编: 通常使用asm()指令嵌入汇编代码,用volatile表示不优化
分支声明:
unlikely(x) - x很少出现,绝少发生,通常为假
likely(y) - y经常出现,通常为真
3.内核编程时缺乏像用户空间那样的内存保护机制
内核中内存不分页。
4.内核编程时难以执行浮点运算
5.内核给每个进程只有一个很小的定长堆栈
6.由于内核支持异步中断、抢占和SMP,必须时刻注意同步和并发
SMP:对称多处理系统。
常用的解决竞争的方法:自旋锁和信号量。
7.要考虑可移植性的重要性
诸如保持字节序,64位对其,不假定字长和页面长度等。