 模块二:内核核心机制)
文章目录一、课程目标二、内存管理整体概述三、物理内存与虚拟内存3.1 物理内存3.2 虚拟内存3.3 虚拟内存核心优势四、MMU内存管理单元核心原理4.1 MMU核心功能4.2 MMU地址转换流程五、页表与内存映射机制5.1 页与页帧概念5.2 二级页表映射ARM32嵌入式主流5.3 缺页异常六、内核内存空间划分ARM326.1 地址空间划分6.2 空间隔离意义七、内核内存分配机制7.1 伙伴系统7.2 内存分配器SLOB/SLUB/SLAB7.3 常用内存分配接口八、实战示例代码示例1内核态内存分配与释放示例2用户态验证虚拟内存独立隔离九、课堂练习十、课后作业十一、本章总结十二、核心关键词第12课 课程回顾总结上一课作业答案 线程管理与调度机制 实战作业代码代码功能说明注意事项一、课程目标理解嵌入式Linux物理内存、虚拟内存的核心概念与本质区别掌握MMU内存管理单元的工作原理、地址转换机制深入理解页表、页帧、映射关系掌握一级/二级页表映射逻辑掌握内核空间与用户空间内存映射、权限隔离、访问保护机制熟悉Linux内核内存分配体系伙伴系统、SLOB/SLUB、kmalloc/vmalloc能够通过用户态、内核态代码验证内存映射与内存分配排查内存越界、内存泄漏问题二、内存管理整体概述内存是嵌入式系统最核心、最紧缺的硬件资源Linux内核专门提供内存管理子系统统一管理所有物理内存。嵌入式设备内存容量小、资源有限无法像PC系统一样冗余配置。因此内核需要精准完成内存分配、回收、隔离、保护避免内存泄漏、内存越界、进程内存相互干扰保障系统稳定运行。Linux内存管理核心分为两大模块硬件层MMU单元负责虚拟地址与物理地址转换、内存权限检查、内存隔离软件层内核内存管理算法伙伴系统、slab分配器、动态内存接口三、物理内存与虚拟内存3.1 物理内存物理内存是硬件真实的内存颗粒拥有唯一的物理地址是系统实际可用的内存资源。物理内存特点地址连续、无权限隔离、所有设备默认共享、直接访问极易造成内存踩踏。3.2 虚拟内存虚拟内存是内核为每个进程独立虚拟出来的地址空间并非真实物理内存。每个进程拥有独立的0~4GB32位系统虚拟地址空间进程之间虚拟地址完全隔离互不影响。3.3 虚拟内存核心优势实现进程地址空间隔离单个进程崩溃不会导致整机崩溃解决物理内存碎片化问题让离散的物理内存映射为连续虚拟内存实现内存权限管控只读、可写、不可访问保护内核关键内存支持内存按需映射节约稀缺的嵌入式物理内存四、MMU内存管理单元核心原理MMUMemory Management Unit内存管理单元是CPU内置的硬件单元是Linux内存管理的硬件基础。所有嵌入式Linux设备必须开启MMU否则无法实现虚拟内存、地址隔离、用户态/内核态权限管控。4.1 MMU核心功能地址转换将进程访问的虚拟地址翻译为真实物理地址权限检查判断当前访问是否合法用户态禁止读写内核内存内存保护拦截非法内存访问触发缺页异常、段错误缓存控制配置内存是否开启Cache适配外设寄存器内存4.2 MMU地址转换流程进程访问虚拟地址发送访问请求至MMUMMU查询当前进程页表匹配虚拟地址对应的物理页帧检查页表权限读写权限、用户/内核权限权限合法转换为物理地址访问真实内存权限非法/无映射触发缺页异常或段错误内核终止异常进程五、页表与内存映射机制MMU无法直接完成地址转换需要内核提前构建页表记录虚拟页与物理页的映射关系。5.1 页与页帧概念虚拟页虚拟内存按照固定大小分页标准页大小4KB物理页帧物理内存按照4KB划分页帧是内存分配最小单位5.2 二级页表映射ARM32嵌入式主流ARM32架构采用二级页表节省页表内存开销适配嵌入式小内存设备一级页表存放段映射负责大范围地址映射二级页表存放精细页映射完成4KB最小粒度映射与权限配置5.3 缺页异常当进程访问的虚拟内存没有物理内存映射或权限不匹配时MMU触发缺页异常。内核捕获异常后动态分配物理内存、建立映射关系该机制称为按需分页极大节约嵌入式内存资源。六、内核内存空间划分ARM3232位ARM Linux将4GB虚拟地址空间固定划分所有进程共享同一内核空间独有用户空间。6.1 地址空间划分用户空间0x00000000 ~ 0xBFFFFFFF0~3G进程独立隔离运行用户态程序只能访问该区域内核空间0xC0000000 ~ 0xFFFFFFFF3G~4G全局共享存放内核代码、驱动、内核全局内存仅内核态可访问6.2 空间隔离意义用户态程序无法直接读写内核空间杜绝非法篡改内核数据保证系统稳定性是Linux系统安全的底层基石。七、内核内存分配机制Linux内核分层管理物理内存从物理页管理到小块内存分配适配嵌入式各种内存场景。7.1 伙伴系统内核底层物理内存管理器以**页4KB**为单位分配、释放物理内存。核心作用解决大块物理内存碎片化保证连续物理内存分配供DMA、硬件外设使用。7.2 内存分配器SLOB/SLUB/SLABSLOB极简分配器代码量小、占用内存低专为嵌入式小内存设备设计嵌入式首选SLAB通用分配器缓存频繁创建销毁的内核对象SLUB性能更高适用于PC、服务器设备7.3 常用内存分配接口kmalloc分配内核连续物理内存速度快大小受限适合小型驱动内存vmalloc分配虚拟连续、物理不连续内存适合大块内核内存分配kfree/vfree对应内存释放接口八、实战示例代码示例1内核态内存分配与释放#include linux/module.h #include linux/kernel.h #include linux/slab.h static int __init mmu_demo_init(void) { char *buf; // 分配1024字节内核内存 buf kmalloc(1024, GFP_KERNEL); if (!buf) { printk(kmalloc 内存分配失败\n); return -ENOMEM; } printk(内核内存分配成功虚拟地址%p\n, buf); // 模拟内存写入 buf[0] 1; buf[1] 2; printk(内存写入测试完成\n); // 释放内核内存 kfree(buf); printk(内核内存释放完成\n); return 0; } static void __exit mmu_demo_exit(void) { printk(MMU内存管理模块卸载\n); } module_init(mmu_demo_init); module_exit(mmu_demo_exit); MODULE_LICENSE(GPL);示例2用户态验证虚拟内存独立隔离#include stdio.h #include unistd.h #include sys/types.h int global_val 666; int main() { pid_t pid fork(); if (pid 0) { // 子进程修改全局变量 global_val 888; printf(子进程pid%d, global_val%d\n, getpid(), global_val); } else { sleep(1); // 父进程数据不受影响验证虚拟地址空间隔离 printf(父进程pid%d, global_val%d\n, getpid(), global_val); } return 0; }九、课堂练习简述物理内存与虚拟内存的区别与作用。MMU的四大核心功能是什么嵌入式系统为什么必须开启MMU什么是缺页异常内核如何通过缺页异常优化内存使用率kmalloc与vmalloc的区别以及各自适用场景SLOB、SLAB、SLUB三种分配器的区别嵌入式首选哪一种十、课后作业画图描述MMU二级页表地址转换完整流程标注虚拟地址、页表、物理地址对应关系。编译运行本课内核内存分配模块通过dmesg查看内存地址观察内核虚拟内存特征。修改用户态虚拟内存隔离代码验证父子进程虚拟空间完全隔离互不干扰。简述用户进程访问内核空间地址为什么会触发段错误底层MMU如何拦截。查阅资料说明嵌入式Linux内存碎片化的危害与优化方案。十一、本章总结本章完整讲解嵌入式Linux内存管理子系统与MMU核心机制是内核五大核心机制中难度最高、最重要的模块之一。课程首先区分物理内存与虚拟内存讲解虚拟地址空间隔离对系统稳定性的决定性作用。重点讲解MMU硬件单元的地址转换、权限检测、内存保护机制拆解二级页表映射原理与缺页异常机制解释Linux按需分配内存的优化逻辑。同时详细介绍ARM32系统用户空间与内核空间的地址划分、隔离规则。针对嵌入式设备场景讲解伙伴系统、SLOB嵌入式专属内存分配器以及kmalloc/vmalloc常用内存接口区分不同内存分配方式的优缺点与适用场景。结合内核态、用户态两段实战代码验证内存分配、内存隔离、地址映射的底层逻辑帮助掌握内存泄漏、内存越界的排查思路为后续驱动内存开发、系统内存优化奠定基础。十二、核心关键词MMU、虚拟内存、物理内存、页表、缺页异常、用户内核空间隔离、伙伴系统、SLOB、kmalloc、vmalloc、内存碎片化第12课 课程回顾总结本课聚焦嵌入式Linux内存管理子系统与MMU核心机制系统讲解Linux内存底层工作原理是理解内核稳定性、内存优化、驱动内存开发的核心课程。课程首先对比物理内存与虚拟内存的差异阐明虚拟地址空间隔离是Linux系统进程隔离、程序容错、系统稳定的核心基础。重点讲解MMU硬件单元的工作机制详细拆解地址转换、权限校验、缺页异常的完整流程解释二级页表在嵌入式ARM架构中的适配优势解决了嵌入式设备内存小、资源紧张的问题。同时明确32位ARM系统用户空间与内核空间的地址划分规则梳理空间隔离的安全价值。课程分层讲解内核内存管理体系底层依靠伙伴系统管理物理页上层通过SLOB/SLAB/SLUB分配器适配不同场景重点适配嵌入式设备主推的SLOB极简分配器。同时区分kmalloc与vmalloc的使用差异覆盖驱动开发常用内存接口。搭配内核态内存分配、用户态内存隔离两段实战代码理论结合实操帮助学习者掌握内存映射、内存隔离、动态内存分配的核心逻辑能够独立排查内存越界、内存泄漏、段错误等常见问题为嵌入式驱动开发、内核裁剪、系统性能优化筑牢核心基础。上一课作业答案 线程管理与调度机制 实战作业代码#include stdio.h #include pthread.h #include unistd.h #include stdlib.h // 全局共享变量验证线程资源共享特性 int share_data 0; // 线程1执行函数 void *thread_func1(void *arg) { for(int i 0; i 5; i) { share_data; printf(线程1运行共享变量值%d\n, share_data); sleep(1); } pthread_exit(NULL); } // 线程2执行函数 void *thread_func2(void *arg) { for(int i 0; i 5; i) { share_data--; printf(线程2运行共享变量值%d\n, share_data); sleep(1); } pthread_exit(NULL); } int main(void) { pthread_t tid1, tid2; // 创建两个子线程 pthread_create(tid1, NULL, thread_func1, NULL); pthread_create(tid2, NULL, thread_func2, NULL); // 主线程等待所有子线程回收 pthread_join(tid1, NULL); pthread_join(tid2, NULL); printf(主线程所有子线程执行完毕程序退出\n); return 0; }代码功能说明本段代码为第11课线程管理与调度机制实战作业基于Linux pthread库创建两个并发子线程通过读写同一全局共享变量直观验证同进程下线程资源共享的核心特性。两个线程循环交替修改变量依靠系统CFS调度机制完成线程切换清晰展示线程调度交替执行的效果。主线程通过pthread_join回收子线程资源避免产生僵死线程。代码完整覆盖线程创建、并发调度、资源共享、线程回收核心知识点贴合嵌入式多线程并发开发场景帮助理解线程调度机制与线程资源特性巩固课程理论知识与实操能力。注意事项编译指令gcc thread_demo.c -o thread_demo -pthread必须链接线程库否则编译报错。多线程并发访问共享变量存在数据竞争本代码仅用于调度演示不做同步保护。线程执行顺序由系统CFS调度器决定每次运行打印顺序可能不一致属于正常现象。必须使用pthread_join回收线程否则会造成线程资源泄漏产生僵死线程。嵌入式实时项目中多线程共享资源必须搭配互斥锁避免数据错乱。禁止在大量循环线程中使用sleep会降低系统实时性影响调度效率。从零到壹嵌入式Linux编程实战教程课第1课嵌入式Linux概述