《linux内核设计与实现》读书笔记从内核出发(代码片段)

东皇※太一 东皇※太一     2022-11-28     248

关键词:

内核源码获取

①可以直接登录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内核设计与实现》读书笔记-内核同步方法(代码片段)

...3.读写自旋锁4.信号量5.读写信号量6.互斥体7.完成变量8.大内核锁9.顺序锁10.禁止抢占11.顺序和屏障12.总结内核中提供了多种方法来防止竞争条件,理解了这些方法的使用场景有助于我们在编写内核代码 查看详情

《linux内核设计与实现》读书笔记linux内核简介

Unix的历史①Unix诞生于1969年,至今仍然被认为是现存操作系统中最强大和最优秀的系统。②Unix起源于一个失败的多用户操作系统Multics,Multics终止而Unix萌生。③1973年整个Unix操作系统用C语言进行了重写,为后面各种... 查看详情

《内核设计与实现》读书笔记-进程管理

...程序以及相关的资源的总称。线程是进程中活动的对象。内核调度的对象是线程,而不是进程。进程和线程的管理操作(比如创建和销毁)都是由内核来实现的。Linux中的进程于Windows相比是很轻量级的,而且不严格区分进程和线... 查看详情

《linux内核设计与实现》读书笔记linux进程管理(代码片段)

...于执行期的程序,通常进程还包含挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程,还包含存放全局变量的数据段等。②线程是进程中活动的对象ÿ... 查看详情

《linux内核设计与实现》读书笔记-内核同步方法(代码片段)

...3.读写自旋锁4.信号量5.读写信号量6.互斥体7.完成变量8.大内核锁9.顺序锁10.禁止抢占11.顺序和屏障12.总结内核中提供了多种方法来防止竞争条件,理解了这些方法的使用场景有助于我们在编写内核代码时选用合适的同步方法&#... 查看详情

《linux内核设计与实现》读书笔记linux进程管理(代码片段)

...于执行期的程序,通常进程还包含挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程,还包含存放全局变量的数据段等。②线程是进程中活动的对象ÿ... 查看详情

《linux内核设计与实现》笔记——内核同步简介

相关概念竞争条件多个执行线程(进程/线程/中断处理程序)并发(并行)访问共享资源,因为执行顺序不一样造成结果不一样的情况,称为竞争条件(racecondition)举例说明#include<thread>usingnamespacestd;inti=0;voidthread1(){//for(intx=0;x&... 查看详情

《linux内核设计与实现》笔记——vfs

关于VFS有一篇很好的博客http://www.ibm.com/developerworks/cn/linux/l-vfs/建议先阅读本文为基础,然后继续阅读该文章。VFS,虚拟文件系统,为用户提供了文件和文件系统相关的接口。这些接口可以跨越各种文件系统和不同介质执行。VFS... 查看详情

linux内核设计与实现的目录

参考技术A译者序序言前言作者简介第1章 Linux内核简介11.1 Unix的历史11.2 追寻Linus足迹:Linux简介21.3 操作系统和内核简介31.4 Linux内核和传统Unix内核的比较51.5 Linux内核版本71.6 Linux内核开发者社区81.7 小结8第2章 从内... 查看详情

《linux内核设计与实现》学习笔记——中断中断处理程序

...线,每个irq线关联一个数值。中断处理程序响应中断时,内核会执行一个函数,中断处理程序/中断服务例程ISR,一个设备的中断处理程序是他的设备驱动的一部分。IO资源包括:中断,I/O端口,共享RAM,DMA。驱动程序需要管理注... 查看详情

《linux内核设计与实现》学习笔记——i/o调度算法

I/O调度子系统用于调度来自多个进程对块设备的I/O请求。电梯调度首先,如果队列中已存在一个对相邻磁盘扇区操作的请求,那么新请求将和这个已经存在的请求合并为一个请求。2.如果队列中存在一个驻留时间过长的请求,那... 查看详情

读书笔记

...制端,防火墙一般不会栏截协议的报文。由于包是由系统内核或进程进行直接处理的,并不通过端口,因此在通信过程中不会占用任何端口,很难被发觉。这种木马通 查看详情

《linux内核设计与实现》知识整合与讲解-第一章

Linux内核简介第一章主要对Linux的内核进行一个大致的介绍,让大家对Linux的内核有一个比较全面的印象。众所周知Linux起源于unix系统,它们之间有着千丝万缕的联系,伟大的linux之父linus不满于当时unix对于源码更改的限制,花费... 查看详情

android深度探索——第十章读书笔记及心得

...学习了解了printk函数。该函数与printf函数类似,用于打印内核调试信息。只是前者运行在内核空间,后者运行在用户空间。即linux驱动这样的linux内核程序只能使用printk函数输出调试信息。Printk函数的原型:asmLinkKageintprintk(constcha... 查看详情

读薄《linux内核设计与实现》-中断与同步

这篇文章是《读薄「Linux内核设计与实现」》系列文章的第IV篇,本文主要讲了以下问题:中断和中断处理程序的概念与实现原理、Linux中的下半部以及内核同步方法。0x00中断和中断处理程序I中断中断是一种特殊的电信号,由硬... 查看详情

android深度探索--hal与驱动开发----第九章读书笔记

...x驱动复杂、不统一的接口。解决了GPL版权问题。由于Linux内核基于GPL协议,而Android基于ApacheLicence2.0、协议。因此Google玩了个“穿越“,将原本位于Linux驱动中的敏感代码向上移了一个层次。这样这些敏感代 查看详情

ssl读书笔记

...全的  在linux系统上,网络上的通信实现由用户空间和内核空间共同实现,内核以模块的方式(tcpip协议栈)提供通信子网,而资源子网由用户程序实现。  TCP/IP是可能被窃听的网络,而HTTP是不加密的传输,可以用一些例如Packe... 查看详情

《linux设计与实现》笔记——系统调用工作原理添加系统调用的过程

系统调用的意义为了和用户空间上的进程进行交互,内核提供的提供的一组接口。应用程序通过这组接口访问硬件和其他操作系统资源。完成对硬件和资源访问的控制。安全、可靠,多任务、虚拟必须硬件设备的抽象(提供设备... 查看详情