【Linux内核及内核编程】Linux内核的组成
·
一、源代码目录:打开内核世界的地图
典型内核源码目录结构(以Linux 5.15为例):
代码语言:javascript
AI代码解释
linux-5.15/
├── arch/ # 硬件架构代码(x86, arm, riscv等)
├── block/ # 块设备层(硬盘、SSD调度)
├── crypto/ # 加密算法(AES, SHA等)
├── drivers/ # 设备驱动(占代码量60%!)
│ ├── gpu/ # 显卡驱动
│ ├── net/ # 网卡驱动
│ └── ... # 其他成千上万驱动
├── fs/ # 文件系统王国
│ ├── ext4/ # 经典日志文件系统
│ ├── nfs/ # 网络文件系统
│ └── proc/ # 虚拟文件系统(/proc)
├── include/ # 头文件库(内核API定义)
├── init/ # 内核启动流程(start_kernel()在此)
├── ipc/ # 进程间通信(信号量、共享内存等)
├── kernel/ # 核心调度器(进程/线程管理)
├── lib/ # 通用库(CRC校验、字符串操作)
├── mm/ # 内存管理(物理&虚拟内存)
├── net/ # 网络协议栈
│ ├── ipv4/ # TCP/IP协议实现
│ └── wireless/ # WiFi协议
└── tools/ # 开发工具(性能分析、测试套件)
二、五大核心组件:内核的功能支柱
如果把内核比作一辆汽车,刚才的目录结构是零件摆放位置,现在我们要组装这些零件,看看它们如何协作实现核心功能。

2.1 进程调度:CPU 资源的公平分配员
(1)进程的三种状态
- 运行态:正在占用 CPU(同一时刻只有一个进程在单核 CPU 上运行)
- 就绪态:准备好运行,排队等待 CPU(比如后台的聊天软件)
- 阻塞态:等待某个事件(如等待用户输入、等待文件读取完成)
(2)调度算法:谁该先用 CPU?
完全公平调度(CFS,针对普通进程):
- 给每个进程一个 "虚拟运行时间",优先运行时间短的进程
- 例子:同时开 10 个网页,CFS 让每个网页标签轮流获得 CPU 时间,避免某个标签卡死整个浏览器
实时调度(FIFO/RR,针对实时进程):
- FIFO(先来先服务):实时进程按到达顺序运行,一旦开始就不中断(如视频会议软件)
- RR(时间片轮转):给实时进程分配固定时间片,时间到了切换到下一个实时进程(如工业控制中的实时任务)
(3)调度时机:什么时候切换进程?
- 进程主动放弃(如调用sleep函数)
- 时间片用完(普通进程最多运行 1-2 毫秒)
- 发生中断(如键盘按下、硬盘读写完成)

2.2 内存管理:让小内存发挥大作用

(1)虚拟内存:每个进程的 "专属内存"
- 原理:每个进程看到 4GB 虚拟地址空间(32 位系统),通过页表映射到物理内存
- 分区:
- 用户空间(0-3GB):存放进程的代码、数据、堆、栈(比如你打开的 Word 文档数据)
- 内核空间(3-4GB):内核代码和数据,所有进程共享(比如内存管理模块、进程调度模块)
- 好处:进程之间互不干扰,一个程序崩溃不会影响其他程序(比如浏览器崩溃不会让整个系统死机)
(2)物理内存分配策略
- 伙伴系统(Buddy System):
- 管理 4KB 以上的内存块,通过二叉树查找连续空闲块
- 解决外部碎片问题(比如合并相邻的空闲块)
- slab 分配器:
- 预先创建常用数据结构的缓存(如task_struct进程描述符)
- 分配速度极快,减少内存碎片(比如频繁创建 / 销毁的网络连接结构体)
(3)swap 空间:内存不够时的 "临时仓库"
- 当物理内存不足,内核把不常用的内存页写入硬盘 swap 分区
- 代价:swap 读写速度比内存慢 100 倍以上,所以服务器通常会配置大内存减少 swap 使用

2.3 虚拟文件系统(VFS):统一文件操作的万能接口

(1)四大核心数据结构
- 超级块(super_block):描述文件系统整体信息(如块大小、空闲块数量),类似硬盘的 "户口本"
- inode:存储文件元数据(大小、权限、数据块位置),每个文件唯一对应一个 inode,类似文件的 "身份证"
- dentry:目录项,记录文件 / 目录名称和父子关系(如/home/user中的user目录项),类似文件的 "门牌号"
- file:进程打开文件的状态(读写位置、打开模式),每个打开的文件对应一个 file 结构体,类似文件的 "使用记录"
(2)操作流程示例(打开一个文件)
- 用户调用open("/etc/hosts", O_RDONLY)
- 内核通过 dentry 从根目录开始查找/etc/hosts的路径
- 找到对应的 inode,根据文件系统类型(如 EXT4)调用ext4_open函数
- 创建 file 结构体,返回文件描述符(如 3)给用户程序
(3)支持多种文件系统的秘密
VFS 定义了一套统一的操作接口(如open/read/write),不同文件系统(EXT4/NFS/FAT32)只需实现这些接口。就像不管是 U 盘还是硬盘,你在电脑上都能用同样的复制粘贴操作,背后是 VFS 在做翻译。
2.4 网络接口:实现跨设备通信的协议栈

(1)TCP/IP 协议栈分层实现
代码语言:javascript
AI代码解释
应用层(HTTP/FTP/SMTP)
├─ 传输层(TCP/UDP:保证数据可靠传输或快速传输)
├─ 网络层(IP:负责路由寻址,比如从北京到上海的路径规划)
└─ 数据链路层(以太网/Wi-Fi:处理数据帧的发送接收,比如局域网内的设备通信)
(2)关键组件
协议处理模块:
- net/ipv4/tcp.c:TCP 协议实现(三次握手、流量控制、错误重传)
- net/ipv4/ip_input.c:处理接收的 IP 数据报
网络设备驱动:
- drivers/net/ethernet/:以太网驱动(如 Intel 网卡驱动)
- drivers/net/wireless/:无线网卡驱动(如 Wi-Fi 模块驱动)
套接字(socket):
- 用户空间与内核网络子系统的接口,通过socket()创建,bind()绑定地址,connect()建立连接
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)