【内核】——从内核出发

1、获取最新内核源码:git clone https://github.com/torvalds/linux

  获取各个版本内核源码:http://mirrors.aliyun.com/linux-kernel/

Ubuntu下解压:unzip linux-master.zip  

2、内核源码树的根目录描述:

3、编译内核

3.1、配置内核

由于内核提供了数不胜数的功能,支持了难以计数的硬件,因而由于许多东西需要配置,想Ubuntu,Redhat的Fedora他们的发布版包含了预编译的内核。而作为一个内核黑客,你应该编译自己的内核,并按照自己的意愿决定包括或者不包含哪个模块。

内核提供了各种不同的工具来简化内核配置,最简单的一种你是字符界面下的命令行工具(不推荐):

$ make config
# 或者你curse库编制的图形界面工具
$ make menuconfig
# 或者,是用基于gtk+的图形工具
$ make gconfig
# 或者,基于默认的配置为你的体系结构创建以配置
$ make defconfig

  这些配置项会被存放在内核代码树根目录下的.config文件中。

  注:我再Ubuntu下配置内核的时候需要很多库支持,可以使用apt-get install 命令安装。

在你修改过配置文件以后,你应该验证和更新配置:

$ make oldconfig

  一旦内核配置好了,就可以使用make来编译它了。


3.2、减少编译的垃圾信息

  如果不像看编译的垃圾信息,又不想错过error或warning,可以重定向:

$ make > ../detritus
# 如果无所谓,可以直接删除
$ make > /dev/null

  

3.3、安装新内核

make modules_install

  以root身份运行上面的命令就可以把所有已经编译的模块安装到正确的主目录/lib/.modules下。

  注:需要使用openssl。因此需要安装:

$ sudo apt-get install libssl-dev

  

  编译时也会在内核代码树的根目录上创建了一个system.map文件。这是一份符号对照表,用以将内核符号和它们的起始地址对应起来。

我们打开system.map显示如下,显然左边是内存地址,右边是容易理解的函数名以及变量名:

 

而这个版本的内核也安装到了自己的系统中,在/lib/modules下,显然我本来的Ubuntu16.04的内核是4.15(uname -r 也可以显示这个版本号),现在安装了5.1:

3.4、内核开发的特点

  内核编程时既不能访问C库也不能访问标准的C头文件:

      内核的头文件是指组成内核源码树的内核头文件。基本的头文件位于内核源码树目录下的include目录下。而体系结构(如x86)相关的头文件集位于内核源代码树的arch/x86/include/asm目录下。

      内核没有提供printf函数,也不同调用printf,但他提供了printk()函数几乎与printf()相同。

  内核编程时必须使用GNU C:

    有内联(inline)函数,内联汇编,分支声明,

  内核编程时缺乏像用户空间那样的内存保护机制

  内核编程时难以执行浮点运算

  内核给每个进程只有一个很小的定长堆栈

  由于内核支持异步中断、抢占和SMP,因此必须时刻保持同步和并发

  要考虑可移植性

这个时候我发现关于版本5.1内容真的太多太多了,真正有意义的源码阅读可能需要从简单的版本读起来,其中建议阅读2.6版本,因为2.6版本开始加入抢占式内核。这是很大的改变

推荐阅读:https://www.cnblogs.com/tcicy/p/8461344.html

https://kernelnewbies.org/LinuxVersions

原文地址:https://www.cnblogs.com/SsoZhNO-1/p/10853510.html