说到内核,需要提两个重要的内容
1.GNU计划:开发了优秀的编译器GCC和调试器GDB等基础设施
2.POSIX标准:可移植的操作系统接口。
一、内核各版本主要特点
文章图片
二、版本的命名
版本有两个小数点,三部分数字,如LINUX 2.6.35, 数字不停的增大,周期2-3个月
三、版本变更的详细信息
在这个网站可以查到http://kernelnewbies.org/LinuxVersions。
四、LINUX内核的近期热点和走向
网址https://www.linuxfoundation.org/news-media/lwf
五、linux 2.6后的内核特点
- 新的调度器:CFS算法或EDF算法
- 内核抢占:内核任务可以被抢占,这样中断速度会更快,当然也保留了不可抢占的区间,如中断上下文、软中断上下文和自旋锁锁住的区间。
如果给Linux内核打上RT-Preempt补丁,则中断和软中断都被线程化了,自旋锁也被互斥体替换,Linux内核变得能支持硬实时。 - 改进的线程模型:采用NPTL模型
- 虚拟内存的变化:融合了r-map(反向映射)技术,显著改善虚拟内存在一定大小负载下的性能。
- 文件系统:增加对日志文件系统的扩展功能支持。
- 音频系统:ALSA架构支持,替换OSS
- 总线、设备和驱动模型:总线match设备和驱动后,调用驱动的probe
- 电源管理:支持高级配置和电源接口(Advanced Configuration and Power
Interface,ACPI), - 联网和IPSec:
- 用户界面层:重写了帧缓冲/控制台层,人机界面层还加入了对近乎所有接口设备的支持
·block:块设备驱动程序I/O调度。
·crypto:常用加密和散列算法(如AES、SHA等),还有一些压缩和CRC校验算法。
·documentation:内核各部分的通用解释和注释。
·drivers:设备驱动程序,每个不同的驱动占用一个子目录,如char、block、net、mtd、i2c等。
·fs:所支持的各种文件系统,如EXT、FAT、NTFS、JFFS2等。
·include:头文件,与系统相关的头文件放置在include/linux子目录下。
·init:内核初始化代码。著名的start_kernel()就位于init/main.c文件中。
·ipc:进程间通信的代码。
·kernel:内核最核心的部分,包括进程调度、定时器等,而和平台相关的一部分代码放在arch//kernel目录下。
·lib:库文件代码。
·mm:内存管理代码,和平台相关的一部分代码放在arch//mm目录下。
·net:网络相关代码,实现各种常见的网络协议。
·scripts:用于配置内核的脚本文件。
·security:主要是一个SELinux的模块。
·sound:ALSA、OSS音频设备的驱动核心代码和常用设备驱动。
·usr:实现用于打包和压缩的cpio等。
·include:内核API级别头文件。
七、内核的组成部分
文章图片
- 进程管理
进程相关的内容可参考这份文档
- 内存管理
内存管理的主要作用是控制多个进程安全地共享主内存区域。
Buddy算法:管理每个页的占用情况,内核空间的slab,用户控件的C库二次管理。
页缓存支持:用内存缓存磁盘,per-BDI flusher线程用于刷回脏的页缓存到磁盘。
Kswapd(交换进程):Linux中用于页面回收(LRU算法)(包括file-backed的页和匿名页)的内核线程。
文章图片
文章图片
网络接口
Linux内核支持的协议栈种类较多,如Internet、UNIX、CAN、NFC、Bluetooth、WiMAX、IrDA等,上层的应用程序统一使用套接字接口。
文章图片
八、内核空间和用户空间
现代CPU内部往往实现了不同操作模式(级别),不同模式有不同功能,高层程序往往不能访问低级功能,而必须以某种方式切换到低级模式。
ARM处理器分为7种工作模式。但是内核只用了其中的2种
·用户模式(usr):大多数应用程序运行在用户模式下,当处
理器运行在用户模式下时,某些被保护的系统资源是不能访问的。
·快速中断模式(fiq):用于高速数据传输或通道处理。
·外部中断模式(irq):用于通用的中断处理。
·管理模式(svc):操作系统使用的保护模式。
·数据访问中止模式(abt):当数据或指令预取中止时进入该模式,可用于虚拟存储及存储保护。
·系统模式(sys):运行具有特权的操作系统任务。
·未定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。
ARM Linux的系统调用实现原理是采用swi软中断从用户(usr)模式陷入管理模式(svc)。
九.编译内核
详细看这篇文章1和文章2
十、内核的引导
一般的SoC内嵌入了bootrom,上电时bootrom运行。对于CPU0而言,bootrom会去引导bootloader,而其他CPU则判断自己是不是CPU0,进入WFI的状态等待CPU0来唤醒它。CPU0引导bootloader,bootloader引导Linux内核,在内核启动阶段,CPU0会发中断唤醒CPU1,之后CPU0和CPU1都投入运行。CPU0导致用户空间的init程序被调用,init程序再派生其他进程,派生出来的进程再派生其他进程。CPU0和CPU1共担这些负载,进行负载均衡。
文章图片
bootrom是固化在cpu里面的,不可改变。
bootloader常见的有U-BOOT
十一、C编程风格
Linux有独特的编码风格,在内核源代码下存在一个文件Documentation/CodingStyle,进行了比较详细的描述。
- 命名:喜欢用_下划线分割单词,如
#def ine PI 3.1415926
int min_value, max_value;
void send_data(void);
- Linux的代码缩进使用“TAB”。
- 对于结构体、if/for/while/switch语句,“{”不另起一行
struct var_data {
int len;
char data[0];
};
if (a == b) {
a = c;
d = a;
}
for (i = 0;
i < 10;
i++) {
a = c;
d = a;
}
- 如果if、for循环后只有1行,不要加“{”和“}”
for (i = 0;
i < 10;
i++)
a = c;
- if和else混用的情况下,else语句不另起一行
if (x == y) {
...
} else if (x > y) {
...
} else {
...
- 对于函数,“{”另起一行
int add(int a, int b)
{
return a + b;
}
- 在switch/case语句方面,Linux建议switch和case对齐
十二、GNU C 和 ANSI C
GNU C 支持如下常用特性:
1.零长度和变量长度数组
2.case可以指定范围
3.语句表达式
4.typeof关键字
5.可变参数宏
6.标号元素
7.当前函数名
8.特殊属性声明
9.内建函数
十三、linux常见语句
do{}while(0)语句
goto语句
【LINUX驱动|LINUX驱动学习之4-LINUX内核和内核编程】十四、开发工具链
- strip可以删除可执行文件中的符号表和调试信息等来实现缩减程序体积的目的。
- gprof在编译过程中在函数入口处插入计数器以收集每个函数的被调用情况和被调用次数,检查程序计数器并在分析时找出与程序计数器对应的函数来统计函数占用的时间。
- objdump是反汇编工具。
- nm则用于显示关于对象文件、可执行文件以及对象文件库里的符号信息。其中,前缀中的“hf”显示该工具链是完全的硬浮点,由于目前主流的ARM芯片都自带VFP或者NEON等浮点处理单元(FPU),所以对硬浮点的需求就更加强烈。Linux的浮点处理可以采用完全软浮点,也可以采用与软浮点兼容,但是使用FPU
硬件的softfp,以及完全硬浮点。具体的ABI(Application BinaryInterface,应用程序二进制接口)通过-mfloat-abi=参数指定,3种情况下的参数分别是-mfloat-abi=soft/softfp/hard。在以前,主流的工具链采用“与软浮点兼容,但是使用FPU硬件的softfp”。softfp使用了硬件的FPU,但是函数的参数仍然使用整型寄存器来传递,完全硬浮点则直接使用FPU的寄存器传递参数。
推荐阅读
- Linux驱动开发(从零开始编写一个驱动程序)
- Linux驱动开发-编写PCF8591(ADC)芯片驱动
- Linux驱动开发-编写(EEPROM)AT24C02驱动
- Linux驱动分析之LCD驱动架构
- Linux驱动之I2C设备驱动
- Linux驱动分析之SPI设备
- Linux驱动分析之SPI驱动架构
- Linux驱动分析之SPI控制器
- Linux驱动之I2C驱动架构