Linux内核总体架构深度解析

6 阅读22分钟

这里详细解析Linux内核的总体架构,并对每个核心模块进行深入的剖析。Linux内核是宏内核架构的典范,但采用了模块化设计,使其兼具高性能和可扩展性。

一、Linux内核总体架构全景

架构层次图

┌─────────────────────────────────────────────────────────────────────┐
│                      用户空间 (Userspace)                            │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐           │
│  │  Shell   │  │ 应用软件 │  │ 库函数   │  │ 运行时   │           │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘           │
├─────────────────────────────────────────────────────────────────────┤
│                     系统调用接口 (System Call Interface)             │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │  POSIX系统调用 │  Linux特有调用 │ 架构相关调用 │ 虚拟系统调用 │  │
│  └─────────────────────────────────────────────────────────────┘  │
├─────────────────────────────────────────────────────────────────────┤
│                   内核空间 (Kernel Space)                            │
│                                                                     │
│  ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐    │
│  │ 进程管理   │ │ 内存管理   │ │ 虚拟文件   │ │ 网络栈     │    │
│  │ 子系统     │ │ 子系统     │ │ 系统(VFS)  │ │           │    │
│  │            │ │            │ │            │ │           │    │
│  │ ┌───────┐  │ │ ┌───────┐  │ │ ┌───────┐  │ │ ┌───────┐  │    │
│  │ │调度器 │  │ │ │分配器 │  │ │ │ 文件  │  │ │ │TCP/IP │  │    │
│  │ │       │  │ │ │伙伴   │  │ │ │ 系统  │  │ │ │协议栈 │  │    │
│  │ │CFS    │  │ │ │系统   │  │ │ │ Ext4  │  │ │ │       │  │    │
│  │ │实时    │  │ │ │Slab  │  │ │ │ XFS   │  │ │ │       │  │    │
│  │ │调度器 │  │ │ │       │  │ │ │ Btrfs │  │ │ │       │  │    │
│  └─┴───────┘  └─┴───────┘  └─┴───────┘  └─┴───────┘    │
│                                                             │
│  ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐    │
│  │ 设备驱动   │ │ IPC        │ │ 安全模块   │ │ 内核模块   │    │
│  │ 模型       │ │ 子系统     │ │           │ │ 机制       │    │
│  │            │ │            │ │           │ │           │    │
│  │ ┌───────┐  │ │ ┌───────┐  │ │ ┌───────┐  │ │ ┌───────┐  │    │
│  │ │字符   │  │ │ │信号   │  │ │ │SELinux│  │ │ │模块   │  │    │
│  │ │设备    │  │ │ │信号量 │  │ │ │AppArm │  │ │ │加载   │  │    │
│  │ │块设备 │  │ │ │共享   │  │ │ │       │  │ │ │卸载   │  │    │
│  │ │网络    │  │ │ │内存   │  │ │ │       │  │ │ │       │  │    │
│  │ │设备    │  │ │ │消息   │  │ │ │       │  │ │ │       │  │    │
│  │ │        │  │ │ │队列   │  │ │ │       │  │ │ │       │  │    │
│  └─┴───────┘  └─┴───────┘  └─┴───────┘  └─┴───────┘    │
│                                                             │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │                硬件抽象层 (Hardware Abstraction Layer)        │  │
│  │  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────┐        │  │
│  │  │中断  │  │时钟  │  │DMA   │  │I/O   │  │电源  │        │  │
│  │  │管理  │  │管理  │  │管理  │  │端口  │  │管理  │        │  │
│  │  │      │  │      │  │      │  │      │  │      │        │  │
│  └──┴──────┘  └──────┘  └──────┘  └──────┘  └──────┘        │  │
├─────────────────────────────────────────────────────────────────────┤
│                    硬件平台 (Hardware Platform)                      │
│  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────┐                  │
│  │CPU   │  │内存  │  │磁盘  │  │网卡  │  │其他  │                  │
│  │      │  │      │  │      │  │      │  │外设  │                  │
│  └──────┘  └──────┘  └──────┘  └──────┘  └──────┘                  │
└─────────────────────────────────────────────────────────────────────┘

二、核心子系统详细解析

1. 进程管理子系统

功能:负责进程的创建、调度、同步和通信。

进程调度架构

// 调度器层次结构
struct sched_class {
    const struct sched_class *next;  // 调度类链表
    
    // 任务入队
    void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
    
    // 任务出队
    void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
    
    // 任务切换
    void (*put_prev_task) (struct rq *rq, struct task_struct *p);
    struct task_struct * (*pick_next_task) (struct rq *rq);
    
    // 时钟中断处理
    void (*task_tick) (struct rq *rq, struct task_struct *p, int queued);
    
    // 任务唤醒
    void (*task_woken) (struct rq *this_rq, struct task_struct *task);
    
    // 任务迁移
    void (*set_cpus_allowed)(struct task_struct *p, const struct cpumask *newmask);
    
    // 任务切换上下文
    void (*switched_from) (struct rq *this_rq, struct task_struct *task);
    void (*switched_to) (struct rq *this_rq, struct task_struct *task);
};

三种调度器实现

1. CFS调度器(完全公平调度器)

