【GNU/Linux kernel源码分析】刨根问底,速览,对初学者友好的底层理解,让你对内核不再迷茫

简介: 【GNU/Linux kernel源码分析】刨根问底,速览,对初学者友好的底层理解,让你对内核不再迷茫

1. Linux kernel


1. 源代码目录结构分析


1、Linux 内核源代码包括三个主要部分


1)内核核心代码:包括linux内核整体架构分析笔记描述的各子系统和子模块,以及其他支撑子系统,如:电源管理、linux初始化等。


2)非核心代码:例如库文件(因为 Linux 内核是一个自包含的内核,即内核不依赖其它的任何软件,自己就可以编译通过)、固件集合、

KVM(虚拟机技术)等。


3)编译脚本、配置文件、帮助文档、版权说明等辅助性文件。

1668319022256.jpg


include/ :内核头文件,需要提供给外部模块(例如用户空间代码)使用。

kernel/ : Linux 内核的核心代码,包含了 进程调度子系统,以及和进程调度相关的模块。

mm/ :内存管理子系统

fs/ ---- VFS 子系统。虚拟文件系统(Virtual File System,简称 VFS)是 Linux 内核的子系统之一

net/ ---- 不包括网络设备驱动的网络子系统。

ipc/ ---- IPC(进程间通信)子系统。

arch// ---- 体系结构相关的代码,例如 arm, x86 等等。

arch//mach- ---- 具体的 machine/board 相关的代码。

arch//include/asm ---- 体系结构相关的头文件。

arch//boot/dts ---- 设备树( Device Tree)文件。

init/ ---- Linux 系统启动初始化相关的代码。

block/ ---- 提供块设备的层次。

sound/ ---- 音频相关的驱动及子系统,可以看作“音频子系统”。

drivers/ ---- 设备驱动

lib/ ---- 实现需要在内核中使用的库函数,例如 CRC、 FIFO、 list、 MD5 等。

crypto/ ----- 加密、解密相关的库函数。

security/ ---- 提供安全特性( SELinux)。

virt/ ---- 提供虚拟机技术( KVM 等)的支持。

usr/ ---- 用于生成 initramfs 的代码。/usr不是user的缩写,其实usr是Unix Software Resource的缩写, 也就是Unix操作系统软件资源所放置的目录,而不是用户的数据;所有系统默认的软件都会放置到/usr, 系统安装完时,这个目录会占用最多的硬盘容量

firmware/ ---- 保存用于驱动第三方设备的固件。

samples/ ---- 一些示例代码。

tools/ ---- 一些常用工具,如性能剖析、自测试等。

Kconfig, Kbuild, Makefile, scripts/ ---- 用于内核编译的配置文件、脚本等。

COPYING ---- 版权声明。

MAINTAINERS —-维护者名单。

CREDITS ---- Linux 主要的贡献者名单。

REPORTING-BUGS ---- Bug 上报的指南。

Documentation, README ---- 帮助、说明文档。


2. linux内核模块编程入门


这里的printk就是print kernal,意思是输出到内核,输出到日志文件


当模块插入执行初始化lkp__init()函数


当模块卸载执行退出函数lkp__exit()

代码示例:


//任何模块都要包含的三个头文件
#include <linux/module.h>    //(module<n>模块; 功能块)包含了对模块的版本控制
#include <linux/kernel.h>    //包含了常用的内核函数
#include <linux/init.h>    //包含了宏__init(告诉编译程序仅初始化的函数和变量)和__exit()
/*
    模块的初始化函数lkp_init()
    __init是用于初始化的修饰符
*/
static int __init lkp_init(void)    //加载函数的入口函数 相当于 main(void)
{
    printk("<1>Hello,world!from the kernel space...\n");//Linux内核下内核编程不能使用c的库
}
/*   
    模块的退出和清理函数lkp_exit()    //入口相对的出口
*/
static void __exit lkp(void)
{
    printk("<1>Goodbye,world!leaving kernel space...\n");
}
/*
    调用函数
*/
module_init(lkp_init);
module_exit(lkp_exit);
/*
    模块的许可证声明GPL
*/
MODULE_LICENSE("GPL");


3. 如何编译内核模块


内核模块的编译需要与常规用户空间应用程序略有不同。 以前的内核版本要求我们关注这些设置,这些设置通常存储在Makefile中。 虽然按层次结构组织,但许多冗余设置在次级Makefile中累积并使它们变大并且难以维护。 幸运的是,有一种新方法可以做这些事情,称为kbuild,外部可加载模块的构建过程现在完全集成到标准内核构建机制中。 要了解有关如何编译不属于官方内核的模块的更多信息(例如本指南中的所有示例),请参阅文件

linux / Documentation / kbuild / modules.txt 。


那么,让我们看一个简单的Makefile来编译一个名为hello-1.c的模块:

obj-m += hello-1.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean


核心思想:告诉哪个头文件放在哪些地方


在这个文件里定义了三个变量


路径的变量


内核版本号变量


