启动ARM架构的Linux内核条件说明

为了启动ARM Linux内核,您需要使用bootloader,它是一个在Linux内核之前运行的一小段程序。bootloader代码需要做的就是初始化CPU的各种控制器和外设,将必要的信息传递给内核,并最终调用Linux内核代码执行。

事实上,bootloader的代码要完成以下基本的工作:
1.设置并初始化RAM(内存);
2.初始化一个串口(方便打印调试信息);
3.检测机器类型(Machine Type);
4.设置传递给内核参数的列表;
5.加载initramfs;
6.调用kernel image执行。
下面我们来逐个详细介绍上面的工作。

1.设置并初始化RAM

bootloader程序需要找到并初始化内核将用于系统中的易失性数据存储的所有RAM。它以机器相关的方式执行此操作。它可以使用内部算法自动定位和调整所有RAM,或者它可以使用机器中RAM的控制器,或者bootloader设计者认为合适的任何其他方法。主要工作就是根据芯片spec初始化其内存控制器,并满足必要的时序要求,这个工作因开发板而异。

2.初始化一个串口

bootloader代码应初始化并启用开发板上的一个串行端口,用于打印调试信息。这允许内核串口驱动程序自动检测,并用于内核控制台(console)。通常用于调试目的。

作为替代方案,bootloader程序可以通过指定端口的标记列表和串行格式选项将相关的'console ='参数传递给内核。

3.检测机器类型

bootloader程序应通过某种方法检测其运行的机器类型。这是硬编码值还是某些查看连接硬件的算法超出了本文档的范围。bootloader程序最终必须能够向内核提供MACH_TYPE_xxx值(可以参考linux/arch/arm/tools/mach-types)。这个值应该通过CPU的R1寄存器传递给kernel。

对于使用设备树(Device Tree)的平台,机器类型将由设备树确定。应该将机器类型值设置为0,这不是必须的,但可以确保它不会与任何现有类型进行匹配。

4.设置启动内核的参数

bootloader程序必须提供内核标记列表或dtb文件,以便将内核配置参数传递给内核。内核启动参数的地址应该保存到CPU的R2寄存器中。

使用标记列表的形式给内核传递参数:

bootloader程序必须创建并初始化内核标记列表。有效的标记列表以ATAG_CORE开头,以ATAG_NONE结尾。ATAG_CORE标记可能为空,也可能不为空。空ATAG_CORE标记的大小字段设置为"2"(0x00000002)。ATAG_NONE必须将size字段设置为零。可以在列表中放置任意数量的标签。未定义重复标记是否附加到前一个标记所携带的信息,或者它是否完全替换了该信息; 一些标签的行为与前者相同,其他标签则与后者相同。bootloader程序必须至少传递系统内存的大小和位置以及根文件系统位置。因此,最小标记列表应如下所示:

	+-----------+
base ->	| ATAG_CORE |  |
	+-----------+  |
	| ATAG_MEM  |  | increasing address
	+-----------+  |
	| ATAG_NONE |  |
	+-----------+  v

在启动内核时标记列表必须保存到RAM中的某个地址,并将此地址告诉内核。标记列表必须放在内存区域中,内核解压缩程序和initrd 'bootp'程序都不会覆盖它。推荐的位置是在RAM的第一个16KiB的中。

使用DTB方式启动Linux内核:

bootloader程序必须将设备树映像(DTB)加载到64位对齐地址的系统RAM中,并使用引导数据对其进行初始化。dtb的格式在Documentation/devicetree/booting-without-of.txt文件中有详细的介绍。内核将在DTB的物理地址处查找值为0xd00dfeed的dtb magic值,以确定是否已传递dtb而不是标记列表。

bootloader程序必须至少传递系统内存的大小和位置以及根文件系统位置。必须将DTB放在内存区域中,内核解压缩程序不会覆盖它,同时保留在内核的低内存映射所覆盖的区域内。从RAM起始地址开始,安全位置就在128MiB边界之上。

5.加载initramfs

如果要使用initramfs,那么与dtb一样,它必须放在内存区域中,内核解压缩程序不会覆盖它,同时还要覆盖内核的低内存映射所覆盖的区域。

安全位置就在设备树blob地址上方,如上所述,它本身将从RAM的起始位置加载到128MiB边界之上。

6.调用内核映像文件执行

调用内核zImage文件有两个选项。如果zImage存储在flash中,并且正确链接以便从flash中运行,那么bootloader程序直接调用flash中的zImage是合法的。

zImage也可以放在系统的RAM中并在内存中执行它。内核应该放在RAM的第一个128MiB中。建议将其加载到32MiB以上,以避免在解压缩之前重新定位,这将使引导过程稍微加快。

无论如何,必须满足以下条件:

--必须停止运行所有支持DMA的设备,以便内存不会被伪造的网络数据包或磁盘数据破坏,这将为您节省大量的调试时间。

--CPU寄存器设置
    r0 = 0;
    r1 = 机器类型ID;
    r2 = 系统RAM中标记列表的物理地址;或系统RAM中设备树文件(dtb)的物理地址。

--CPU模式
    必须禁用所有形式的中断(IRQ和FIQ);
    对于不包含ARM虚拟化扩展的CPU,CPU必须处于SVC模式;

--Caches, MMUs设置
    MMU必须关闭;
    Dcache必须关闭;
    Icache可以打开或关闭;

--bootloader程序通过直接跳转到内核映像的第一条指令来调用内核映像文件;
    在支持ARM指令集的CPU上,该条目必须在ARM状态下进行,即使对于Thumb-2内核也是如此;
    在仅支持Thumb指令集(如Cortex-M类CPU)的CPU上,必须在Thumb状态下进入内核。

猜你喜欢

转载自blog.csdn.net/caihaitao2000/article/details/82814706