内核架构概览

Linux 内核是一个宏内核(Monolithic Kernel)设计,但通过模块化实现了一定程度的微内核特性。本章将深入探讨 Linux 内核的整体架构。

内核架构层次

┌─────────────────────────────────────────────────────┐
│            用户空间 (User Space)                     │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐          │
│  │应用程序  │  │系统工具  │  │Shell     │          │
│  └─────┬────┘  └─────┬────┘  └─────┬────┘          │
└────────┼─────────────┼─────────────┼────────────────┘
         │             │             │
    系统调用接口 (System Call Interface)
         │             │             │
┌────────┼─────────────┼─────────────┼────────────────┐
│        ↓             ↓             ↓                 │
│  ┌──────────────────────────────────────────────┐  │
│  │         虚拟文件系统 (VFS)                    │  │
│  └───────┬──────────────────────────────────────┘  │
│          │                                          │
│  ┌───────┴──────┬──────────┬──────────┬─────────┐ │
│  │  进程调度    │  内存管理│  网络协议│ 设备驱动│ │
│  │  Scheduler   │  MM      │  Stack   │ Drivers │ │
│  └──────────────┴──────────┴──────────┴─────────┘ │
│                                                      │
│              内核空间 (Kernel Space)                 │
└──────────────────────┬───────────────────────────────┘
                       │
                   硬件层 (Hardware)

主要子系统

1. 进程管理子系统

核心职责

  • 进程创建和销毁
  • 进程调度(CFS - Completely Fair Scheduler)
  • 进程间通信(IPC)
  • 信号处理

核心概念

进程描述符(task_struct)是内核中最重要的数据结构之一,它包含了进程的完整信息:

  • 进程状态:运行、就绪、睡眠、停止等状态
  • 进程标识:PID(进程ID)和 TGID(线程组ID)
  • 调度信息:优先级、调度策略、时间片
  • 内存空间:虚拟地址空间描述符
  • 文件系统:当前工作目录、根目录
  • 打开文件:文件描述符表
  • 进程关系:父进程、子进程、兄弟进程

2. 内存管理子系统

核心功能

  • 虚拟内存管理
  • 物理内存分配(Buddy 算法、Slab 分配器)
  • 页面回收(Page Reclaim)
  • 交换机制(Swap)
  • 内存映射(mmap)

内存布局

用户空间内存布局(64 位系统):

0x0000000000000000  ┌─────────────────┐
                    │   Text Segment  │  代码段
                    ├─────────────────┤
                    │   Data Segment  │  数据段
                    ├─────────────────┤
                    │   BSS Segment   │  未初始化数据
                    ├─────────────────┤
                    │      Heap       │  堆(向上增长)
                    │        ↓        │
                    ├─────────────────┤
                    │                 │
                    │   Memory Map    │  内存映射区
                    │                 │
                    ├─────────────────┤
                    │        ↑        │
                    │      Stack      │  栈(向下增长)
0x00007FFFFFFFFFFF  └─────────────────┘

内核空间内存布局:

0xFFFF800000000000  ┌─────────────────┐
                    │   Direct Map    │  直接映射物理内存
                    ├─────────────────┤
                    │    vmalloc      │  vmalloc 区域
                    ├─────────────────┤
                    │   Kernel Text   │  内核代码段
                    ├─────────────────┤
                    │   Kernel Data   │  内核数据段
                    ├─────────────────┤
                    │   Modules       │  内核模块
0xFFFFFFFFFFFFFFFF  └─────────────────┘

3. 虚拟文件系统(VFS)

设计思想

  • 提供统一的文件操作接口
  • 支持多种文件系统(Ext4、XFS、Btrfs、NFS 等)
  • 实现 dentry cache 和 inode cache

VFS 对象模型

// 超级块对象(描述文件系统)
struct super_block {
    struct list_head s_list;
    dev_t s_dev;
    unsigned long s_blocksize;
    struct file_system_type *s_type;
    const struct super_operations *s_op;
    struct dentry *s_root;
};

// inode 对象(描述文件)
struct inode {
    umode_t i_mode;
    uid_t i_uid;
    gid_t i_gid;
    loff_t i_size;
    struct timespec i_atime;
    struct timespec i_mtime;
    struct timespec i_ctime;
    const struct inode_operations *i_op;
    const struct file_operations *i_fop;
};

// dentry 对象(目录项)
struct dentry {
    struct dentry *d_parent;
    struct qstr d_name;
    struct inode *d_inode;
    const struct dentry_operations *d_op;
    struct super_block *d_sb;
};

// file 对象(打开的文件)
struct file {
    struct path f_path;
    const struct file_operations *f_op;
    loff_t f_pos;
    fmode_t f_mode;
};

4. 网络协议栈

层次结构

应用层
    ↓
套接字层 (Socket Layer)
    ↓
传输层 (TCP/UDP/SCTP)
    ↓
网络层 (IP/ICMP/IGMP)
    ↓
链路层 (Ethernet/ARP)
    ↓
网络设备驱动 (Device Driver)
    ↓
硬件 (NIC)

核心数据结构

