当前位置:首页 > 嵌入式 > 嵌入式分享
[导读]嵌入式Linux上电后,从CPU复位到用户应用程序跑起来,经历了一条清晰的链路:Bootloader→内核解压→设备树解析→根文件系统挂载→init进程→应用层。理解这条链路,是定位启动故障、优化启动时间的根基。


嵌入式Linux上电后,从CPU复位到用户应用程序跑起来,经历了一条清晰的链路:Bootloader→内核解压→设备树解析→根文件系统挂载→init进程→应用层。理解这条链路,是定位启动故障、优化启动时间的根基。

第一阶段:Bootloader(以U-Boot为例)

CPU上电后首先执行固化在ROM中的一级启动代码,初始化时钟、DDR控制器,然后将Bootloader(通常是U-Boot)从Flash拷贝到DDR并跳转执行。U-Boot的主要任务是初始化硬件、加载内核和设备树到内存,然后跳转到内核入口。

# U-Boot环境变量示例

setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p2 rw'

setenv loadaddr 0x42000000

setenv fdtaddr 0x43000000


# 从SD卡加载内核和设备树

mmc read ${loadaddr} 0x800 0x8000

mmc read ${fdtaddr} 0x7800 0x1000


# 启动内核

bootm ${loadaddr} - ${fdtaddr}

bootm命令会将内核镜像解压到指定地址,同时将设备树传递给内核。设备树(DTB)告诉内核板上有哪些外设、地址映射、中断等信息。

第二阶段:内核启动

内核入口函数start_kernel()接管控制权,进行一系列初始化:CPU架构相关设置、内存管理(MMU)、中断向量表、调度器、时间子系统等。随后调用setup_arch()解析设备树,注册平台设备和驱动。关键步骤包括:

控制台初始化:根据console=参数激活串口,从此能看到内核打印信息。

根文件系统挂载:内核根据root=参数找到根设备,调用对应文件系统驱动(ext4、squashfs、initramfs等)。

执行init进程:挂载根文件系统后,内核寻找并执行第一个用户空间程序。查找顺序:/sbin/init → /etc/init → /bin/init → /bin/sh。如果找不到,内核会panic。

第三阶段:init进程与系统初始化

init进程是所有用户进程的祖先进程。嵌入式系统中常见两种:

BusyBox init:轻量级,读取/etc/inittab启动脚本。典型inittab内容:

::sysinit:/etc/init.d/rcS

::respawn:-/bin/sh

rcS脚本负责挂载/proc、/sys、/dev,配置网络,启动守护进程等。

systemd:功能强大但体积大,适用于资源充足的设备。通过单元文件并行启动服务,支持依赖管理和socket激活。

第四阶段:应用层启动

init进程启动完毕后,最终会执行用户的业务程序。常见做法:

在rcS末尾直接调用/usr/bin/myapp &

使用supervisor或monit等进程管理工具,保证应用崩溃后自动重启

对于systemd,编写service文件:

[Unit]

Description=My Embedded App

After=network.target


[Service]

ExecStart=/usr/bin/myapp

Restart=always


[Install]

WantedBy=multi-user.target

启动加速技巧

了解完整链路后,可以从各阶段入手缩短启动时间:

Bootloader:去掉不必要的延时,如bootdelay=0;使用FIT镜像合并内核和设备树,减少加载次数。

内核:裁剪不需要的驱动,使用initramfs内置根文件系统,省去挂载块设备的时间。

用户空间:将关键初始化移到内核启动参数中(如ip=dhcp提前获取IP),使用prctl(PR_SET_TIMING)等系统调用优化。

调试利器:printk与initcall_debug

如果启动卡住,在内核命令行添加initcall_debug可以打印每个初始化函数的执行时间和返回值。用户空间启动问题则通过strace跟踪init进程的系统调用:

# 在initramfs中临时替换init为strace

exec /usr/bin/strace -f -o /tmp/strace.log /sbin/init

写在最后

从Bootloader的bootm到应用层的main(),嵌入式Linux启动的每一步都有明确的职责和可观测的接口。掌握这条链路,你就能在系统无法启动时迅速判断是内核崩溃、根文件系统缺失还是应用脚本出错,也能有针对性地优化开机速度。对于追求毫秒级启动的工业设备,甚至可以跳过Bootloader直接由内核引导(XIP),但那又是另一个故事了。

关键词:启动流程Bootloader,init进程



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

在嵌入式系统中,固件安全是保障设备长期可靠运行的核心防线。当设备通过OTA或串口接收新固件时,若缺乏完整性与身份验证机制,攻击者可轻易注入恶意代码,导致设备失控、数据泄露或物理损坏。二级启动方案通过Bootloader对...

关键字: CRC校验 Bootloader

在嵌入式系统开发中,U-Boot作为关键的引导加载程序,其环境变量的稳定性和内核更新的便捷性直接影响开发效率和系统可靠性。本文将深入探讨U-Boot环境变量的冗余备份机制,并详细介绍通过TFTP/NFS网络协议实现内核更...

关键字: Bootloader U-Boot

在嵌入式系统开发中,Bootloader是连接硬件与操作系统的桥梁,其安全性直接关系到整个系统的可信度。本文将结合RK3588、STM32等典型平台,解析Bootloader从硬件初始化到内核加载的全流程,并深入探讨安全...

关键字: Bootloader 上电启动

在工业物联网与智能设备领域,嵌入式系统的固件升级是保障功能迭代与安全修复的关键环节。传统单分区升级方案存在升级中断导致系统崩溃的风险,而双分区(Dual Bank)结合Bootloader架构通过“备份-切换”机制,可实...

关键字: Bootloader 嵌入式固件

在物联网设备、工业控制器等嵌入式系统中,固件升级是功能迭代与漏洞修复的关键环节。然而,升级过程中断电或固件损坏可能导致设备变砖(无法启动)。本文聚焦双分区固件升级架构与防砖保护机制,提供可落地的开发方案。

关键字: Bootloader 嵌入式开发
关闭