arm+uboot+ubuntu系统的启动流程

1.概要

2.内容

以下是 ARM + U-Boot + Ubuntu 系统的完整启动流程,分阶段详细说明:


1. 硬件上电与复位

  • ARM处理器启动
    • ARM CPU上电后,从固定的复位地址(如 0x00000000)读取第一条指令。
    • 对于大多数SoC(如Allwinner、Rockchip、Qualcomm),复位向量通常被重映射到内部Boot ROM地址(如 0xFFFF0000)。
    • Boot ROM执行最小初始化(如关闭看门狗、配置时钟),然后跳转到固化在芯片中的 一级引导加载程序(BL1)
  • BL1(First-Stage Bootloader)
    • 通常由芯片厂商提供,负责初始化SRAM、加载二级引导程序(如U-Boot SPL)到内存。
    • 部分SoC(如Allwinner A64)的BL1可能直接从SPI Flash加载U-Boot SPL。

2. U-Boot启动阶段

2.1 SPL(Secondary Program Loader)
  • 作用:轻量级二级引导程序,用于初始化DRAM等关键硬件。
  • 流程
    1. 从存储介质(如SPI Flash、SD卡)加载 u-boot-spl.bin 到内存。
    2. 初始化DDR内存控制器,为后续代码运行准备内存空间。
    3. 跳转到U-Boot主程序(u-boot.img)。
2.2 U-Boot主程序
  • 硬件初始化
    • 初始化串口、GPIO、网络控制器、USB等外设。
    • 加载设备树(Device Tree Blob, dtb),描述硬件配置(如CPU、内存、外设)。
  • 环境变量加载
    • 从存储介质(如Flash分区)读取环境变量(如 bootcmdbootargs)。
    • 示例环境变量:

      bootcmd=run findfdt; ext4load mmc 0:1 ${kernel_addr_r} /boot/Image; ext4load mmc 0:1 ${fdt_addr_r} /boot/dtb; booti ${kernel_addr_r} - ${fdt_addr_r}
      bootargs=console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait rw
  • 内核加载
    • 根据 bootcmd 指令,从存储介质(如eMMC、SD卡)加载Linux内核镜像(如 Image 或 zImage)和设备树到内存。
    • 支持多种协议:TFTP(网络启动)、NFS(挂载根文件系统)、USB等。

3. Linux内核启动

3.1 内核解压与初始化
  • 启动参数传递
    • U-Boot通过寄存器(如 r0-r3)传递启动参数(如 bootargs 和设备树地址)。
  • 内核解压
    • 如果内核是压缩格式(如 zImage),U-Boot会先解压到内存。
  • 内核入口
    • 跳转到内核入口地址(如 0x80008000),开始执行 start_kernel() 函数。
3.2 内核初始化阶段
  • 硬件抽象层(HAL)初始化
    • 初始化CPU、中断控制器、定时器、内存管理单元(MMU)。
  • 设备驱动加载
    • 根据设备树(DTB)加载对应的外设驱动(如USB、网络、存储控制器)。
  • 根文件系统挂载
    • 解析 root= 参数(如 root=/dev/mmcblk0p2),挂载根文件系统(如ext4)。
    • 如果使用 initramfs,内核会先解压并挂载临时根文件系统,再切换到真实根文件系统。

4. 用户空间初始化

4.1 init进程启动
  • PID 1进程
    • 内核启动 init 进程(如 systemd 或 sysvinit),负责初始化用户空间服务。
  • 系统初始化
    • 挂载文件系统(如 /proc/sys/dev)。
    • 启动系统服务(如网络服务、日志服务、SSH)。
4.2 用户登录
  • 显示登录界面
    • 如果是图形界面(如Ubuntu Desktop),启动显示管理器(如GDM、LightDM)。
    • 如果是命令行界面(如Ubuntu Server),直接显示登录提示符。

5. 完整流程总结

硬件上电 → BL1初始化 → SPL加载U-Boot → U-Boot初始化硬件/加载内核 → 内核启动 → 挂载根文件系统 → 启动init进程 → 用户登录

