news 2026/4/22 14:21:19

从零到壹嵌入式Linux编程实战教程课: 第7课 嵌入式Linux内核架构解析 模块二:内核核心机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零到壹嵌入式Linux编程实战教程课: 第7课 嵌入式Linux内核架构解析 模块二:内核核心机制

第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 half)
      • 4.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语言进阶(适配实战)模块一:基础入门
    • 代码功能说明
    • 注意事项

一、课程目标

  1. 理解嵌入式Linux内核的核心定位与运行机制

  2. 掌握进程管理、调度、内存管理、中断管理、系统调用五大核心机制

  3. 理解内核空间与用户空间的隔离原理

  4. 掌握内核同步、锁机制、定时器、工作队列基础原理

  5. 为后续内核裁剪、驱动开发打下理论基础


二、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:小内存分配器(嵌入式常用SLOB)

3.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发送信号,触发内核处理(如键盘、网卡、GPIO)

4.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、mmap

5.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

  • 完成量 completion

6.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");

四、课堂练习

  1. 简述用户空间与内核空间的区别。

  2. 中断处理为什么要分上半部和下半部?

  3. 嵌入式内核为什么常用SLOB分配器?

  4. 进程调度的作用是什么?

  5. 系统调用的作用是什么?


五、课后作业

  1. 画图描述Linux内核五大核心机制之间的关系。

  2. 说明中断、软中断、tasklet、工作队列的区别与适用场景。

  3. 解释内核同步为什么在中断中只能用自旋锁。

  4. 简述虚拟内存作用及其在嵌入式中的价值。

  5. 查阅资料,说明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语言核心语法,为后续驱动开发打下基础。

注意事项

  1. 编译命令:gcc homework.c -o homework

  2. 数组下标不可越界,循环范围必须正确

  3. 函数必须先声明后调用

  4. switch-case必须加break避免穿透

  5. 浮点数运算注意精度问题

  6. 变量必须初始化,避免随机值导致异常


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 14:20:40

原神帧率解锁终极指南:如何免费突破60FPS限制获得丝滑体验

原神帧率解锁终极指南&#xff1a;如何免费突破60FPS限制获得丝滑体验 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock genshin-fps-unlock是一款专为《原神》玩家设计的开源工具&#xf…

作者头像 李华
网站建设 2026/4/22 14:18:24

Phi-3.5-mini-instruct保姆级教学:WebSocket长连接支持与流式响应开启

Phi-3.5-mini-instruct保姆级教学&#xff1a;WebSocket长连接支持与流式响应开启 1. 模型简介 Phi-3.5-mini-instruct是微软推出的轻量级开源指令微调大模型&#xff0c;在长上下文代码理解(RepoQA)和多语言MMLU等基准测试中表现优异。该模型特别适合本地或边缘部署&#xf…

作者头像 李华
网站建设 2026/4/22 14:16:04

用Python处理GEDI激光雷达数据:从HDF5文件到森林高度图(附代码)

用Python处理GEDI激光雷达数据&#xff1a;从HDF5文件到森林高度图&#xff08;附代码&#xff09; 当第一次打开GEDI的HDF5数据文件时&#xff0c;那种面对海量激光雷达波形数据的茫然感&#xff0c;相信很多研究者都深有体会。作为目前轨道分辨率最高的星载激光雷达系统&…

作者头像 李华
网站建设 2026/4/22 14:15:33

Python-pptx实战:从数据到演示文稿的自动化生成

1. Python-pptx入门&#xff1a;从安装到第一个演示文稿 如果你经常需要制作重复性高的PPT报告&#xff0c;比如每周的数据分析汇报&#xff0c;那么手动操作不仅耗时还容易出错。Python-pptx这个库就是来解决这个痛点的。它允许你用代码自动生成和修改PPT文件&#xff0c;特别…

作者头像 李华