// kernel/sched/fair.c
// 核心算法:红黑树管理虚拟运行时间
struct cfs_rq {
    struct load_weight load;           // 队列权重
    unsigned int nr_running;           // 运行任务数
    u64 min_vruntime;                  // 最小虚拟运行时间
    
    // 红黑树根节点
    struct rb_root_cached tasks_timeline;
    
    // 当前运行任务
    struct sched_entity *curr;
    struct sched_entity *next;
    struct sched_entity *last;
    
    // 统计信息
    unsigned long h_nr_running;        // 层次运行任务数
};

// 虚拟运行时间计算
static void update_curr(struct cfs_rq *cfs_rq) {
    struct sched_entity *curr = cfs_rq->curr;
    u64 now = rq_clock_task(rq_of(cfs_rq));
    u64 delta_exec;
    
    if (unlikely(!curr))
        return;
    
    // 计算实际运行时间
    delta_exec = now - curr->exec_start;
    if (unlikely((s64)delta_exec <= 0))
        return;
    
    curr->exec_start = now;
    
    // 更新虚拟运行时间
    curr->vruntime += calc_delta_fair(delta_exec, curr);
    
    // 更新cfs_rq的最小虚拟运行时间
    if (entity_before(curr, cfs_rq->min_vruntime))
        cfs_rq->min_vruntime = curr->vruntime;
}

2. 实时调度器

// kernel/sched/rt.c
// 实时调度类定义
const struct sched_class rt_sched_class = {
    .next = &fair_sched_class,
    .enqueue_task = enqueue_task_rt,
    .dequeue_task = dequeue_task_rt,
    .yield_task = yield_task_rt,
    .check_preempt_curr = check_preempt_curr_rt,
    
    .pick_next_task = pick_next_task_rt,
    .put_prev_task = put_prev_task_rt,
    
    .set_cpus_allowed = set_cpus_allowed_rt,
    .task_tick = task_tick_rt,
    
    .get_rr_interval = get_rr_interval_rt,
    
    .prio_changed = prio_changed_rt,
    .switched_to = switched_to_rt,
};

3. Deadline调度器

// kernel/sched/deadline.c
// 截止时间调度策略
struct sched_dl_entity {
    struct rb_node rb_node;           // 红黑树节点
    u64 dl_runtime;                   // 运行时间预算
    u64 dl_deadline;                  // 相对截止时间
    u64 dl_period;                    // 周期
    u64 dl_bw;                        // 带宽
    u64 dl_density;                   // 密度
    
    // 运行队列
    struct hrtimer dl_timer;          // 高分辨率定时器
    struct hrtimer inactive_timer;    // 非活跃定时器
};

进程状态转换

// 进程状态定义
#define TASK_RUNNING        0x0000
#define TASK_INTERRUPTIBLE  0x0001
#define TASK_UNINTERRUPTIBLE 0x0002
#define __TASK_STOPPED      0x0004
#define __TASK_TRACED       0x0008
#define EXIT_DEAD           0x0010
#define EXIT_ZOMBIE         0x0020
#define TASK_PARKED         0x0040
#define TASK_DEAD           0x0080
#define TASK_WAKEKILL       0x0100
#define TASK_WAKING         0x0200
#define TASK_NOLOAD         0x0400
#define TASK_NEW            0x0800
#define TASK_STATE_MAX      0x1000

// 状态转换函数
static void __set_task_state(struct task_struct *tsk, int state) {
    set_mb(tsk->state, state);
}

2. 内存管理子系统

功能:管理物理和虚拟内存,包括分配、回收、映射等。

三层内存模型

┌─────────────────────────────────────────────┐
│              物理内存架构                    │
├─────────────────────────────────────────────┤
│  节点0 (Node 0)   节点1 (Node 1)  ...       │
│  ┌─────────────┐ ┌─────────────┐           │
│  │  区域0 DMA  │ │  区域0 DMA  │           │
│  │  区域1 DMA32│ │  区域1 DMA32│           │
│  │  区域2 普通 │ │  区域2 普通 │           │
│  └─────────────┘ └─────────────┘           │
└─────────────────────────────────────────────┘

物理内存管理算法

1. 伙伴系统(Buddy System)

// mm/page_alloc.c
// 伙伴系统空闲区域管理
struct free_area {
    struct list_head free_list[MIGRATE_TYPES];
    unsigned long nr_free;
};

// 内存区域定义
struct zone {
    // 水线
    unsigned long watermark[NR_WMARK];
    
    // 伙伴系统空闲列表
    struct free_area free_area[MAX_ORDER];
    
    // 每CPU页面缓存
    struct per_cpu_pageset __percpu *pageset;
    
    // 统计信息
    atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
    
    // 页回收
    unsigned long flags;
    
    // 内存紧缩
    spinlock_t lock;
};

2. SLAB分配器

// mm/slab.c
// SLAB缓存结构
struct kmem_cache {
    // 每CPU缓存
    struct array_cache __percpu *cpu_cache;
    
    // 节点缓存
    struct kmem_cache_node *node[MAX_NUMNODES];
    
    // 对象大小和对齐
    unsigned int size;
    unsigned int align;
    