关键概念补充

  • 设备树(Device Tree)
    描述硬件配置的二进制文件(.dtb),替代传统硬编码方式,提高代码复用性。
  • U-Boot环境变量
    存储启动参数(如内核路径、IP地址),支持持久化存储(如Flash分区)。
  • 安全启动(Secure Boot)
    可选流程,U-Boot验证内核和设备树的签名,防止恶意代码注入。

通过以上流程,ARM+U-Boot+Ubuntu系统实现了从硬件复位到用户登录的完整启动链。

3.关联链接

4.关联知识

1.启动设备,比如从u盘或者TF启动,这个选择的步骤在哪里

在 ARM + U-Boot + Ubuntu 的启动流程中,选择启动设备(如U盘、TF卡) 的步骤主要发生在 U-Boot阶段,具体通过以下两种方式实现:


1. 通过U-Boot环境变量预设启动设备

1.1 核心机制:bootcmd 环境变量
  • 作用bootcmd 是U-Boot自动执行的启动命令,默认从指定设备加载内核。
  • 修改方法
    • 在U-Boot命令行中输入 printenv bootcmd 查看当前配置。
    • 通过 setenv bootcmd <命令> 修改启动设备(如从TF卡启动):

      setenv bootcmd 'mmc dev 0; ext4load mmc 0:1 ${kernel_addr_r} /boot/Image; booti ${kernel_addr_r} - ${fdt_addr_r}'
      saveenv
    • 示例命令解析:
      • mmc dev 0:选择TF卡设备(0 对应设备编号)。
      • ext4load mmc 0:1 ...:从TF卡的第一个分区(0:1)加载内核。
      • booti:启动ARM64内核。
1.2 常见启动设备标识

设备类型U-Boot命令示例说明
TF卡mmc dev 0; ext4load mmc 0:1 ...0 为设备号,0:1 为分区
U盘usb start; ext4load usb 0:1 ...需先执行 usb start 初始化
eMMCmmc dev 1; ext4load mmc 1:2 ...设备号可能因硬件而异
网络tftpboot ${kernel_addr_r} Image通过TFTP从服务器加载内核

2. 手动选择启动设备(交互模式)

2.1 进入U-Boot命令行
  • 触发方式
    • 在U-Boot启动倒计时阶段(如 Hit any key to stop autoboot: 3)按 空格键 打断自动启动。
    • 直接进入U-Boot命令行界面。
2.2 手动指定启动设备
  • 示例流程(从U盘启动)
    1. 初始化USB控制器:
      usb start
    2. 列出USB设备:
      usb info
    3. 加载内核和设备树:

      ext4load usb 0:1 ${kernel_addr_r} /boot/Image
      ext4load usb 0:1 ${fdt_addr_r} /boot/dtb
    4. 启动内核:
      booti ${kernel_addr_r} - ${fdt_addr_r}

3. 启动设备选择的底层逻辑

3.1 设备枚举与驱动支持
  • U盘:需依赖U-Boot的 USB驱动(如 usb_storage.c)和文件系统驱动(如 ext4)。
  • TF卡:通过 MMC子系统 支持,需正确配置SD/MMC控制器驱动。
  • 网络:需启用 TFTP/NFS客户端 并配置IP地址(通过 bootargs 或 ipaddr 变量)。
3.2 启动优先级控制
  • 默认启动顺序:通过 CONFIG_BOOTCOMMAND 宏预设(位于U-Boot配置文件 include/configs/<board>.h)。
  • 回退机制:若默认设备启动失败,U-Boot可能自动尝试其他设备(需配置 bootdelay 和 bootcmd 逻辑)。

4. 完整流程图示

硬件上电 → BL1初始化 → SPL加载U-Boot → 
├─ 自动启动:执行预设的 bootcmd(从TF卡/U盘/网络加载内核)
└─ 手动干预:进入U-Boot命令行 → 输入命令选择设备 → 加载内核 → 启动系统
→ 内核启动 → 用户空间初始化

