Linux/LoongArch 启动指南:BootLoader 传参协议与 EFI 内核镜像头结构解析

发布时间:2026/11/11 12:44:22

Linux/LoongArch 启动指南:BootLoader 传参协议与 EFI 内核镜像头结构解析 Linux/LoongArch 启动指南BootLoader 传参协议与 EFI 内核镜像头结构解析【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux本文基于 Linux 内核源码树中的 Documentation/arch/loongarch/booting.rst 官方文档系统讲解 LoongArch 架构下 BootLoader 与内核之间的启动握手协议从kernel_entry传入的 3 个寄存器参数到 Linux/LoongArch 内核镜像作为 EFI/PE 文件所携带的 64 字节镜像头布局并逐一映射到 arch/loongarch 下的真实源码实现。读完本文你将掌握 LoongArch 平台启动链路的完整图景能够理解boot.cfg、UEFI/PMON 等引导环境如何与内核约定内存布局与入口也能在阅读 head.S、efi-header.S 等汇编时做到心中有数。BootLoader 传递给内核的信息LoongArch 架构同时支持 ACPI 与 FDT扁平设备树两种固件表描述方式。无论走哪条路径BootLoader 需要传递给内核的信息都包括内存布局memmap、initrd、内核命令行command line以及可选的 ACPI/FDT 表。这些信息不是通过某个结构体一次性打包而是通过kernel_entry入口处的 3 个通用寄存器约定传递寄存器名称含义a0efi_boot标志位表示当前引导环境是否完全符合 UEFI 规范a1cmdline指向内核命令行字符串的指针a2systemtable指向 EFI System Table 的指针文档特别强调此阶段涉及的所有指针均为物理地址All pointers involved at this stage are in physical addresses此时内核尚未开启 MMU 页表映射BootLoader 必须保证传入的是可直接访问的物理地址。源码中的参数落盘fw_arg0 / fw_arg1 / fw_arg2内核在入口汇编 arch/loongarch/kernel/head.S 中第一时间将这 3 个寄存器保存到三个全局变量中la.pcrel t0, fw_arg0 PTR_S a0, t0, 0 # firmware arguments la.pcrel t0, fw_arg1 PTR_S a1, t0, 0 la.pcrel t0, fw_arg2 PTR_S a2, t0, 0三个变量在 arch/loongarch/kernel/setup.c 中定义并在 include/asm/bootinfo.h 中导出unsigned long fw_arg0, fw_arg1, fw_arg2;后续 C 代码对它们的消费集中在 arch/loongarch/kernel/env.c 的init_environ()void __init init_environ(void) { int efi_boot fw_arg0; char *cmdline early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE); if (efi_boot) set_bit(EFI_BOOT, efi.flags); else clear_bit(EFI_BOOT, efi.flags); strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE); strscpy(init_command_line, cmdline, COMMAND_LINE_SIZE); early_memunmap(cmdline, COMMAND_LINE_SIZE); efi_system_table fw_arg2; }可以看到三个参数的消费路径与文档描述完全一致fw_arg0efi_boot非零时置位EFI_BOOT标志否则清除。该标志决定后续内核是否按完整 UEFI 环境处理例如是否使用 EFI 运行时服务、efifb 等。fw_arg1cmdline通过early_memremap_ro做早期只读临时映射这正是此时还是物理地址的体现拷贝进boot_command_line/init_command_line后立即early_memunmap释放。而在支持可重定位CONFIG_RELOCATABLE的启动路径中relocate.c 同样用early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE)读取命令行用于 KASLR 决策。fw_arg2systemtable保存到全局efi_system_table类型为u64env.c作为后续 EFI 驱动与运行时服务访问的根。此外kexec 路径也复用了这套约定machine_kexec.c 将fw_arg0/fw_arg2保存进kimage-arch保证二次启动内核时能继承 UEFI 环境信息。Linux/LoongArch 内核镜像的头部Linux/LoongArch 内核镜像本身是EFI 镜像。作为 PE 文件它在文件开头携带一个64 字节的定制头其布局如下来自原文档字段注释已保留u32 MZ_MAGIC /* MZ, MS-DOS header */ u32 res0 0 /* Reserved */ u64 kernel_entry /* Kernel entry point */ u64 _end - _text /* Kernel image effective size */ u64 load_offset /* Kernel image load offset from start of RAM */ u64 res1 0 /* Reserved */ u64 res2 0 /* Reserved */ u64 res3 0 /* Reserved */ u32 LINUX_PE_MAGIC /* Magic number */ u32 pe_header - _head /* Offset to the PE header */逐字段说明MZ_MAGICMZ两字节 DOS 头魔数是 PE 文件的基本签名。内核通过它识别一个合法的 LoongArch 镜像。kernel_entry内核入口点的物理地址BootLoader 最终跳转的目标。_end - _text内核镜像的有效大小effective size即从_text到_end的字节数。load_offset内核镜像相对内存起始处的加载偏移load offset from start of RAMBootLoader 据此决定把镜像放到内存的哪个位置。LINUX_PE_MAGICLinux PE 魔数用于在MZ之外进一步确认这是 Linux 格式的 PE 镜像。pe_header - _head从镜像头起点到完整 PE 头COFF/可选头的偏移量指向紧随其后的标准 PE 头部结构。镜像头在汇编中的真实定义这一 64 字节头在 arch/loongarch/kernel/head.SCONFIG_EFI_STUB使能时中逐字节落地_head: .word IMAGE_DOS_SIGNATURE /* MZ, MS-DOS header */ .org 0x8 .dword _kernel_entry /* Kernel entry point (physical address) */ .dword _kernel_asize /* Kernel image effective size */ .quad PHYS_LINK_KADDR /* Kernel image load offset from start of RAM */ .org 0x38 /* 0x20 ~ 0x37 reserved */ .long LINUX_PE_MAGIC .long pe_header - _head /* Offset to the PE header */ pe_header: __EFI_PE_HEADER与文档字段一一对应_kernel_entry、_kernel_asize、PHYS_LINK_KADDR、LINUX_PE_MAGIC、pe_header - _head中间0x20 ~ 0x37共 24 字节为保留区对应三个u64 res。头部符号在链接脚本中的定义这些头字段引用的符号在 arch/loongarch/kernel/vmlinux.lds.S 中定义_kernel_entry ABSOLUTE(kernel_entry PHYSADDR_MASK); _kernel_asize ABSOLUTE(_end - _text); _kernel_fsize ABSOLUTE(_edata - _text); _kernel_vsize ABSOLUTE(_end - __initdata_begin); _kernel_rsize ABSOLUTE(_edata - __initdata_begin);_kernel_entry将汇编入口kernel_entry用PHYSADDR_MASK掩码为物理地址印证了文档入口点是物理地址的说法_kernel_asize _end - _text与文档公式完全一致同组还导出了_kernel_fsize文件大小、_kernel_vsize虚拟大小、_kernel_rsize供后续 EFI stub 与 PE 头使用。C 侧的对等结构体定义在 arch/loongarch/include/asm/image.hstruct loongarch_image_header { uint8_t dos_sig[2]; uint16_t padding_1[3]; uint64_t kernel_entry; uint64_t kernel_asize; uint64_t text_offset; uint32_t padding_2[7]; uint32_t pe_header; };并配套提供loongarch_header_check_dos_sig()辅助函数用于校验M Z签名image.h。该结构体被 kexec 的 EFI 加载路径直接复用kexec_efi.c 中读取kernel_asize作为内存段大小、text_offset作为buf_min并以kernel_segment-mem h-kernel_entry - text_offset计算二次内核的入口最后设置image-startkexec_efi.c保证跳转目标与头部声明的入口一致。load_offset 与内存加载地址load_offset在汇编中取值为PHYS_LINK_KADDR其定义为PHYSADDR(VMLINUX_LOAD_ADDRESS)include/asm/addrspace.h。而VMLINUX_LOAD_ADDRESS由 arch/loongarch/Makefile 按位宽决定ifdef CONFIG_32BIT load-y 0xa0200000 else load-y 0x9000000000200000 endif即32 位内核默认加载地址为0xa020000064 位内核为0x90000000002000000x9000_0000_0000_0000之上的地址属于 LoongArch 的窗口映射段。这一地址同时通过KBUILD_CPPFLAGS以-DVMLINUX_LOAD_ADDRESS...注入编译Makefile。可重定位内核CONFIG_RELOCATABLE在此基础上叠加 KASLR 随机偏移最终运行时地址可通过kaslr_offset()include/asm/setup.h换算。紧随其后的完整 PE/COFF 头64 字节定制头只是前菜其后pe_header处才是标准 PE/COFF 头由宏__EFI_PE_HEADER在 arch/loongarch/kernel/efi-header.S 中生成要点如下COFF 文件头IMAGE_NT_SIGNATURE后Machine字段在CONFIG_32BIT下为IMAGE_FILE_MACHINE_LOONGARCH32否则为IMAGE_FILE_MACHINE_LOONGARCH64efi-header.SCharacteristics标记为可执行镜像、去调试信息。可选头PE32使用IMAGE_NT_OPTIONAL_HDR64_MAGIC即 64 位 PE32 格式AddressOfEntryPoint指向__efistub_efi_pe_entry - _headefi-header.S即真正的 EFI stub 入口ImageBase为 0、Subsystem为IMAGE_SUBSYSTEM_EFI_APPLICATIONEFI 应用。节表定义了.text代码、可读可执行与.data已初始化数据、可读可写两个节efi-header.S对齐常量取PECOFF_SEGMENT_ALIGN0x10000。因此一个完整的 Linux/LoongArch 内核镜像在磁盘上的结构是64 字节定制头含 MZ 签名→ 标准 PE 头 → .text/.data 节。UEFI 固件可将其作为标准 EFI 应用直接加载执行进入__efistub_efi_pe_entry而传统 BootLoader如 PMON则读取定制头字段自行搬运镜像并跳转到kernel_entry。内核入口 kernel_entry 的启动汇编流程无论从哪条路径进入最终都会汇聚到kernel_entryhead.S。其启动顺序可归纳为基础环境设置SETUP_TWINS/SETUP_MODES/JUMP_VIRT_ADDR/SETUP_DMWINS完成窗口映射DMW与虚拟地址切换。清零 .bss从__bss_start循环清到__bss_stophead.S。保存固件参数将a0/a1/a2写入fw_arg0/fw_arg1/fw_arg2即上文所述协议落盘。初始化 percpu 与栈将CSR_IMPCTL1中 percpu 相关位清零、KSave3/u0置 0并设置init_task、init_stack与sphead.S。可重定位与 KASLRCONFIG_RELOCATABLE时调用relocate_kernel若再开启CONFIG_RANDOMIZE_BASE则按随机偏移跳入新内核new_pc current_pc random_offsethead.S。KASAN 早期初始化CONFIG_KASAN时调用kasan_early_init。进入 C 世界bl start_kernel其后是永不返回的ASM_BUG()兜底。此外SMP 从核slave CPU不经过 BootLoader 传参协议而是由主核通过cpuboot_data传递任务、栈和偏移后进入smpboot_entryhead.S。小结围绕官方文档 booting.rst本文串起了 LoongArch 启动链路的完整闭环协议层a0 efi_boot、a1 cmdline、a2 systemtable三个物理地址参数经 head.S 落盘为fw_arg0/1/2再被 env.c 的init_environ()消费驱动 EFI 标志、命令行与系统表初始化镜像层内核镜像是带 64 字节定制头的 EFI/PE 文件字段由 head.S 生成、由 vmlinux.lds.S 定义符号、由 image.h 描述 C 结构并被 kexec 的 kexec_efi.c 作为加载依据入口层kernel_entry完成建栈、清 BSS、保存固件参数、可重定位与跳转start_kernel的全过程。对 BootLoader、固件开发者或内核移植工程师而言理解这套寄存器传参 头部自描述的约定是在 LoongArch 平台上正确引导 Linux 的关键第一步。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/10 1:09:14

