18c2ecf20Sopenharmony_ciChinese translated version of Documentation/arm64/booting.rst 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ciIf you have any comment or update to the content, please contact the 48c2ecf20Sopenharmony_cioriginal document maintainer directly. However, if you have a problem 58c2ecf20Sopenharmony_cicommunicating in English you can also ask the Chinese maintainer for 68c2ecf20Sopenharmony_cihelp. Contact the Chinese maintainer if this translation is outdated 78c2ecf20Sopenharmony_cior if there is a problem with the translation. 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ciM: Will Deacon <will.deacon@arm.com> 108c2ecf20Sopenharmony_cizh_CN: Fu Wei <wefu@redhat.com> 118c2ecf20Sopenharmony_ciC: 55f058e7574c3615dea4615573a19bdb258696c6 128c2ecf20Sopenharmony_ci--------------------------------------------------------------------- 138c2ecf20Sopenharmony_ciDocumentation/arm64/booting.rst 的中文翻译 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 168c2ecf20Sopenharmony_ci交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 178c2ecf20Sopenharmony_ci译存在问题,请联系中文版维护者。 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci英文版维护者: Will Deacon <will.deacon@arm.com> 208c2ecf20Sopenharmony_ci中文版维护者: 傅炜 Fu Wei <wefu@redhat.com> 218c2ecf20Sopenharmony_ci中文版翻译者: 傅炜 Fu Wei <wefu@redhat.com> 228c2ecf20Sopenharmony_ci中文版校译者: 傅炜 Fu Wei <wefu@redhat.com> 238c2ecf20Sopenharmony_ci本文翻译提交时的 Git 检出点为: 55f058e7574c3615dea4615573a19bdb258696c6 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci以下为正文 268c2ecf20Sopenharmony_ci--------------------------------------------------------------------- 278c2ecf20Sopenharmony_ci 启动 AArch64 Linux 288c2ecf20Sopenharmony_ci ================== 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci作者: Will Deacon <will.deacon@arm.com> 318c2ecf20Sopenharmony_ci日期: 2012 年 09 月 07 日 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci本文档基于 Russell King 的 ARM 启动文档,且适用于所有公开发布的 348c2ecf20Sopenharmony_ciAArch64 Linux 内核代码。 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ciAArch64 异常模型由多个异常级(EL0 - EL3)组成,对于 EL0 和 EL1 异常级 378c2ecf20Sopenharmony_ci有对应的安全和非安全模式。EL2 是系统管理级,且仅存在于非安全模式下。 388c2ecf20Sopenharmony_ciEL3 是最高特权级,且仅存在于安全模式下。 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci基于本文档的目的,我们将简单地使用‘引导装载程序’(‘boot loader’) 418c2ecf20Sopenharmony_ci这个术语来定义在将控制权交给 Linux 内核前 CPU 上执行的所有软件。 428c2ecf20Sopenharmony_ci这可能包含安全监控和系统管理代码,或者它可能只是一些用于准备最小启动 438c2ecf20Sopenharmony_ci环境的指令。 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci基本上,引导装载程序(至少)应实现以下操作: 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci1、设置和初始化 RAM 488c2ecf20Sopenharmony_ci2、设置设备树数据 498c2ecf20Sopenharmony_ci3、解压内核映像 508c2ecf20Sopenharmony_ci4、调用内核映像 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci1、设置和初始化 RAM 548c2ecf20Sopenharmony_ci----------------- 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci必要性: 强制 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci引导装载程序应该找到并初始化系统中所有内核用于保持系统变量数据的 RAM。 598c2ecf20Sopenharmony_ci这个操作的执行方式因设备而异。(它可能使用内部算法来自动定位和计算所有 608c2ecf20Sopenharmony_ciRAM,或可能使用对这个设备已知的 RAM 信息,还可能是引导装载程序设计者 618c2ecf20Sopenharmony_ci想到的任何合适的方法。) 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci2、设置设备树数据 658c2ecf20Sopenharmony_ci--------------- 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci必要性: 强制 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci设备树数据块(dtb)必须 8 字节对齐,且大小不能超过 2MB。由于设备树 708c2ecf20Sopenharmony_ci数据块将在使能缓存的情况下以 2MB 粒度被映射,故其不能被置于必须以特定 718c2ecf20Sopenharmony_ci属性映射的2M区域内。 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci注: v4.2 之前的版本同时要求设备树数据块被置于从内核映像以下 748c2ecf20Sopenharmony_citext_offset 字节处算起第一个 512MB 内。 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci3、解压内核映像 778c2ecf20Sopenharmony_ci------------- 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci必要性: 可选 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciAArch64 内核当前没有提供自解压代码,因此如果使用了压缩内核映像文件 828c2ecf20Sopenharmony_ci(比如 Image.gz),则需要通过引导装载程序(使用 gzip 等)来进行解压。 838c2ecf20Sopenharmony_ci若引导装载程序没有实现这个功能,就要使用非压缩内核映像文件。 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci4、调用内核映像 878c2ecf20Sopenharmony_ci------------- 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci必要性: 强制 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci已解压的内核映像包含一个 64 字节的头,内容如下: 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci u32 code0; /* 可执行代码 */ 948c2ecf20Sopenharmony_ci u32 code1; /* 可执行代码 */ 958c2ecf20Sopenharmony_ci u64 text_offset; /* 映像装载偏移,小端模式 */ 968c2ecf20Sopenharmony_ci u64 image_size; /* 映像实际大小, 小端模式 */ 978c2ecf20Sopenharmony_ci u64 flags; /* 内核旗标, 小端模式 * 988c2ecf20Sopenharmony_ci u64 res2 = 0; /* 保留 */ 998c2ecf20Sopenharmony_ci u64 res3 = 0; /* 保留 */ 1008c2ecf20Sopenharmony_ci u64 res4 = 0; /* 保留 */ 1018c2ecf20Sopenharmony_ci u32 magic = 0x644d5241; /* 魔数, 小端, "ARM\x64" */ 1028c2ecf20Sopenharmony_ci u32 res5; /* 保留 (用于 PE COFF 偏移) */ 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci映像头注释: 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci- 自 v3.17 起,除非另有说明,所有域都是小端模式。 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci- code0/code1 负责跳转到 stext. 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci- 当通过 EFI 启动时, 最初 code0/code1 被跳过。 1128c2ecf20Sopenharmony_ci res5 是到 PE 文件头的偏移,而 PE 文件头含有 EFI 的启动入口点 1138c2ecf20Sopenharmony_ci (efi_stub_entry)。当 stub 代码完成了它的使命,它会跳转到 code0 1148c2ecf20Sopenharmony_ci 继续正常的启动流程。 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci- v3.17 之前,未明确指定 text_offset 的字节序。此时,image_size 为零, 1178c2ecf20Sopenharmony_ci 且 text_offset 依照内核字节序为 0x80000。 1188c2ecf20Sopenharmony_ci 当 image_size 非零,text_offset 为小端模式且是有效值,应被引导加载 1198c2ecf20Sopenharmony_ci 程序使用。当 image_size 为零,text_offset 可假定为 0x80000。 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci- flags 域 (v3.17 引入) 为 64 位小端模式,其编码如下: 1228c2ecf20Sopenharmony_ci 位 0: 内核字节序。 1 表示大端模式,0 表示小端模式。 1238c2ecf20Sopenharmony_ci 位 1-2: 内核页大小。 1248c2ecf20Sopenharmony_ci 0 - 未指定。 1258c2ecf20Sopenharmony_ci 1 - 4K 1268c2ecf20Sopenharmony_ci 2 - 16K 1278c2ecf20Sopenharmony_ci 3 - 64K 1288c2ecf20Sopenharmony_ci 位 3: 内核物理位置 1298c2ecf20Sopenharmony_ci 0 - 2MB 对齐基址应尽量靠近内存起始处,因为 1308c2ecf20Sopenharmony_ci 其基址以下的内存无法通过线性映射访问 1318c2ecf20Sopenharmony_ci 1 - 2MB 对齐基址可以在物理内存的任意位置 1328c2ecf20Sopenharmony_ci 位 4-63: 保留。 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci- 当 image_size 为零时,引导装载程序应试图在内核映像末尾之后尽可能 1358c2ecf20Sopenharmony_ci 多地保留空闲内存供内核直接使用。对内存空间的需求量因所选定的内核 1368c2ecf20Sopenharmony_ci 特性而异, 并无实际限制。 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci内核映像必须被放置在任意一个可用系统内存 2MB 对齐基址的 text_offset 1398c2ecf20Sopenharmony_ci字节处,并从该处被调用。2MB 对齐基址和内核映像起始地址之间的区域对于 1408c2ecf20Sopenharmony_ci内核来说没有特殊意义,且可能被用于其他目的。 1418c2ecf20Sopenharmony_ci从映像起始地址算起,最少必须准备 image_size 字节的空闲内存供内核使用。 1428c2ecf20Sopenharmony_ci注: v4.6 之前的版本无法使用内核映像物理偏移以下的内存,所以当时建议 1438c2ecf20Sopenharmony_ci将映像尽量放置在靠近系统内存起始的地方。 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci任何提供给内核的内存(甚至在映像起始地址之前),若未从内核中标记为保留 1468c2ecf20Sopenharmony_ci(如在设备树(dtb)的 memreserve 区域),都将被认为对内核是可用。 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci在跳转入内核前,必须符合以下状态: 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci- 停止所有 DMA 设备,这样内存数据就不会因为虚假网络包或磁盘数据而 1518c2ecf20Sopenharmony_ci 被破坏。这可能可以节省你许多的调试时间。 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci- 主 CPU 通用寄存器设置 1548c2ecf20Sopenharmony_ci x0 = 系统 RAM 中设备树数据块(dtb)的物理地址。 1558c2ecf20Sopenharmony_ci x1 = 0 (保留,将来可能使用) 1568c2ecf20Sopenharmony_ci x2 = 0 (保留,将来可能使用) 1578c2ecf20Sopenharmony_ci x3 = 0 (保留,将来可能使用) 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci- CPU 模式 1608c2ecf20Sopenharmony_ci 所有形式的中断必须在 PSTATE.DAIF 中被屏蔽(Debug、SError、IRQ 1618c2ecf20Sopenharmony_ci 和 FIQ)。 1628c2ecf20Sopenharmony_ci CPU 必须处于 EL2(推荐,可访问虚拟化扩展)或非安全 EL1 模式下。 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci- 高速缓存、MMU 1658c2ecf20Sopenharmony_ci MMU 必须关闭。 1668c2ecf20Sopenharmony_ci 指令缓存开启或关闭皆可。 1678c2ecf20Sopenharmony_ci 已载入的内核映像的相应内存区必须被清理,以达到缓存一致性点(PoC)。 1688c2ecf20Sopenharmony_ci 当存在系统缓存或其他使能缓存的一致性主控器时,通常需使用虚拟地址 1698c2ecf20Sopenharmony_ci 维护其缓存,而非 set/way 操作。 1708c2ecf20Sopenharmony_ci 遵从通过虚拟地址操作维护构架缓存的系统缓存必须被配置,并可以被使能。 1718c2ecf20Sopenharmony_ci 而不通过虚拟地址操作维护构架缓存的系统缓存(不推荐),必须被配置且 1728c2ecf20Sopenharmony_ci 禁用。 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci *译者注:对于 PoC 以及缓存相关内容,请参考 ARMv8 构架参考手册 1758c2ecf20Sopenharmony_ci ARM DDI 0487A 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci- 架构计时器 1788c2ecf20Sopenharmony_ci CNTFRQ 必须设定为计时器的频率,且 CNTVOFF 必须设定为对所有 CPU 1798c2ecf20Sopenharmony_ci 都一致的值。如果在 EL1 模式下进入内核,则 CNTHCTL_EL2 中的 1808c2ecf20Sopenharmony_ci EL1PCTEN (bit 0) 必须置位。 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci- 一致性 1838c2ecf20Sopenharmony_ci 通过内核启动的所有 CPU 在内核入口地址上必须处于相同的一致性域中。 1848c2ecf20Sopenharmony_ci 这可能要根据具体实现来定义初始化过程,以使能每个CPU上对维护操作的 1858c2ecf20Sopenharmony_ci 接收。 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci- 系统寄存器 1888c2ecf20Sopenharmony_ci 在进入内核映像的异常级中,所有构架中可写的系统寄存器必须通过软件 1898c2ecf20Sopenharmony_ci 在一个更高的异常级别下初始化,以防止在 未知 状态下运行。 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci 对于拥有 GICv3 中断控制器并以 v3 模式运行的系统: 1928c2ecf20Sopenharmony_ci - 如果 EL3 存在: 1938c2ecf20Sopenharmony_ci ICC_SRE_EL3.Enable (位 3) 必须初始化为 0b1。 1948c2ecf20Sopenharmony_ci ICC_SRE_EL3.SRE (位 0) 必须初始化为 0b1。 1958c2ecf20Sopenharmony_ci - 若内核运行在 EL1: 1968c2ecf20Sopenharmony_ci ICC_SRE_EL2.Enable (位 3) 必须初始化为 0b1。 1978c2ecf20Sopenharmony_ci ICC_SRE_EL2.SRE (位 0) 必须初始化为 0b1。 1988c2ecf20Sopenharmony_ci - 设备树(DT)或 ACPI 表必须描述一个 GICv3 中断控制器。 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci 对于拥有 GICv3 中断控制器并以兼容(v2)模式运行的系统: 2018c2ecf20Sopenharmony_ci - 如果 EL3 存在: 2028c2ecf20Sopenharmony_ci ICC_SRE_EL3.SRE (位 0) 必须初始化为 0b0。 2038c2ecf20Sopenharmony_ci - 若内核运行在 EL1: 2048c2ecf20Sopenharmony_ci ICC_SRE_EL2.SRE (位 0) 必须初始化为 0b0。 2058c2ecf20Sopenharmony_ci - 设备树(DT)或 ACPI 表必须描述一个 GICv2 中断控制器。 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci以上对于 CPU 模式、高速缓存、MMU、架构计时器、一致性、系统寄存器的 2088c2ecf20Sopenharmony_ci必要条件描述适用于所有 CPU。所有 CPU 必须在同一异常级别跳入内核。 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci引导装载程序必须在每个 CPU 处于以下状态时跳入内核入口: 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci- 主 CPU 必须直接跳入内核映像的第一条指令。通过此 CPU 传递的设备树 2138c2ecf20Sopenharmony_ci 数据块必须在每个 CPU 节点中包含一个 ‘enable-method’ 属性,所 2148c2ecf20Sopenharmony_ci 支持的 enable-method 请见下文。 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci 引导装载程序必须生成这些设备树属性,并在跳入内核入口之前将其插入 2178c2ecf20Sopenharmony_ci 数据块。 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci- enable-method 为 “spin-table” 的 CPU 必须在它们的 CPU 2208c2ecf20Sopenharmony_ci 节点中包含一个 ‘cpu-release-addr’ 属性。这个属性标识了一个 2218c2ecf20Sopenharmony_ci 64 位自然对齐且初始化为零的内存位置。 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci 这些 CPU 必须在内存保留区(通过设备树中的 /memreserve/ 域传递 2248c2ecf20Sopenharmony_ci 给内核)中自旋于内核之外,轮询它们的 cpu-release-addr 位置(必须 2258c2ecf20Sopenharmony_ci 包含在保留区中)。可通过插入 wfe 指令来降低忙循环开销,而主 CPU 将 2268c2ecf20Sopenharmony_ci 发出 sev 指令。当对 cpu-release-addr 所指位置的读取操作返回非零值 2278c2ecf20Sopenharmony_ci 时,CPU 必须跳入此值所指向的地址。此值为一个单独的 64 位小端值, 2288c2ecf20Sopenharmony_ci 因此 CPU 须在跳转前将所读取的值转换为其本身的端模式。 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci- enable-method 为 “psci” 的 CPU 保持在内核外(比如,在 2318c2ecf20Sopenharmony_ci memory 节点中描述为内核空间的内存区外,或在通过设备树 /memreserve/ 2328c2ecf20Sopenharmony_ci 域中描述为内核保留区的空间中)。内核将会发起在 ARM 文档(编号 2338c2ecf20Sopenharmony_ci ARM DEN 0022A:用于 ARM 上的电源状态协调接口系统软件)中描述的 2348c2ecf20Sopenharmony_ci CPU_ON 调用来将 CPU 带入内核。 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci *译者注: ARM DEN 0022A 已更新到 ARM DEN 0022C。 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci 设备树必须包含一个 ‘psci’ 节点,请参考以下文档: 2398c2ecf20Sopenharmony_ci Documentation/devicetree/bindings/arm/psci.yaml 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci- 辅助 CPU 通用寄存器设置 2438c2ecf20Sopenharmony_ci x0 = 0 (保留,将来可能使用) 2448c2ecf20Sopenharmony_ci x1 = 0 (保留,将来可能使用) 2458c2ecf20Sopenharmony_ci x2 = 0 (保留,将来可能使用) 2468c2ecf20Sopenharmony_ci x3 = 0 (保留,将来可能使用) 247