    // 构造函数/析构函数
    void (*ctor)(void *);
    
    // 标志
    slab_flags_t flags;
    
    // 统计
    unsigned int num;
    unsigned int gfporder;
    
    // 着色
    unsigned int colour;
    unsigned int colour_off;
};

3. SLUB分配器(默认)

// mm/slub.c
// SLUB缓存结构
struct kmem_cache {
    struct kmem_cache_cpu __percpu *cpu_slab;
    unsigned long flags;
    unsigned long min_partial;
    int size;            // 对象大小
    int object_size;     // 实际对象大小
    int offset;          // 空闲指针偏移
    int cpu_partial;     // 每CPU部分空闲对象数
    
    struct kmem_cache_order_objects oo;
    struct kmem_cache_order_objects max;
    struct kmem_cache_order_objects min;
    
    gfp_t allocflags;    // 分配标志
    int refcount;
    
    void (*ctor)(void *);
    int inuse;           // 实际使用大小
    int align;           // 对齐
    int reserved;        // 保留字节
    
    const char *name;    // 名称
    struct list_head list;  // 缓存链表
    int remote_node_defrag_ratio;
    
    struct kmem_cache_node *node[MAX_NUMNODES];
};

虚拟内存管理

1. 页表管理

// 四级页表结构(x86_64)
typedef struct { unsigned long p4d; } p4d_t;
typedef struct { unsigned long pud; } pud_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pte; } pte_t;

// 页表项标志
#define _PAGE_PRESENT 0x001
#define _PAGE_RW      0x002
#define _PAGE_USER    0x004
#define _PAGE_PWT     0x008
#define _PAGE_PCD     0x010
#define _PAGE_ACCESSED 0x020
#define _PAGE_DIRTY   0x040
#define _PAGE_PSE     0x080
#define _PAGE_GLOBAL  0x100
#define _PAGE_NX      0x8000000000000000ULL

2. 虚拟内存区域(VMA)管理

// mm_types.h
struct vm_area_struct {
    // 内存区域边界
    unsigned long vm_start;
    unsigned long vm_end;
    
    // 链接结构
    struct mm_struct *vm_mm;
    pgprot_t vm_page_prot;
    unsigned long vm_flags;
    
    // 红黑树节点
    struct rb_node vm_rb;
    
    // 文件映射
    struct file *vm_file;
    unsigned long vm_pgoff;
    
    // 匿名映射
    struct anon_vma *anon_vma;
    struct list_head anon_vma_chain;
    
    // 操作函数
    const struct vm_operations_struct *vm_ops;
    
    // 名称
    const char *vm_name;
};

3. 虚拟文件系统(VFS)

功能:为不同文件系统提供统一的抽象接口。

VFS核心数据结构

// 超级块结构
struct super_block {
    // 超级块操作
    const struct super_operations *s_op;
    
    // 文件系统类型
    struct file_system_type *s_type;
    
    // 根目录
    struct dentry *s_root;
    
    // 活动inode链表
    struct list_head s_inodes;
    
    // 块大小
    unsigned long s_blocksize;
    
    // 最大文件大小
    loff_t s_maxbytes;
    
    // 文件系统特定信息
    void *s_fs_info;
    
    // 引用计数
    atomic_t s_count;
};

文件系统操作抽象

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 *);
    ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
    ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
    int (*iterate) (struct file *, struct dir_context *);
    unsigned int (*poll) (struct file *, struct poll_table_struct *);
    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
    long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
    int (*mmap) (struct file *, struct vm_area_struct *);
    int (*open) (struct inode *, struct file *);
    int (*flush) (struct file *, fl_owner_t id);
    int (*release) (struct inode *, struct file *);
    int (*fsync) (struct file *, loff_t, loff_t, int datasync);
    int (*fasync) (int, struct file *, int);
    int (*lock) (struct file *, int, struct file_lock *);
    ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
    unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
    int (*check_flags)(int);
    int (*flock) (struct file *, int, struct file_lock *);
    ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
    ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
    int (*setlease)(struct file *, long, struct file_lock **, void **);
    long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len);
    void (*show_fdinfo)(struct seq_file *m, struct file *f);
};

文件系统类型

1. Ext4文件系统

// fs/ext4/ext4.h
// Ext4超级块
struct ext4_super_block {
    __le32 s_inodes_count;         // inode总数
    __le32 s_blocks_count_lo;      // 块总数
    __le32 s_r_blocks_count_lo;    // 保留块数
    __le32 s_free_blocks_count_lo; // 空闲块数
    __le32 s_free_inodes_count;    // 空闲inode数
    __le32 s_first_data_block;     // 第一个数据块
    __le32 s_log_block_size;       // 块大小
    __le32 s_log_cluster_size;     // 簇大小
    __le32 s_blocks_per_group;     // 每组块数
    __le32 s_clusters_per_group;   // 每组簇数
    __le32 s_inodes_per_group;     // 每组inode数
    __le32 s_mtime;                // 挂载时间
    __le32 s_wtime;                // 写时间
    __le16 s_mnt_count;            // 挂载计数
    __le16 s_max_mnt_count;        // 最大挂载计数
    __le16 s_magic;                // 魔术字
    __le16 s_state;                // 文件系统状态
    __le16 s_errors;               // 错误处理
    __le16 s_minor_rev_level;      // 次版本
    __le32 s_lastcheck;            // 最后检查时间
    __le32 s_checkinterval;        // 检查间隔
    __le32 s_creator_os;           // 创建者OS
    __le32 s_rev_level;            // 版本级别
    __le16 s_def_resuid;           // 默认保留用户ID
    __le16 s_def_resgid;           // 默认保留组ID
    // ... 更多字段
};

