当前位置: 首页 > news >正文

Linux基础 -- SoC从uboot到linux kernel的全过程

总体流程概览(ARM 平台,Device Tree 支持)

[上电 / 复位]
     ↓
[Boot ROM (SoC 内部)]
     ↓
[1st Stage Bootloader (如 SPL)]
     ↓
[2nd Stage Bootloader: U-Boot]
     ↓
[Load Linux Kernel、DTB、Initramfs]
     ↓
[设置内核启动参数/设备树/内存布局]
     ↓
[跳转到内核入口 __start(),Kernel 开始执行]

一、上电后的 BootROM 阶段(由 SoC 厂商固化)

  • 通常由 ARM SoC 厂商提供,不可修改;
  • 功能:初始化 Boot 设备(SPI-NAND、eMMC、SD、USB等);
  • 加载 SPL(二级引导前的小型启动代码)到 SRAM,跳转执行。

二、SPL(Secondary Program Loader)阶段

功能:

  • 初始化 DRAM;
  • 加载完整的 U-Boot 镜像到内存;
  • 跳转到 U-Boot。

注意:若 SoC 有 SRAM 限制严重,必须使用 SPL 机制;否则直接进入 U-Boot。


三、U-Boot 主程序阶段(bootloader)

这是 加载并启动 Linux 的关键阶段


1. 加载内核镜像、设备树、initramfs(可选)

  • 一般从 eMMC/NAND/SD 卡/FAT/ext4 文件系统中读取:
ext4load mmc 0:1 0x80000 Image         # 加载内核
ext4load mmc 0:1 0x40000 dtb           # 加载设备树
ext4load mmc 0:1 0x2000000 initrd.img  # 可选加载 initramfs

U-Boot 通常使用如下内存地址布局(不同平台略有不同):

模块地址(示例)
kernel0x800000x80080000
dtb0x400000x83000000
initrd0x2000000

2. 设置 bootargs / ATAG / FDT 参数

  • 设置传给内核的启动参数(cmdline):
setenv bootargs "console=ttyAMA0 root=/dev/mmcblk0p2 rootwait"
  • ARMv7: 使用 ATAG 参数结构体(较老)
  • ARMv8: 使用设备树(FDT)

U-Boot 通过环境变量 bootargs 构造 cmdline


3. 调用 bootm / booti 命令启动内核

  • bootm:用于启动传统的 uImage(带 U-Boot header)
  • booti:用于启动裸内核 Image(AArch64)
  • bootz:启动 zImage(压缩内核)

示例命令:

booti 0x80000 - 0x40000
#         │     │     └── 设备树地址
#         │     └── initrd(若无填 -)
#         └── kernel image 加载地址

四、U-Boot 跳转到 Linux 内核入口

在调用 booti/bootm 时,U-Boot 做了以下事情:

设置 CPU 运行状态

  • ARMv7:设置为 SVC 模式(关闭中断);
  • ARMv8:设置 EL2 → EL1,以 EL1 执行内核;
  • 关闭 MMU、Cache,或根据配置保留 L2;

设置寄存器

  • ARMv7:

    • R0 = 0(机器 ID)
    • R1 = 机器 ID(老方式)
    • R2 = ATAG 地址或 DTB 地址
  • ARMv8:

    • x0 = FDT blob 地址(必须)
    • x1~x3 = 0

最后使用汇编跳转:

# ARMv7:
mov     r0, #0
ldr     r1, =machine_id
ldr     r2, =atags_addr  ; 或 dtb
mov     pc, r0           ; 跳转到内核入口

# ARMv8:
mov     x0, dtb_addr
br      x1               ; x1 指向 kernel __start

五、Linux 内核执行入口 (__start)

内核镜像的起始点通常是:

// ARMv8-A arch/arm64/kernel/head.S
ENTRY(__start)
    // 关闭 MMU/Cache(如果 U-Boot 没做)
    // 设置页表、栈、EL级别
    // 跳转到 start_kernel()

总结:U-Boot 启动 Linux 的关键点

阶段关键任务
SPL初始化 RAM,加载 U-Boot
U-Boot初始化设备、加载 kernel/dtb/initrd
设置参数设定 bootargs,填充 FDT
跳转设置寄存器、进入内核入口
内核启动进入 start_kernel(),开始内核世界

推荐配置文件(U-Boot)

在移植或开发过程中,关注:

  • include/configs/xxx.h:配置内存映射、启动参数;
  • board/xxx/xxx.c:板级初始化;
  • cmd/booti.c / cmd/bootm.c:启动命令实现;
  • arch/arm/lib/bootm.c:真正的跳转代码。

相关文章:

  • 从感知器准则到最小平方误差准则——与神经网络的发展类比
  • 使用Python可视化图结构:从GraphML文件生成节点关系图(lightrag 生成)
  • FPGA中串行执行方式之流水线(Pipeline)
  • 大数据学习(84)-Hive数仓
  • IIS漏洞攻略
  • C# 属性(Property)‌详解
  • 了解TikTok直播不推流的原因及流量异常的解决方案
  • 基于SpringBoot的电影售票系统
  • spring和maven
  • 内网渗透基础
  • 稳健投资新标杆,云济会布局国库券回购助推金融市场优化
  • 优化 Docker 镜像 技巧
  • 【PCIe 总线及设备入门学习专栏 5.3 -- PCIe 与 EP 中的 DMA协同工作介绍】
  • 【redis】哨兵:人工恢复主节点故障和哨兵自动恢复主节点故障
  • Flask的app.run()里发生了什么
  • 20250324-使用 `nltk` 的 `sent_tokenize`, `word_tokenize、WordNetLemmatizer` 方法时报错
  • 前端 Babel 入门简介
  • 系统思考与心智模式
  • 计算机网络--第四章 网络层(1)
  • 基于SpringBoot的“社区居民诊疗健康管理系统”的设计与实现(源码+数据库+文档+PPT)
  • 保险经纪公司元保在纳斯达克挂牌上市,去年净赚4.36亿元
  • 沈晓萍︱严金清:比斯坦因更早获得敦煌文物的无锡名士
  • 五一假期,这些短剧值得一刷
  • 马上评|扩大高速免费救援范围,打消出行后顾之忧
  • 南京106亿元成交19宗涉宅地块:建邺区地块楼面单价重回4.5万元
  • 迎接八方来客:全国多地“五一”假期党政机关大院停车场免费开放