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

在尝试内核开发之前,需要对内核有个整体的了解。

主要内容:

获取内核源码

内核源码的结构

编译内核的方法

内核开发的特点

1. 获取内核源码

内核是开源的,所有获取源码特别方便,参照以下的网址,可以通过git或者直接下载压缩好的源码包。

2. 内核源码的结构

目录   说明  
arch   特定体系结构的代码  
block   块设备I/O层  
crypo   加密API  
Documentation   内核源码文档  
drivers   设备驱动程序  
firmware   使用某些驱动程序而需要的设备固件  
fs   VFS和各种文件系统  
include   内核头文件  
init   内核引导和初始化  
ipc   进程间通信代码  
kernel   像调度程序这样的核心子系统  
lib   同样内核函数  
mm   内存管理子系统和VM  
net   网络子系统  
samples   示例,示范代码  
scripts   编译内核所用的脚本  
security   Linux 安全模块  
sound   语音子系统  
usr   早期用户空间代码(所谓的initramfs)  
tools   在Linux开发中有用的工具  
virt   虚拟化基础结构  

3. 编译内核的方法

还未实际尝试过手动编译内核,只是用yum更新过内核。这部分等以后手动编译过再补上。

安装新的内核后,重启时会提示进入哪个内核。当多次安装新的内核后,启动列表会很长(因为有很多版本的内核),显得不是很方便。

下面介绍3种删除那些不用的内核的方法:(是如何安装的就选择相应的删除方法)

3.1 rpm 删除法

rpm -qa | grep kernel*  (查找所有linux内核版本)
  rpm -e kernel-(想要删除的版本)

3.2 yum 删除法

yum remove kernel-(要删除的版本)

3.3 手动删除

删除/lib/modules/目录下不需要的内核库文件
  删除/usr/src/kernel/目录下不需要的内核源码
  删除/boot目录下启动的核心档案禾内核映像
  更改grub的配置,删除不需要的内核启动列表

4. 内核开发的特点 4.1  无标准C库

为了保证内核的小和高效,内核开发中不能使用C标准库,所以连最常用的printf函数也没有,但是还好有个printk函数来代替。

4.2 使用GNU C,推荐用gcc 4.4或以后的版本来编译内核

因为使用GNU C,所有内核中常使用GNU C中的一些扩展:

4.2.1 内联函数

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

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

内联函数示例:static inline void sample();

4.2.2 内联汇编

内联汇编用于偏近底层或对执行时间严格要求的地方。示例如下:

unsigned int low, high; asm volatile("rdtsc" : "=a" (low), "=d" (high)); /* low 和 high 分别包含64位时间戳的低32位和高32位 */

4.2.3 分支声明

如果能事先判断一个if语句时经常为真还是经常为假,那么可以用unlikely和likely来优化这段判断的代码。

/* 如果error在绝大多数情况下为0(假)*/
if (unlikely(error)) {
   
/* ...*/
}

/* 如果success在绝大多数情况下不为0(真)*/
if (likely(success)) {
   
/* ...*/
}

4.3 没有内存保护

因为内核是最低层的程序,所以如果内核访问的非法内存,那么整个系统都会挂掉!!所以内核开发的风险比用户程序开发的风险要大。

而且,内核中的内存是不分页的,每用一个字节的内存,物理内存就少一个字节。所以内核中使用内存一定要谨慎。

4.4 不使用浮点数

内核不能完美的支持浮点操作,使用浮点数时,需要人工保存和恢复浮点寄存器及其他一些繁琐的操作。

4.5 内核栈容积小且固定

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

查看内核栈大小的方法:

ulimit -a | grep "stack size"

4.6 同步和并发

Linux是多用户的操作系统,所以必须处理好同步和并发操作,防止因竞争而出现死锁。

4.7 可移植性

Linux内核可用于不用的体现结构,支持多种硬件。所以开发时要时刻注意可移植性,尽量使用体系结构无关的代码。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/3b179749d1126fc9496b1d1b8784e595.html