货物贸易进出口:条码如何打通跨境链路

货物贸易进出口,到底在统计什么 实物商品的进口与出口活动,构成了国际贸易中最基础的一环。货物进出口总额,指的是在一定时期内,一国或地区全部实际进出口商品的总金额,它直接反映出一国对外贸易的规模与发展水平。 中…

2026/11/10 0:48:13

嵌入式入门避坑指南:从裸机点亮到ARM Linux真实开发路径

1. 这不是退学,是及时止损:一个嵌入式初学者的真实踩坑时间线“花两个月学了嵌入式,已退学,不想有人再上当”——这句话在技术社区里像一块烧红的铁,烫得人不敢直视。它背后没有情绪宣泄,只有一份被压缩到极…

2026/11/10 1:55:38

Android Compose热重载技术解析与实践指南

1. Compose热重载技术解析最近在Android开发社区掀起一阵热潮的Compose HotSwan技术,本质上是一种实时代码更新机制。作为一名长期奋战在Android开发一线的工程师,我亲测这项技术确实能实现"改完代码1秒生效"的效果,彻底告别了传统…

2026/11/11 12:44:21

电工证报考多钱费用 2026河南最新政策怎么走

电工证报考多钱费用 2026河南最新政策怎么走 之前考的证在外省能不能转过来?这个问题真的让不少在河南想干电工的小伙伴头疼。特别是在2026年河南最新政策调整后,很多外省的电工证不再可以直接使用,必须按照新流程进行换证或重新报考。这不仅影响…