5. 常见问题排查

  • 设备未识别
    • 检查U-Boot是否编译了对应驱动(如 CONFIG_USB_STORAGECONFIG_MMC)。
    • 确认设备连接正常(如U盘需格式化为FAT/EXT4)。
  • 内核加载失败
    • 检查内核路径是否正确(如 /boot/Image 是否存在)。
    • 验证设备树(DTB)与硬件是否匹配。

通过灵活配置U-Boot的环境变量和命令行交互,可以实现从任意支持的设备启动系统。

2.在U-Boot启动倒计时阶段(如 Hit any key to stop autoboot: 3)按 空格键 打断自动启动,针对这一句,我上电后一直按空格,没有发挥作用,系统任然进入了ubuntu系统 

遇到U-Boot启动倒计时阶段按空格键无法打断自动启动的问题,可能由以下原因导致。以下是逐步排查和解决方案:


1. 检查U-Boot配置:bootdelay 是否生效

1.1 确认 bootdelay 环境变量
  • 作用bootdelay 控制U-Boot启动倒计时的等待时间(单位:秒)。
  • 查看当前值
    在U-Boot命令行输入:
    printenv bootdelay
    • 如果输出 bootdelay=0,表示U-Boot不会等待,直接启动。
    • 正常值应为 3(等待3秒)或其他正整数。
1.2 临时修改 bootdelay
  • 在U-Boot命令行输入:

    setenv bootdelay 3
    saveenv
    • 重启设备测试是否生效。
1.3 永久修改配置(需重新编译U-Boot)
  • 如果环境变量修改后仍不生效,可能是U-Boot编译时未启用 CONFIG_BOOTDELAY
  • 解决方案
    1. 修改开发板配置文件(如 include/configs/<board>.h):
      #define CONFIG_BOOTDELAY 3 // 确保此宏存在且值为正整数
    2. 重新编译并烧录U-Boot。

2. 检查串口控制台配置

2.1 确认串口输入已启用
  • U-Boot需启用串口输入支持(如 CONFIG_CONSOLE_MUX 或具体串口驱动)。
  • 检查配置
    在U-Boot源码中搜索 CONFIG_CONSOLE_MUX 或 CONFIG_SERIAL_MULTI,确保相关宏已定义。
2.2 测试串口输入
  • 在U-Boot命令行输入任意字符(如 help),观察是否有响应。
  • 如果无响应,可能是串口线路、波特率或驱动问题。

3. 按键时机与硬件问题

3.1 按键时机
  • 现象:U-Boot启动速度过快,倒计时提示一闪而过。
  • 解决方案
    • 增加 bootdelay 时间(如设为5秒)。
    • 使用逻辑分析仪或示波器观察串口输出,确认倒计时阶段是否实际存在。
3.2 硬件问题
  • 可能性
    • 串口转USB芯片(如CH340、FTDI)驱动问题。
    • 目标板串口引脚虚焊或短路。
  • 测试方法
    • 更换串口线或USB转接器。
    • 短接目标板的串口TX/RX引脚,观察是否回显输入字符。

4. 强制进入U-Boot命令行

4.1 通过环境变量禁用自动启动
  • 在U-Boot命令行输入:

    setenv bootcmd 'echo "Manual mode"; sleep 1000000'
    saveenv
    • 重启后,U-Boot会暂停1000000秒(约11.5天),等待手动输入命令。
4.2 通过硬件复位引脚触发
  • 部分开发板支持通过特定GPIO引脚(如 RESET 引脚)强制进入U-Boot。
  • 查阅硬件手册,确认是否存在此功能。

5. 完整排查流程

  1. 进入U-Boot命令行

    • 重启设备,在倒计时阶段疯狂按 空格键 或 回车键
    • 如果成功进入,立即检查 bootdelay 和 bootcmd
  2. 修改配置并测试

    setenv bootdelay 5
    saveenv
    reset
  3. 若仍失败

    • 检查串口连接和驱动。
    • 重新编译U-Boot,确保 CONFIG_BOOTDELAY 和串口输入支持已启用。