内核源代码所在路径变量


1668319117032.jpg


内核模块插入到内核里

超级用户的权限插入


#insmod + 模块名.ko

1668319136647.jpg

1668319147639.jpg



4. 源码在线阅读的网站


源码在线阅读

源码在线阅读2

linux内核编程入门


参考原文


linux内核源码分析笔记


2. 内核常用数据结构


Linux 内核代码中广泛使用了数据结构和算法,其中最常用的两个是链表和红黑树。

linux内核源码分析笔记


3. TTY


在 Linux 中,TTY也许是跟 终端 有关系的最为混乱的术语。. TTY是TeleTYpe的一个老缩写。. Teletypes,或者teletypewriters,原来指的是 电传打字机 ,是通过串行线用打印机键盘通过阅读和发送信息的东西,和古老的 电报机 区别并不是很大。. 之后,当计算机只能以 批处理 方式运行时(当时穿孔卡片 阅读器 是唯一一种使程序载入运行的方式),电传打字机成为唯一能够被使用的“实时”输入/ 输出设备 。. 最终,电传打字机被键盘和显示器终端所取代,但在终端或TTY接插的地方,操作系统仍然需要一个程序来监视 串行端口 。. 一个getty“Get TTY”的处理过程是:一个程序监视物理的TTY/终端接口。.


4. 晶振


晶振是一个被加了电压就会产生稳定节拍的东西,我们只需要找一个东西去记录节拍,便可以达到作为一个时钟信号的产生器。

1668318951288.jpg

相关文章
|
1月前
|
存储 Linux 数据处理
探索Linux操作系统的内核与文件系统
本文深入探讨了Linux操作系统的核心组件,包括其独特的内核结构和灵活的文件系统。文章首先概述了Linux内核的主要功能和架构,接着详细分析了文件系统的工作原理以及它如何支持数据存储和检索。通过比较不同的文件系统类型,本文旨在为读者提供一个关于如何根据特定需求选择合适文件系统的参考框架。
|
18天前
|
Linux API 调度
技术笔记:Linux内核跟踪和性能分析
技术笔记:Linux内核跟踪和性能分析
|
5天前
|
Linux
查看linux内核版本
在Linux中查看内核版本可使用`uname -r`、`cat /proc/version`、`lsb_release -a`、`cat /etc/*release`、`dmesg | grep Linux`、`hostnamectl`、`kernrelease`(部分系统)、`rpm -q kernel`(RPM系统)或`dpkg -l linux-image-*`(Debian系)。
9 2
|
27天前
|
Linux
查看linux内核版本
在Linux中查看内核版本可使用`uname -r`、`cat /proc/version`、`lsb_release -a`(若安装LSB)、`/etc/*release`或`/etc/*version`文件、`dmesg | grep Linux`、`cat /sys/class/dmi/id/product_name`、`hostnamectl`、`kernrelease`(如果支持)、`rpm -q kernel`(RPM系统)和`dpkg -l linux-image-*`(Debian系统)。
31 4
|
28天前
|
安全 Linux 数据处理
探索Linux的kmod命令:管理内核模块的利器
`kmod`是Linux下管理内核模块的工具,用于加载、卸载和管理模块及其依赖。使用`kmod load`来加载模块,`kmod remove`卸载模块,`kmod list`查看已加载模块,`kmod alias`显示模块别名。注意需有root权限,且要考虑依赖关系和版本兼容性。最佳实践包括备份、查阅文档和使用额外的管理工具。
|
10天前
|
Linux 调度
部署03---Linux操作系统的诞生,Linux操作系统由系统的内核和系统的操作系统所组成
部署03---Linux操作系统的诞生,Linux操作系统由系统的内核和系统的操作系统所组成
|
1月前
|
运维 NoSQL Ubuntu
深入理解Linux中的"crash"命令:内核崩溃的调试利器
`crash`是Linux内核崩溃调试工具,用于分析内核崩溃转储文件,提供GDB-like的交互式CLI。通过加载`vmcore`文件和内核映像,管理员可以查看系统状态、调用栈、内存布局等。安装`crash`可使用包管理器,如`apt-get`或`yum/dnf`。尽管有学习曲线且依赖转储文件,但`crash`在系统故障排查中极其重要。
|
18天前
|
监控 Unix Shell
探秘GNU/Linux Shell:命令行的魔法世界
探秘GNU/Linux Shell:命令行的魔法世界
20 0
|
1月前
|
Linux 编译器 C语言
编译Linux内核:基础、重要性和交叉编译方法
Linux内核作为操作系统的心脏,负责管理计算机的硬件资源,同时也是运行所有其他程序的基础。理解如何编译Linux内核对于系统管理员、开发者乃至高级用户来说都是一项极其宝贵的技能。本文将介绍编译Linux内核的基本知识、编译的重要性、具体步骤以及交叉编译的概念。
100 0
|
1月前
|
Linux Unix 程序员
02. 【Linux教程】GNU 项目简介
02. 【Linux教程】GNU 项目简介
22 0