2026/11/11 12:44:21

电工证捡证过期了怎么办?官方回应来了,别再踩坑

电工证捡证过期了怎么办?官方回应来了,别再踩坑 证书过期了不知道怎么复审延期,这事儿在河南公路工程行业特别常见。不少电工朋友手上拿着电工证捡证,却因为没及时复审,结果证一过期,项目上不让上岗,工资也受影响。别急,官方回应已经来了,河南省应急…

2026/11/11 12:44:21

电工证算执业资格吗?上岗必备的实操考试怎么准备

电工证算执业资格吗?上岗必备的实操考试怎么准备 实操考试心里没底怕挂科,尤其是初次报考电工证的新乡朋友,面对复杂的流程和严格的操作标准,真的会手足无措。别急,今天就把电工证算执业资格吗这个问题讲明白,还会告诉你怎么准备上岗必备的考试,避免走…

2026/11/11 12:44:21

电工作业证在哪里考取保姆级教程

电工作业证在哪里考取保姆级教程 不知道去哪报名怕被中介坑?别慌,这篇文章就是为你量身打造的保姆级教程,手把手带你搞清楚电工作业证到底在哪里考取,怎么避开那些坑,省时省力又省心! 一、电工作业证到底在哪里考取?别再被中介忽悠了…

2026/11/11 12:42:59

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/11 0:02:26

考低压电工证通过率考试真题与备考技巧

低压电工证通过率高不高?学历不高也能考,值不值得考? 你是不是总听说电工证能帮你找高薪工作,但又担心自己学历不够,考不上?其实,低压电工证考试门槛并没有你想象中那么高,关键是方法对不对。这篇文章就告诉你, 考低压电工证通过率到底有多高 ,…

2026/11/11 0:02:26

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名 你是不是也和我一样,刚毕业就听说低压电工证学时必须达标才能上岗?可一打听,发现报名机构五花八门,价格参差不齐, 不知道去哪报名怕被中介坑…

2026/11/10 20:08:15

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/10 10:29:37

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