编辑
2025-03-03
工作知识
0
请注意,本文编写于 95 天前,最后修改于 95 天前,其中某些信息可能已经过时。

目录

一:查看bootcmd变量
二:为非distro启动方式新增distro启动
2.1 解析自定义的distro方式启动
三:启动方案介绍
3.1 加载启动成功日志
四、注意事项
4.1 设备树匹配
4.2 启动缺陷
4.2.1 仅能安装在第一个设备上
4.2.2 仅能启动第一个分区
4.2.3 mmc系统优于scsi系统并优于nvme

因为有一些uboot机器的环境变量不一致,导致标准的distro安装不能通用,所以需要在uboot的shell界面设置一下变量,从而使得机器支持uboot正常安装和启动。这里分享如何自定义uboot启动来支持uboot安装镜像

一:查看bootcmd变量

进入uboot环境中,需要确定bootcmd变量是否为sysboot加载的extlinux文件,如果是,则无需修改,如果不是,则需要自行配置。

如:

distro_bootcmd=run load_kernel; run load_initrd; run load_fdt; run boot_os boot_os=bootm $kernel_addr -:- $ft_fdt_addr

上述启动方式为直接引导内核地址,initrd地址和fdt地址,然后调用bootm的方式直接启动。故此方式不是标准的distro系统启动方式,需要修改

如:

bootcmd=run distro_bootcmd; distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done .....;. boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf

则此方式为distro系统的uboot启动方式,uboot无需额外修改

二:为非distro启动方式新增distro启动

对于直接启动的方式,我们需要将其设置为标准distro方式启动。故需要如下设置, 20231027新增支持mmc安装,mmc启动优先级在scsi,nvme之前。

setenv uboot_env "setenv kernel_addr_r 0x90100000;setenv ramdisk_addr_r 0x95000000;setenv fdt_addr_r 0x90000000;" setenv find_and_boot 'if $devtype dev 0; then if fstype $devtype 0:1 bootfstype;then for prefix in / /boot/; do sysboot $devtype 0:1 any 0x90000000 $prefix/extlinux/extlinux.conf; done; fi; fi' setenv usb_boot "usb start; run uboot_env; setenv devtype usb; run find_and_boot" setenv scsi_boot "setenv devtype scsi; run find_and_boot" setenv nvme_boot "setenv devtype nvme; run find_and_boot" setenv mmc_boot "setenv devtype mmc; run find_and_boot" setenv bootcmd_kylin "setenv board e2000q-test-b-ddr4; run uboot_env; run usb_boot; run mmc_boot; run scsi_boot; run nvme_boot" setenv bootcmd "run bootcmd_kylin" saveenv

2.1 解析自定义的distro方式启动

uboot_env变量: 设置内核加载地址为0x90100000,ramdisk加载地址为0x95000000,设备树加载地址为0x90000000,此三个地址和直接启动方式地址一致 find_and_boot变量: 对每个类型(usb scsi nvme)的设备的第一个设备进行判断,如果其第一个分区是bootfstype(ext4、vfat)则遍历/和/boot目录,寻找其extlinux/extlinux.conf目录,如果存在,则通过sysboot加载extlinux.conf来加载uImage和uInitrd usb_boot变量:U盘启动盘的启动方式,uboot阶段打开usb,设置启动方式为usb后启动 mmc_boot变量:设置启动方式为mmc后启动 scsi_boot变量:设置启动方式为scsi后启动 nvme_boot变量:设置启动方式为nvme后启动 bootcmd_kylin变量:设置板卡为e2000q-test-b-ddr4(这里以32s的板卡为例),配置uboot环境,配置usb启动,配置scsi启动,配置nvme启动 bootcmd变量:修改当前的启动方式为bootcmd_kylin saveenv:保存当前配置信息,以便后续启动生效

三:启动方案介绍

通过如上信息可以知道,uboot本身可以直接通过地址引导,也就是如下

ext4load usb 0:1 $kernel_addr boot/uImage-5.4.18-63.52-e2000-rc15-generic; ext4load usb 0:1 $ft_fdt_addr boot/dtb/e2000q-test-b-ddr4.dtb; bootm $kernel_addr -:- $ft_fdt_addr

它通过ext4load的方式直接将内核,设备树加载到对应地址来启动。这也是通常uboot的启动方式。但它不适合常用的发行版系统的安装。

而通过extlinux方式启动能够为常用发行版安装提供良好的方式。

这里配置文件内容如下

default install menu title Installer prompt 0 timeout 10 label install menu label kylinos installer linux /boot/uImage initrd /boot/uInitrd fdtdir /boot/dtb append root=LABEL=kylinos earlycon=pl011,0x2800d000 console=ttyAMA1,115200 rw boot=vkylin uboottype cma=96M security=none audit=1

