从零开始移植最新版本(2023.10)主线Uboot到Orange Pi 3(全志H6)
yuyutoo 2025-07-03 01:49 3 浏览 0 评论
本文将从零开始通过一步一步操作来实现将主线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就是瘦身版本的uboot
- bl31 我们这里采用Arm Trusted Fireware(ATF)源码编译出来的bl31,这个是arm公司提供的开源代码,回头我们专门写篇文章来讲它
- bl32没有,bl33就是bootloader,这里我们是uboot
- bl33 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.git
cd trusted-firmware-a
make 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 MiB
Trying to boot from MMC1
NOTICE: BL31: v2.9(debug):
NOTICE: BL31: Built : 17:49:06, Sep 9 2023
NOTICE: BL31: Detected Allwinner H6 SoC (1728)
NOTICE: BL31: Found U-Boot DTB at 0xa09ae88, model: OrangePi 3
INFO: ARM GICv2 driver initialized
INFO: Configuring SPC Controller
INFO: PMIC: Probing AXP805 on RSB
INFO: PMIC: aldo1 voltage: 3.300V
INFO: PMIC: aldo2 voltage: 3.300V
INFO: PMIC: aldo3 voltage: 3.300V
INFO: PMIC: bldo1 voltage: 1.800V
INFO: PMIC: bldo2 voltage: 1.800V
INFO: PMIC: cldo1 voltage: 3.300V
INFO: PMIC: dcdcd voltage: 0.960V
INFO: PMIC: dcdce voltage: 1.200V
INFO: BL31: Platform setup done
INFO: BL31: Initializing runtime services
INFO: BL31: cortex_a53: CPU workaround for erratum 855873 was applied
INFO: BL31: cortex_a53: CPU workaround for erratum 1530924 was applied
INFO: PSCI: Suspend is unavailable
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x4a000000
INFO: SPSR = 0x3c9
U-Boot 2023.10-rc4-00031-gc0c08be546-dirty (Sep 10 2023 - 01:10:43 +0800) Allwinner Technology
CPU: Allwinner H6 (SUN50I)
Model: OrangePi 3
DRAM: 2 GiB
Core: 63 devices, 17 uclasses, devicetree: separate
WDT: Not starting watchdog@7020400
MMC: mmc@4020000: 0, mmc@4021000: 2, mmc@4022000: 1
Loading Environment from FAT... ** No valid partitions found **
In: serial@5000000
Out: serial@5000000
Err: serial@5000000
Net: No ethernet found.
starting USB...
Bus usb@5101000: USB EHCI 1.00
Bus usb@5101400: USB OHCI 1.0
Bus usb@5200000: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
Bus usb@5311000: USB EHCI 1.00
Bus usb@5311400: USB OHCI 1.0
scanning bus usb@5101000 for devices... 1 USB Device(s) found
scanning bus usb@5101400 for devices... 1 USB Device(s) found
scanning bus usb@5200000 for devices... 3 USB Device(s) found
scanning bus usb@5311000 for devices... 1 USB Device(s) found
scanning bus usb@5311400 for devices... 1 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
** Invalid partition 1 **
Couldn't find partition mmc 0:1
switch to partitions #0, OK
mmc1(part 0) is current device
Scanning mmc 1:1...
Card did not respond to voltage select! : -110
No EFI system partition
No EFI system partition
Failed to persist EFI variables
BootOrder not defined
EFI boot manager: Cannot load any image
Device 0: unknown device
No ethernet found.
missing environment variable: pxeuuid
Retrieving file: pxelinux.cfg/00000000
No ethernet found.
Retrieving file: pxelinux.cfg/0000000
No ethernet found.
Retrieving file: pxelinux.cfg/000000
No ethernet found.
Retrieving file: pxelinux.cfg/00000
No ethernet found.
Retrieving file: pxelinux.cfg/0000
No ethernet found.
Retrieving file: pxelinux.cfg/000
No ethernet found.
Retrieving file: pxelinux.cfg/00
No ethernet found.
Retrieving file: pxelinux.cfg/0
No ethernet found.
Retrieving file: pxelinux.cfg/default-arm-sunxi-sunxi
No ethernet found.
Retrieving file: pxelinux.cfg/default-arm-sunxi
No ethernet found.
Retrieving file: pxelinux.cfg/default-arm
No ethernet found.
Retrieving file: pxelinux.cfg/default
No ethernet found.
Config file not found
No ethernet found.
No ethernet found.
=>
前面一段可以看出是UBOOT SPL和bl31阶段的log,后面就是UBOOT 2023运行之后的log,这里因为我们没有在任何存储介质提供linux 内核镜像,所以报EFI boot manager: Cannot load any image错误而无法继续加载引导linux,这是正常的。
相关推荐
- 电脑 CMD 命令大全:简单粗暴收藏版
-
电脑CMD命令大全包括了许多常用的命令,这些命令可以帮助用户进行各种系统管理和操作任务。以下是一些常用的CMD命令及其功能:1、系统信息和管理...
- 电脑维修高手必备!8个神奇DOS命令,自己动手不求人
-
我相信搞电脑维修或者维护的基本都会些DOS的命令。就算Windows操作系统是可视化的界面,但很多维护检查是离不开DOS命令的。掌握好这些命令,你不仅能快速诊断问题,还能解决90%的常见电脑故障。下...
- 一个互联网产品总监的设计技巧总结 - 技术篇
-
古语:工欲善其事必先利其器。往往在利其器后我们才能事半功倍。从这个角度出发成为一个合格的产品经理你需要的是“利其器”,这样你才能产品的设计过程中如鱼得水,得心应手。有些产品经理刚入职,什么都感觉自己欠...
- 超详解析Flutter渲染引擎|业务想创新,不了解底层原理怎么行?
-
作者|万红波(远湖)出品|阿里巴巴新零售淘系技术部前言Flutter作为一个跨平台的应用框架,诞生之后,就被高度关注。它通过自绘UI,解决了之前RN和weex方案难以解决的多端一致性...
- 瑞芯微RK3568|SDK开发之环境安装及编译操作
-
1.SDK简介一个通用LinuxSDK工程目录包含有buildroot、app、kernel、device、docs、external等目录。其中一些特性芯片如RK3308/RV1108/R...
- 且看L-MEM ECC如何守护i.MXRT1170从核CM4
-
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是恩智浦i.MXRT1170上Cortex-M4内核的L-MEMECC功能。本篇是《简析i.MXRT1170Cortex-M7F...
- ECC给i.MXRT1170 FlexRAM带来了哪些变化?
-
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是恩智浦i.MXRT1170上Cortex-M7内核的FlexRAMECC功能。ECC是“ErrorCorrectingCode”...
- PHP防火墙代码,防火墙,网站防火墙,WAF防火墙,PHP防火墙大全
-
PHP防火墙代码,防火墙,网站防火墙,WAF防火墙,PHP防火墙大全资源宝整理分享:https://www.htple.net...
- 从零开始移植最新版本(2023.10)主线Uboot到Orange Pi 3(全志H6)
-
本文将从零开始通过一步一步操作来实现将主线U-Boot最新代码移植到OrangePi3(全志H6)开发板上并正常运行起来。本文从通用移植思路的角度,展现是思考的过程,通过这种方式希望能让读者一通百...
- 可视化编程工具Blockly——定制工具箱
-
1概述本文重点讲解如何定制Blocklytoolbox上,主要包含如下几点目标:如何为toolbox不同类别添加背景色如何改变选中的类别的外观如何为toolbox类别添加定制化的css如何改变类别...
- 用户界面干货盘点(用户界面的基本操作方法)
-
DevExpressDevExpressWPF的DXSplashScreen控件在应用加载的时候显示一个启动界面。添加DXSplashScreen后,会默认生成一个XAML文件,当然,你也可...
- Vue3+Bootstrap5整合:企业级后台管理系统实战
-
简洁而不简单,优雅而不失强大在当今快速发展的企业数字化进程中,高效、美观的后台管理系统已成为企业运营的核心支撑。作为前端开发者,我们如何选择技术栈,才能既保证开发效率,又能打造出专业级的用户体验?答案...
- 什么?这三款i.MXRT型号也开放了IAP API?
-
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT1050/1020/1015系列ROM中的FlexSPI驱动API使用。今天痞子衡去4S店给爱车做保养了,...
- OneCode基础组件介绍——表格组件(Grid)
-
在企业级应用开发中,表格组件是数据展示与交互的核心载体。OneCode平台自研的Grid表格组件,以模型驱动设计...
- 开源无线LoRa传感器(光照温湿度甲醛Tvoc)
-
本开源项目基于ShineBlinkC2M低代码单片机实现,无需复杂单片机C语言开发。即使新手也可很容易用FlexLua零门槛开发各种功能丰富稳定可靠的IoT硬件,更多学习教程可参考Flex...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)