5.1. 在 32-bit soft-float ARM 上引导安装程序

5.1.1. 启动映像格式

在基于 ARM 的系统中,大多数情况下使用两种引导映像格式之一:a) 标准的 Linux zImage 格式内核(vmlinuz)与标准的Linux初始化内存盘(initrd.gz)结合使用 或 b)uImage格式的内核(uImage)与相应的初始化内存盘(uInitrd)结合使用。

uImage/uInitrd 是为许多基于 ARM 的系统(大多数为 32 位系统)使用的 U-Boot 固件设计的映像格式。较旧的 U-Boot 版本只能以 uImage/uInitrd 格式启动文件,因此通常在较旧的 armel 系统上使用。除了启动 uImage/uInitrd 外,较新的 U-Boot 版本还可以引导标准的 Linux 内核和内存盘映像,但是这样做的命令语法与启动 uImage 时的略有不同。

对于使用多平台内核的系统,除内核和初始化内存盘之外,还需要一个所谓的设备树文件(或设备树 blob,dtb)。它特定于每个受支持的系统,并包含特定硬件的描述。设备上的固件应该会提供 dtb,但实际上通常需要加载较新的 dtb。

5.1.2. 从 TFTP 引导

从网络引导需要网络连接和一台 TFTP 网络引导服务器 (也可能是 DHCP、RARP 或 BOOTP 服务器,以进行自动网络配置)。

参见第 4.3 节 “为使用 TFTP 网络引导准备文件”设置用于支持网络引导的服务器端。

5.1.2.1. 在 U-Boot 中启动 TFTP

使用 U-Boot 固件上的网络引导需要三个步骤:a)配置网络,b)将映像(内核/初始化内存盘/dtb)加载到内存中,c)执行预加载的代码。

首先,您必须运行

setenv autoload no
dhcp

使用 DHCP 自动配置网络,或者手动设置环境变量

setenv ipaddr <ip address of the client>
setenv netmask <netmask>
setenv serverip <ip address of the tftp server>
setenv dnsip <ip address of the nameserver>
setenv gatewayip <ip address of the default gateway>

如果您愿意,可以运行

saveenv

命令,保存这些设置。之后,您需要将映像(内核/初始化内存盘/dtb)加载到内存中。这可以通过 tftpboot 命令来完成,但该命令必须提供内存地址,然后将映像存储于此。不幸的是,内存映射因系统而异,所以没有一般规则可以预测哪些地址可用。

在某些系统上, U-Boot 预定义了一组环境变量,其中存有适当的加载地址:kernel_addr_r、ramdisk_addr_r和fdt_addr_r。您可以运行

printenv kernel_addr_r ramdisk_addr_r fdt_addr_r

,来检查它们是否已定义。如果未定义,则必须查看系统文档以获取适当的值并手动设置。对于基于 Allwinner SunXi SOC 的系统(例如Allwinner A10,架构名 sun4i 或 Allwinner A20,架构名 sun7i),您可以使用以下值:

setenv kernel_addr_r 0x46000000
setenv fdt_addr_r 0x47000000
setenv ramdisk_addr_r 0x48000000

定义加载地址后,将映像加载到内存中,可以使用之前定义的 tftp 服务器

tftpboot ${kernel_addr_r} <内核映像文件名>
tftpboot ${fdt_addr_r} <dtb 文件名>
tftpboot ${ramdisk_addr_r} <初始化内存盘映像文件名>

第三部分是设置内核命令行并实际执行加载的代码。U-Boot 将 bootargs 环境变量的内容作为命令行传递给内核,因此内核和安装程序的任何参数(如控制台设备)(请参见第 5.3.1 节 “启动控制台”)或预设选项(请参见第 5.3.2 节 “Debian 安装程序的参数” >和附录 B, 使用预置自动进行安装) - 可以使用命令,如

setenv bootargs console=ttyS0,115200 rootwait panic=10

执行先前加载的代码的确切命令取决于所使用的映像格式。要使用 uImage/uInitrd,命令是

bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}

,若要使用原生 Linux 映像,则是

bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}

注意:引导标准的 linux 映像时,重要的是在内核和 dtb 之后加载初始化内存盘映像,因为 U-Boot 将 filesize 变量设置为最后一个加载文件的大小,并且 bootz 命令需要 ramdisk 映像的大小才能正常工作。在引导特定平台的内核时,即没有设备树的内核,省略 ${fdt_addr_r} 参数即可。

5.1.3. 在 U-Boot 下从 U 盘启动

许多现代 U-Boot 版本支持 USB ,并允许从 USB 大容量存储设备(如 U 盘)启动。不幸的是,这样做的确切步骤可能因设备的不同而会有所不同。

U-Boot v2014.10 引入了通用的命令行处理和自动启动框架。这使得构建任何系统上都能工作的通用引导映像成为可能。debian-installer 支持在这样的系统上从 U 盘安装,但不幸的是,并不是所有的平台都采用了这个新框架。

要构建安装 debian 的可引导 U 盘,请将 hd-media tarball(请参见第 4.2.1 节 “在哪里能找到安装映像”)解压到 U 盘上,并使用您设备 U-Boot 版本支持的文件系统。对于现代的 U-Boot 而言,FAT16/FAT32/ext2/ext3/ext4 通常都可以正常工作。然后复制第一个 Debian 安装 CD/DVD ISO 映像文件到 U 盘上。

现代 U-Boot 版本中的自动启动框架工作原理与 PC BIOS 中的启动顺序选项相似,即它会检查可能的引导设备列表,以获取有效的启动映像,然后启动所找到的第一个。如果没有安装操作系统,则插入 USB 棒并启动系统应该会启动安装程序。在 U-Boot 提示符中,您也随时可以输入 run bootcmd_usb0 命令启动 USB 引导过程。

使用串行控制台从 U 盘启动时,一个可能出现的问题是控制台波特率不匹配。如果在 U-Boot 中定义了控制台变量,那么 debian-installer 引导脚本会自动将其传递给内核,如果合适,则会设置控制台波特率。不幸的是,对控制台变量的处理因平台而异 - 在某些平台上,控制台变量包含波特率(如 console=ttyS0,115200),而在其他平台上,控制台变量只包含设备(如 console=ttyS0)。当 U-Boot 和内核之间的默认波特率不同时,后一种情况将导致控制台输出乱码。现代 U-Boot 版本通常使用 115200 波特率,而内核仍默认传统的 9600 波特率。如果发生这种情况,您应该手动设置控制台变量,将其包括正确的系统波特率,然后使用 run bootcmd_usb0 命令启动安装程序。