1.操作系统和内核简介
linux 把操作系统划分为内核空间和用户空间。
对于提供保护机制的现代系统来说,内核拥有受保护的内存空间和访问硬件设备的所有权限。相对的,应用程序在用户空间执行,其通过系统调用和内核通信来运行。
linux是一个单内核,linux运行于单独的内核地址空间。不过他也汲取了微内核的精华:模块化设计、抢占式内核、支持内核线程以及动态装载内核。同时避免了微内核性能上的缺陷,直接调用函数,无需消息传递。
2.从内核出发
2.1编译内核
linux源码随手可得,在编译内核之前必须配置其选项。可以配置的各种选项以COFIG为前缀,如对称多处理SMP的配置选项为COFIG_SMP。配置项可以是yes 、no或者会多一个module。module意味着配置项被选定,但编译时 以模块形式生成。
内核提供了不同的工具简化配置,如
$ make config
该工具遍历所有配置项,要求用户选择yes no module.这会花费很长时间。所以应选基于ncurse或X11或gtk+的图形工具。
$ make menuconfig
$ make xconfig
$ make gconfig
这三种工具将配置项分门别类放置。
$ make defconfig将创建默认配置。
这些配置项存放于内核代码根目录的config文件。
修改过配置文件后,用 $ make oldconfig验证和更新配置。配置后,用 $ make 编译。
编译时为看到错误和警告信息,而不是掠过屏幕的垃圾信息,可用 $ make >../some_other_file 来实现。
2.3编译内核
以root运行 % make modules_install就可将已编译的模块安装到/lib下。
2..4内核开发的特点
1.内核编程不能访问C库
2.内核编程必须使用 GNU C
3.内核编程缺乏像用户空间那样的内存保护机制
4.内核编程很难使用浮点数
5.内核只有一个很小的定长堆栈
6.内核支持异步中断、抢占和SMP,因此必须时刻注意同步和并发。
7.考虑可移植性的重要
2.41没有libc库
内核不能连接使用标准c函数库,原因有很多,其中就包括先有鸡还是先有蛋的悖论,但最主要的是C库太大了,内核的速度大小受限。
谈论头文件时,指的都是组成内核代码树的内核头文件而不是外部头文件。例如printk与printf。
2.42 GNU C
内核代码中所使用的C扩展
1.内联函数
内核开发者通常把那些对时间要求比较高、本身长度比较短的函数定义为内联函数。
2.内联汇编
gcc编译器支持在C函数中嵌入汇编指令。
3.分支声明
gcc对条件选择语句用指令进行了优化。在一个条件经常或很少出现时,编译器根据这条指令对条件分支选择进行优化。
2.43没有内存保护机制
如果内存非法访问了内存,他很可能会死掉。此外,内核的内存不分页。
2.44不轻易在内核中使用浮点数
不要在内核中使用浮点数
2.45容积小而固定的栈
用户空间的栈空间大且可动态增长,内核的栈随体系结构而变。