2. Btrfs文件系统

// fs/btrfs/ctree.h
// Btrfs超级块
struct btrfs_super_block {
    __le64 bytenr;           // 物理地址
    __le64 flags;           // 标志
    __u8 csum[BTRFS_CSUM_SIZE];  // 校验和
    __u8 fsid[BTRFS_FSID_SIZE];  // 文件系统ID
    __le64 magic;           // 魔术字
    __le64 generation;      // 代
    __le64 root;           // 根地址
    __le64 chunk_root;     // 块树根
    __le64 log_root;       // 日志根
    __le64 log_root_transid; // 日志根事务ID
    __le64 total_bytes;    // 总字节数
    __le64 bytes_used;     // 已用字节数
    __le64 root_dir_objectid; // 根目录对象ID
    __le64 num_devices;    // 设备数
    __le32 sectorsize;     // 扇区大小
    __le32 nodesize;       // 节点大小
    __le32 leafsize;       // 叶大小
    __le32 stripesize;     // 条带大小
    __le32 sys_chunk_array_size; // 系统块数组大小
    __le64 chunk_root_generation; // 块树根代
    __le64 compat_flags;   // 兼容标志
    __le64 compat_ro_flags; // 只读兼容标志
    __le64 incompat_flags; // 不兼容标志
    __le16 csum_type;      // 校验和类型
    __u8 root_level;       // 根级别
    __u8 chunk_root_level; // 块树根级别
    __u8 log_root_level;   // 日志根级别
    struct btrfs_dev_item dev_item; // 设备项
    __le64 cache_generation; // 缓存代
    __le64 uuid_tree_generation; // UUID树代
    __le64 reserved[30];   // 保留
    __u8 metadata_uuid[BTRFS_FSID_SIZE]; // 元数据UUID
};

4. 网络子系统

功能:实现各种网络协议,提供网络通信能力。

网络协议栈架构

┌─────────────────────────────────────────┐
│          应用程序层 (Application)        │
├─────────────────────────────────────────┤
│       套接字层 (Socket Layer)           │
├─────────────────────────────────────────┤
│     传输层 (Transport Layer)           │
│     TCP      UDP       SCTP            │
├─────────────────────────────────────────┤
│      网络层 (Network Layer)            │
│     IPv4     IPv6      ICMP            │
├─────────────────────────────────────────┤
│    数据链路层 (Data Link Layer)         │
│    以太网    WiFi      PPP              │
├─────────────────────────────────────────┤
│     物理层 (Physical Layer)            │
└─────────────────────────────────────────┘

套接字缓冲区(sk_buff)

// include/linux/skbuff.h
struct sk_buff {
    // 链表管理
    union {
        struct {
            struct sk_buff *next;
            struct sk_buff *prev;
            union {
                struct net_device *dev;
                unsigned long dev_scratch;
            };
        };
        struct rb_node rbnode;  // 用于快速路径
    };
    
    // 缓冲区指针
    unsigned char *head;
    unsigned char *data;
    unsigned char *tail;
    unsigned char *end;
    
    // 长度信息
    unsigned int len;
    unsigned int data_len;
    __u16 mac_len;
    __u16 hdr_len;
    
    // 协议信息
    __be16 protocol;
    __u16 transport_header;
    __u16 network_header;
    __u16 mac_header;
    
    // 校验和
    __wsum csum;
    __u32 csum_start;
    __u32 csum_offset;
    
    // 拥塞控制
    __u32 priority;
    __u16 queue_mapping;
    __u8 pfmemalloc:1;
    __u8 ignore_df:1;
    __u8 cloned:1;
    __u8 ip_summed:2;
    __u8 nohdr:1;
    __u8 nfctinfo:3;
    __u8 pkt_type:3;
    __u8 ipvs_property:1;
    __u8 inner_protocol_type:1;
    __u8 remcsum_offload:1;
    
    // 时间戳
    __u32 tstamp;
    
    // 所有者
    struct sock *sk;
    struct nf_conntrack *nfct;
    
    // 安全
    struct sec_path *sp;
    
    // 扩展头
    char cb[48] __aligned(8);
    unsigned long _skb_refdst;
    void (*destructor)(struct sk_buff *skb);
};

TCP协议实现

// net/ipv4/tcp.c
// TCP控制块
struct tcp_sock {
    // 继承inet_connection_sock
    struct inet_connection_sock inet_conn;
    
    // 发送序列号
    u32 snd_una;    // 最早未确认序列号
    u32 snd_nxt;    // 下一个发送序列号
    u32 snd_up;     // 紧急指针
    u32 snd_wl1;    // 窗口更新段序列号
    u32 snd_wl2;    // 窗口更新段确认号
    u32 iss;        // 初始发送序列号
    u32 irs;        // 初始接收序列号
    
