嵌入式Linux系统启动与内核驱动开发全解

一、嵌入式Linux整体组成

嵌入式Linux系统由4大部分构成:Bootloader(U-Boot)、Linux内核Kernel、根文件系统rootfs、应用程序APP

  1. U-Boot:引导加载程序,初始化硬件,把内核镜像加载到内存,传递启动参数,启动内核。
  2. Linux内核:管理硬件资源、进程、内存、驱动,提供系统调用,向上给应用层提供接口。
  3. 根文件系统:存放系统配置、库、命令程序、设备节点,内核启动后挂载rootfs。
  4. 应用程序:用户层代码(我们写的led/beep/key测试APP),通过系统调用操作驱动。

二、系统完整启动流程

  1. 上电 → CPU复位,执行固化在ROM里的一级启动代码(i.MX6ULL的BOOT ROM)
  2. 加载U-Boot到内存,运行U-Boot
    • U-Boot初始化时钟、DDR、串口等基础硬件
    • 读取环境变量,设置bootargs启动参数
    • 从SD卡/TFTP/NAND读取zImage内核镜像、dtb设备树到DDR内存
    • 调用内核入口,启动Linux内核
  3. 内核启动
    • 内核自解压,初始化内存管理、进程调度
    • 解析设备树dtb,根据DTS节点自动创建platform设备
    • 初始化内置驱动、字符设备、misc子系统
    • 挂载根文件系统rootfs
  4. 根文件系统启动
    • 执行/linuxrc或/sbin/init
    • 启动shell,进入串口命令行,开发板终端可用
  5. 用户操作:insmod加载驱动 → 运行APP测试硬件

三、U-Boot部分核心知识点

  1. U-Boot两大核心任务:硬件初始化 + 引导内核
  2. 关键命令:
    • printenv:打印环境变量
    • setenv:设置环境变量
    • saveenv:保存环境变量
    • tftpboot:网络加载镜像
    • bootz:启动zImage内核(附带dtb设备树)
  3. bootargs启动参数:告诉内核根文件系统位置、控制台串口。

四、设备树DTS

  1. 作用:描述板载硬件资源(引脚、GPIO、中断、寄存器),代替旧时代硬编码。
  2. 编译流程:.dts源文件 → 编译器dtc → .dtb二进制文件,U-Boot把dtb一起传给内核。
  3. 节点结构:node{ 属性; };,核心属性compatible用于platform总线匹配。
  4. 内核启动阶段解析dtb,自动生成platform设备。

五、Linux内核驱动三大版本(和前面笔记衔接)

驱动本质:内核模块,给用户APP提供访问硬件的接口,依赖内核,运行在内核态

版本1:纯Misc驱动(无设备树)

硬件信息GPIO号硬编码写在驱动代码

  • 模块加载insmod直接执行module_init入口函数
  • 直接gpio_request申请引脚,misc_register注册杂项设备
  • 缺点:软硬件耦合,换引脚要改驱动代码重编译

版本2:Misc + DTS(无Platform)

硬件信息写到设备树,驱动代码里使用of_find_node_by_name主动查找DTS节点,读取GPIO

  • 不用硬编码GPIO
  • 没有总线匹配机制,模块加载就直接初始化,写法不标准

版本3:Platform + DTS + Misc(标准企业写法)

Platform总线分离设备(DTS描述) 和驱动(platform_driver代码)

  1. DTS节点 = 设备,带compatible匹配字符串
  2. platform_driver里of_match_table存放匹配字符串
  3. 内核自动对比compatible,匹配成功自动调用probe函数
  4. probe函数:读取DTS硬件资源、申请GPIO、注册misc设备
  5. rmmod卸载驱动,自动调用remove释放资源

三者关系:

  • Misc:负责生成/dev/xxx设备节点,提供read/write供用户APP调用
  • DTS:描述硬件信息,软硬件解耦
  • Platform总线:管理设备驱动匹配、驱动生命周期

六、内核态与用户态

  1. 用户态:APP程序,权限低,不能直接操作硬件。通过**系统调用(open/read/write/close)**陷入内核态。
  2. 内核态:驱动代码,拥有全部硬件访问权限,管理硬件寄存器。
  3. 数据交互:
    • 用户→内核:copy_from_user(LED/BEEP写操作)
    • 内核→用户:copy_to_user(KEY读操作)

七、模块操作命令(开发板shell)

sh 复制代码
insmod xxx_drv.ko  #加载内核模块
lsmod              #查看已加载模块
rmmod xxx_drv      #卸载模块
mdev -s            #自动创建设备节点 /dev/xxx
dmesg              #查看内核打印信息,调试驱动

八、根文件系统rootfs

  1. 包含:基础命令(ls、echo、cat)、动态库、配置脚本、设备目录模板
  2. 内核启动的最后一步:挂载rootfs,之后才能启动shell。
  3. 目录:/dev设备节点、/proc内核信息、/syssysfs文件系统、/bin命令

九、补充:驱动的两种开发思路

  1. 模块方式(我们实验用的):驱动编译成.ko,动态加载,不需要重新编译整个内核,调试方便。
  2. 内置到内核:驱动直接编译进zImage内核镜像,内核启动自动加载,适合产品正式发布。

十、整体逻辑串联一句话

上电U-Boot引导内核,内核解析设备树生成platform设备;我们写的Platform驱动加载后,内核匹配设备,执行probe,注册misc设备生成/dev节点;用户APP调用open/read/write系统调用进入内核驱动,控制LED/蜂鸣器/按键硬件。

相关推荐
字节跳动的猫1 小时前
LikeShop 商品评价体系二开:追评、晒图审核与评价标签筛选功能开发
运维·数据结构·数据库
晴天的雨.9921 小时前
【Linux】基础开发工具---软件包管理器
linux·运维·服务器
mi20061 小时前
不合规MAC地址导致通信故障
运维
sbjdhjd1 小时前
云安全 | 从特权容器到旧版 runC:Docker 宿主机访问与运行时缺陷复盘
运维·网络安全·docker·云原生·kubernetes·云计算·云安全
xiaoqiMikko2 小时前
Linux 实战(三):服务起不来、定时任务不执行 —— CentOS 7 / Rocky 9 / Ubuntu 24.04 实测差异
linux·centos
Hello_Pyhx2 小时前
Ventoy:Linux制盘与排障
linux·运维·服务器
pt10432 小时前
从阿波罗13号到命令行的网络实验转向
运维·网络
Jason_zhao_MR2 小时前
电力数据采集核心板选型指南
linux·嵌入式硬件·fpga开发·嵌入式
见闻小天地2 小时前
空调机房赛莱默B&G冷冻泵/冷却泵的核心技术特性分析
大数据·运维·数据库