Linux 内核概览

一、内核设计哲学

二、内核版本

5.10  长期支持版(LTS)
5.15  LTS(很多发行版采用)
6.1   LTS
6.6   LTS

格式:主版本.次版本.修订版本
- 偶数次版本 = 稳定
- 奇数次版本 = 开发(早期)

三、源码结构(5.x)

linux/
├── arch/        架构相关代码(arm, arm64, x86, riscv...)
├── block/       块设备核心
├── crypto/      加密算法
├── drivers/     各种驱动
│   ├── char/
│   ├── block/
│   ├── net/
│   ├── i2c/
│   ├── spi/
│   ├── gpio/
│   ├── pinctrl/
│   ├── tty/
│   ├── usb/
│   ├── mmc/
│   └── ...
├── fs/          文件系统(ext4, fat, proc, sysfs...)
├── include/     头文件
├── init/        启动代码(main.c)
├── ipc/         进程间通信
├── kernel/      调度、模块、信号等
├── lib/         通用库(排序、校验和、压缩)
├── mm/          内存管理
├── net/         网络协议栈
├── samples/     示例代码
├── scripts/     构建脚本
├── security/    SELinux, apparmor
├── sound/       音频
├── tools/       perf, bpf 等
├── usr/         initramfs 生成
├── virt/        KVM
├── Documentation/   大量文档(必看)
├── Kconfig
├── Kbuild
├── Makefile
├── README
├── COPYING
└── MAINTAINERS

四、内核 vs 用户态

特性 用户态 内核态
特权级
内存访问 受限 全部
8MB 4-16KB
调度 可被抢占 代码段可能关闭抢占
库函数 glibc 内核自实现(printk, kmalloc)
标准 C 全部可用 部分(无 libc)
浮点 可以 禁用(需特别启用)
错误处理 errno 返回 -ERRNO 指针

五、内核编译

1. 配置

# 多种方式
make defconfig                     # 默认
make xxxx_defconfig                # 板级默认
make menuconfig                    # TUI 配置
make nconfig                       # 新的 TUI
make xconfig                       # Qt 配置(需 qt)
make gconfig                       # GTK(需 gtk)
make oldconfig                     # 升级旧 .config
make savedefconfig                 # 提取最小配置

# 配置已保存到 .config

2. 编译

make -j$(nproc)
make zImage          # ARM 旧格式
make Image           # ARM 未压缩
make uImage          # U-Boot 格式(需安装 mkimage)
make dtbs            # 编译设备树
make modules         # 编译模块
make modules_install INSTALL_MOD_PATH=/path/to/rootfs
make install         # 安装内核到 /boot

3. 输出

arch/arm/boot/zImage          ARM 压缩内核
arch/arm/boot/dts/*.dtb       设备树二进制
vmlinux                       未压缩、含符号的 ELF(调试用)

六、启动流程(ARM)

上电
  ↓
ROM/BOOT ROM(芯片内置)
  ↓
Bootloader 第一阶段(可选:固化在板载 NOR Flash)
  ↓
Bootloader 第二阶段(U-Boot)
  ↓
内核自解压 → start_kernel()
  ↓
setup_arch()、sched_init()、页表初始化、trap_init()
  ↓
rest_init() → kernel_init → 启动 init 进程
  ↓
挂载 rootfs
  ↓
执行 /sbin/init(或 /init)
  ↓
systemd / busybox init
  ↓
用户空间启动

七、内核主要子系统

子系统 位置 职责
进程调度 kernel/sched/ CFS、实时调度
内存管理 mm/ 页表、虚拟内存
VFS fs/ 通用文件系统抽象
网络 net/ 协议栈、设备
IPC ipc/ 信号量、共享内存、消息队列
设备驱动 drivers/ 各种硬件
中断 kernel/irq/ 中断处理
时间 kernel/time/ tick、定时器
安全 security/ SELinux、capability

八、内核编程基础

1. 头文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>      // copy_to_user / copy_from_user
#include <linux/io.h>           // ioremap / iounmap
#include <linux/slab.h>         // kmalloc / kfree
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>           // device tree

2. 常用宏

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Me");
MODULE_DESCRIPTION("A demo");
MODULE_VERSION("0.1");

pr_info("hello %s\n", __func__);
pr_err("failed: %d\n", ret);
dev_err(dev, "msg");   // 自动包含设备名
dev_info(dev, "msg");

3. 内核不能用的用户态函数

// 不能用:
printf   pr_info / printk / dev_info
malloc   kmalloc / kvmalloc
free     kfree
memcpy   memcpy  // 这个能用
strcpy   strscpy / strlcpy推荐
memset   memset
open     filp_open
sleep   msleep / ssleep / schedule_timeout
usleep  udelay / usleep_range  // 短延迟
exit()   return  // 模块函数

九、内核调试基础