// Socket 缓冲区
struct sk_buff {
    struct sk_buff *next;
    struct sk_buff *prev;
    struct sock *sk;
    struct net_device *dev;
    unsigned int len;
    unsigned int data_len;
    unsigned char *head;
    unsigned char *data;
    unsigned char *tail;
    unsigned char *end;
};

// 网络设备
struct net_device {
    char name[IFNAMSIZ];
    unsigned long state;
    struct net_device_stats stats;
    const struct net_device_ops *netdev_ops;
    const struct ethtool_ops *ethtool_ops;
    unsigned int mtu;
    unsigned char dev_addr[MAX_ADDR_LEN];
};

5. 设备驱动框架

设备模型

Bus (总线)
 ├── Device (设备)
 │   ├── Driver (驱动)
 │   └── Platform Device
 └── Class (设备类)
     ├── Character Device (字符设备)
     ├── Block Device (块设备)
     └── Network Device (网络设备)

字符设备驱动框架

// 文件操作结构
struct file_operations {
    struct module *owner;
    loff_t (*llseek) (struct file *, loff_t, int);
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
    int (*open) (struct inode *, struct file *);
    int (*release) (struct inode *, struct file *);
};

// 字符设备注册
int register_chrdev(unsigned int major, const char *name,
                   const struct file_operations *fops);

内核配置选项

查看当前内核配置:

# 查看当前运行内核的配置
cat /boot/config-$(uname -r)

# 或者(如果支持)
zcat /proc/config.gz

# 查看已加载的内核模块
lsmod

# 查看内核参数
sysctl -a

# 修改内核参数(临时)
sysctl -w net.ipv4.ip_forward=1

# 修改内核参数(永久)
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

内核版本演进

版本命名规则

主版本.次版本.修订版本[-发布版本]

例如:5.15.0-91-generic
  5    - 主版本
  15   - 次版本
  0    - 修订版本
  91   - 发布版本
  generic - 发行版标识

重要版本里程碑

  • Linux 2.6 (2003):引入 NPTL、O(1) 调度器
  • Linux 3.0 (2011):版本号重置,改进电源管理
  • Linux 4.0 (2015):实时内核补丁、Live Patching
  • Linux 5.0 (2019):改进 Energy Aware Scheduling
  • Linux 6.0 (2022):Rust 语言支持初步引入

内核源码结构

linux/
├── arch/          # 架构相关代码(x86、ARM、MIPS 等)
├── block/         # 块设备层
├── crypto/        # 加密 API
├── Documentation/ # 文档
├── drivers/       # 设备驱动
│   ├── char/      # 字符设备
│   ├── block/     # 块设备
│   ├── net/       # 网络设备
│   └── ...
├── fs/            # 文件系统
│   ├── ext4/      # Ext4 文件系统
│   ├── btrfs/     # Btrfs 文件系统
│   └── ...
├── include/       # 头文件
│   └── linux/     # 内核头文件
├── init/          # 初始化代码
├── ipc/           # 进程间通信
├── kernel/        # 核心子系统
│   ├── sched/     # 调度器
│   ├── time/      # 时间管理
│   └── ...
├── lib/           # 库函数
├── mm/            # 内存管理
├── net/           # 网络协议栈
│   ├── ipv4/      # IPv4
│   ├── ipv6/      # IPv6
│   └── ...
├── scripts/       # 编译脚本
├── security/      # 安全模块(SELinux、AppArmor)
└── tools/         # 内核工具

实践:探索内核信息

#!/bin/bash
# kernel-info.sh - 内核信息收集脚本

echo "======================================"
echo "Linux 内核信息汇总"
echo "======================================"

# 内核版本
echo ""
echo "1. 内核版本:"
uname -a

# CPU 架构
echo ""
echo "2. CPU 架构:"
lscpu | grep "Architecture\|CPU(s)\|Model name"

# 内存信息
echo ""
echo "3. 内存信息:"
free -h

# 内核编译时间
echo ""
echo "4. 内核编译信息:"
cat /proc/version

# 命令行参数
echo ""
echo "5. 内核启动参数:"
cat /proc/cmdline

# 加载的模块数量
echo ""
echo "6. 已加载模块数:"
lsmod | wc -l

# 进程数
echo ""
echo "7. 当前进程数:"
ps aux | wc -l

# 系统运行时间
echo ""
echo "8. 系统运行时间:"
uptime

# 内核消息
echo ""
echo "9. 最近的内核消息(最后 10 条):"
dmesg | tail -10

echo ""
echo "======================================"

关键概念总结

1. 内核空间 vs 用户空间

  • 内核空间拥有最高权限(Ring 0)
  • 用户空间权限受限(Ring 3)
  • 通过系统调用接口通信

2. 宏内核 vs 微内核

  • Linux 采用宏内核设计
  • 所有核心服务运行在内核空间
  • 通过模块化实现灵活性

3. 抢占式多任务

  • 内核可以抢占用户进程
  • 内核可以抢占其他内核任务(CONFIG_PREEMPT)

4. SMP(对称多处理)

  • 支持多 CPU/多核心
  • 自旋锁、信号量等同步机制

下一步:学习 启动流程详解 章节。