DeviceTree 启动¶
在 Linux/ppc64 内核开发期间,更准确地说,是在添加旧的 IBM pSeries/iSeries 组合之外的新平台类型时,决定强制执行一些关于内核入口以及引导程序 <-> 内核接口的严格规则,以避免 ppc32 内核入口点及其添加新平台方式所发生的退化。传统的 iSeries 平台由于早于该方案而打破了这些规则,但主线代码树将不再接受任何未正确遵循这些规则的新板级支持。此外,自从用于 ppc32 和 ppc64 的 arch/powerpc 合并架构问世以来,新的 32 位平台以及迁移到 arch/powerpc 的 32 位平台也将被要求使用这些规则。
下文将更详细定义的主要需求是存在一个设备树 (device-tree),其格式根据 Open Firmware 规范定义。然而,为了让嵌入式板卡厂商的生活更轻松,内核并不要求设备树代表系统中的每个设备,而只要求存在某些节点和属性。例如,内核不要求您为系统中的每个 PCI 设备创建一个节点。但必须为 PCI 主桥 (host bridge) 提供一个节点,以便提供中断路由信息以及内存/IO 范围等。同时,建议为芯片上 (on-chip) 设备以及其他不完全符合现有 OF 规范的总线定义节点。这为内核探测这些设备并为设备匹配驱动程序的方式提供了极大的灵活性,而无需硬编码各种表格。这也使得板卡厂商在进行小型硬件升级时更加灵活,而不会显著影响内核代码或充斥着特殊情况处理。
入口点¶
内核只有一个入口点,位于内核镜像的开始处。该入口点支持两种调用约定
a) 从 Open Firmware 启动。如果您的固件与 Open Firmware (IEEE 1275) 兼容或提供兼容 OF 的客户端接口 API(不需要支持 forth 单词的 “interpret” 回调),您可以通过以下方式进入内核
r5 : 由 powerpc 的 IEEE 1275 绑定定义的 OF 回调指针。目前仅支持 32 位客户端接口
r3, r4 : 如果有 initrd,则是其地址和长度,否则为 0
MMU 可以是开启或关闭状态;内核将运行位于 arch/powerpc/kernel/prom_init.c 中的跳板代码,以从 open firmware 中提取设备树和其他信息,并构建如 b) 中所述的扁平化设备树。然后,
prom_init()将使用第二种方法重新进入内核。该跳板代码在固件的上下文中运行,固件应当在此期间处理所有异常。b) 使用扁平化设备树块直接进入。该入口点在 OF 跳板之后由 a) 调用,也可以由不支持 Open Firmware 客户端接口的引导程序直接调用。“kexec”也使用该方法来实现从先前运行的内核“热”启动新内核。由于方法 a) 只是标准的 Open Firmware,因此应根据定义它及其与 PowerPC 平台绑定的各种标准文档来实现,这也是我在本文档中将更详细描述的方法。此时入口点定义变为
r3 : 指向 RAM 中设备树块(在第二章中定义)的物理指针
r4 : 指向内核自身的物理指针。如果进入内核时 MMU 处于启用状态且使用了非 1:1 映射,汇编代码将使用它来正确禁用 MMU。
r5 : NULL(用于与方法 a 区分)
关于 SMP 入口的注意事项:要么您的固件将您的其他 CPU 置于 ROM 中的某些睡眠循环或自旋循环中,您可以通过软复位或其他手段将其唤醒,这种情况下您无需关心;要么您必须让所有 CPU 一起进入内核。如何通过方法 b) 做到这一点将在本文档的后续修订版本中描述。
板级支持(平台)不是排他的配置选项。可以在单个内核镜像中构建任意一组板级支持。内核将根据设备树的内容“知道”针对给定平台使用哪组函数。因此,您应该
a) 仿照 PPC_PSERIES 和 PPC_PMAC 的例子,在 arch/powerpc/Kconfig 中将您的平台支持添加为一个 _boolean_ 选项。后者可能是开始编写板级支持的一个好例子。
b) 创建您的主平台文件 “arch/powerpc/platforms/myplatform/myboard_setup.c”,并根据您的
CONFIG_选项将其添加到 Makefile 中。该文件将定义一个类型为 “ppc_md” 的结构,其中包含通用代码将用于调用您的平台特定代码的各种回调函数
一个内核镜像可以支持多个平台,但前提是这些平台具有相同的核心架构。单个内核构建不能同时支持 Book E 配置和经典 PowerPC 架构配置。