    // 接收序列号
    u32 rcv_nxt;    // 下一个期望序列号
    u32 rcv_wup;    // 窗口更新前一个rcv_nxt
    u32 copied_seq; // 已拷贝到用户空间的序列号
    
    // 窗口
    u32 snd_wnd;    // 发送窗口
    u32 snd_cwnd;   // 拥塞窗口
    u32 snd_ssthresh; // 慢启动阈值
    u32 rcv_wnd;    // 接收窗口
    
    // 定时器
    unsigned long retrans_stamp; // 重传时间戳
    u32 retrans_out;  // 重传输出段数
    u32 undo_marker;  // 撤销标记
    int undo_retrans; // 撤销重传计数
    
    // 状态
    u32 syn_retries;  // SYN重试次数
    u32 tcp_header_len; // TCP头部长度
    u32 mss_cache;    // 缓存的MSS
    
    // 拥塞控制
    u32 snd_cwnd_cnt; // 拥塞窗口计数
    u32 snd_cwnd_clamp; // 拥塞窗口钳制
    u32 snd_cwnd_used;  // 使用的拥塞窗口
    u32 snd_cwnd_stamp; // 拥塞窗口时间戳
    
    // 接收缓冲区
    u32 rcv_ssthresh;  // 接收慢启动阈值
    u32 rcv_rtt_last_tsecr;
    u32 rcv_rtt_est_seq;
    u32 rcv_rtt_est_res;
    
    // 时间戳
    u32 tsoffset;  // 时间戳偏移
    
    // 扩展选项
    u32 ts_recent;  // 最近时间戳
    u32 ts_recent_stamp; // 最近时间戳时间
    
    // 选择性确认
    struct tcp_sack_block duplicate_sack[1]; // 重复SACK
    struct tcp_sack_block selective_acks[4]; // 选择性确认
    u8 num_sacks;  // SACK数量
    u8 dup_ack_counter;  // 重复ACK计数
    
    // 快速重传/恢复
    u32 prior_ssthresh;  // 先前慢启动阈值
    u32 lost_out;  // 丢失段数
    u32 retrans_out;  // 重传段数
    u32 fackets_out;  // FACK输出段数
    
    // 状态标志
    u16 advmss;  // 通告MSS
    u8 reordering;  // 重排序等级
    u8 nonagle;  // Nagle算法控制
    u8 thin_lto;  // 薄流超时
    u8 thin_dupack;  // 薄重复ACK
    u8 repair;  // 修复模式
    u8 do_early_retrans;  // 早期重传
    u8 syn_data;  // SYN携带数据
    u8 syn_fastopen;  // 快速打开SYN
    u8 syn_data_acked;  // SYN数据已确认
    u8 is_cwnd_limited;  // 拥塞窗口受限
    
    // 高精度定时器
    u32 tcp_mstamp;  // 最近接收段时间戳
    u32 srtt_us;  // 平滑RTT(微秒)
    u32 mdev_us;  // 平均偏差
    u32 mdev_max_us;  // 最大平均偏差
    u32 rttvar_us;  // RTT方差
    
    // 拥塞控制算法
    struct tcp_congestion_ops  *ca_ops;
    u32 prior_cwnd;  // 先前拥塞窗口
    u32 high_seq;  // 高序列号
    u32 snd_limited;  // 发送受限
};

5. 设备驱动模型

功能:统一设备管理框架,支持热插拔、电源管理等。

设备模型核心

// 设备结构
struct device {
    struct device *parent;  // 父设备
    struct device_private *p;  // 私有数据
    
    struct kobject kobj;  // kobject
    const char *init_name;  // 初始名称
    const struct device_type *type;  // 设备类型
    
    struct mutex mutex;  // 互斥锁
    
    struct bus_type *bus;  // 总线类型
    struct device_driver *driver;  // 设备驱动
    void *platform_data;  // 平台数据
    void *driver_data;  // 驱动数据
    struct device_node *of_node;  // 设备树节点
    struct fwnode_handle *fwnode;  // 固件节点
    
    dev_t devt;  // 设备号
    u32 id;  // 设备ID
    
    spinlock_t devres_lock;
    struct list_head devres_head;
    
    struct class *class;  // 设备类
    const struct attribute_group **groups;  // 属性组
    
    void (*release)(struct device *dev);  // 释放函数
    struct iommu_group *iommu_group;  // IOMMU组
    
    bool offline_disabled:1;  // 禁止离线
    bool offline:1;  // 离线状态
};

总线-设备-驱动模型

// 总线类型
struct bus_type {
    const char *name;  // 总线名称
    const char *dev_name;  // 设备名称
    struct device *dev_root;  // 根设备
    
    const struct attribute_group **bus_groups;  // 总线属性组
    const struct attribute_group **dev_groups;  // 设备属性组
    const struct attribute_group **drv_groups;  // 驱动属性组
    
