这里从零开始移植的意思紧张是指从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的一个总的启动流程:
启动流程1
Arm启动流程
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芯片的启动流程我们选择的便是下面这种比较盛行的办法:
启动流程2
盛行启动流程
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代码,https://github.com/orangepi-xunlong/OrangePiH6_uboot 。
当然这里我选择第二种办法,也便是将来无论拿过来一款新的开拓板,我们都可以以此相同的步骤进行移植,第二种办法更有普遍性。
第二种办法主线移植也分两种情形来差异对待:
如果uboot主线版本代码已经合入Orange PI 3开拓板干系代码,那就非常大略,和上面说的第一种办法移植一样,下载代码编译运行即可。如果主线最新版本没有合入Orange PI 3开拓板干系代码,那就须要找一款主控芯片也是全志H6的开拓板作参考,基于参考板子进行配置,修正代码,编译再运行。为什么要找主控芯片同等的开拓板作为根本进行移植?紧张是为了减轻事情量,由于这样主控干系代码大多不须要修正,只是对两个板子硬件上有差异的地方进行配置修正即可,比如常见像RAM或者EMMC或者外设硬件干系代码的配置修正。
我们从 Das uboot的官方代码仓:https://source.denx.de/u-boot/u-boot/ 文件搜索开拓板名称oange pi 3,我们可以看到干系的defconfig默认配置文件以及设备树文件都有了,很明显最新2023.10-rc4-00031版本已经支持该开拓板,这样我们事情量就小很多,下面便是按部就班的下载源码,配置,编译,运行了。
搜索仓库
下面我们按照工具安装,下载代码,配置,编译,运行的一样平常步骤走起来。
安装交叉编译工具链为了编译U-Boot,您须要一个适宜您的主机平台的编译器。如果您不是在目标平台上构建,则还须要 GCC 交叉编译器。
这里我们选择GCC工具链,工具链的安装搭建请参考官方文档:https://u-boot.readthedocs.io/en/latest/build/gcc.html
我的编译主机是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官方文档,https://u-boot.readthedocs.io/en/latest/build/source.html。
您可以通过以下办法下载源代码
git clone https://source.denx.de/u-boot/u-boot.git
或者Github 上掩护着源镜像
git clone https://github.com/u-boot/u-boot
不加分支默认下载最新代码。
编译代码源码编译过程参考Uboot官方文档https://u-boot.readthedocs.io/en/latest/board/allwinner/sunxi.html。
基于全志 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 https://git.trustedfirmware.org/TF-A/trusted-firmware-a.gitcd 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,这是正常的。