《Linux内核设计与实现》读书笔记从内核出发

Posted 东皇※太一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Linux内核设计与实现》读书笔记从内核出发相关的知识,希望对你有一定的参考价值。

内核源码获取

①可以直接登录linux内核官方网站http://www.kernel.org,可以随时获取当前版本的linux源代码

②也可以使用git工具从远程仓库下载,地址:Linux Kernel: Linux 内核源码镜像

如:git clone git@gitee.com:mirrors/linux_old1.git

这是码云上的linux镜像仓库,国内通过这个仓库下载速度很快,并且每日会同步一次,可以看到目前为止已经有上百万次提交记录

内核源码结构

目录

说明

arch

包含和硬件体系结构相关的代码,存放的是各平台芯片对Linux内核进程调度、内存管理、中断等的支持等

block

块设备驱动程序I/O调度

crypo

常用加密和散列算法(如AES、SHA等),还有一些压缩和CRC校验算法

Documentation

内核各部分的通用解释和注释

drivers

设备驱动程序,每个不同的驱动占用一个子目录,如char、block、net、i2c等。

firmware

使用某些驱动程序而需要的设备固件

fs

所支持的各种文件系统,如EXT、FAT、NTFS、JFFS2等

include

内核头文件

init

内核初始化代码。著名的start_kernel()就位于init/main.c文件中

ipc

进程间通信代码

kernel

内核最核心的部分,包括进程调度、定时器等,而和平台相关的一部分代码放在arch/*/kernel目录下。

lib

通用内核函数,库文件代码

mm

内存管理代码,平台相关的一部分代码放在arch/*/mm目录下

net

网络子系统,实现各种常见的网络协议

samples

示例,示范代码

scripts

编译内核所用的脚本

security

Linux 安全模块

sound

ALSA、OSS音频设备的驱动核心代码和常用设备驱动

usr

早期用户空间代码(所谓的initramfs)

tools

在Linux开发中有用的工具

virt

虚拟化基础结构

内核配置与编译

由于内核提供了数不胜数的功能,支持难以计数的硬件,所以在编译内核之前,必须对它进行配置,让它知道你使用的是哪种架构,哪种芯片,有哪些需要支持的模块等

内核提供了各种不同的工具来简化内核配置

①一种是一个字符界面下的命令行工具

make config

该工具会逐一遍历所有配置项,要求用户选择yes, no或者module

②一种是通过图形界面工具配置

make menuconfig或者make gconfig

配置完之后会在内核代码根目录下生成.config文件,其中就包含了各种配置参数,你也可以直接修改其中的参数

③配置完后就可进行编译

make 也可以 make -jn

这里n是要衍生出的作业数,每个核心一般可以衍生出一个或两个作业,如在16核处理器上,可以输入如下命令:make -j32,就相当于32个线程在同时编译内核

内核开发的特点

①不能访问C库也不能访问标准的C头文件

内核不能链接使用标准C函数库,这是因为C库的效率跟大小限制,所以没采用C库,但大部分常用的C库函数在内核中都已经实现,如操作字符串的函数都在lib/string.c,只要包含<linux/string.h>头文件就可以使用它们。

其中没有实现的printf可以用printk代替,并且printk允许通过指定标志来设置打印优先级,如:

printk(KERN_ERR “this is an error!\\n”);

②必须使用GNU C,推荐用gcc4.4或以后的版本编译内核

Linux内核是用C语言编写的,但内核并不完全符合ANSI X标准,内核开发者总是要用到gcc提供的许多语言的扩展部分,推荐用gcc4.4或之后的版本编译

内联函数:编译时会在它被调用的地方展开,减少了函数调用的开销,性能较好。但是,频繁的使用内联函数也会使代码变长,从而在运行时占用更多的内存。

所以内联函数使用时最好要满足以下几点:函数较小,会被反复调用,对程序的时间要求比较严格。

内联汇编:gcc编译器支持在C函数中嵌入汇编指令,通常使用asm()指令嵌入汇编代码,内联汇编用于偏近底层或对执行时间严格要求的地方,如:

Unsigned int low, high;

Asm volatile(“rdtsc” : “=a” (low), “=d” (high));

/* low和high分别包含64位时间戳的低32位和高32位 */

③没有内存保护机制

内核是最底层的程序,如果内核自己非法访问了内存,或者引用了空指针等,会导致oops,会使系统挂掉,根本不会告诉你一声

④不要轻易使用浮点运算

内核并不能完美的支持浮点操作,因为它本身不能陷入,在内核中使用浮点数时,除了要人工保存和恢复浮点寄存器,还有一些其他琐碎的事情要做,所以,除了一些极少的情况,最好不要在内核中使用浮点操作

⑤堆栈容量小且固定

内核栈的大小有编译内核时决定的,对于不用的体系结构,内核栈的大小虽然不一样,但都是固定的。查看内核栈大小的方法:

ulimit -a | grep "stack size"

⑥支持异步中断、抢占和SMP,所以要特别注意同步和并发

Linux是多用户的操作系统,和单线程的用户空间程序不同,内核的许多特性都要求能够并发地访问共享数据,所以必须处理好同步和并发操作,防止因竞争而出现死锁。

⑦要考虑可移植性

linux内核是一个可移植的操作系统,大部分C代码与体系结构无关,内核开发必须把与体系结构相关的代码从内行代码树的特定目录中适当的分离出来

小结

内核有独一无二的特质,拥有整个系统最高的管理权限,内核源代码是可以免费获取的,直接用就可以了,在内核开发之路上最重要的步骤是要意识到内核并没有那么可怕,陌生是肯定的,但真的就不可逾越?事实并非如此。

以上是关于《Linux内核设计与实现》读书笔记从内核出发的主要内容,如果未能解决你的问题,请参考以下文章

《Linux内核设计与实现》读书笔记从内核出发

《Linux内核设计与实现》读书笔记(十九)- 可移植性

《linux内核设计与实现》读书笔记第十八章

《Linux内核设计与实现》读书笔记 - 目录 (完结)转

《Linux内核设计与实现》Chapter 2 读书笔记

《Linux内核设计与实现》第3章读书笔记