    int (*match)(struct device *dev, struct device_driver *drv);  // 匹配函数
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);  // 热插拔事件
    int (*probe)(struct device *dev);  // 探测函数
    int (*remove)(struct device *dev);  // 移除函数
    void (*shutdown)(struct device *dev);  // 关闭函数
    
    int (*online)(struct device *dev);  // 上线函数
    int (*offline)(struct device *dev);  // 下线函数
    
    int (*suspend)(struct device *dev, pm_message_t state);  // 挂起函数
    int (*resume)(struct device *dev);  // 恢复函数
    
    const struct dev_pm_ops *pm;  // 电源管理操作
    struct iommu_ops *iommu_ops;  // IOMMU操作
    struct subsys_private *p;  // 私有数据
    struct lock_class_key lock_key;  // 锁类键
};

6. 中断子系统

功能:处理硬件中断,提供中断控制器抽象。

中断描述符

// 中断描述符
struct irq_desc {
    struct irq_common_data irq_common_data;  // 通用数据
    struct irq_data irq_data;  // 中断数据
    unsigned int __percpu *kstat_irqs;  // 统计
    irq_flow_handler_t handle_irq;  // 中断处理函数
    struct irqaction *action;  // 中断动作
    unsigned int status_use_accessors;  // 状态
    unsigned int core_internal_state__do_not_mess_with_it;  // 核心内部状态
    unsigned int depth;  // 深度
    unsigned int wake_depth;  // 唤醒深度
    unsigned int irq_count;  // 中断计数
    unsigned long last_unhandled;  // 最后未处理
    unsigned int irqs_unhandled;  // 未处理中断数
    raw_spinlock_t lock;  // 自旋锁
    struct cpumask *percpu_enabled;  // 每CPU启用
    const struct cpumask *percpu_affinity;  // 每CPU亲和性
    struct rcuwait wait_for_threads;  // 线程等待
};

中断控制器

// 中断控制器芯片
struct irq_chip {
    struct device *parent_device;  // 父设备
    const char *name;  // 名称
    unsigned int (*irq_startup)(struct irq_data *data);  // 启动
    void (*irq_shutdown)(struct irq_data *data);  // 关闭
    void (*irq_enable)(struct irq_data *data);  // 启用
    void (*irq_disable)(struct irq_data *data);  // 禁用
    
    void (*irq_ack)(struct irq_data *data);  // 确认
    void (*irq_mask)(struct irq_data *data);  // 掩码
    void (*irq_mask_ack)(struct irq_data *data);  // 掩码并确认
    void (*irq_unmask)(struct irq_data *data);  // 取消掩码
    void (*irq_eoi)(struct irq_data *data);  // 中断结束
    
    int (*irq_set_affinity)(struct irq_data *data,  // 设置亲和性
                const struct cpumask *dest, bool force);
    int (*irq_retrigger)(struct irq_data *data);  // 重触发
    int (*irq_set_type)(struct irq_data *data, unsigned int flow_type);  // 设置类型
    int (*irq_set_wake)(struct irq_data *data, unsigned int on);  // 设置唤醒
    
    void (*irq_bus_lock)(struct irq_data *data);  // 总线锁
    void (*irq_bus_sync_unlock)(struct irq_data *data);  // 总线同步解锁
    
    void (*irq_cpu_online)(struct irq_data *data);  // CPU上线
    void (*irq_cpu_offline)(struct irq_data *data);  // CPU下线
    
    void (*irq_suspend)(struct irq_data *data);  // 挂起
    void (*irq_resume)(struct irq_data *data);  // 恢复
    void (*irq_pm_shutdown)(struct irq_data *data);  // 电源管理关闭
    
    void (*irq_calc_mask)(struct irq_data *data);  // 计算掩码
    
    void (*irq_print_chip)(struct irq_data *data, struct seq_file *p);  // 打印芯片
    int (*irq_request_resources)(struct irq_data *data);  // 请求资源
    void (*irq_release_resources)(struct irq_data *data);  // 释放资源
    
    unsigned long flags;  // 标志
};

三、内核关键算法实现

1. 调度器算法

// CFS调度器pick_next_task算法
static struct task_struct *
pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) {
    struct cfs_rq *cfs_rq = &rq->cfs;
    struct sched_entity *se;
    struct task_struct *p;
    
    // 如果没有任务,返回idle
    if (!cfs_rq->nr_running)
        return NULL;
    
    // 如果设置了跳过标志,直接返回
    if (prev && prev->sched_class == &fair_sched_class && 
        rq->cfs.skip == prev)
        goto simple;
    
    // 从红黑树中选择最小vruntime的任务
    se = pick_next_entity(cfs_rq, NULL);
    p = task_of(se);
    
    // 如果选择的是idle任务,返回NULL
    if (p == rq->idle)
        return NULL;
    
simple:
    // 简单情况:只有一个任务
    if (cfs_rq->nr_running == 1) {
        se = __pick_first_entity(cfs_rq);
        p = task_of(se);
        if (p != rq->idle)
            goto found;
        return NULL;
    }
    
    // 设置跳过标志
    rq->cfs.skip = NULL;
    
found:
    // 更新统计数据
    update_stats_wait_start(cfs_rq, se);
    
    return p;
}

2. 伙伴系统算法

