前言:
现时朋友们对“booting from ubuntu”大概比较关心,你们都需要知道一些“booting from ubuntu”的相关资讯。那么小编也在网络上搜集了一些有关“booting from ubuntu””的相关内容,希望看官们能喜欢,兄弟们一起来了解一下吧!本文将从零开始通过一步一步操作来实现将主线U-Boot最新代码移植到Orange Pi 3(全志H6)开发板上并正常运行起来。本文从通用移植思路的角度,展现是思考的过程,通过这种方式希望能让读者一通百通,授之以渔,一定要读完!后续持续更新系统移植系列文章,欢迎关注、点赞、收藏。
这里从零开始移植的意思主要是指从Das Uboot官方网站或者代码库下载写这篇文章时的最新版本(2023.10-rc4-00031-gc0c08be546-dirty)代码,开始构建编译环境,配置,编译,TF安装,到最后在Orange Pi 3硬件板子上run起来。
移植前思考主控芯片的启动流程
我们知道uboot属于系统启动过程中加载操作系统内核,运行内核代码的作用,所以我们知道cpu肯定会在系统启动的某一个阶段会执行uboot固件代码,uboot再引导linux内核,但是因为不同的主控芯片不同的CPU核启动也会流程也会不一样。
所以在移植之前,我们一定要弄清楚CPU的启动流程以及分多少个阶段,需要多少个bin文件,uboot属于哪个启动阶段,必须要从启动流程宏观上了解清楚。
全志H6属于armV8 64位体系结构,armv8 体系结构相较于之前的armv7都有很大不同,下图是ARMV8的一个总的启动流程:
armv8-a 一般最先运行bl1阶段固件,也即是boot rom,这个一般固化在cpu的 rom里面,这是上电之后执行的第一段代码,主要是加载bl2阶段代码到iram执行bl2阶段代码放在存储媒介,比如emmc中,由bl1负责 运行起来,因为bl1代码并未初始化DDR,所以加载到片内SRAM中执行,在这个阶段完成外部DDR的初始化,并加载bl31到DDR运行bl31一般称为EL3 Service,属于runtime,负责切换non secure和secure两个世界环境,运行一些服务,比如PSCI,SCMI等,同时负责把bl32和bl33代码加载运行起来bl32属于trusted OS,如果不需要这个或者硬件不支持,可以去掉bl32,这个是可选的bl33一般是bootlaoder,负责引导后面的操作系统内核
在这里我们h6芯片的启动流程我们选择的就是下面这种比较流行的方式:
bl1阶段是boot rom,固化在irom,这个没什么好说的bl2是uboot编译出来的SPL uboot,专门用于第二阶段启动的,SPL就是瘦身版本的ubootbl31 我们这里采用Arm Trusted Fireware(ATF)源码编译出来的bl31,这个是arm公司提供的开源代码,回头我们专门写篇文章来讲它bl32没有,bl33就是bootloader,这里我们是ubootbl33 uboot后面让它来引导linux操作系统内核
总的来说,后面我们需要3个文件,分别是:编译ATF得到BL31, uboot编译得到spl-uboot和完整uboot,然后再将这三个文件合并成一个最终文件,写入TF卡启动运行。
uboot移植的方式
一般移植uboot有以下几种方式:
找Orange PI 3这款硬件公司其已经配置修改好的uboot代码,编译运行就行找Das UBOOT官方的主线代码结合目标硬件平台自己修改配置,这个要求高一下,要求必须熟悉uboot,这种方式也更具挑战性
以第一种方式,其实硬件公司给我们提供了现场的uboot代码, 。
当然这里我选择第二种方式,也就是将来无论拿过来一款新的开发板,我们都可以以此相同的步骤进行移植,第二种方式更有普遍性。
第二种方式主线移植也分两种情况来区别对待:
如果uboot主线版本代码已经合入Orange PI 3开发板相关代码,那就非常简单,和上面说的第一种方式移植一样,下载代码编译运行即可。如果主线最新版本没有合入Orange PI 3开发板相关代码,那就需要找一款主控芯片也是全志H6的开发板作参考,基于参考板子进行配置,修改代码,编译再运行。
为什么要找主控芯片一致的开发板作为基础进行移植?主要是为了减轻工作量,因为这样主控相关代码大多不需要修改,只是对两个板子硬件上有差异的地方进行配置修改即可,比如常见像RAM或者EMMC或者外设硬件相关代码的配置修改。
我们从 Das uboot的官方代码仓: 文件搜索开发板名称oange pi 3,我们可以看到相关的defconfig默认配置文件以及设备树文件都有了,很明显最新2023.10-rc4-00031版本已经支持该开发板,这样我们工作量就小很多,下面就是按部就班的下载源码,配置,编译,运行了。
下面我们按照工具安装,下载代码,配置,编译,运行的一般步骤走起来。
安装交叉编译工具链
为了编译U-Boot,您需要一个适合您的主机平台的编译器。如果您不是在目标平台上构建,则还需要 GCC 交叉编译器。
这里我们选择GCC工具链,工具链的安装搭建请参考官方文档:
我的编译主机是Ubuntu22.04,是基于 Debian的。目标平台硬件主控芯片是全志H6,查看芯片手册,cpu 核心是Quad-Core ARM Cortex-A53,架构是ARMV8 64.
在基于 Debian 的系统上,交叉编译器包名为 gcc--linux-gnu。
可以使用以下命令安装 GCC 和适用于 ARMv8 架构的 GCC 交叉编译器
sudo apt-get install gcc gcc-aarch64-linux-gnu
可能需要依赖包
sudo apt-get install bc bison build-essential coccinelle \ device-tree-compiler dfu-util efitools flex gdisk graphviz imagemagick \ liblz4-tool libgnutls28-dev libguestfs-tools libncurses-dev \ libpython3-dev libsdl2-dev libssl-dev lz4 lzma lzma-alone openssl \ pkg-config python3 python3-asteval python3-coverage python3-filelock \ python3-pkg-resources python3-pycryptodome python3-pyelftools \ python3-pytest python3-pytest-xdist python3-sphinxcontrib.apidoc \ python3-sphinx-rtd-theme python3-subunit python3-testtools \ python3-virtualenv swig uuid-dev
ubuntu命令行运行以下指令,如果正常出现版本信息那就表示GCC交叉工具链安装正确了。
aarch64-linux-gnu-gcc --version
下载代码
下载步骤可以参考Das Uboot官方文档,。
您可以通过以下方式下载源代码
git clone
或者Github 上维护着源镜像
git clone
不加分支默认下载最新代码。
编译代码
源码编译过程参考Uboot官方文档。
基于全志 SoC 的开发板
对于所有使用基于 Allwinner ARM 的 SoC(“sunxi”)的开发板,U-Boot 编译系统会生成单个集成镜像文件:u-boot-sunxi-with-spl.bin. 该文件可用于 SD 卡、eMMC 设备、SPI 闪存以及基于 USB-OTG 的启动方法(FEL)。
要编译出此文件:
对于 64 位 SoC,首先要编译出可信固件(TF-A,以前称为 ATF),您将需要其bl31.bin. 请参阅下面的更多细节。(可选)在 64 位 SoC 上编译出the crust management processor firmware,也就是scp.bin文件.,这个文件是可选,这里我没有用这个bin文件。编译uboot镜像uboot.bin文件通用步骤:
$ export BL31=/path/to/bl31.bin # required for 64-bit SoCs$ export SCP=/path/to/scp.bin # optional for some 64-bit SoCs$ make <yourboardname>_defconfig #生成开发板配置$ make #编译uboot.bin
The traditional SD card location the Allwinner BootROM loads from is 8KB (sector 16). This works fine with the old MBR partitioning scheme, which most SD cards come formatted with. However this is in the middle of a potential GPT partition table, which will become invalid in this step. Newer SoCs (starting with the H3 from late 2014) also support booting from 128KB, which is beyond even a GPT and thus a safer location.
从上面通用编译步骤看出,要编译出uboot.bin必须要用到bl31.bin文件,scp.bin文件可选,主要是要将它们一起合并到一个最终uboot.bin文件。
编译bl31.bin(ATF)
使用 64 位 Soc(A64、H5、H6、H616、R329)的主板需要 bl31阶段的Arm Trusted Firmware-A固件 。这为 Armv8-A 提供了安全软件环境,并提供 PSCI 和 SMCCC 服务。全志支持已完全主流化。编译 bl31.bin:
git clone trusted-firmware-amake CROSS_COMPILE=aarch64-linux-gnu- PLAT=sun50i_h6 DEBUG=1 bl31
A64 和 H5 SoC 的目标平台 ( PLAT=) 为 sun50i_a64,H6 sun50i_h6、H616 sun50i_h616 和 R329 sun50i_r329 的目标平台为 sun50i_a64。使用:
$ find plat/allwinner -name platform.mk
查找所有支持的平台。TF-A 的docs/plat/allwinner.rst包含更多信息并列出了一些编译选项。
编译完成之后会生成bl31.bin文件
$ export BL31=$(pwd)/build/sun50i_h6/debug/bl31.bin
因为我们这里没用scp.bin,所以这里就不需要生产它了。
配置
编译代码之前我们要选择开发板相关配置项,上面我们查找过,最新版本uboot项目中是存在orange pi 3的默认配置文件的。
通过运行以下指令,我们可以查看,
git grep -l sun50i-h6-orangepi-3 configs
可以看到在configs目录下是存在orangepi_3_defconfig默认配置文件的,使用它即可生成配置文件.config.
make orangepi_3_defconfig编译对于 64 位板,这需要设置 BL31 环境变量BL31,找到上面生成的bl31.bin的位置(如上面 TF-A 编译示例中所示),或者在编译命令行上提供同时还要制定使用的交叉编译器前缀CROSS_COMPILE=aarch64-linux-gnu-因为scp.bin文件我们没用,所以要指定为/dev/null,即SCP=/dev/null,否者会提示Image 'u-boot-sunxi-with-spl' is missing external blobs and is non-functional: scp错误
make CROSS_COMPILE=aarch64-linux-gnu- BL31=/home/albert/Documents/h6/arm-trusted-firmware-master/build/sun50i_h6/debug/bl31.bin SCP=/dev/null
编译完成之后,顶层目录下会生成u-boot-sunxi-with-spl.bin文件,这个就是最终文件,里面包含ATF和SPL和uboot主体还有设备树。
除了原始 NAND 闪存设备外,这个相同的文件可用于任何启动源。它将包含 SPL 映像,配有 BROM 识别的正确签名以及所需的校验和。此外,它将至少包含正确的 U-Boot,或者以传统 U-Boot 映像格式包装,或者以 FIT 映像包装。该板的设备树也包含在内,或者附加到 U-Boot 适当的映像中,或者包含在 FIT 映像中。如果 SoC 需要,此 FIT 文件还将包含其他固件映像。
运行Uboot烧写到TF卡上
用读卡器将TF卡插入UBUNTU系统,使用DISKR软件现将TF卡所有分区删除,打开DISK软件,找到TF卡存储设备,点击减号,删除所有分区。
所有 Allwinner SoC 都会尝试在连接到第一个 MMC 控制器的 SD 卡的第 16 扇区 (8KB) 处查找启动映像。要将生成的镜像烧写到 SD 卡,请从任何带有(微型)SD 卡读卡器的 Linux 设备(包括开发板本身),输入:
$ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1k seek=8
/dev/sdx需要替换为SD卡读卡器的块设备名称。在某些机器上这可能是/dev/mmcblkX。较新的 SoC(从 2014 年的 H3 开始,包括所有 ARM64 SoC)也会查看扇区 256 (128KB) 的签名(在检查了 8KB 位置之后)。在那里安装固件的优点是不与 GPT 分区表重叠。只需将上面的“ seek=8”替换为“ seek=128”即可。
连接UART0串口终端
TF卡启动卡制作完成之后,插入开发板TF口,然后通过USB转TTL小板子连接电脑主机和开发板,上位机打开一个串口工具软件,比如ubuntu putty或者windows SecureCRT,使用软件打开串口,确保U转串没问题之后,给开发板上电。
如果都没有问题,我们会看到uboot运行起来之后从UART0 串口终端输出的运行日志:
U-Boot SPL 2023.10-rc4-00031-gc0c08be546-dirty (Sep 10 2023 - 01:10:43 +0800)DRAM: 2048 MiBTrying to boot from MMC1NOTICE: BL31: v2.9(debug):NOTICE: BL31: Built : 17:49:06, Sep 9 2023NOTICE: BL31: Detected Allwinner H6 SoC (1728)NOTICE: BL31: Found U-Boot DTB at 0xa09ae88, model: OrangePi 3INFO: ARM GICv2 driver initializedINFO: Configuring SPC ControllerINFO: PMIC: Probing AXP805 on RSBINFO: PMIC: aldo1 voltage: 3.300VINFO: PMIC: aldo2 voltage: 3.300VINFO: PMIC: aldo3 voltage: 3.300VINFO: PMIC: bldo1 voltage: 1.800VINFO: PMIC: bldo2 voltage: 1.800VINFO: PMIC: cldo1 voltage: 3.300VINFO: PMIC: dcdcd voltage: 0.960VINFO: PMIC: dcdce voltage: 1.200VINFO: BL31: Platform setup doneINFO: BL31: Initializing runtime servicesINFO: BL31: cortex_a53: CPU workaround for erratum 855873 was appliedINFO: BL31: cortex_a53: CPU workaround for erratum 1530924 was appliedINFO: PSCI: Suspend is unavailableINFO: BL31: Preparing for EL3 exit to normal worldINFO: Entry point address = 0x4a000000INFO: SPSR = 0x3c9U-Boot 2023.10-rc4-00031-gc0c08be546-dirty (Sep 10 2023 - 01:10:43 +0800) Allwinner TechnologyCPU: Allwinner H6 (SUN50I)Model: OrangePi 3DRAM: 2 GiBCore: 63 devices, 17 uclasses, devicetree: separateWDT: Not starting watchdog@7020400MMC: mmc@4020000: 0, mmc@4021000: 2, mmc@4022000: 1Loading Environment from FAT... ** No valid partitions found **In: serial@5000000Out: serial@5000000Err: serial@5000000Net: No ethernet found.starting USB...Bus usb@5101000: USB EHCI 1.00Bus usb@5101400: USB OHCI 1.0Bus usb@5200000: Register 2000140 NbrPorts 2Starting the controllerUSB XHCI 1.00Bus usb@5311000: USB EHCI 1.00Bus usb@5311400: USB OHCI 1.0scanning bus usb@5101000 for devices... 1 USB Device(s) foundscanning bus usb@5101400 for devices... 1 USB Device(s) foundscanning bus usb@5200000 for devices... 3 USB Device(s) foundscanning bus usb@5311000 for devices... 1 USB Device(s) foundscanning bus usb@5311400 for devices... 1 USB Device(s) found scanning usb for storage devices... 0 Storage Device(s) foundHit any key to stop autoboot: 0 switch to partitions #0, OKmmc0 is current device** Invalid partition 1 **Couldn't find partition mmc 0:1switch to partitions #0, OKmmc1(part 0) is current deviceScanning mmc 1:1...Card did not respond to voltage select! : -110No EFI system partitionNo EFI system partitionFailed to persist EFI variablesBootOrder not definedEFI boot manager: Cannot load any imageDevice 0: unknown deviceNo ethernet found.missing environment variable: pxeuuidRetrieving file: pxelinux.cfg/00000000No ethernet found.Retrieving file: pxelinux.cfg/0000000No ethernet found.Retrieving file: pxelinux.cfg/000000No ethernet found.Retrieving file: pxelinux.cfg/00000No ethernet found.Retrieving file: pxelinux.cfg/0000No ethernet found.Retrieving file: pxelinux.cfg/000No ethernet found.Retrieving file: pxelinux.cfg/00No ethernet found.Retrieving file: pxelinux.cfg/0No ethernet found.Retrieving file: pxelinux.cfg/default-arm-sunxi-sunxiNo ethernet found.Retrieving file: pxelinux.cfg/default-arm-sunxiNo ethernet found.Retrieving file: pxelinux.cfg/default-armNo ethernet found.Retrieving file: pxelinux.cfg/defaultNo ethernet found.Config file not foundNo ethernet found.No ethernet found.=>
前面一段可以看出是UBOOT SPL和bl31阶段的log,后面就是UBOOT 2023运行之后的log,这里因为我们没有在任何存储介质提供linux 内核镜像,所以报EFI boot manager: Cannot load any image错误而无法继续加载引导linux,这是正常的。
标签: #booting from ubuntu