上述配置步骤概述如下:

  • 开机默认开启usb控制器
  • 对usb的第一个分区进行查询,判断是否存在/extlinux/extlinux.conf或/boot/extlinux/extlinux.conf目录
  • 通过sysboot加载extlinux.conf文件
  • extlinux.conf文件描述了uImage和uInitrd的位置,这里位置默认在/boot/uImage,/boot/uInitrd,/boot/dtb目录下
  • sysboot会直接启动uImage和uInitrd来运行安装界面
  • 安装完成之后,拔掉u盘,下次启动会遍历usb,scsi,nvme来加载系统,这时因为安装过程会把系统安装到scsi或nvme上,则系统会正常启动

3.1 加载启动成功日志

starting USB... Bus usb3@31a00000: Register 2000110 NbrPorts 2 Starting the controller USB XHCI 1.10 Bus usb3@31a20000: Register 2000110 NbrPorts 2 Starting the controller USB XHCI 1.10 scanning bus usb3@31a00000 for devices... 2 USB Device(s) found scanning bus usb3@31a20000 for devices... 4 USB Device(s) found scanning usb for storage devices... 1 Storage Device(s) found Device 0: Vendor: Kingston Rev: PMAP Prod: DataTraveler 3.0 Type: Removable Hard Disk Capacity: 14784.0 MB = 14.4 GB (30277632 x 512) ... is now current device Scanning usb 0:1... Found /boot/extlinux/extlinux.conf Retrieving file: /boot/extlinux/extlinux.conf 1: kylinos installer Retrieving file: /boot/uInitrd Retrieving file: /boot/uImage append: root=LABEL=kylinos earlycon=pl011,0x2800d000 console=tty0,115200 rw boot=vkylin uboottype cma=96M security=none audit=1 Retrieving file: /boot/dtb/e2000q-test-b-ddr4.dtb ## Booting kernel from Legacy Image at 90100000 ... Image Name: Linux-5.4.18-63.52-e2000-rc17-ge Image Type: AArch64 Linux Kernel Image (uncompressed) Data Size: 25207296 Bytes = 24 MiB Load Address: 80080000 Entry Point: 80080000 Verifying Checksum ... OK ## Loading init Ramdisk from Legacy Image at 95000000 ... Image Name: uInitrd Image Type: ARM Linux RAMDisk Image (gzip compressed) Data Size: 103216845 Bytes = 98.4 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Flattened Device Tree blob at 90000000 Booting using the fdt blob at 0x90000000 Loading Kernel Image Loading Ramdisk to f39ca000, end f9c396cd ... OK Loading Device Tree to 00000000f39c1000, end 00000000f39c975a ... OK run in ft_board_setup fdt_addr 00000000f39c1000 N: Phytium System Service Call: 0xc2000005 mb_count = 0x2 mb_blocks[0].mb_size = 0x7c000000 mb_blocks[1].mb_size = 0x80000000 fdt : can not find /memory@01 node fdt : add node memory@01 fdt : dram size 0x100000000 update successfully Starting kernel ...

通过上述可以判断其正常加载了uImage,uInitrd,dtb。

四、注意事项

4.1 设备树匹配

uboot启动需要设备树完全匹配,这里设备树分安装时需要的设备树和启动时需要的设备树。

安装时的设备树需要放在iso的boot/dtb目录下存在和板子要求设备树一致的

板子设备树可以通过如下查询:

print board

这里会提供设备树名字,如e2000q-test-b-ddr4,此时需要在u盘的boot/dtb/e2000q-test-b-ddr4.dtb文件保证存在,否则U盘无法启动

启动时的设备树需要放在系统的/boot/dtb/下,如果系统安装在nvme下,则需要在nvme的下的boot分区内有/dtb/e2000q-test-b-ddr4.dtb。否则安装了也无法启动

记住,这里board对应的设备树需要和机器硬件功能完全一致

4.2 启动缺陷

4.2.1 仅能安装在第一个设备上

如上述配置可以发现,这里遍历无论是usb,scsi还是nvme,都是选择第一个设备来启动,如果系统存在多个usb,scsi,nvme设备,则需要安装系统到第一个设备上,否则启动不了。

对于此缺陷,可以尝试修复,主要方式为遍历所有的存储设备,而不是指定设备号为0

4.2.2 仅能启动第一个分区

如上述配置可以发现,只能启动0:1分区的内容,也就是boot分区必须要在第一个分区。如果系统存在多个分区,启动分区不在第一个,则系统启动不了

对于此缺陷,可以尝试修复,主要方式为通过part list devtype{devtype} {devnum} -bootable devplist 来遍历所有的分区,然后对每个分区来进行for循环查找extlinux文件

4.2.3 mmc系统优于scsi系统并优于nvme

如上述配置可以发现,usb>mmc>scsi>nvme,usb优先主要用于安装,mmc>scsi>nvme是默认配置的,如果mmc,scsi和nvme上都有系统,则默认启动mmc的系统

对于此缺陷,可以尝试修复,调整bootcmd_kylin的启动顺序即可