手撕ARM64启动栈(三):QEMU + TF-A(ATF) BL1 核心职责——`bl1_main()` 逐函数拆解与 BL2 加载
系列文章目录手撕ARM64启动栈一QEMU TF-A → OP-TEE → U-Boot → Linux 全链路总览手撕ARM64启动栈二QEMU TF-A(ATF) BL1 执行上下文——GDB 实测复位到 BL2手撕ARM64启动栈三QEMU TF-A(ATF) BL1 核心职责——bl1_main()逐函数拆解与 BL2 加载手撕ARM64启动栈四QEMU TF-A(ATF) BL2 详解文章目录系列文章目录[手撕ARM64启动栈一QEMU TF-A → OP-TEE → U-Boot → Linux 全链路总览](https://blog.csdn.net/zheng_wuling/article/details/162657151?spm1011.2124.3001.6209) [手撕ARM64启动栈二QEMU TF-A(ATF) BL1 执行上下文——GDB 实测复位到 BL2](https://blog.csdn.net/zheng_wuling/article/details/162769218?spm1011.2124.3001.6209) [手撕ARM64启动栈三QEMU TF-A(ATF) BL1 核心职责——bl1_main() 逐函数拆解与 BL2 加载](https://blog.csdn.net/zheng_wuling/article/details/162847153?spm1011.2124.3001.6209) [手撕ARM64启动栈四QEMU TF-A(ATF) BL2 详解](https://blog.csdn.net/zheng_wuling/article/details/162975843?spm1011.2124.3001.6209)1. 引言2. bl1_main() 调用序列总览3. 逐函数拆解每个函数的职责3.1 plat_setup_early_console() / bl1_early_platform_setup()初始化控制台GDB 实测UARTCR.UARTEN 从 0 变 13.2 bl1_plat_arch_setup() / bl1_arch_setup()建立地址转换并设定下一级架构状态GDB 实测SCTLR_EL3.M 从 0 变 13.3 crypto_mod_init() / auth_mod_init()初始化校验框架3.4 bl1_platform_setup()注册镜像加载的 IO 后端4. 加载 BL2GDB 实测desc-image_info 从取到描述符到镜像已搬运5. 本篇小结日志与代码的对应关系1. 引言上一篇讲了 BL1 启动瞬间的执行上下文复位向量、el3_entrypoint_common、异常向量表以及 BL1 退出前交给 BL2 的最后状态。本篇回到bl1_main()bl1/bl1_main.c:50内部逐个拆解从打印欢迎信息到加载 BL2 之间调用的每一个平台初始化函数的功能。本篇结论基于TF_A_TRUSTED_BOARD_BOOTn见第一篇配置矩阵。涉及关键词ATF / TF-A / ARM Trusted Firmware、QEMU virt aarch64、BL1、bl1_main、OPTEE、OP-TEE。2.bl1_main()调用序列总览关键调用序列对照bl1/bl1_main.c的bl1_main()voidbl1_main(void){plat_setup_early_console();bl1_early_platform_setup();// 初始化串口之后才能打印bl1_plat_arch_setup();// 建页表、开 MMUNOTICE(FIRMWARE_WELCOME_STR);// Booting Trusted FirmwareNOTICE(BL1: %s\n,build_version_string);// BL1: v2.14.0(debug):v2.14.0NOTICE(BL1: %s\n,build_message);// BL1: Built : ...INFO(BL1: RAM %p - %p\n,...);// 打印 BL1 可见的 Trusted RAM 范围bl1_arch_setup();// 设 SCR_EL3.RW1下一级 EL 用 AArch64crypto_mod_init();// 初始化 crypto 框架auth_mod_init();// 初始化认证框架bl1_plat_mboot_init();// 度量启动初始化bl1_platform_setup();// 调 plat_qemu_io_setup()注册 FIP/semihosting IO 后端image_idbl1_plat_get_next_image_id();// QEMU virt 恒返回 BL2_IMAGE_IDif(image_idBL2_IMAGE_ID)bl1_load_bl2();// 正常启动加载 BL2elseNOTICE(BL1-FWU: *******FWU Process Started*******\n);// 固件升级分支...bl1_prepare_next_image(image_id);// 构造 BL2 的 entry_point_info上一篇已展开}bl1_plat_get_next_image_id()在QEMU 平台使用的是plat/common/plat_bl1_common.c里的弱符号默认实现恒定返回BL2_IMAGE_ID——所以永远走if加载 BL2。真实平台可以重写该函数如检测按键/GPIO/寄存器等返回非BL2_IMAGE_ID值以进入else的 FWU固件升级/恢复流程。bl1_main()调用序列流程图如下3. 逐函数拆解每个函数的职责bl1_main()里这串调用绝大多数是 TF-A 定义的平台移植钩子platform hook——框架规定了调用时机和函数签名具体实现交给各平台。其中bl1_early_platform_setup/bl1_plat_arch_setup/bl1_platform_setup是移植时必须实现的强制钩子官方《Porting Guide》trusted-firmware-a/docs/porting-guide.rst逐个给了职责定义。下面逐个说明每个钩子设计上负责什么。3.1plat_setup_early_console()/bl1_early_platform_setup()初始化控制台bl1_early_platform_setup()是 BL1 的早期平台初始化钩子。官方 porting guideporting-guide.rst:1653-1673原文Function : bl1_early_platform_setup() [mandatory]Argument : void Return : voidThis function executes with the MMU and data caches disabled. It is only calledby the primary CPU.On Arm standard platforms, this function:Enables a secure instance of SP805 to act as the Trusted Watchdog.Initializes a UART (PL011 console), which enables access to theprintffamily of functions in BL1.Enables issuing of snoop and DVM (Distributed Virtual Memory) requests tothe CCI slave interface corresponding to the cluster that includes theprimary CPU.——trusted-firmware-a/docs/porting-guide.rst:1653-1673即在 MMU 和数据 cache 关闭的状态下执行只由主 CPU 调用在 Arm 标准平台上负责使能 Trusted Watchdog、初始化一个 UARTPL011 控制台从而让 BL1 能用printf、以及使能 CCI 的 snoop/DVM 请求。也就是说它的核心职责是在 BL1 打印第一条日志之前把串口控制台拉起来。plat_setup_early_console()bl1_main.c:55则是它之前一个可选的最早期控制台钩子由EARLY_CONSOLE编译开关控制。QEMU 平台的bl1_early_platform_setup()plat/qemu/common/qemu_bl1_setup.c:52-60做两件事调qemu_console_init()初始化控制台并记录 BL1 可见的 Trusted RAM 范围voidbl1_early_platform_setup(void){/* Initialize the console to provide early debug support */qemu_console_init();/* Allow BL1 to see the whole Trusted RAM */bl1_tzram_layout.total_baseBL_RAM_BASE;bl1_tzram_layout.total_sizeBL_RAM_SIZE;}qemu_console_init()plat/qemu/common/qemu_console.c:14-22调用console_pl011_register()注册一个 PL011 UART 作启动运行时控制台。至此串口初始化完成BL1 从这里开始就能通过串口输出 log 了。GDB 实测UARTCR.UARTEN从 0 变 1执行前0x300—— PL011 复位默认值TXEbit8/RXEbit9默认打开但UARTENbit0默认关闭此时串口硬件还不能收发。Step Over 执行完这一行后0x301——UARTEN位被置 1串口正式使能。执行完bl1_early_platform_setup()UARTCR0x301表明已经把 UART 拉起其中$SCTLR_EL30x30c5183aM位/bit0 为0表明MMU还没enable。3.2bl1_plat_arch_setup()/bl1_arch_setup()建立地址转换并设定下一级架构状态bl1_plat_arch_setup()是平台相关的架构初始化钩子。官方 porting guideporting-guide.rst:1675-1689原文Function : bl1_plat_arch_setup() [mandatory]Argument : void Return : voidThis function performs any platform-specific and architectural setup that theplatform requires. Platform-specific setup might include configuration ofmemory controllers and the interconnect.In Arm standard platforms, this function enables the MMU.This function helps fulfill requirement 2 above.——trusted-firmware-a/docs/porting-guide.rst:1675-1689即执行平台特定和架构相关的设置平台特定部分可能包括内存控制器和互连interconnect的配置。QEMU 平台的实现plat/qemu/common/qemu_bl1_setup.c:73-90为建页表 开 MMUvoidbl1_plat_arch_setup(void){constmmap_region_tbl_regions[]{MAP_BL1_TOTAL,MAP_BL1_RO,{0}};setup_page_tables(bl_regions,plat_qemu_get_mmap());enable_mmu_el3(0);}GDB 实测SCTLR_EL3.M从 0 变 1执行前上一节截图同一时刻0x30c5183aM位bit0为0——MMU 尚未开启此时的取指/取数都是物理地址直通。Step Over 执行完这一行后0x30cd183fM位变为1——页表已建好MMU 正式生效。bl1_arch_setup()bl1/aarch64/bl1_arch_setup.c:15-19是平台无关的通用代码负责架构相关的 EL3 初始化当前实现是把下一级异常级别设为 AArch64voidbl1_arch_setup(void){/* Set the next EL to be AArch64 */write_scr_el3(read_scr_el3()|SCR_RW_BIT);}即置SCR_EL3.RW1告诉硬件下一级 ELBL2 所在的 S-EL1用 AArch64 指令集。3.3crypto_mod_init()/auth_mod_init()初始化校验框架这两个函数是 TF-A **可信启动Trusted Board Boot**认证框架的入口本质是初始化 crypto / 认证框架为后面加载镜像时的验签做准备。本文配置下 secure boot 关闭TF_A_TRUSTED_BOARD_BOOTnsecure boot 打开后它们才会真正初始化校验框架这里暂不关注留到后续 secure boot 相关文档详细介绍。3.4bl1_platform_setup()注册镜像加载的 IO 后端bl1_platform_setup()是完整平台初始化钩子。官方 porting guideporting-guide.rst:1691-1706原文Function : bl1_platform_setup() [mandatory]Argument : void Return : voidThis function executes with the MMU and data caches enabled. It is responsiblefor performing any remaining platform-specific setup that can occur after theMMU and data cache have been enabled.In Arm standard platforms, this function initializes the storage abstractionlayer used to load the next bootloader image.This function helps fulfill requirement 4 above.——trusted-firmware-a/docs/porting-guide.rst:1691-1706即在 MMU 和数据 cache 使能之后执行负责在 MMU/dcache 打开后才能进行的剩余平台特定设置在 Arm 标准平台上这个函数初始化用于加载下一个 bootloader 镜像的存储抽象层。QEMU 平台的实现plat/qemu/common/qemu_bl1_setup.cvoidbl1_platform_setup(void){plat_qemu_io_setup();}plat_qemu_io_setup()plat/qemu/common/qemu_io_storage.c注册 FIP 和 semihosting 两套 IO 后端的 policy 表规定每个镜像先从哪里读、失败后退到哪里: BL1 加载 BL2 时先尝试 FIP失败后回退到 semihosting。4. 加载 BL2bl1_main()调用序列里最后、也是最关键的一步是加载 BL2staticvoidbl1_load_bl2(void){descbl1_plat_get_image_desc(BL2_IMAGE_ID);INFO(BL1: Loading BL2\n);errload_auth_image(BL2_IMAGE_ID,info);NOTICE(BL1: Booting BL2\n);}对应日志INFO: BL1: Loading BL2 NOTICE: BL1: Booting BL2load_auth_image()common/bl_common.c:198-208内部按编译期开关分两条路径auth_mod_verify_img()做签名验证的那条路径由TRUSTED_BOARD_BOOT开关控制本篇配置下是n走的是纯搬运路径load_image()staticintload_auth_image_internal(unsignedintimage_id,image_info_t*image_data){#ifTRUSTED_BOARD_BOOTif(dyn_is_auth_disabled()0){returnload_auth_image_recursive(image_id,image_data);}#endifreturnload_image(image_id,image_data);// ← 本例实际执行这一行}签名验证相关的load_auth_image_recursive()/auth_mod_verify_img()留到后续 secure boot 专题文档展开本篇只关注load_image()这条路径。从bl1_load_bl2()起先经load_auth_image()→load_auth_image_internal()转发到load_image()TBBn 时无任何校验分支再进入load_image()common/bl_common.c:73-153内部找到镜像源 → 打开 → 读大小 → 检查大小 → 搬运数据到内存GDB 实测desc-image_info从取到描述符到镜像已搬运断点打在bl1_main.c:176info desc-image_info;bl1_load_bl2()内部desc bl1_plat_get_image_desc(BL2_IMAGE_ID);刚执行完的下一行WATCH 里把局部变量desc整个展开字段值说明desc0xe0ee080 bl2_img_desc静态描述符表里 BL2 那一项的地址非堆/栈临时对象desc-image_id0x1即BL2_IMAGE_IDdesc-state0x0IMAGE_STATE_RESET尚未开始加载desc-image_info.image_base0xe05b000BL2 将被搬运到的目标物理地址desc-image_info.image_max_size0x35000分配给 BL2 的最大空间对应BL2_BASE BL31_BASE - 0x35000platform_def.hdesc-image_info.image_size0x0此刻还没有加载大小未知desc-ep_info.pc0xe05b000与image_base相同——BL2 的入口地址就是它被搬运到的起始地址image_base 0xe05b000正是上一篇《执行上下文》断点 4/5 里next_bl_ep-pc/ELR_EL3最终被写入的那个值——两篇的实测数据在这里完全对得上本篇看到的是BL2 要被搬到哪上一篇看到的是BL1 ERET 跳到哪同一个地址。5. 本篇小结日志与代码的对应关系日志行 / 关键事实代码位置在 QEMU virt 上是否真实动作NOTICE: Booting Trusted Firmwarebl1_main.c:78—NOTICE: BL1: v2.14.0(debug):v2.14.0bl1_main.c:79—串口可以打印字符bl1_early_platform_setup()→qemu_console_init()qemu_console.c:14-22PL011 0x09000000plat_setup_early_console()本身因EARLY_CONSOLE0是空函数✅ 真实寄存器配置BL1 页表建立、MMU 开启bl1_plat_arch_setup()qemu_bl1_setup.c:73-90✅ 真实软件页表非内存控制器SCR_EL3.RW1bl1_arch_setup()bl1_arch_setup.c:15-19✅ 真实单条寄存器写load_auth_image()实际行为common/bl_common.cload_auth_image_internal()❌ TBBn 时等价于load_image()无校验NOTICE: BL1: Booting BL2bl1_load_bl2()末尾数据搬运完成至此BL1 阶段全部分析完成上一篇讲执行上下文复位向量、异常向量表、退出前状态本篇讲核心职责–逐函数拆解——串口初始化mmu页表建立与使能BL2镜像加载等。综合两篇,BL1 的主要职责已经清晰:上电复位后完成必要的底层初始化(硬件寄存器、EL3 异常向量表),建立 C 运行时环境与调用栈;随后进入 bl1_main() 执行平台相关初始化(串口、MMU 等;crypto/认证框架在本配置 TBBn 下为空);最后加载并跳转到 BL2,完成使命。下一篇开始进入BL2阶段分析BL2的详细流程其实到这里我们就可以知道ARM TF-A已将BL1流程(复位入口、C 运行时、bl1_main() 主序列)框架写好,芯片相关部分抽象成 bl1_early_platform_setup、bl1_plat_arch_setup、bl1_platform_setup 等平台钩子。如果需要移植到自己真实芯片,只要实现对应的钩子(串口、MMU、加载 BL2 的 IO 后端),BL1 就能跑起来并加载 BL2。

相关新闻

一键解锁HS2-HF_Patch:Honey Select 2游戏体验的终极增强方案

一键解锁HS2-HF_Patch:Honey Select 2游戏体验的终极增强方案

一键解锁HS2-HF_Patch:Honey Select 2游戏体验的终极增强方案 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 在Honey Select 2的游戏世界中&#x…

2026/7/26 8:57:22 阅读更多 →
Music Tag Web 怎么用 Docker Compose 部署:从目录挂载到首次登录

Music Tag Web 怎么用 Docker Compose 部署:从目录挂载到首次登录

Music Tag Web 怎么用 Docker Compose 部署:从目录挂载到首次登录 如果你的音乐库放在 NAS 或 Linux 主机里,Music Tag Web 这类带 Web UI 的工具,会比本地桌面标签工具更适合长期维护。官方文档已经给了 Docker Compose 的最小示例&#xff…

2026/7/26 8:57:22 阅读更多 →
RT V-Bench:动态场景下MLLM三维能力评估新标准

RT V-Bench:动态场景下MLLM三维能力评估新标准

1. 项目背景与核心价值在2025年NIPS会议上亮相的RT V-Bench,标志着多模态大语言模型(MLLM)评估体系的重要突破。这个基准测试框架的独特之处在于,它首次系统性地解决了动态连续场景下模型的三维能力评估难题——实时感知&#xff…

2026/7/26 8:57:22 阅读更多 →

最新新闻

GitHub界面汉化插件:3分钟告别英文困扰,让编程更丝滑

GitHub界面汉化插件:3分钟告别英文困扰,让编程更丝滑

GitHub界面汉化插件:3分钟告别英文困扰,让编程更丝滑 【免费下载链接】github-chinese GitHub 汉化插件,GitHub 中文化界面。 (GitHub Translation To Chinese) 项目地址: https://gitcode.com/gh_mirrors/gi/github-chinese 还在为Gi…

2026/7/26 9:16:31 阅读更多 →
视觉语言模型在实体导航中的应用与优化

视觉语言模型在实体导航中的应用与优化

1. 项目概述:当视觉语言模型遇上实体导航 VLingNav这个项目名称拆解开来,实际上揭示了三个关键技术要素:"V"代表视觉(Visual),"Ling"代表语言(Linguistic)&…

2026/7/26 9:16:31 阅读更多 →
神经网络与模型预测控制在无人机控制中的应用

神经网络与模型预测控制在无人机控制中的应用

1. 项目背景与核心价值去年在实验室调试四旋翼无人机时,我们遇到了一个经典难题:传统PID控制在复杂气流扰动下表现不稳定,而基于模型的控制方法又难以应对系统非线性特性。当时尝试将神经网络与模型预测控制结合,实测效果提升了约…

2026/7/26 9:16:31 阅读更多 →
企业级Docker镜像构建与内网分发实践指南

企业级Docker镜像构建与内网分发实践指南

1. 项目背景与核心价值最近在帮企业做内部系统升级时遇到一个典型需求:开发团队需要统一测试环境的基础镜像,但不同项目对JDK版本要求各异(从JDK 8到JDK 17都有)。更麻烦的是,外网下载速度慢且存在安全审计要求&#x…

2026/7/26 9:16:31 阅读更多 →
英雄联盟智能助手Seraphine:3步开启数据驱动的游戏决策新时代

英雄联盟智能助手Seraphine:3步开启数据驱动的游戏决策新时代

英雄联盟智能助手Seraphine:3步开启数据驱动的游戏决策新时代 【免费下载链接】Seraphine 英雄联盟战绩查询工具 项目地址: https://gitcode.com/gh_mirrors/se/Seraphine 在英雄联盟的对局中,你是否曾因为缺乏队友信息而错失BP优势?是…

2026/7/26 9:16:31 阅读更多 →
TI WiLink8模块适配板硬件解析与实战调试指南

TI WiLink8模块适配板硬件解析与实战调试指南

1. 项目概述与核心价值如果你正在评估或集成德州仪器(TI)的WiLink™ 8系列无线连接模块(比如WL1837MOD),并且被那一堆密密麻麻的100引脚COM模块接口搞得头疼,那么WL18xxCOM82SDMMC这块适配板绝对是你的“救…

2026/7/26 9:15:31 阅读更多 →

日新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

月新闻