// 伙伴系统内存分配
static struct page *__rmqueue(struct zone *zone, unsigned int order,
                int migratetype, unsigned int alloc_flags) {
    struct page *page;
    
retry_reserve:
    // 首先尝试从指定迁移类型的空闲列表中分配
    page = __rmqueue_smallest(zone, order, migratetype);
    
    if (unlikely(!page) && migratetype != MIGRATE_RESERVE) {
        // 如果失败,尝试从备选迁移类型分配
        page = __rmqueue_fallback(zone, order, migratetype);
        
        // 如果还是失败,使用保留页
        if (!page && alloc_flags & ALLOC_NO_WATERMARKS) {
            migratetype = MIGRATE_RESERVE;
            goto retry_reserve;
        }
    }
    
    trace_mm_page_alloc_zone_locked(page, order, migratetype);
    return page;
}

// 从最小order开始搜索
static struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
                        int migratetype) {
    unsigned int current_order;
    struct free_area *area;
    struct page *page;
    
    // 从请求的order开始,向上搜索
    for (current_order = order; current_order < MAX_ORDER; ++current_order) {
        area = &(zone->free_area[current_order]);
        page = list_first_entry_or_null(&area->free_list[migratetype],
                        struct page, lru);
        if (!page)
            continue;
        
        // 从空闲列表中删除
        list_del(&page->lru);
        rmv_page_order(page);
        area->nr_free--;
        
        // 扩展页面(如果需要分裂)
        expand(zone, page, order, current_order, area, migratetype);
        set_pcppage_migratetype(page, migratetype);
        return page;
    }
    
    return NULL;
}

3. TCP拥塞控制算法

// CUBIC拥塞控制算法
static inline void bictcp_update(struct bictcp *ca, u32 cwnd, u32 acked) {
    u32 delta, bic_target, max_cnt;
    u64 offs;
    u32 t = ca->delay_min >> 3;  // 最小延迟
    
    // 重置计数
    ca->ack_cnt += acked;
    if (ca->last_cwnd == cwnd &&
        (s32)(tcp_jiffies32 - ca->last_time) <= HZ / 32)
        return;
    
    ca->last_cwnd = cwnd;
    ca->last_time = tcp_jiffies32;
    
    if (ca->epoch_start == 0) {  // 新周期开始
        ca->epoch_start = tcp_jiffies32;
        ca->ack_cnt = acked;
        ca->tcp_cwnd = cwnd;
        
        if (ca->last_max_cwnd <= cwnd) {
            ca->bic_K = 0;
            ca->bic_origin_point = cwnd;
        } else {
            // 计算新的K值
            ca->bic_K = cubic_root(cube_factor
                * (ca->last_max_cwnd - cwnd));
            ca->bic_origin_point = ca->last_max_cwnd;
        }
    }
    
    // 计算目标窗口
    t = (s32)(tcp_jiffies32 - ca->epoch_start);
    t += msecs_to_jiffies(ca->delay_min >> 3);
    offs = (t * t * t) << 3;
    bic_target = ca->bic_origin_point + (offs >> 10);
    
    if (bic_target < cwnd) {  // 凸区域
        ca->cnt = cwnd / (cwnd - bic_target);
    } else {  // 凹区域
        ca->cnt = 100 * cwnd;
    }
    
    // 限制cnt增长过快
    if (ca->cnt > 2)
        ca->cnt = 2;
}

四、内核模块机制

模块加载机制

// 模块结构
struct module {
    enum module_state state;  // 模块状态
    struct list_head list;  // 模块链表
    char name[MODULE_NAME_LEN];  // 模块名称
    
    // 版本控制
    struct module_version_attribute *version_attrs;
    const char *version;
    const char *srcversion;
    
    // 符号表
    const struct kernel_symbol *syms;
    const unsigned long *crcs;
    unsigned int num_syms;
    
    // GPL符号
    const struct kernel_symbol *gpl_syms;
    const unsigned long *gpl_crcs;
    unsigned int num_gpl_syms;
    
    // 异常表
    const struct exception_table_entry *extable;
    unsigned int num_exentries;
    
    // 初始化/退出函数
    int (*init)(void);
    void *module_init;
    void *module_core;
    unsigned int init_size, core_size;
    unsigned int init_text_size, core_text_size;
    unsigned int init_ro_size, core_ro_size;
    unsigned int init_data_size, core_data_size;
    
    // 权限
    const struct kernel_param *kp;
    unsigned int num_kp;
    
    // 签名
    bool sig_ok;
    
    bool async_probe_requested;
    
    // 符号查找
    bool using_gplonly_symbols;
    
    // 异常处理
    struct exception_table_entry *extable;
    unsigned int num_exentries;
    
    // 模块引用
    struct module *refptr;
    
    // 内核对象
    struct kobject kobj;
    
    // 许可证
    const char *license;
    
    // 损坏标志
    unsigned int taints;
    
    // 每CPU数据
    void *percpu;
    unsigned int percpu_size;
    
    // 驱动程序数据
    char *args;
    
    // 核心模块标志
    bool core_kernel;
};

五、内核启动流程

启动阶段

