5.1. 在 32-bit hard-float ARMv7 上引导安装程序

5.1.1. 引导映像的格式

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

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

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

5.1.2. 控制台配置

网络启动 tarball(第 5.1.3.2 节 “预构建的网络引导 tarball”)和安装程序的 SD 卡映像(第 5.1.5 节 “使用带有安装程序的预构建 SD 卡映像”)使用 U-Boot 在 console 变量中定义的(针对特定平台的)默认控制台。大多数情况下,这是一个串行控制台,所以在这些平台上,默认需要使用串行控制台电缆来使用安装程序。

在同样支持视频控制台的平台上,如果希望安装程序在视频控制台上启动,那么可以修改对应的 U-Boot console 变量。

5.1.3. 从 TFTP 引导

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

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

5.1.3.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 命令需要虚拟硬盘映像的大小才能正常工作。在引导特定平台的内核时,也就是没有设备树的内核时,省略 ${fdt_addr_r} 参数即可。

5.1.3.2. 预构建的网络引导 tarball

Debian 提供了一个预构建的 tarball( .../images/netboot/netboot.tar.gz ),可以直接在 tftp 服务器上解压,其中包含了网络引导所需的所有文件。它还包括一个引导脚本,可自动执行加载安装程序的所有步骤。现代的 U-Boot 版本包含了 tftp 自动引导功能,当没有可供引导的本地存储设备(MMC/SD、USB、IDE/SATA/SCSI)时会自动启动,然后从 tftp 服务器加载该引导脚本。使用此功能的先决条件是您的网络中有 dhcp 服务器,可为客户端提供 tftp 服务器的地址。

如果要从 U-Boot 命令行使用 tftp 自动启动功能,可以使用以下命令:

run bootcmd_dhcp

要手动加载 tarball 提供的引导脚本,您还可以在 U-Boot 提示符执行以下命令:

setenv autoload no
dhcp
tftpboot ${scriptaddr} /debian-installer/armhf/tftpboot.scr
source ${scriptaddr}

5.1.4. 在 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 盘已经用您设备上 U-Boot 版本所支持的文件系统来格式化。对于现代的 U-Boot 版本而言,FAT16 / FAT32 / ext2 / ext3 / ext4 通常都可以正常工作。然后将第一个 Debian 安装 CD 或 DVD 上的 ISO 映像文件复制到 U 盘上。

现代 U-Boot 版本中的自动引导框架的工作原理类似于PC BIOS/UEFI 中的引导顺序选项,即它会检查可能的引导设备列表,以找到有效的引导镜像,并启动第一个找到的设备。如果没有安装操作系统,那么插上 U 盘并给系统上电应该会启动安装程序。也可以在任何时候从 U-Boot 提示符输入 run bootcmd_usb0 命令来启动 USB-boot 进程。

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

5.1.5. 使用带有安装程序的预构建 SD 卡映像

对于许多系统,Debian 还提供 SD 卡映像,其中包含 U-Boot 和 debian-installer。这些映像有两种变体—— 一种用于通过网络下载软件包(可在 .../images/netboot/SD-card-images/ 上获得),另一种使用 Debian CD/DVD 进行离线安装(可在 .../images/hd-media/SD-card-images/ 上获得)。为了节省空间和网络带宽,映像由两部分组成——系统相关部分,名为 firmware.<system-type>.img.gz,和与系统无关的部分,名为 partition.img.gz

要在 Linux 系统上从两个部分创建一个完整的映像,可以使用 zcat,如下所示:

zcat firmware.<system-type>.img.gz partition.img.gz > complete_image.img

。在 Windows 系统上,您必须首先分别解压这两个部分,可使用例如 7-Zip 来完成,然后在 Windows CMD.exe 窗口中运行命令

copy /b firmware.<system-type>.img + partition.img complete_image.img

,将解压的两个部分连接起来。

将生成的映像写入 SD 卡,例如在 Linux 系统上运行以下命令:

cat complete_image.img > /dev/SD_CARD_DEVICE

。将 SD 卡插入目标系统并为系统上电后,安装程序将从 SD 卡中加载。如果使用 hd-media 变体进行离线安装,则必须在单独的介质上向安装程序提供第一个 Debian CD/DVD,例如可以是 U 盘上的 CD/DVD ISO 映像。

当进入安装程序中的分区步骤(请参见第 6.3.4 节 “分区与选择挂载点”)时,可以删除或替换卡上任何先前的分区。一旦安装程序启动,它将完全在系统的主内存中运行,不需要再访问 SD 卡,所以可以使用用于安装 Debian 的整个 SD卡。要在 SD 卡上创建正确的分区布局,最简单的方法是让安装程序为您自动创建一个(请参见第 6.3.4.2 节 “导引式分区”)。