6. 替代方案:通过 bootcmd 预设启动设备

如果无法进入U-Boot命令行,可通过以下方式强制从指定设备启动:

  1. 烧录U-Boot时,在 bootcmd 中直接指定设备(如TF卡):
    
    

    setenv bootcmd 'mmc dev 0; ext4load mmc 0:1 ${kernel_addr_r} /boot/Image; booti ${kernel_addr_r} - ${fdt_addr_r}'
    saveenv

  2. 重启设备,观察是否从TF卡启动。

通过以上步骤,应能定位并解决无法打断U-Boot自动启动的问题。如果问题依旧,建议提供具体开发板型号和U-Boot版本,以便进一步分析。

1.如何进入uboot命令行

 

进入U-Boot命令行是调试和修改启动配置的关键步骤。以下是详细操作指南,结合常见问题解决方案:


方法一:通过倒计时打断自动启动(推荐)

1. 确认U-Boot配置
  • 关键变量bootdelay
    • 在U-Boot命令行输入 printenv bootdelay,确认输出为正整数(如 3)。
    • 若为 0,需修改:

      setenv bootdelay 3
      saveenv
2. 操作步骤
  1. 重启设备,观察启动日志。
  2. 在倒计时阶段(如 Hit any key to stop autoboot: 3)快速按 空格键回车键 或 任意键
    • ⚠️ 注意:部分开发板可能对按键敏感度不同,需在提示出现后立即连续按键。
3. 失败排查
  • 现象:按键无反应,直接进入系统。
  • 可能原因
    • 串口配置错误:波特率不匹配(常见为 115200)、数据位/停止位错误。
    • U-Boot编译未启用交互支持:需检查 CONFIG_BOOTDELAY 和 CONFIG_CONSOLE_MUX
    • 硬件问题:串口线松动、USB转接器驱动异常。

方法二:强制进入U-Boot命令行(无需按键)

1. 修改 bootcmd 环境变量
  • 目的:让U-Boot启动后直接进入命令行,而非加载内核。
  • 操作

    setenv bootcmd 'echo "Entering U-Boot CLI"; sleep 1000000'
    saveenv
    reset
    • 解释:sleep 1000000 会让U-Boot暂停约11.5天,等待手动输入命令。
2. 恢复自动启动
  • 测试完成后,恢复原 bootcmd

    setenv bootcmd 'run original_bootcmd' # 假设原命令保存在 `original_bootcmd`
    saveenv

方法三:通过硬件复位引脚触发

  • 适用场景:开发板支持通过特定GPIO引脚强制进入U-Boot。
  • 操作
    1. 查阅硬件手册,找到复位引脚(如 RESET)。
    2. 上电时短接该引脚到地(GND),触发U-Boot进入命令行。

方法四:重新编译U-Boot(终极方案)

1. 启用交互式启动支持
  • 修改配置文件(如 include/configs/<board>.h):

    #define CONFIG_BOOTDELAY 3 // 确保倒计时生效
    #define CONFIG_ZERO_BOOTDELAY_CHECK // 允许 bootdelay=0 时通过按键打断
    #define CONFIG_CONSOLE_MUX // 启用串口输入
2. 重新编译并烧录
  • 执行 make clean 后重新编译U-Boot,烧录到开发板。

验证是否成功

  • 成功标志:进入U-Boot命令行后,应看到 => 提示符。
  • 常用命令测试

    printenv # 查看环境变量
    version # 显示U-Boot版本
    help # 列出所有命令

常见问题解决

问题解决方案
按键无反应检查串口配置(波特率、数据位)、更换串口线或USB转接器。
倒计时未出现确认 bootdelay 非零,重新编译U-Boot启用 CONFIG_BOOTDELAY
进入命令行后无响应检查U-Boot是否卡死,尝试 reset 重启或硬件复位。

通过以上方法,您应能成功进入U-Boot命令行进行调试。如果问题依旧,请提供具体开发板型号和U-Boot版本以进一步分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值