// 内核启动主函数
asmlinkage __visible void __init start_kernel(void) {
    char *command_line;
    char *after_dashes;
    
    // 1. 早期初始化
    set_task_stack_end_magic(&init_task);
    smp_setup_processor_id();
    debug_objects_early_init();
    
    // 2. 陷阱和中断初始化
    boot_cpu_init();
    page_address_init();
    pr_notice("%s", linux_banner);
    setup_arch(&command_line);
    
    // 3. 内存初始化
    mm_init_cpumask(&init_mm);
    setup_command_line(command_line);
    setup_nr_cpu_ids();
    setup_per_cpu_areas();
    smp_prepare_boot_cpu();
    
    // 4. 构建内存区域列表
    build_all_zonelists(NULL);
    page_alloc_init();
    
    // 5. 解析命令行参数
    pr_notice("Kernel command line: %s\n", boot_command_line);
    parse_early_param();
    after_dashes = parse_args("Booting kernel",
                  static_command_line, __start___param,
                  __stop___param - __start___param,
                  -1, -1, NULL, &unknown_bootoption);
    
    // 6. 初始化跳转标签
    jump_label_init();
    
    // 7. 设置控制台
    console_init();
    
    // 8. 锁定验证
    lockdep_init();
    
    // 9. 内存管理初始化
    mem_encrypt_init();
    setup_per_cpu_pageset();
    numa_policy_init();
    if (late_time_init)
        late_time_init();
    
    // 10. 调度器初始化
    sched_init();
    
    // 11. RCU初始化
    rcu_init();
    
    // 12. 跟踪和性能监控
    trace_init();
    
    // 13. 上下文跟踪
    context_tracking_init();
    
    // 14. 随机数生成器
    random_init(command_line);
    
    // 15. 定时器初始化
    time_init();
    timekeeping_init();
    
    // 16. 性能事件
    perf_event_init();
    
    // 17. 分析
    profile_init();
    call_function_init();
    WARN(!irqs_disabled(),
         "Interrupts were enabled *very* early, fixing it\n");
    local_irq_disable();
    
    // 18. 中断初始化
    early_boot_irqs_disabled = false;
    local_irq_enable();
    
    // 19. 控制台初始化完成
    console_init();
    
    // 20. 延迟初始化
    if (panic_later)
        panic("Too many boot %s vars at `%s'", panic_later,
              panic_param);
    
    // 21. 虚拟文件系统缓存
    vfs_caches_init_early();
    
    // 22. 排序异常表
    sort_main_extable();
    
    // 23. 陷阱初始化
    trap_init();
    mm_init();
    
    // 24. 调度器时钟初始化
    sched_init_smp();
    
    // 25. 初始化工作队列
    workqueue_init_early();
    
    // 26. RCU调度初始化
    rcu_init_sched();
    
    // 27. 跟踪调度器
    trace_sched_switch_init();
    
    // 28. 软中断初始化
    softirq_init();
    timekeeping_init();
    time_init();
    
    // 29. 性能计数器
    perf_trace_init();
    profile_init();
    
    // 30. 控制台初始化完成
    console_init();
    
    // 31. 延迟初始化
    if (panic_later)
        panic("Too many boot %s vars at `%s'", panic_later,
              panic_param);
    
    // 32. 虚拟文件系统缓存
    vfs_caches_init();
    
    // 33. 缓冲区缓存初始化
    buffer_init();
    
    // 34. 密钥管理
    key_init();
    security_init();
    dbg_late_init();
    vfs_caches_init();
    signals_init();
    
    // 35. 页缓存初始化
    pagecache_init();
    
    // 36. 信号初始化
    signals_init();
    
    // 37. 进程初始化
    proc_root_init();
    nsfs_init();
    
    // 38. 控制组初始化
    cgroup_init();
    
    // 39. 延迟ACPI初始化
    acpi_early_init();
    
    // 40. 文件系统初始化
    sched_init_smp();
    
    // 41. 创建init进程
    rest_init();
}

六、内核设计模式

1. 分层架构模式

  • 硬件抽象层:屏蔽硬件差异
  • 核心服务层:提供基本服务
  • 系统接口层:向用户空间提供接口

2. 模块化设计模式

  • 编译时模块化:通过条件编译选择功能
  • 运行时模块化:通过内核模块动态加载

3. 面向对象设计模式

  • 封装:通过结构体和函数指针实现
  • 继承:通过结构体嵌入实现
  • 多态:通过函数指针表实现

4. 发布-订阅模式

  • 通知链:用于内核事件通知
  • 观察者模式:用于文件系统变化通知

七、总结

Linux内核架构体现了宏内核的优化和模块化设计的完美结合:

  1. 进程管理:多调度器策略,支持实时和公平调度
  2. 内存管理:复杂的伙伴系统和slab分配器,优化内存使用
  3. 文件系统:统一的VFS抽象,支持多种文件系统
  4. 网络栈:完整的TCP/IP实现,支持各种网络协议
  5. 设备驱动:统一的设备模型,支持热插拔
  6. 安全机制:多种安全模块,支持强制访问控制
  7. 模块化:支持运行时模块加载,提高灵活性

Linux内核的持续演进展示了开源协作的威力,其架构设计已成为操作系统设计的典范。