第7课 嵌入式Linux内核架构解析 模块二内核核心机制文章目录第7课 嵌入式Linux内核架构解析 模块二内核核心机制一、课程目标二、Linux内核核心定位三、内核核心机制详解含原理说明样例代码1. 内核核心机制进程与线程管理1.1 基本概念1.2 进程状态1.3 示例代码内核模块查看进程信息2. 内核核心机制进程调度2.1 调度功能2.2 常见调度策略2.3 调度核心指标2.4 示例代码查看进程调度类3. 内核核心机制内存管理3.1 物理内存与虚拟内存3.2 内存分配机制3.3 内核空间与用户空间3.4 示例代码内核内存分配4. 内核核心机制中断与异常处理4.1 中断作用4.2 中断处理流程4.3 下半部机制bottom half4.4 示例嵌入式GPIO中断流程4.5 示例代码tasklet 下半部5. 内核核心机制系统调用5.1 基本概念5.2 典型系统调用5.3 示例代码系统调用演示6. 内核核心机制同步与互斥6.1 作用6.2 使用原则6.3 示例代码自旋锁7. 内核核心机制定时器与延时机制7.1 内核定时器7.2 延时函数7.3 示例代码内核定时器8. 内核核心机制工作队列与内核线程8.1 基本概念8.2 示例代码工作队列四、课堂练习五、课后作业六、本章总结七、核心关键词回顾总结上一节课作业答案 嵌入式C语言进阶适配实战模块一基础入门代码功能说明注意事项一、课程目标理解嵌入式Linux内核的核心定位与运行机制掌握进程管理、调度、内存管理、中断管理、系统调用五大核心机制理解内核空间与用户空间的隔离原理掌握内核同步、锁机制、定时器、工作队列基础原理为后续内核裁剪、驱动开发打下理论基础二、Linux内核核心定位Linux内核是硬件与应用层之间的核心中间层负责统一管理硬件资源、调度任务、分配内存、处理中断并为应用程序提供稳定接口。嵌入式Linux内核特点体积小、可裁剪、实时性可控、支持多种CPU架构ARM、MIPS、RISC-V。三、内核核心机制详解含原理说明样例代码1. 内核核心机制进程与线程管理1.1 基本概念进程程序运行的实体拥有独立内存空间线程轻量级进程共享进程资源PCB进程控制块内核管理进程的核心数据结构1.2 进程状态运行态、就绪态、阻塞态、终止态嵌入式中常见中断唤醒阻塞进程1.3 示例代码内核模块查看进程信息#include linux/module.h #include linux/sched.h #include linux/init.h static int __init process_demo_init(void) { printk(当前进程 PID: %d\n, current-pid); printk(进程名称: %s\n, current-comm); printk(进程状态: %d\n, current-state); return 0; } static void __exit process_demo_exit(void) { printk(进程模块卸载\n); } module_init(process_demo_init); module_exit(process_demo_exit); MODULE_LICENSE(GPL);2. 内核核心机制进程调度2.1 调度功能决定哪个进程使用CPU是嵌入式系统实时性的关键。2.2 常见调度策略CFS调度普通进程公平调度RT调度实时进程高优先级优先嵌入式常用PREEMPT_RT补丁提升实时性2.3 调度核心指标响应时间、切换开销、优先级、抢占性2.4 示例代码查看进程调度类#include linux/module.h #include linux/sched.h static int __init sched_demo_init(void) { printk(当前进程调度类: %s\n, current-sched_class fair_sched_class ? CFS 公平调度 : current-sched_class rt_sched_class ? RT 实时调度 : 其他); return 0; } static void __exit sched_demo_exit(void) { printk(调度模块卸载\n); } module_init(sched_demo_init); module_exit(sched_demo_exit); MODULE_LICENSE(GPL);3. 内核核心机制内存管理3.1 物理内存与虚拟内存内核负责将虚拟地址映射为物理地址嵌入式系统通常开启MMU实现地址隔离与保护3.2 内存分配机制伙伴系统管理物理页框SLAB/SLOB/Slub小内存分配器嵌入式常用SLOB3.3 内核空间与用户空间0~3G用户空间3G~4G内核空间ARM 32位应用程序不能直接访问内核必须通过系统调用3.4 示例代码内核内存分配#include linux/module.h #include linux/slab.h static int __init mem_demo_init(void) { void *buf; buf kmalloc(1024, GFP_KERNEL); if (!buf) { printk(内存分配失败\n); return -ENOMEM; } printk(内核内存分配成功: %p\n, buf); kfree(buf); return 0; } static void __exit mem_demo_exit(void) { printk(内存模块卸载\n); } module_init(mem_demo_init); module_exit(mem_demo_exit); MODULE_LICENSE(GPL);4. 内核核心机制中断与异常处理4.1 中断作用硬件向CPU发送信号触发内核处理如键盘、网卡、GPIO4.2 中断处理流程中断发生 → 保存现场 → 执行中断服务程序 → 恢复现场4.3 下半部机制bottom half软中断、tasklet、工作队列目的缩短中断关闭时间提升系统实时性4.4 示例嵌入式GPIO中断流程按键按下 → GPIO中断触发 → 驱动中断处理 → 唤醒应用进程4.5 示例代码tasklet 下半部#include linux/module.h #include linux/interrupt.h void tasklet_func(unsigned long data) { printk(tasklet 下半部执行: %lu\n, data); } DECLARE_TASKLET(my_tasklet, tasklet_func, 666); static int __init irq_demo_init(void) { tasklet_schedule(my_tasklet); printk(tasklet 调度成功\n); return 0; } static void __exit irq_demo_exit(void) { tasklet_kill(my_tasklet); printk(中断模块卸载\n); } module_init(irq_demo_init); module_exit(irq_demo_exit); MODULE_LICENSE(GPL);5. 内核核心机制系统调用5.1 基本概念系统调用是用户程序进入内核的唯一合法入口。应用程序通过软中断ARM为svc进入内核态执行内核函数后返回用户态。5.2 典型系统调用open、read、write、ioctl、fork、mmap5.3 示例代码系统调用演示#include linux/module.h #include linux/syscalls.h static int __init syscall_demo_init(void) { printk(系统调用号: %lu\n, __NR_getpid); printk(用户程序通过系统调用进入内核\n); return 0; } static void __exit syscall_demo_exit(void) { printk(系统调用模块卸载\n); } module_init(syscall_demo_init); module_exit(syscall_demo_exit); MODULE_LICENSE(GPL);6. 内核核心机制同步与互斥6.1 作用嵌入式多任务并发必须保证资源安全内核提供自旋锁 spinlock互斥锁 mutex信号量 semaphore完成量 completion6.2 使用原则中断上下文用自旋锁进程上下文可用互斥锁。6.3 示例代码自旋锁#include linux/module.h #include linux/spinlock.h static spinlock_t my_lock; static int __init sync_demo_init(void) { unsigned long flags; spin_lock_init(my_lock); spin_lock_irqsave(my_lock, flags); printk(自旋锁加锁成功\n); spin_unlock_irqrestore(my_lock, flags); return 0; } static void __exit sync_demo_exit(void) { printk(同步模块卸载\n); } module_init(sync_demo_init); module_exit(sync_demo_exit); MODULE_LICENSE(GPL);7. 内核核心机制定时器与延时机制7.1 内核定时器基于硬件时钟中断用于周期性任务、超时处理7.2 延时函数udelay、mdelay、msleep原子上下文不能用睡眠函数7.3 示例代码内核定时器#include linux/module.h #include linux/timer.h static struct timer_list my_timer; void timer_func(struct timer_list *timer) { printk(定时器超时执行\n); } static int __init timer_demo_init(void) { my_timer.expires jiffies HZ * 2; my_timer.function timer_func; add_timer(my_timer); printk(定时器启动成功\n); return 0; } static void __exit timer_demo_exit(void) { del_timer_sync(my_timer); printk(定时器模块卸载\n); } module_init(timer_demo_init); module_exit(timer_demo_exit); MODULE_LICENSE(GPL);8. 内核核心机制工作队列与内核线程8.1 基本概念工作队列把任务推后执行运行在进程上下文可睡眠。内核线程由内核创建只在内核态运行用于后台处理。8.2 示例代码工作队列#include linux/module.h #include linux/workqueue.h static struct work_struct my_work; void work_func(struct work_struct *work) { printk(工作队列执行\n); } static int __init workq_demo_init(void) { INIT_WORK(my_work, work_func); schedule_work(my_work); printk(工作队列调度成功\n); return 0; } static void __exit workq_demo_exit(void) { flush_work(my_work); printk(工作队列模块卸载\n); } module_init(workq_demo_init); module_exit(workq_demo_exit); MODULE_LICENSE(GPL);四、课堂练习简述用户空间与内核空间的区别。中断处理为什么要分上半部和下半部嵌入式内核为什么常用SLOB分配器进程调度的作用是什么系统调用的作用是什么五、课后作业画图描述Linux内核五大核心机制之间的关系。说明中断、软中断、tasklet、工作队列的区别与适用场景。解释内核同步为什么在中断中只能用自旋锁。简述虚拟内存作用及其在嵌入式中的价值。查阅资料说明CFS与RT调度器的区别。六、本章总结本章讲解嵌入式Linux内核八大核心机制进程管理、调度、内存管理、中断处理、系统调用、同步互斥、定时器、工作队列。内核是系统资源管理者通过地址空间隔离保证稳定通过调度保证响应速度通过中断对接硬件通过同步保证安全。这些机制是理解内核裁剪、移植、驱动开发的基础必须熟练掌握。七、核心关键词Linux内核、进程管理、调度、内存管理、中断、系统调用、同步机制、定时器、工作队列、内核空间回顾总结本课系统讲解嵌入式Linux内核的核心机制是深入内核开发的必备理论基础。课程围绕内核最关键的八大机制展开包括进程与线程管理、进程调度、内存管理、中断处理、系统调用、同步互斥、定时器延时、工作队列与内核线程。通过学习理解内核作为硬件与应用中间层的核心作用掌握用户空间与内核空间的隔离机制理解MMU、虚拟地址、物理地址的关系。中断机制是嵌入式设备与内核交互的关键课程重点说明上半部与下半部的区别以及软中断、tasklet、工作队列的使用场景。同步与互斥机制保证多进程、多中断并发访问资源安全明确自旋锁与互斥锁的使用原则。系统调用是应用程序进入内核的唯一合法入口是驱动与应用交互的基础。调度机制决定系统实时性CFS与RT调度器适用于不同场景。定时器与延时、工作队列与内核线程是内核实现定时、延后、后台任务的常用方式。本课所有内容均面向嵌入式场景强调小体积、可裁剪、实时性、资源有限等特点为后续内核配置、内核移植、设备驱动开发打下坚实理论基础。熟练掌握这些机制能真正理解Linux运行原理提升嵌入式系统开发与调试能力。上一节课作业答案 嵌入式C语言进阶适配实战模块一基础入门#include stdio.h // 温度转换函数摄氏转华氏 float convert_c2f(float c) { return c * 1.8 32; } int main() { // 模拟传感器电压数组 float voltage[10] {3.2, 3.5, 3.3, 3.6, 3.4, 3.1, 3.7, 3.2, 3.5, 3.6}; float sum 0; int i; // 计算平均值 for (i 0; i 10; i) { sum voltage[i]; } float avg sum / 10; printf(电压数组); for (i 0; i 10; i) { printf(%.2f , voltage[i]); } printf(\n平均电压%.2fV\n, avg); // 模式控制演示 int mode 2; switch (mode) { case 1: printf(设备模式待机\n); break; case 2: printf(设备模式运行\n); break; case 3: printf(设备模式休眠\n); break; default: printf(模式异常\n); } // LED闪烁3次模拟 for (i 0; i 3; i) { printf(LED 闪烁 %d\n, i 1); } printf(LED 熄灭\n); // 温度转换 float temp_c 28.0; float temp_f convert_c2f(temp_c); printf(温度%.2f℃ → %.2f℉\n, temp_c, temp_f); return 0; }代码功能说明该程序是嵌入式C语言基础综合实战作业涵盖数组、循环、分支、函数、运算等核心知识点。程序定义电压数组并计算平均值模拟传感器采集与数据处理使用switch-case实现设备模式控制通过for循环实现LED闪烁三次后熄灭编写函数实现摄氏温度转华氏温度。代码贴近嵌入式真实场景可用于练习变量、运算、流程控制、函数封装、数组遍历等基础能力适合嵌入式入门者巩固C语言核心语法为后续驱动开发打下基础。注意事项编译命令gcc homework.c -o homework数组下标不可越界循环范围必须正确函数必须先声明后调用switch-case必须加break避免穿透浮点数运算注意精度问题变量必须初始化避免随机值导致异常