第一章 Linux内核简介
一、Unix的历史
Unix操作系统尽管已经使用了40年,但在计算机领域中仍然处于最优秀的地位,Unix的地位之所以重要,归结原因如下:
1.Unix的内核和相关的系统工具软件是用C语言编写的
2.在Unix中所有的东西都被当做文件对待
3.Unix提供了一套非常简单但又很稳定的进程间通讯元语,使得Unix的程序把目标放在一次执行保质保量的完成一个任务上
处理器在任何指定时间点上的活动范围可以概括为下列三者之一:
运行于内核空间,处于进程上下文,代表某个特定的进程执行。
运行于内核空间,处于中断上下文,与任何进程无关,处理某个特定的中断。
运行于用户空间,执行用户进程。
Linux内核和传统Unix系统之间存在一些差异:
1. Linux支持动态加载内核模块。
2. Linux支持对称多处理(SMP)机制
3. Linux内核可以抢占。
4. Linux内核并不区分线程和其他的一般进程
5. Linux提供具有设备类的面向对象的设备模型、热插播事件以及sysfs
Kernel版本命名规则:
在Linux内核官方网站http://www.kernel.org,可以随时获取当前版本的Linux源代码
如果压缩形式是bzip2,则运行:
$ tar xvjf linux-x.y.z.tar.bz2
如果压缩形式是GNU的zip,则运行
$ tar xvzf linux-x.y.z.tar.gz
解压后的源代码位于linux-x.y.z.目录下。
何处安装源码:内核源码一般安装在/usr/src/linux目录下。
要应用增量补丁,从你的内部源码树开始,只是运行:
$ patch p1 < ../patch-x.y.z
一般说来,一个给定版本的内核补丁总是打在前一个版本上
我利用命令来对输出进行重定向
make >../detritus
一旦需要查看编译的输出信息,可以查看这个文件。不过,因为错误和警告都会在屏幕上显示,所以你需要看这个文件的可能性不大。事实上,我只不过敲入如下命令
$ make > /dev/null
这就把无用的输出信息重定向到永无返回值的黑洞/dev/null。
为了以多个作业编译内核,使用以下命令: $ make -jn • 这里,n是要衍生的作业数,在实际中,每个处理器上一般衍生一个或者两个作业。例如,在一个双处理器上,可以输入如下命令: $ make –j4
以root身份,只要运行: % make modules_install 就可以把所有已编译的模块安装到正确的主目录/lib下。
Linux内核编程与用户空间内应用程序开发的差异
1.Linux内核编程时不能访问C库
2.Linux内核编程时必须使用GNU C
3.Linux内核编程时缺乏像用户空间那样的内存保护机制。
4.Linux内核编程时浮点数很难使用。
5.内核只有一个很小的定长堆栈。
6.由于内核支持异步中断、抢占式和SMP,因此必须时刻注意同步和并发。
7.要考虑可移植性的重要性。
在所有没有实现的函数中,最著名的就数printf()函数了。内核代码虽然无法调用printf(),但它可以调用printk()函数。
内核开发者使用的C语言涵盖了ISO C995标准和GNU C扩展特性。
1.内联(inline)函数
2.内联汇编
3.分支声明
如果一个用户程序试图进行一次非法的内存访问,内核会发现这个错误,发送 SIGSEGV,并结束整个进程。
内核中发生的内存错误会导致oops,这是内核中出现的最常见的一类错误。
内核中的内存都不分页。
在执行浮点指令时到底会做些什么,因体系结构不同,内核的选择也不同,但是,内核通常捕获陷阱并做相应处理。
和用户空间进程不同,内核并不能完美地支持浮点操作,因为它本身不能陷入。
内核栈的准确大小随体系结构而变。在x86上,栈的大小在编译时配置,可以是4KB也可以是8KB。
从历史上说,内核栈的大小是两页,这就意味着,32位机的内核栈是8KB,而64位机是16KB,这是固定不变的。
Linux是抢占多任务操作系统。内核的进程调度程序即兴对进程进行调度和重新调度。内核必须对这些任务同步。
Linux内核支持多处理器系统。
中断是异步到来的,完全不顾及当前正在执行的代码。
Linux内核可以抢占。
Linux是一个可移植的操作系统,
必须把体系结构相关的代码从内核代码树的特定目录中适当地分离出来。
原文:http://www.cnblogs.com/20132109HKK/p/5287173.html