程序项目代做,有需求私信(vue、React、Java、爬虫、电路板设计、嵌入式linux等)

Rockchip RK3566 - orangepi-build编译

----------------------------------------------------------------------------------------------------------------------------

开发板 :Orange Pi 3B开发板
eMMC32GB
LPDDR42GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot2017.09
linux6.6/5.10
----------------------------------------------------------------------------------------------------------------------------

一、Linux SDK

本节主要介绍一下 Orange Pi 3BLinux SDK——orangepi-build使用说明,有关Orange Pi 3B硬件知识本篇只做简单介绍。

1.1 Orange Pi 3B

Orange Pi 3B采用了瑞芯微RK3566四核64Cortex-A55处理器,采用的22nm工艺,主频最高可达1.8GHz,集成ARM Mali-G52 GPU,内嵌高性能2D图像加速模块,内置0.8Tops算力的AI加速器NPU,可选2GB4GB或者8GB内存,具有高达4K显示处理能力。

Orange Pi 3B引出了相当丰富的接口,包括HDMI输出、M.2 PCIe2.0x1、千兆网口、USB2.0USB3.0接口和40pin扩展排针等。可广泛适用于高端平板、边缘计算、人工智能、云计算、AR/VR、智能安防、智能家居等领域,覆盖 AIoT各个行业。

Orange Pi 3B支持Android11ubuntu 22.04ubuntu 20.04debian11debian12、开源鸿蒙4.0 Beta1Orange Pi OS(Arch)、基于开源鸿蒙的Orange Pi OS(OH)等操作系统。

1.2 orangepi-build

orangepi-build是由香橙派官方提供的适用于自家产品的Linux SDK,其与Rockchip Linux SDK有很多的差别,其源码位于https://github.com/orangepi-xunlong/orangepi-build

编译orangepi-build要求我们的宿主机为ubuntu 22.04系统。所以下载orangepi-build前,请首先确保自己电脑已安装的ubuntu版本是ubuntu 22.04

查看电脑已安装的ubuntu版本的命令如下所示:

root@ubuntu:/$  lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.4 LTS
Release:        22.04
Codename:       jammy

如果release字段显示的不是22.04,说明当前使用的ubuntu版本不符合要求,请更换系统后再进行下面的操作。

1.2.1 下载源码

Linux SDK其实指的就是orangepi-build这套代码,orangepi-build是基于armbian build编译系统修改而来的,使用orangepi-build可以编译出多个版本的Linux镜像(这里指的是包含ubootkernelrootfs等的统一镜像)。

首先下载orangepi-build的代码,命令如下所示:

root@ubuntu:/work/sambashare/rk3566$ sudo git clone https://github.com/orangepi-xunlong/orangepi-build.git -b next

Orange Pi 3B开发板是需要下载orangepi-buildnext分支源码的,上面的git clone命令需要指定orangepi-build源码的分支为next

注意:由于内核和u-boot等源码都是存放在github上的,所以编译镜像的时候请确保电脑能正常从github下载代码,这点是非常重要的。

1.2.2 版本

开发板当前使用的u-bootkernel版本如下所示:

分支 u-boot版本 Linux内核版本
legacy u-boot 2017.09 Linux 5.10

这里所说的分支和orangepi-build源代码的分支不是同一个东西,请不要搞混了。此分支主要是用来区分不同内核源码版本的。

目前RK提供的Linux5.10 BSP内核我们定义为legacy分支,如果以后支持主线内核了,就会添加一个current分支

1.2.3 目录介绍

orangepi-build目录结构如下:

root@ubuntu:/work/sambashare/rk3566$ cd orangepi-build/
root@ubuntu:/work/sambashare/rk3566/orangepi-build$ ll
-rwxr-xr-x 1 root root  9277  7月 10 13:39 build.sh*
drwxr-xr-x 7 root root  4096  7月 10 13:40 external/
drwxr-xr-x 8 root root  4096  7月 10 13:40 .git/
-rw-r--r-- 1 root root  1337  7月 10 13:39 .gitignore
-rw-r--r-- 1 root root 18026  7月 10 13:39 LICENSE
-rw-r--r-- 1 root root   402  7月 10 13:39 README.md
drwxr-xr-x 2 root root  4096  7月 10 13:40 scripts/

其中:

  • build.sh:编译启动脚本;
  • external:包含编译镜像需要用的配置文件、特定功能的脚本以及部分程序的源码,编译镜像过程中缓存的rootfs压缩包也存放在 external中;
  • LICENSEGPL 2许可证文件;
  • scripts:编译过程中使用到的通用脚本。

github下载的orangepi-build的代码并没有包含u-bootlinux内核的源码,也没有编译u-bootlinux内核需要用到交叉编译工具链,这是正常的,因为这些东西都存放在其它单独的github仓库或者某些服务器上了。

orangepi-build在脚本和配置文件中会指定u-bootlinux内核和交叉编译工具链的地址,运行orangepi-build时,当其发现本地没有这些东西,会自动去相应的地方下载的。

orangepi-build第一次编译Linux镜像的时候会去下载交叉编译工具链、u-bootlinux内核源码,成功编译完后会生成以下文件夹;

  • kernel:存放linux内核的源码,里面名为orange-pi-5.10-rk35xx的文件夹存放的就是RK3588/RK3588S/RK3566系列开发板legacy分支的内核源码,内核源码的文件夹的名字请不要手动修改,如果修改了,编译系统运行时会重新下载内核源码;
  • output:存放编译生成的u-bootlinux kerneldeb包、编译日志以及编译生成的镜像等文件;
  • toolchains:存放交叉编译工具链;
  • u-boot:存放u-boot的源码,里面名为v2017.09-rk3588的文件夹存放的就是RK3588/RK3588S/RK3566系列开发板legacy分支的u-boot源码,u-boot源码的文件夹的名字请不要手动修改,如果修改了,编译系统运行时会重新下载u-boot源码;
  • userpatches:存放编译脚本需要用到的配置文件。

1.3 下载交叉编译工具链

x64的电脑中使用orangepi-build编译镜像才会下载交叉编译工具链。在开发板的ubuntu 22.04中编译是不会下载交叉编译工具链的,此时orangepi-build/toolchains会是一个空文件夹。

orangepi-build第一次运行的时候会自动下载交叉编译工具链放在toolchains文件夹中,每次运行orangepi-buildbuild.sh脚本后,都会检查toolchains中的交叉编译工具链是否都存在,如果不存在则会重新开始下载,如果存在则直接使用,不会重复下载;

交叉编译工具链在中国境内的镜像网址为清华大学的开源软件镜像站:https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/

toolchains下载完后会包含多个版本的交叉编译工具链:

zhengyang@ubuntu:/work/sambashare/rk3566/orangepi-build$ ll toolchains/
drwxr-xr-x  9 root root 4096  7月 10 14:38 gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/
drwxr-xr-x  9 root root 4096  7月 10 14:37 gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf/
drwxr-xr-x  9 root root 4096  7月 10 14:36 gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/
drwxr-xr-x  9 root root 4096  7月 10 14:34 gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/
drwxr-xr-x  8 root root 4096  7月 10 14:29 gcc-linaro-4.9.4-2017.01-x86_64_aarch64-linux-gnu/
drwxr-xr-x  8 root root 4096  7月 10 14:28 gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/
drwxr-xr-x  8 root root 4096  7月 10 14:30 gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabihf/
drwxr-xr-x  8 root root 4096  7月 10 14:31 gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/
drwxr-xr-x  8 root root 4096  7月 10 14:30 gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi/
drwxr-xr-x  7 root root 4096  7月 10 14:26 gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/
drwxr-xr-x  7 root root 4096  7月 10 14:27 gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/
drwxr-xr-x  7 root root 4096  7月 10 14:27 gcc-linaro-arm-none-eabi-4.8-2014.04_linux/

编译u-bootkernel源码使用的交叉编译工具链为: gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu

二、uboot编译和测试

u-boot源码存放在git仓库地址如下:https://github.com/orangepi-xunlong/u-boot-orangepi/tree/v2017.09-rk3588

编译使用的板载defconfig配置文件为:<SDK>/u-boot/v2017.09-rk3588/configs/orangepi-3b-rk3566_defconfig

编译使用的dts文件为:<SDK>/u-boot/v2017.09-rk3588/arch/arm/dts/rk3566-orangepi-3b.dts

2.1 编译u-boot

运行build.sh脚本,输入如下命令:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo ./build.sh
2.1.1 编译配置

选择U-boot package,然后回车;

接着选择开发板的型号,这里选择organgepo3b

然后选择u-boot版本,这里我们虽然选择current,实际上并不是主线u-boot

2.1.2 编译步骤

编译过程中会执行如下步骤:

  • 为宿主机ubuntu 22.04系统安装基础包,比如dialoguuiduuid-runtime等;
  • 创建配置文件userpatches/config-example.conf
  • 为宿主机ubuntu 22.04系统安装构建依赖包,编译过程中需要使用到;
  • 下载多个版本的交叉编译工具链;
  • 从指定位置下载u-boot源码;
  • 编译u-boot源码并生成deb软件包。

2.2 编译信息

编译完整体日志如下:

点击查看代码
# 安装基础依赖包
[ .... ] Installing basic packages [ dialog uuid uuid-runtime  ]
正在选中未选择的软件包 dialog。
(正在读取数据库 ... 系统当前共安装有 320504 个文件和目录。)
准备解压 .../dialog_1.3-20211214-1_amd64.deb  ...
正在解压 dialog (1.3-20211214-1) ...
正在选中未选择的软件包 libossp-uuid16:amd64。
准备解压 .../libossp-uuid16_1.6.2-1.5build9_amd64.deb  ...
正在解压 libossp-uuid16:amd64 (1.6.2-1.5build9) ...
正在选中未选择的软件包 uuid。
准备解压 .../uuid_1.6.2-1.5build9_amd64.deb  ...
正在解压 uuid (1.6.2-1.5build9) ...
正在设置 libossp-uuid16:amd64 (1.6.2-1.5build9) ...
正在设置 dialog (1.3-20211214-1) ...
正在设置 uuid (1.6.2-1.5build9) ...
正在处理用于 man-db (2.10.2-1) 的触发器 ...
正在处理用于 libc-bin (2.35-0ubuntu3.8) 的触发器 ...

# 创建配置文件
[ o.k. ] Create example config file using template [ config-default.conf ]
[ o.k. ] Using config file [ /work/sambashare/rk3566/orangepi-build/userpatches/config-example.conf ]
[ .... ] Extension being added [ rkbin-tools :: added by ./build.sh:305 -> scripts/main.sh:386 -> scripts/configuration.sh:151 -> external/config/sources/families/rockchip-rk356x.conf:1 -> external/config/sources/families/include/rockchip64_common.inc:5 -> scripts/extensions.sh:0 ]
[ o.k. ] Extension manager [ processed 3 Extension Methods calls and 3 Extension Method implementations ]
[ o.k. ] Preparing [ host ]
[ o.k. ] Build host OS release [ jammy ]

# 安装构建依赖包
[ .... ] Installing build dependencies
正在从软件包中解出模板:100%
正在预设定软件包 ...
(正在读取数据库 ... 系统当前共安装有 320670 个文件和目录。)
正在卸载 g++-multilib (4:11.2.0-1ubuntu1) ...
正在卸载 gcc-multilib (4:11.2.0-1ubuntu1) ...
正在选中未选择的软件包 distcc。
(正在读取数据库 ... 系统当前共安装有 320667 个文件和目录。)
准备解压 .../00-distcc_3.4+really3.3.5-3build1_amd64.deb  ...
正在解压 distcc (3.4+really3.3.5-3build1) ...
正在选中未选择的软件包 pigz。
准备解压 .../01-pigz_2.6-1_amd64.deb  ...
正在解压 pigz (2.6-1) ...
正在选中未选择的软件包 libssh2-1:amd64。
准备解压 .../02-libssh2-1_1.10.0-3_amd64.deb  ...
正在解压 libssh2-1:amd64 (1.10.0-3) ...
正在选中未选择的软件包 libaria2-0:amd64。
准备解压 .../03-libaria2-0_1.36.0-1_amd64.deb  ...
正在解压 libaria2-0:amd64 (1.36.0-1) ...
正在选中未选择的软件包 aria2。
准备解压 .../04-aria2_1.36.0-1_amd64.deb  ...
正在解压 aria2 (1.36.0-1) ...
正在选中未选择的软件包 btrfs-progs。
准备解压 .../05-btrfs-progs_5.16.2-1_amd64.deb  ...
正在解压 btrfs-progs (5.16.2-1) ...
正在选中未选择的软件包 libhiredis0.14:amd64。
准备解压 .../06-libhiredis0.14_0.14.1-2_amd64.deb  ...
正在解压 libhiredis0.14:amd64 (0.14.1-2) ...
正在选中未选择的软件包 ccache。
准备解压 .../07-ccache_4.5.1-1_amd64.deb  ...
.......
正在设置 libjq1:amd64 (1.6-2.1ubuntu3) ...
正在设置 aria2 (1.36.0-1) ...
正在设置 ccache (4.5.1-1) ...
Updating symlinks in /usr/lib/ccache ...
正在设置 libc6-dev-armhf-cross (2.35-0ubuntu1cross3) ...
正在设置 lib32ncurses6 (6.3-2ubuntu0.1) ...
正在设置 p7zip-full (16.02+dfsg-8) ...
正在设置 lib32ncursesw6 (6.3-2ubuntu0.1) ...
正在设置 libgcc-11-dev-armhf-cross (11.4.0-1ubuntu1~22.04cross1) ...
正在设置 dwarves (1.25-0ubuntu1~22.04.2) ...
正在设置 jq (1.6-2.1ubuntu3) ...
正在设置 cpp-arm-linux-gnueabihf (4:11.2.0-1ubuntu1) ...
正在设置 gcc-11-arm-linux-gnueabihf (11.4.0-1ubuntu1~22.04cross1) ...
正在设置 gcc-arm-linux-gnueabihf (4:11.2.0-1ubuntu1) ...
正在设置 lib32ncurses-dev (6.3-2ubuntu0.1) ...
正在处理用于 libc-bin (2.35-0ubuntu3.8) 的触发器 ...
正在处理用于 man-db (2.10.2-1) 的触发器 ...
正在处理用于 dbus (1.12.20-2ubuntu4.1) 的触发器 ...
正在处理用于 initramfs-tools (0.140ubuntu13.5) 的触发器 ...
update-initramfs: Generating /boot/initrd.img-6.5.0-41-generic

[ o.k. ] Syncing clock [ cn.pool.ntp.org ]
# 下载交叉编译工具
[ o.k. ] Checking for external GCC compilers
[ .... ] downloading using http(s) network [ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz ]
[#6ea7c3 24MiB/24MiB(97%) CN:1 DL:3.0MiB]
[ o.k. ] Verified [ PGP ]
[ .... ] decompressing
[ .... ] gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz: 24.9MiB [13.6MiB/s] [=========================================>] 100%
[ .... ] downloading using http(s) network [ gcc-linaro-arm-none-eabi-4.8-2014.04_linux.tar.xz ]
[#5daa49 33MiB/33MiB(99%) CN:1 DL:2.2MiB]
[ o.k. ] Verified [ PGP ]
[ .... ] decompressing
[ .... ] gcc-linaro-arm-none-eabi-4.8-2014.04_linux.tar.xz: 33.9MiB [9.46MiB/s] [============================================>] 100%
......
[ .... ] downloading using http(s) network [ gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabihf.tar.xz ]
[#e536ad 87MiB/87MiB(99%) CN:1 DL:1.7MiB]
[ o.k. ] Verified [ MD5 ]
[ .... ] decompressing
[ .... ] gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabihf.tar.xz: 87.7MiB [13.4MiB/s] [===================================>] 100%
[ .... ] downloading using http(s) network [ gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi.tar.xz ]
[#387804 102MiB/104MiB(98%) CN:1 DL:3.1MiB]
[ o.k. ] Verified [ MD5 ]
[ .... ] decompressing
[ .... ] gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi.tar.xz:  104MiB [13.0MiB/s] [=====================================>] 100%

# 下载u-boot源码
[ o.k. ] Downloading sources
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/u-boot v2017.09-rk3588 ]
[ .... ] Creating local copy
[ .... ] Fetching updates
remote: Enumerating objects: 26724, done.
remote: Counting objects: 100% (8606/8606), done.
remote: Compressing objects: 100% (4846/4846), done.
remote: Total 26724 (delta 4388), reused 3777 (delta 3760), pack-reused 18118
接收对象中: 100% (26724/26724), 30.33 MiB | 1.88 MiB/s, 完成.
处理 delta 中: 100% (11458/11458), 完成.
来自 https://github.com/orangepi-xunlong/u-boot-orangepi
 * branch              v2017.09-rk3588 -> FETCH_HEAD
 * [新分支]            v2017.09-rk3588 -> origin/v2017.09-rk3588
[ .... ] Checking out
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/external/cache/sources/rkbin-tools master ]
[ .... ] Creating local copy
[ .... ] Fetching updates
remote: Enumerating objects: 1046, done.
remote: Counting objects: 100% (361/361), done.
remote: Compressing objects: 100% (159/159), done.
remote: Total 1046 (delta 267), reused 228 (delta 202), pack-reused 685
接收对象中: 100% (1046/1046), 44.14 MiB | 2.20 MiB/s, 完成.
处理 delta 中: 100% (515/515), 完成.
来自 https://github.com/armbian/rkbin
 * branch            master     -> FETCH_HEAD
 * [新分支]          master     -> origin/master
[ .... ] Checking out
[ o.k. ] Installing [ rkbin-tools ]
[ o.k. ] Cleaning /work/sambashare/rk3566/orangepi-build/output/debs for [ orangepi3b current ]

# 编译u-boot并生成deb包
[ o.k. ] Compiling u-boot [ v2017.09 ]
[ o.k. ] Compiler version [ aarch64-none-linux-gnu-gcc 9.2.1 ]
[ o.k. ] Started patching process for [ u-boot rockchip-rk356x-orangepi3b-current ]
[ o.k. ] Looking for user patches in [ userpatches/u-boot/u-boot-rockchip-rk356x ]
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  SHIPPED scripts/kconfig/zconf.tab.c
  SHIPPED scripts/kconfig/zconf.lex.c
  SHIPPED scripts/kconfig/zconf.hash.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#
scripts/kconfig/conf  --silentoldconfig Kconfig
#
# configuration written to .config
#
  CHK     include/config.h
  UPD     include/config.h
  CFG     u-boot.cfg
  GEN     include/autoconf.mk.dep
  CFG     spl/u-boot.cfg
  CFG     tpl/u-boot.cfg
  GEN     tpl/include/autoconf.mk
  GEN     include/autoconf.mk
  GEN     spl/include/autoconf.mk
  CHK     include/config/uboot.release
  CHK     include/generated/timestamp_autogenerated.h
./"arch/arm/mach-rockchip/make_fit_atf.sh" \
arch/arm/dts/rk3566-orangepi-3b.dtb > u-boot.its
  UPD     include/generated/timestamp_autogenerated.h
  UPD     include/config/uboot.release
  HOSTCC  scripts/dtc/dtc.o
  ......
    OBJCOPY spl/u-boot-spl-nodtb.bin
  CAT     spl/u-boot-spl-dtb.bin
  COPY    spl/u-boot-spl.bin
Image Type:   Rockchip RK35 boot image
Init Data Size: 59392 bytes
Boot Data Size: 256000 bytes
记录了0+0 的读入
记录了0+0 的写出
0字节已复制,0.00013379 s,0.0 kB/s
警告: 所产生的分区没有适当为获得最佳性能而对齐:64s % 2048s != 0s
警告: 所产生的分区没有适当为获得最佳性能而对齐:1024s % 2048s != 0s
记录了620+0 的读入
记录了620+0 的写出
317440字节(317 kB,310 KiB)已复制,0.00110509 s,287 MB/s
记录了3020+0 的读入
记录了3020+0 的写出
1546240字节(1.5 MB,1.5 MiB)已复制,0.00431695 s,358 MB/s
Image Type:   Rockchip RK35 boot image
Init Data Size: 59392 bytes
Boot Data Size: 256000 bytes
[ o.k. ] Building deb [ linux-u-boot-current-orangepi3b_1.0.6_arm64.deb ]
[ o.k. ] U-boot build done [ @host ]
[ o.k. ] Target directory [ /work/sambashare/rk3566/orangepi-build/output/debs/u-boot ]
[ o.k. ] File name [ linux-u-boot-current-orangepi3b_1.0.6_arm64.deb ]
[ o.k. ] Runtime [ 14 min ]
[ o.k. ] Repeat Build Options [ sudo ./build.sh  BOARD=orangepi3b BRANCH=current BUILD_OPT=u-boot  ]
2.2.1 u-boot源码

在输出的日志信息中,我们可以看到u-boot版本信息:

[ o.k. ] Compiling u-boot [ v2017.09 ]

源码位于u-boot/v2017.09-rk3588目录;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ ls u-boot/v2017.09-rk3588/
api                  cmd        Documentation  idbloader.img  MAINTAINERS    README            tools       u-boot.its
arch                 common     drivers        include        Makefile       rkspi_loader.img  tpl         u-boot.lds
bl31_0x00040000.bin  config.mk  dts            Kbuild         make.sh        scripts           u-boot      u-boot.map
bl31_0xfdcc9000.bin  configs    env            Kconfig        net            snapshot.commit   u-boot.cfg  u-boot-nodtb.bin
bl31_0xfdcd0000.bin  disk       examples       lib            post           spl               u-boot.dtb
board                doc        fs             Licenses       PREUPLOAD.cfg  test              u-boot.itb
2.2.2 交叉编译工具链

在输出的日志信息中,我们可以看到交叉编译工具链的版本;

[ o.k. ] Compiler version [ aarch64-none-linux-gnu-gcc 9.2.1 ]
2.2.3 u-boot deb

在输出的日志信息中,我们可以看到编译生成的u-boot deb信息;

[ o.k. ] Building deb [ linux-u-boot-current-orangepi3b_1.0.6_arm64.deb ]
[ o.k. ] U-boot build done [ @host ]
[ o.k. ] Target directory [ /work/sambashare/rk3566/orangepi-build/output/debs/u-boot ]
[ o.k. ] File name [ linux-u-boot-current-orangepi3b_1.0.6_arm64.deb ]
[ o.k. ] Runtime [ 14 min ]
2.2.4 重复编译

重复编译u-boot的命令,使用下面的命令无需通过图形界面选择,可以直接开始编译u-boot

sudo ./build.sh  BOARD=orangepi3b BRANCH=current BUILD_OPT=u-boot
2.2.5 关闭源码同步

orangepi-bulid编译系统编译u-boot源码时首先会将u-boot的源码和github服务器的u-boot源码进行同步,所以如果想修改u-boot的源码,首先需要关闭源码的下载更新功能,否则所作的修改都会被还原,方法如下,

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ vim userpatches/config-default.conf
IGNORE_UPDATES="yes"

即设置userpatches/config-default.conf中的IGNORE_UPDATES变量为yes

注意:需要完整编译过一次u-boot后才能关闭这个功能,否则会提示找不到u-boot的源码。

2.3 烧录测试

调试u-boot代码时,可以使用下面的方法来更新Linux镜像中的u-boot进行测试。

2.3.1 查看deb

编译生成的u-boot deb包名为linux-u-boot-current-orangepi3b_1.0.6_arm64.deb ,位于/work/sambashare/rk3566/orangepi-build/output/debs/u-boot目录。

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ ll output/debs/u-boot/
-rw-r--r-- 1 root sudo 552548  7月 10 14:40 linux-u-boot-current-orangepi3b_1.0.6_arm64.deb

用下面的命令可以解压deb包:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$cd output/debs/u-boot/
root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/u-boot$ sudo dpkg -x linux-u-boot-current-orangepi3b_1.0.6_arm64.deb  .
root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/u-boot$ ls
linux-u-boot-current-orangepi3b_1.0.6_arm64.deb  usr

解压后的文件如下所示:

root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/u-boot$ tree usr/
usr/            # 默认安装到/usr目录
└── lib
    ├── linux-u-boot-current-orangepi3b_1.0.6_arm64
    │   ├── idbloader.img
    │   ├── rkspi_loader.img
    │   └── u-boot.itb
    └── u-boot
        ├── LICENSE
        ├── orangepi-3b-rk3566_defconfig
        └── platform_install.sh

3 directories, 6 files

通过文件名我们大概就可以看出该SDK编译的系统采用的TPL/SPL引导方式,更多细节可以参考《Rockchip RK3399 - TPL/SPL方式加载uboot》。

这里我们简单介绍一下这些文件:

  • idbloader.img:是一个Rockchip格式的预加载程序,在SoC启动时工作,它包含:
    • Rockchip BootROM知道的IDBlock头;
    • DDR初始化程序,由BootROM加载到SRAM,运行在SRAM内部;
    • 下一级加载程序,由BootROM加载并运行在DDR上;
  • rkspi_loader.img:由idbloader.imgu-boot.itb合并得到一个镜像文件;
  • u-boot.itb:是u-boot.img的另一个变种,通过mkimage构建出来的,里面除了u-boot.dtbu-boot-nodtb.bin这两个uboot源码编译出来的文件之外,还包含了bl31.elfbl32.bintee.binARM trust固件。其中bl31.elf是必须要有的,bl32.bintee.bin是可选的,可以没有;
  • rangepi-3b-rk3566_defconfig:编译使用的板载defconfig配置文件;
  • platform_install.sh:通过dd命令实现u-boot的安装功能。

其中:idbloader.imgu-boot.itb是需要烧录到eMMC的。

这里我们看一下platform_install.sh脚本:

# 这里是deb包的安装目录
DIR=/usr/lib/linux-u-boot-current-orangepi3b_1.0.6_arm64

# 根据指定的目录$1中的文件,将特定的u-boot相关文件写入到目标设备$2中指定的位置
write_uboot_platform ()
{
    if [[ -f $1/rksd_loader.img ]]; then
        dd if=$1/rksd_loader.img of=$2 seek=64 conv=notrunc status=none > /dev/null 2>&1;
    else
    	# 通过dd命令将idbloader.img写入到0x40扇区处
    	# 通过dd命令将u-boot.itb写入到0x4000扇区处
        if [[ -f $1/u-boot.itb ]]; then
            dd if=$1/idbloader.img of=$2 seek=64 conv=notrunc status=none > /dev/null 2>&1;
            dd if=$1/u-boot.itb of=$2 seek=16384 conv=notrunc status=none > /dev/null 2>&1;
        else
            if [[ -f $1/uboot.img ]]; then
                dd if=$1/idbloader.bin of=$2 seek=64 conv=notrunc status=none > /dev/null 2>&1;
                dd if=$1/uboot.img of=$2 seek=16384 conv=notrunc status=none > /dev/null 2>&1;
                dd if=$1/trust.bin of=$2 seek=24576 conv=notrunc status=none > /dev/null 2>&1;
            else
                echo "[write_uboot_platform]: Unsupported u-boot processing configuration!";
                exit 1;
            fi;
        fi;
    fi
}

# 用于写入SPI设备的u-boot相关镜像文件到目标设备$2中。
write_uboot_platform_mtd ()
{
    if [[ -f $1/rkspi_loader.img ]]; then
        dd if=$1/rkspi_loader.img of=$2 conv=notrunc status=none > /dev/null 2>&1;
    else
        echo "SPI u-boot image not found!";
        exit 1;
    fi
}

# 用于设置在/proc/cmdline中是否包含了ubootpart参数,并据此确定目标设备的名称
setup_write_uboot_platform ()
{
    if grep -q "ubootpart" /proc/cmdline; then
        local tmp=$(cat /proc/cmdline);
        tmp="${tmp##*ubootpart=}";
        tmp="${tmp%% *}";
        [[ -n $tmp ]] && local part=$(findfs PARTUUID=$tmp 2>/dev/null);
        [[ -n $part ]] && local dev=$(lsblk -n -o PKNAME $part 2>/dev/null);
        [[ -n $dev ]] && DEVICE="/dev/$dev";
    fi
}
2.3.2 上传deb

将编译好的u-bootdeb包上传到开发板的Linux系统中;

root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/u-boot$ scp linux-u-boot-current-orangepi3b_1.0.6_arm64.deb root@192.168.0.100:/root
2.3.3 卸载旧包

然后登录到开发板,卸载已安装的u-bootdeb包;

root@orangepi:~# apt purge -y linux-u-boot-orangepi3b-legacy
2.3.4 安装新包

再安装刚才上传的新的u-bootdeb包;

root@orangepi:~# dpkg -i linux-u-boot-current-orangepi3b_1.0.6_arm64.deb

由于未指定安装目录, 默认会安装到系统的根目录的各个目录。

然后运行nand-sata-install脚本(有兴趣可以研究一下该脚本,位于/user/sbin目录,其内部调用的platform_install.sh);

root@orangepi:~# nand-sata-install

然后选择5 Install/Update the bootloader on SD/eMMC来更新SD/eMMC中的u-boot,或者选择7 Install/Update the bootloader on SPI Flash来更新SPI Flash中的u-boot

更新完成后,就可以重启开发板来测试u-boot的修改是否生效了。

三、Linux kernel编译和测试

Linux kernel源码存放在git仓库地址如下:

对于legacy版本:

  • 编译使用的内核配置文件为:<SDK>/external/config/kernel/linux-rockchip-rk356x-legacy.config
  • v1.1开发板:编译使用的dts文件为:<SDK>/kernel/orange-pi-5.10-rk35xx/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dts
  • v2.1开发板:编译使用的dts文件为:<SDK>/kernel/orange-pi-5.10-rk35xx/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b-v2.dts

对于current版本:

  • 编译使用的内核配置文件为:<SDK>/external/config/kernel/linux-rockchip-rk356x-current.config
  • 编译使用的dts文件为:<SDK>/kernel/orange-pi-6.6-rk35xx/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dts

3.1 编译kernel

运行build.sh脚本,输入如下命令:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo ./build.sh
3.1.1 编译配置

选择Kernel package,然后回车;

然后会提示是否需要显示内核配置界面,如果不需要修改内核配置,则选择第一个即可,如果需要修改内核配置,则选择第二个;

注意:如果选择了需要显示内核配置菜单(第二个选项),则会弹出通过make menuconfig打开的内核配置的界面,此时可以直接修改内核的配置,修改完后再保存退出即可,退出后会开始编译内核源码。

接着选择开发板的型号,这里选择organgepo3b

然后选择kernel版本,目前支持两种版本,这里我们选择current,使用的是linux 6.6版本;

3.1.2 编译步骤

编译过程中会执行如下步骤:

  • 为宿主机ubuntu 22.04系统安装基础包,比如dialoguuiduuid-runtime等;(前面已经安装,这里会跳过)
  • 设置配置文件userpatches/config-example.conf
  • 为宿主机ubuntu 22.04系统安装构建依赖包,编译过程中需要使用到;(前面已经安装,这里会跳过)
  • 下载多个版本的交叉编译工具链;(前面已经安装,这里会跳过)
  • 从指定位置下载kernel源码;
  • 编译kernel源码并生成deb软件包。

3.2 编译信息

编译完整体日志如下:

点击查看代码
# 设置配置文件
[ o.k. ] Using config file [ /work/sambashare/rk3566/orangepi-build/userpatches/config-example.conf ]
[ .... ] Extension being added [ rkbin-tools :: added by ./build.sh:305 -> scripts/main.sh:386 -> scripts/configuration.sh:151 -> external/config/sources/families/rockchip-rk356x.conf:1 -> external/config/sources/families/include/rockchip64_common.inc:5 -> scripts/extensions.sh:0 ]
[ o.k. ] Extension manager [ processed 3 Extension Methods calls and 3 Extension Method implementations ]
[ o.k. ] Preparing [ host ]
[ o.k. ] Build host OS release [ jammy ]

# 安装构建依赖包
[ .... ] Installing build dependencies

[ o.k. ] Syncing clock [ cn.pool.ntp.org ]

# 下载交叉编译工具
[ o.k. ] Checking for external GCC compilers

# 下载kernel源码
[ o.k. ] Downloading sources
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/kernel orange-pi-6.6-rk35xx ]
[ .... ] Creating local copy
[ .... ] Fetching updates
remote: Enumerating objects: 151377, done.
remote: Counting objects: 100% (12546/12546), done.
remote: Compressing objects: 100% (11914/11914), done.
remote: Total 151377 (delta 1407), reused 632 (delta 632), pack-reused 138831
接收对象中: 100% (151377/151377), 373.78 MiB | 3.26 MiB/s, 完成.
处理 delta 中: 100% (38805/38805), 完成.
来自 https://github.com/orangepi-xunlong/linux-orangepi
 * branch                orange-pi-6.6-rk35xx -> FETCH_HEAD
 * [新分支]              orange-pi-6.6-rk35xx -> origin/orange-pi-6.6-rk35xx
[ .... ] Checking out
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/external/cache/sources/rkbin-tools master ]
[ .... ] Fetching updates
remote: Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
来自 https://github.com/armbian/rkbin
 * branch            master     -> FETCH_HEAD
[ .... ] Checking out
[ o.k. ] Installing [ rkbin-tools ]
[ o.k. ] Cleaning /work/sambashare/rk3566/orangepi-build/output/debs for [ orangepi3b current ]
[ o.k. ] Started patching process for [ kernel rockchip-rk356x-current ]
[ o.k. ] Looking for user patches in [ userpatches/kernel/rockchip-rk356x-current ]

# 编译kernel源码并生成deb软件包
[ o.k. ] Compiling current kernel [ 6.6.0-rc5 ]
[ o.k. ] Compiler version [ aarch64-none-linux-gnu-gcc 9.2.1 ]
[ o.k. ] Using kernel config file [ /work/sambashare/rk3566/orangepi-build/external/config/kernel/linux-rockchip-rk356x-current.config ]
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/confdata.o
  HOSTCC  scripts/kconfig/expr.o
  LEX     scripts/kconfig/lexer.lex.c
  YACC    scripts/kconfig/parser.tab.[ch]
  HOSTCC  scripts/kconfig/lexer.lex.o
  HOSTCC  scripts/kconfig/menu.o
  HOSTCC  scripts/kconfig/parser.tab.o
  HOSTCC  scripts/kconfig/preprocess.o
  HOSTCC  scripts/kconfig/symbol.o
  HOSTCC  scripts/kconfig/util.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#
  WRAP    arch/arm64/include/generated/uapi/asm/kvm_para.h
  WRAP    arch/arm64/include/generated/uapi/asm/errno.h
  WRAP    arch/arm64/include/generated/uapi/asm/ioctl.h
  WRAP    arch/arm64/include/generated/uapi/asm/ioctls.h
  WRAP    arch/arm64/include/generated/uapi/asm/ip
  .....
    LD [M]  net/qrtr/qrtr-tun.ko
  LD [M]  net/qrtr/qrtr-mhi.ko
[ .... ] Creating packages
  GEN     debian
dpkg-buildpackage --build=binary --no-pre-clean --unsigned-changes -r'fakeroot -u' -a$(cat debian/arch)
dpkg-buildpackage: info: 源码包 linux-6.6.0-rc5-rockchip-rk356x
dpkg-buildpackage: info: 源码版本 1.0.6
dpkg-buildpackage: info: source distribution jammy
dpkg-buildpackage: info: 源码修改者 Orange Pi <leeboby@aliyun.com>
dpkg-buildpackage: info: 主机架构 arm64
make KERNELRELEASE=6.6.0-rc5-rockchip-rk356x ARCH=arm64         KBUILD_BUILD_VERSION=1.0.6 -f ./Makefile
  CALL    scripts/checksyscalls.sh
  UPD     init/utsversion-tmp.h
  CC      init/version.o
  AR      init/built-in.a
  CHK     kernel/kheaders_data.tar.xz
  AR      built-in.a
  AR      vmlinux.a
  LD      vmlinux.o
  OBJCOPY modules.builtin.modinfo
  GEN     modules.builtin
  MODPOST Module.symvers
  UPD     include/generated/utsversion.h
  CC      init/version-timestamp.o
  LD      .tmp_vmlinux.kallsyms1
  NM      .tmp_vmlinux.kallsyms1.syms
  KSYMS   .tmp_vmlinux.kallsyms1.S
  AS      .tmp_vmlinux.kallsyms1.S
  LD      .tmp_vmlinux.kallsyms2
  NM      .tmp_vmlinux.kallsyms2.syms
  KSYMS   .tmp_vmlinux.kallsyms2.S
  AS      .tmp_vmlinux.kallsyms2.S
  LD      vmlinux
  NM      System.map
  SORTTAB vmlinux
  OBJCOPY arch/arm64/boot/Image
make KERNELRELEASE=6.6.0-rc5-rockchip-rk356x ARCH=arm64         KBUILD_BUILD_VERSION=1.0.6 -f ./Makefile intdeb-pkg
sh ./scripts/package/builddeb
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/rk3566-orangepi-3b.dtb
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-uart9-m2.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-uart7-m2.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-uart3-m0.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-i2c2-m1.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-i2c3-m0.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-i2c4-m0.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-pwm11-m1.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-pwm15-m1.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-spi3-m0-cs0-spidev.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-gpu.dtbo
  INSTALL debian/tmp/usr/lib/linux-image-6.6.0-rc5-rockchip-rk356x/rockchip/overlay/rk356x-fixup.scr
......
  INSTALL debian/tmp/lib/modules/6.6.0-rc5-rockchip-rk356x/kernel/net/hsr/hsr.ko
  INSTALL debian/tmp/lib/modules/6.6.0-rc5-rockchip-rk356x/kernel/net/nsh/nsh.ko
  INSTALL debian/tmp/lib/modules/6.6.0-rc5-rockchip-rk356x/kernel/net/qrtr/qrtr.ko
  INSTALL debian/tmp/lib/modules/6.6.0-rc5-rockchip-rk356x/kernel/net/qrtr/qrtr-tun.ko
  INSTALL debian/tmp/lib/modules/6.6.0-rc5-rockchip-rk356x/kernel/net/qrtr/qrtr-mhi.ko
  DEPMOD  debian/tmp/lib/modules/6.6.0-rc5-rockchip-rk356x
dpkg-deb: 正在 '../linux-image-current-rockchip-rk356x_1.0.6_arm64.deb' 中构建软件包 'linux-image-current-rockchip-rk356x'。
dpkg-deb: 正在 '../linux-dtb-current-rockchip-rk356x_1.0.6_arm64.deb' 中构建软件包 'linux-dtb-current-rockchip-rk356x'。
  HOSTCC  scripts/unifdef
  HDRINST usr/include/asm-generic/mman.h
  HDRINST usr/include/asm-generic/signal-defs.h
  HDRINST usr/include/asm-generic/ioctl.h
  HDRINST usr/include/asm-generic/errno.h
  HDRINST usr/include/asm-generic/shmbuf.h
 ......
   HDRINST usr/include/asm/sockios.h
  HDRINST usr/include/asm/socket.h
  HDRINST usr/include/asm/siginfo.h
  INSTALL debian/headertmp/usr/include
dpkg-deb: 正在 '../linux-libc-dev_1.0.6_arm64.deb' 中构建软件包 'linux-libc-dev'。
  CLEAN   init
  CLEAN   certs
  CLEAN   arch/arm64/boot
  CLEAN   crypto/asymmetric_keys
  CLEAN   arch/arm64/crypto
  CLEAN   arch/arm64/kernel/vdso
  CLEAN   arch/arm64/kvm/hyp/nvhe
  CLEAN   arch/arm64/kernel
  CLEAN   net/bpfilter
  CLEAN   lib/raid6
  CLEAN   arch/arm64/kvm
  CLEAN   kernel
  CLEAN   lib
  CLEAN   security/apparmor
  CLEAN   security/selinux
  CLEAN   security/tomoyo
  CLEAN   net/wireless
  CLEAN   fs/unicode
  CLEAN   usr/include
  CLEAN   drivers/firmware/efi/libstub
  CLEAN   usr
  CLEAN   drivers/scsi
  CLEAN   drivers/tty/vt
  CLEAN   drivers/video/logo
echo "WARNING: This driver is obsolete. Use http://github.com/lwfinger/rtw88.git instead"
  CLEAN   .
  CLEAN   modules.builtin modules.builtin.modinfo .vmlinux.export.c
patching file tools/include/tools/be_byteshift.h
patching file tools/include/tools/le_byteshift.h
dpkg-deb: 正在 '../linux-headers-current-rockchip-rk356x_1.0.6_arm64.deb' 中构建软件包 'linux-headers-current-rockchip-rk356x'。
dpkg-genchanges: info: binary-only upload (no source code included)
dpkg-buildpackage: info: binary-only upload (no source included)
[ o.k. ] Kernel build done [ @host ]
[ o.k. ] Target directory [ /work/sambashare/rk3566/orangepi-build/output/debs/ ]
[ o.k. ] File name [ linux-image-current-rockchip-rk356x_1.0.6_arm64.deb ]
[ o.k. ] Runtime [ 42 min ]
[ o.k. ] Repeat Build Options [ sudo ./build.sh  BOARD=orangepi3b BRANCH=current BUILD_OPT=kernel KERNEL_CONFIGURE=no  ]
3.2.1 kernel源码

在输出的日志信息中,我们可以看到kernel版本信息:

[ o.k. ] Compiling current kernel [ 6.6.0-rc5 ]

源码位于u-boot/orange-pi-6.6-rk35xx目录;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ ls kernel/orange-pi-6.6-rk35xx/
arch   COPYING  debian         fs       io_uring  Kconfig  LICENSES     mm              README   scripts   tools
block  CREDITS  Documentation  include  ipc       kernel   MAINTAINERS  Module.symvers  rust     security  usr
certs  crypto   drivers        init     Kbuild    lib      Makefile     net             samples  sound     virtb
3.2.2 交叉编译工具链

在输出的日志信息中,我们可以看到交叉编译工具链的版本;

[ o.k. ] Compiler version [ aarch64-none-linux-gnu-gcc 9.2.1 ]
3.2.3 内核配置文件

编译使用的内核配置文件为<SDK>/external/config/kernel/linux-rockchip-rk356x-current.config

[ o.k. ] Using kernel config file [ /work/sambashare/rk3566/orangepi-build/external/config/kernel/linux-rockchip-rk356x-current.config ]
3.2.4 kernel deb

在输出的日志信息中,我们可以看到kernel deb的构建信息;

dpkg-deb: 正在 '../linux-image-current-rockchip-rk356x_1.0.6_arm64.deb' 中构建软件包 'linux-image-current-rockchip-rk356x'。
dpkg-deb: 正在 '../linux-dtb-current-rockchip-rk356x_1.0.6_arm64.deb' 中构建软件包 'linux-dtb-current-rockchip-rk356x'。
dpkg-deb: 正在 '../linux-libc-dev_1.0.6_arm64.deb' 中构建软件包 'linux-libc-dev'。
dpkg-deb: 正在 '../linux-headers-current-rockchip-rk356x_1.0.6_arm64.deb' 中构建软件包 'linux-headers-current-rockchip-rk356x'。

编译生成的内核相关的deb包的路径:

[ o.k. ] Target directory [ /work/sambashare/rk3566/orangepi-build/output/debs/ ]
3.2.5 重复编译

重复编译kernel的命令,使用下面的命令无需通过图形界面选择,可以直接开始编译kernel

[ o.k. ] Repeat Build Options [ sudo ./build.sh  BOARD=orangepi3b BRANCH=current BUILD_OPT=kernel KERNEL_CONFIGURE=no  ]
3.2.6 关闭源码同步

orangepi-bulid编译系统编译kernel源码时首先会将kernel的源码和github服务器的kernel源码进行同步,所以如果想修改kernel的源码,首先需要关闭源码的下载更新功能,否则所作的修改都会被还原,方法如下,

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ vim userpatches/config-default.conf
IGNORE_UPDATES="yes"

即设置userpatches/config-default.conf中的IGNORE_UPDATES变量为yes

注意:需要完整编译过一次kernel后才能关闭这个功能,否则会提示找不到kernel的源码。

3.3 烧录测试

调试kernel代码时,可以使用下面的方法来更新Linux镜像中的kernel进行测试。

3.3.1 查看deb

编译生成的kernrl deb位于<SDK>/output/debs目录下,查看编译生成的内核相关的deb包:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ ll output/debs/
-rw-r--r-- 1 root sudo    20756  7月 10 16:24 linux-dtb-current-rockchip-rk356x_1.0.6_arm64.deb
-rw-r--r-- 1 root sudo 12937944  7月 10 16:24 linux-headers-current-rockchip-rk356x_1.0.6_arm64.deb
-rw-r--r-- 1 root sudo 40470560  7月 10 16:24 linux-image-current-rockchip-rk356x_1.0.6_arm64.deb
-rw-r--r-- 1 root sudo  1295212  7月 10 16:24 linux-libc-dev_1.0.6_arm64.deb

其中:

  • linux-dtb-current-rockchip-rk356x_1.0.6_arm64.deb:包含内核使用的dtb文件;
  • linux-headers-current-rockchip-rk356x_1.0.6_arm64.deb:包含内核头文件,用于开发其他软件或编译内核模块;
  • linux-image-current-rockchip-rk356x_1.0.6_arm64.deb:包含内核镜像和内核模块,用于安装和引导新的内核;
  • linux-libc-dev_1.0.6_arm64.deb:用于构建用户空间软件的头文件和静态库;

这些生成的debian包可以在 debian或基于debian的系统上安装和使用。

解压deb包,查看生成的linux-imagedeb包包含的文件;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ cd output/debs
root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs$ sudo mkdir test
root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs$ sudo cp linux-image-current-rockchip-rk356x_1.0.6_arm64.deb test
root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs$ cd test/
root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/test$ sudo dpkg -x linux-image-current-rockchip-rk356x_1.0.6_arm64.deb .
root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/test$ ls
boot  etc  lib  linux-image-current-rockchip-rk356x_1.0.6_arm64.deb  usr

解压后的文件如下所示:

root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/test$ tree -L 4
├── boot                  # 默认安装到/boot目录
│   ├── config-6.6.0-rc5-rockchip-rk356x   # 编译使用的内核配置文件
│   ├── System.map-6.6.0-rc5-rockchip-rk356x
│   └── vmlinuz-6.6.0-rc5-rockchip-rk356x  # 内核Image,可直接引导linux系统启
├── etc
│   └── kernel
│       ├── postinst.d
│       ├── postrm.d
│       ├── preinst.d
│       └── prerm.d
├── lib
│   └── modules          
│       └── 6.6.0-rc5-rockchip-rk356x   # 内核模块, 默认安装到/lib/modules/6.6.0-rc5-rockchip-rk356x目录下
│           ├── kernel
│           ├── modules.alias
│           ├── modules.alias.bin
│           ├── modules.builtin
│           ├── modules.builtin.alias.bin
│           ├── modules.builtin.bin
│           ├── modules.builtin.modinfo
│           ├── modules.dep
│           ├── modules.dep.bin
│           ├── modules.devname
│           ├── modules.order
│           ├── modules.softdep
│           ├── modules.symbols
│           └── modules.symbols.bin
└── usr
    ├── lib         
    │   └── linux-image-6.6.0-rc5-rockchip-rk356x      # 包含设备树
    │       └── rockchip             # 包含overlay目录以及rk3566-orangepi-3b.dtb	文件
    └── share
        └── doc
            └── linux-image-current-rockchip-rk356x
3.3.2 上传deb

将编译好的kerneldeb包上传到开发板的Linux系统中;

root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/u-boot$ scp linux-image-current-orangepi3b_1.0.6_arm64.deb root@192.168.0.100:/root
3.3.3 卸载旧包

然后登录到开发板,卸载已安装的kerneldeb包;

root@orangepi:~# apt purge -y linux-image-legacy-rockchip-rk356x
3.3.4 安装新包

再安装刚才上传的新的kerneldeb包;

root@orangepi:~# dpkg -i linux-image-current-rockchip-rk356x_1.0.6_arm64.deb

由于未指定安装目录, 默认会安装到系统的根目录的各个目录。

然后重启开发板,再查看内核相关的修改是否已生效;

root@orangepi:~# reboot

四、rootfs编译

4.1 编译rootfs

运行build.sh脚本,输入如下命令:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo ./build.sh
4.1.1 编译配置

选择Rootfs and all deb packages,然后回车;

接着选择开发板的型号,这里选择organgepo3b

然后选择目标kernel版本,这里我们选择current

然后选择Linux发行版的类型,这里我们选择bullseye Debian 11 Bullseye

然后选择镜像的类型,这里我们选择Image with console interface (server)

其中:

  • Image with console interface (server)表示服务器版的镜像,体积比较小;如果是编译服务器版的镜像,还可以选择编译Standard版本或者Minimal版本,Minimal版本预装的软件会比Standard版本少很多(没特殊需求请不要选择Minimal版本,因为很多东西默认没有预装,部分功能可能用不了);
  • Image with desktop environment表示带桌面的镜像,体积比较大;如果是编译桌面版本的镜像还需要选择桌面环境的类型,目前:
    • ubuntu Jammy主要维护XFCEGnome两种桌面;
    • ubuntu focal只维护XFCE桌面;
    • debian bullseye主要维护XFCEKDE桌面。

然后选择标准版本Standard image with console interface

注意:如果是桌面版的镜像,然后可以选择需要安装的额外的软件包,可以按下回车键直接跳过。

4.1.2 编译步骤

然后就会开始编译rootfs,编译过程中会执行如下步骤:

  • 为宿主机ubuntu 22.04系统安装基础包,比如dialoguuiduuid-runtime等;(前面已经安装,这里会跳过)
  • 设置配置文件userpatches/config-example.conf
  • 为宿主机ubuntu 22.04系统安装构建依赖包,编译过程中需要使用到;(前面已经安装,这里会跳过)
  • 下载多个版本的交叉编译工具链;(前面已经安装,这里会跳过)
  • 从指定位置下载Linux发行版基础包;
  • 配置并安装软件包;

4.2 编译信息

编译完整体日志如下:

点击查看代码
# 1. 设置配置文件userpatches/config-example.conf
[ o.k. ] Using config file [ /work/sambashare/rk3566/orangepi-build/userpatches/config-example.conf ]
[ .... ] Extension being added [ rkbin-tools :: added by ./build.sh:305 -> scripts/main.sh:386 -> scripts/configuration.sh:151 -> external/config/sources/families/rockchip-rk356x.conf:1 -> external/config/sources/families/include/rockchip64_common.inc:5 -> scripts/extensions.sh:0 ]
[ o.k. ] Extension manager [ processed 3 Extension Methods calls and 3 Extension Method implementations ]
[ o.k. ] Preparing [ host ]
[ o.k. ] Build host OS release [ jammy ]

# 2. 安装构建依赖包
[ .... ] Installing build dependencies
[ o.k. ] Syncing clock [ cn.pool.ntp.org ]

# 3. 下载交叉编译工具链
[ o.k. ] Checking for external GCC compilers

# 4. 下载源码
[ o.k. ] Downloading sources
# 4.1 下载rkbin-tools
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/external/cache/sources/rkbin-tools master ]
[ .... ] Up to date
[ o.k. ] Cleaning /work/sambashare/rk3566/orangepi-build/output/debs for [ orangepi3b current ]
[ o.k. ] Building deb [ orangepi-config ]
[ o.k. ] Building deb [ orangepi-zsh ]
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/external/cache/sources/oh-my-zsh master ]
[ .... ] Creating local copy
[ .... ] Fetching updates
remote: Enumerating objects: 2540, done.
remote: Counting objects: 100% (2540/2540), done.
remote: Compressing objects: 100% (1923/1923), done.
remote: Total 2540 (delta 763), reused 2101 (delta 583), pack-reused 0
接收对象中: 100% (2540/2540), 3.48 MiB | 2.46 MiB/s, 完成.
处理 delta 中: 100% (763/763), 完成.
来自 https://github.com/robbyrussell/oh-my-zsh
 * branch            master     -> FETCH_HEAD
 * [新分支]          master     -> origin/master
[ .... ] Checking out
# 4.2 下载evalcache
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/external/cache/sources/evalcache master ]
[ .... ] Creating local copy
[ .... ] Fetching updates
remote: Enumerating objects: 46, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 46 (delta 6), reused 5 (delta 5), pack-reused 36
展开对象中: 100% (46/46), 13.77 KiB | 66.00 KiB/s, 完成.
来自 https://github.com/mroth/evalcache
 * branch            master     -> FETCH_HEAD
 * [新分支]          master     -> origin/master
[ .... ] Checking out
# 4.3 下载firmware,并构建deb包
[ o.k. ] Building deb [ orangepi-plymouth-theme ]
[ o.k. ] Merging and packaging linux firmware [ @host ]
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/external/cache/sources/orangepi-firmware-git master ]
[ .... ] Creating local copy
[ .... ] Fetching updates
remote: Enumerating objects: 590, done.
remote: Counting objects: 100% (590/590), done.
remote: Compressing objects: 100% (420/420), done.
remote: Total 590 (delta 177), reused 555 (delta 142), pack-reused 0
接收对象中: 100% (590/590), 22.21 MiB | 1.68 MiB/s, 完成.
处理 delta 中: 100% (177/177), 完成.
来自 https://github.com/orangepi-xunlong/firmware
 * branch            master     -> FETCH_HEAD
 * [新分支]          master     -> origin/master
[ .... ] Checking out
[ o.k. ] Building firmware package [ orangepi-firmware_1.0.6_all ]
# 4.4 创建BSP包,构建rootfs镜像
[ o.k. ] Creating board support package for CLI [ orangepi-bsp-cli-orangepi3b ]
[ .... ] Adding files from [ /work/sambashare/rk3566/orangepi-build/external/config/optional/boards/orangepi3b/_packages/bsp-cli ]
[ o.k. ] Starting rootfs and image building process for [ current orangepi3b bullseye null null no ]
[ o.k. ] local not found [ Creating new rootfs cache for bullseye ]
# 阶段1
[ o.k. ] Installing base system [ Stage 1/2 ]
I: Retrieving InRelease
I: Checking Release signature
I: Valid Release signature (key id A4285295FC7B1A81600062A9605C66F00D6C9793)
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
I: Checking component main on http://repo.huaweicloud.com/debian...
I: Retrieving adduser 3.118+deb11u1
I: Validating adduser 3.118+deb11u1
I: Retrieving apt 2.2.4
I: Validating apt 2.2.4
I: Retrieving apt-utils 2.2.4
I: Validating apt-utils 2.2.4
I: Retrieving base-files 11.1+deb11u10
I: Validating base-files 11.1+deb11u10
I: Retrieving base-passwd 3.5.51
I: Validating base-passwd 3.5.51
I: Retrieving bash 5.1-2+deb11u1
I: Validating bash 5.1-2+deb11u1
I: Retrieving bsdutils 1:2.36.1-8+deb11u2
I: Validating bsdutils 1:2.36.1-8+deb11u2
......
# 阶段2
[ o.k. ] Installing base system [ Stage 2/2 ]
I: Installing core packages...
I: Unpacking required packages...
I: Unpacking adduser...
I: Unpacking apt...
I: Unpacking base-files...
I: Unpacking base-passwd...
I: Unpacking bash...
......

I: Configuring gnupg...
I: Configuring libc-bin...
I: Configuring ca-certificates...
I: Configuring initramfs-tools...
I: Base system installed successfully.
# 在根文件系统配置和安装软件包
[ o.k. ] Diverting [ initctl/start-stop-daemon ]
[ o.k. ] Configuring locales [ en_US.UTF-8 ]
Generating locales (this might take a while)...
  en_US.UTF-8... done
Generation complete.
The keyboard is in some unknown mode
Changing to the requested mode may make your keyboard unusable, please use -f to force the change.
[ o.k. ] Updating package list [ bullseye ]
Hit:1 https://repo.huaweicloud.com/debian bullseye InRelease
Get:2 https://repo.huaweicloud.com/debian bullseye-updates InRelease [44.1 kB]
Get:3 https://repo.huaweicloud.com/debian bullseye-backports InRelease [49.0 kB]
Get:4 https://repo.huaweicloud.com/debian-security bullseye-security InRelease [48.4 kB]
Get:5 https://repo.huaweicloud.com/debian bullseye/main armhf Packages [7840 kB]
Get:6 https://repo.huaweicloud.com/debian bullseye/main Translation-en [6236 kB]
......
Fetched 16.6 MB in 10s (1681 kB/s)
Reading package lists...
[ o.k. ] Upgrading base packages [ Orange Pi ]
Reading package lists...
Building dependency tree...
Calculating upgrade...
The following packages will be upgraded:
  libgssapi-krb5-2 libk5crypto3 libkrb5-3 libkrb5support0
4 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 682 kB of archives.
After this operation, 0 B of additional disk space will be used.
Get:1 https://repo.huaweicloud.com/debian-security bullseye-security/main arm64 libk5crypto3 arm64 1.18.3-6+deb11u5 [115 kB]
Get:2 https://repo.huaweicloud.com/debian-security bullseye-security/main arm64 libkrb5support0 arm64 1.18.3-6+deb11u5 [65.1 kB]
Get:3 https://repo.huaweicloud.com/debian-security bullseye-security/main arm64 libkrb5-3 arm64 1.18.3-6+deb11u5 [347 kB]
Get:4 https://repo.huaweicloud.com/debian-security bullseye-security/main arm64 libgssapi-krb5-2 arm64 1.18.3-6+deb11u5 [156 kB]
Fetched 682 kB in 1s (1086 kB/s)
(Reading database ... 11389 files and directories currently installed.)
Preparing to unpack .../libk5crypto3_1.18.3-6+deb11u5_arm64.deb ...
Unpacking libk5crypto3:arm64 (1.18.3-6+deb11u5) over (1.18.3-6+deb11u4) ...
Setting up libk5crypto3:arm64 (1.18.3-6+deb11u5) ...
(Reading database ... 11389 files and directories currently installed.)
Preparing to unpack .../libkrb5support0_1.18.3-6+deb11u5_arm64.deb ...
Unpacking libkrb5support0:arm64 (1.18.3-6+deb11u5) over (1.18.3-6+deb11u4) ...
Setting up libkrb5support0:arm64 (1.18.3-6+deb11u5) ...
(Reading database ... 11389 files and directories currently installed.)
Preparing to unpack .../libkrb5-3_1.18.3-6+deb11u5_arm64.deb ...
Unpacking libkrb5-3:arm64 (1.18.3-6+deb11u5) over (1.18.3-6+deb11u4) ...
Setting up libkrb5-3:arm64 (1.18.3-6+deb11u5) ...
(Reading database ... 11389 files and directories currently installed.)
Preparing to unpack .../libgssapi-krb5-2_1.18.3-6+deb11u5_arm64.deb ...
Unpacking libgssapi-krb5-2:arm64 (1.18.3-6+deb11u5) over (1.18.3-6+deb11u4) ...
Setting up libgssapi-krb5-2:arm64 (1.18.3-6+deb11u5) ...
Processing triggers for libc-bin (2.31-13+deb11u10) ...
[ o.k. ] Installing the main packages for [ Orange Pi ]
Reading package lists...
Building dependency tree...
Reading state information...
ca-certificates is already the newest version (20210119).
console-setup is already the newest version (1.205).
keyboard-configuration is already the newest version (1.205).
crda is already the newest version (4.14+git20191112.9856751-1).
haveged is already the newest version (1.9.14-1).
initramfs-tools is already the newest version (0.140).
iw is already the newest version (5.9-3).
linux-base is already the newest version (4.6).
sudo is already the newest version (1.9.5p2-3+deb11u1).
libpam-systemd is already the newest version (247.3-7+deb11u5).
wireless-regdb is already the newest version (2022.04.08-2~deb11u1).
The following additional packages will be installed:
  aptitude-common autoconf autotools-dev bind9-dnsutils bind9-host bind9-libs binutils binutils-aarch64-linux-gnu binutils-common
  bsdextrautils cpp cpp-10 dctrl-tools distro-info-data dpkg-dev file fontconfig fontconfig-config fonts-cantarell
  fonts-dejavu-core fuse g++ g++-10 gcc gcc-10 gir1.2-glib-2.0 gir1.2-packagekitglib-1.0 git-man groff-base iso-codes keyutils
  libapt-pkg-perl libasan6 libasound2 libasound2-data libatomic1 libatopology2 libbinutils libbluetooth3 libboost-iostreams1.74.0
  libbrotli1 libc-dev-bin libc6-dev libcaca0 libcairo2 libcbor0 libcc1-0 libcpufreq0 libcrypt-dev libctf-nobfd0 libctf0
  libcurl3-gnutls libcurl4 libcwidget4 libdaemon0 libdatrie1 libdpkg-perl libdrm-common libdrm2 libedit2 liberror-perl
  libevent-2.1-7 libexporter-tiny-perl libfdt1 libfftw3-single3 libfido2-1 libfontconfig1 libfreetype6 libfribidi0 libfstrm0
  libgcc-10-dev libgdbm-compat4 libgdbm6 libgirepository-1.0-1 libglib2.0-0 libgomp1 libgpm2 libgraphite2-3 libharfbuzz0b libi2c0
  libicu67 libip6tc2 libiperf0 libisl23 libitm1 libiw30 libjansson4 libjq1 liblist-moreutils-perl liblist-moreutils-xs-perl
  liblmdb0 liblsan0 liblzo2-2 libmagic-mgc libmagic1 libmaxminddb0 libmm-glib0 libmpc3 libmpdec3 libmpfr6 libncurses6 libndp0
  libnetfilter-conntrack3 libnetplan0 libnfnetlink0 libnfsidmap2 libnftnl11 libnghttp2-14 libnl-route-3-200 libnm0 libnsl-dev
  libntfs-3g883 libonig5 libpackagekit-glib2-18 libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libparted2 libpcap0.8 libpci3
......
0 upgraded, 321 newly installed, 0 to remove and 0 not upgraded.
Need to get 167 MB of archives.
After this operation, 662 MB of additional disk space will be used.
Get:1 https://repo.huaweicloud.com/debian bullseye/main arm64 bsdextrautils arm64 2.36.1-8+deb11u2 [142 kB]
Get:2 https://repo.huaweicloud.com/debian bullseye/main arm64 libuchardet0 arm64 0.0.7-1 [67.9 kB]
Get:3 https://repo.huaweicloud.com/debian bullseye/main arm64 groff-base arm64 1.22.4-6 [883 kB]
Get:4 https://repo.huaweicloud.com/debian bullseye/main arm64 libgdbm6 arm64 1.19-2 [64.0 kB]
Get:5 https://repo.huaweicloud.com/debian bullseye/main arm64 libpipeline1 arm64 1.5.3-1 [33.0 kB]
Get:6 https://repo.huaweicloud.com/debian bullseye/main arm64 man-db arm64 2.9.4-2 [1336 kB]
Get:7 https://repo.huaweicloud.com/debian bullseye/main arm64 perl-modules-5.32 all 5.32.1-4+deb11u3 [2823 kB]
......
Fetched 167 MB in 1min 43s (1617 kB/s)
Extracting templates from packages: 100%
Preconfiguring packages ...
Selecting previously unselected package bsdextrautils.
(Reading database ... 11389 files and directories currently installed.)
Preparing to unpack .../00-bsdextrautils_2.36.1-8+deb11u2_arm64.deb ...
Unpacking bsdextrautils (2.36.1-8+deb11u2) ...
Selecting previously unselected package libuchardet0:arm64.
Preparing to unpack .../01-libuchardet0_0.0.7-1_arm64.deb ...
Unpacking libuchardet0:arm64 (0.0.7-1) ...
Selecting previously unselected package groff-base.
......
Setting up libpython2.7-stdlib:arm64 (2.7.18-8+deb11u1) ...
Setting up liberror-perl (0.17029-1) ...
Setting up command-not-found (20.10.1-1+deb11u1) ...
You need to run 'update-command-not-found' as root to update the cache.
Setting up git (1:2.30.2-1+deb11u2) ...
Setting up plymouth-themes (0.9.5-3) ...
update-initramfs: deferring update (trigger activated)
Setting up build-essential (12.9) ...
Setting up python2.7 (2.7.18-8+deb11u1) ...
Setting up libpython2-stdlib:arm64 (2.7.18-3) ...
Setting up python2 (2.7.18-3) ...
Setting up python-is-python2 (2.7.18-9) ...
Processing triggers for libc-bin (2.31-13+deb11u10) ...
Processing triggers for dbus (1.12.28-0+deb11u1) ...
Processing triggers for initramfs-tools (0.140) ...
Processing triggers for resolvconf (1.87) ...
[ o.k. ] Uninstall packages
[ o.k. ] Purging residual packages for [ Orange Pi ]
Reading package lists...
Building dependency tree...
Reading state information...
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 0 个软件包未被升级。
[ o.k. ] Free SD cache [ 12% ]
[ o.k. ] Mount point
[ o.k. ] Ending debootstrap process and preparing cache [ bullseye ]
[ o.k. ] Unmounting [ /work/sambashare/rk3566/orangepi-build/.tmp/rootfs-f2463abf-3ed3-479f-8d73-3219cd77ff42 ]
bullseye-cli-arm64.0ed...079.tar.lz4: 1.03GiB [61.5MiB/s] [===================================================================] 106%
[ o.k. ] Rootfs build done [ @host ]
[ o.k. ] Target directory [ /work/sambashare/rk3566/orangepi-build/external/cache/rootfs ]
[ o.k. ] File name [ bullseye-cli-arm64.0edbcd2a28a8ca68562ecdfac789d079.tar.lz4 ]
4.2.1 rootfs类型

在输出的日志信息中,我们可以看到rootfs类型信息;

[ o.k. ] local not found [ Creating new rootfs cache for bullseye ]
4.2.2 rootfs

在制作roofs过程中,.tmp/rootfs-f2463abf-3ed3-479f-8d73-3219cd77ff42作为根文件系统的挂载目录;

[ o.k. ] Mount point
[ o.k. ] Ending debootstrap process and preparing cache [ bullseye ]
[ o.k. ] Unmounting [ /work/sambashare/rk3566/orangepi-build/.tmp/rootfs-f2463abf-3ed3-479f-8d73-3219cd77ff42 ]

在输出的日志信息中,我们可以看到编译生成的rootfs压缩包的存放路径;

[ o.k. ] Target directory [ /work/sambashare/rk3566/orangepi-build/external/cache/rootfs ]

编译生成的rootfs压缩包的名字;

[ o.k. ] File name [ bullseye-cli-arm64.0edbcd2a28a8ca68562ecdfac789d079.tar.lz4 ]

查看编译生成的rootfs压缩包;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ ll external/cache/rootfs/
-rw-rw-r-- 1 root root 450204218  7月 10 17:21 bullseye-cli-arm64.0edbcd2a28a8ca68562ecdfac789d079.tar.lz4
-rw-rw-r-- 1 root root         0  7月 10 17:21 bullseye-cli-arm64.0edbcd2a28a8ca68562ecdfac789d079.tar.lz4.current
-rw-rw-r-- 1 root root      5871  7月 10 17:21 bullseye-cli-arm64.0edbcd2a28a8ca68562ecdfac789d079.tar.lz4.list

bullseye-cli-arm64.0edbcd2a28a8ca68562ecdfac789d079.tar.lz4rootfs的压缩包,名字各字段的含义为:

  • bullseye表示rootfsLinux发行版的类型;
  • xfce表示rootfs为桌面版的类型,cli则表示服务器版类型;
  • arm64表示rootfs的架构类型;
  • arm64.0edbcd2a28a8ca68562ecdfac789d079是由rootfs安装的所有软件包的包名生成的MD5哈希值,只要没有修改rootfs安装的软件包的列表,那么这个值就不会变,编译脚本会通过这个MD5哈希值来判断是否需要重新编译rootfs

bullseye-cli-arm64.0edbcd2a28a8ca68562ecdfac789d079.tar.lz4.list列出了rootfs安装的所有软件包的包名(这里总共有514个包);

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ cat external/cache/rootfs/bullseye-cli-arm64.0edbcd2a28a8ca68562ecdfac789d079.tar.lz4.list
adduser
alsa-utils
apt
apt-file
apt-utils
aptitude
aptitude-common
autoconf
automake
....

如果需要的rootfsexternal/cache/rootfs下已经存在,那么再次编译rootfs就会直接跳过编译过程,不会重新开始编译,编译镜像的时候也会去external/cache/rootfs下查找是否已经有缓存可用的rootfs,如果有就直接使用,这样可以节省大量的下载编译时间。

五、Linux镜像编译

由于前面我们已经分别进行了u-bootkernelrootfs的编译,为了加速编译过程,这里我们直接关闭源码同步功能。

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo vim userpatches/config-default.conf
IGNORE_UPDATES="yes"

5.1 编译

运行build.sh脚本,输入如下命令:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo ./build.sh
5.1.1 编译配置

选择Full OS image for flashing,然后回车;

然后会提示是否需要显示内核配置界面,这里不需要修改内核配置;

接着选择开发板的型号,这里选择organgepo3b

然后选择目标kernel版本,这里我们选择current

然后选择Linux发行版的类型,这里我们选择bullseye Debian 11 Bullseye

然后选择镜像的类型,这里我们选择Image with console interface (server)

然后选择标准版本Standard image with console interface

5.1.2 编译步骤

然后就会开始编译,我们可以将编译过程分为以下几个阶段:

(1) 准备阶段:

  • 为宿主机ubuntu 22.04系统安装基础包,比如dialoguuiduuid-runtime等;(前面已经安装,这里会跳过);
  • 设置配置文件userpatches/config-example.conf
  • 为宿主机ubuntu 22.04系统安装构建依赖包,编译过程中需要使用到;(前面已经安装,这里会跳过)
  • 下载多个版本的交叉编译工具链;(前面已经安装,这里会跳过);
  • 下载u-bootLinux内核等源码;(如果已经缓存,则只更新代码);

(2) 源码编译,生成deb包;

  • 编译u-boot源码,生成u-bootdeb包;
  • 编译Linux kernel源码,生成Linux kernel相关的deb包;
  • 制作Linux firmwaredeb包;
  • 制作orangepi-config工具的deb包;
  • 制作板级支持的deb包,如果是编译desktop版镜像,还会制作desktop相关的deb包;

(3) 制作根文件系统;

  • 检查rootfs是否已经缓存,如果没有缓存,则重新制作rootfs,如果已经缓存,则直接解压使用;
  • 安装前面生成的deb包到rootfs中;
  • 对不同的开发板和不同类型镜像做一些特定的设置,如预装额外的软件包,修改系统配置等;

(4) 制作镜像文件;

  • 制作镜像文件,并格式化分区,rootfs分区类型为ext4bootfs分区类型为vfat
  • 再将配置好的rootfs拷贝到镜像的分区中;
  • 然后更新initramfs
  • 最后将u-bootbin文件通过dd命令写入到镜像中。
5.1.3 编译日志

编译完整体日志如下:

点击查看代码
# 设置配置文件
[ o.k. ] Using config file [ /work/sambashare/rk3566/orangepi-build/userpatches/config-example.conf ]
[ .... ] Extension being added [ rkbin-tools :: added by ./build.sh:305 -> scripts/main.sh:386 -> scripts/configuration.sh:151 -> external/config/sources/families/rockchip-rk356x.conf:1 -> external/config/sources/families/include/rockchip64_common.inc:5 -> scripts/extensions.sh:0 ]
[ o.k. ] Extension manager [ processed 3 Extension Methods calls and 3 Extension Method implementations ]
[ o.k. ] Preparing [ host ]
[ o.k. ] Build host OS release [ jammy ]

# 安装构建依赖包
[ .... ] Installing build dependencies
[ o.k. ] Syncing clock [ cn.pool.ntp.org ]

# 下载交叉编译工具
[ o.k. ] Checking for external GCC compilers

# 下载u-boot源码 (如果配置了IGNORE_UPDATES="yes",这一步跳过)
[ o.k. ] Downloading sources
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/u-boot v2017.09-rk3588 ]
[ .... ] Fetching updates
remote: Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
来自 https://github.com/orangepi-xunlong/u-boot-orangepi
 * branch              v2017.09-rk3588 -> FETCH_HEAD
[ .... ] Checking out

# 下载kernel源码 (如果配置了IGNORE_UPDATES="yes",这一步跳过)
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/kernel orange-pi-6.6-rk35xx ]
[ .... ] Fetching updates
remote: Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
来自 https://github.com/orangepi-xunlong/linux-orangepi
 * branch                orange-pi-6.6-rk35xx -> FETCH_HEAD
[ .... ] Checking out
[ o.k. ] Checking git sources [ /work/sambashare/rk3566/orangepi-build/external/cache/sources/rk35xx_packages rk35xx_packages ]
[ .... ] Creating local copy
......

[ o.k. ] Cleaning /work/sambashare/rk3566/orangepi-build/output/debs for [ orangepi3b current ]

# 编译u-boot和生成deb包
[ o.k. ] Compiling u-boot [ v2017.09 ]
[ o.k. ] Compiler version [ aarch64-none-linux-gnu-gcc 9.2.1 ]
[ o.k. ] Started patching process for [ u-boot rockchip-rk356x-orangepi3b-current ]
[ o.k. ] Looking for user patches in [ userpatches/u-boot/u-boot-rockchip-rk356x ]
#
# configuration written to .config
#
scripts/kconfig/conf  --silentoldconfig Kconfig
#
# configuration written to .config
#
  CHK     include/config.h
  CFG     u-boot.cfg
  GEN     include/autoconf.mk.dep
  CFG     spl/u-boot.cfg
  CFG     tpl/u-boot.cfg
  GEN     tpl/include/autoconf.mk
  GEN     include/autoconf.mk
  GEN     spl/include/autoconf.mk
  CHK     include/config/uboot.release
  CHK     include/generated/timestamp_autogenerated.h
./"arch/arm/mach-rockchip/make_fit_atf.sh" \
arch/arm/dts/rk3566-orangepi-3b.dtb > u-boot.its
  UPD     include/generated/timestamp_autogenerated.h
  CHK     include/generated/version_autogenerated.h
......
  LD      drivers/usb/gadget/built-in.o
  CC      lib/display_options.o
  LD      lib/built-in.o
  LD      u-boot
  OBJCOPY u-boot-nodtb.bin
start=$(ccache aarch64-none-linux-gnu-nm u-boot | grep __rel_dyn_start | cut -f 1 -d ' '); end=$(ccache aarch64-none-linux-gnu-nm u-boot | grep __rel_dyn_end | cut -f 1 -d ' '); tools/relocate-rela u-boot-nodtb.bin 0x00a00000 $start $end
make[2]: “arch/arm/dts/rk3566-orangepi-3b.dtb”已是最新。
  COPY    u-boot.dtb
  MKIMAGE u-boot.itb
  CC      spl/common/spl/spl.o
  CC      spl/arch/arm/cpu/armv8/fwcall.o
  LD      spl/arch/arm/cpu/armv8/built-in.o
  CC      spl/lib/display_options.o
  LD      spl/lib/built-in.o
  LD      spl/common/spl/built-in.o
  LD      spl/u-boot-spl
  OBJCOPY spl/u-boot-spl-nodtb.bin
  CAT     spl/u-boot-spl-dtb.bin
  COPY    spl/u-boot-spl.bin
Image Type:   Rockchip RK35 boot image
Init Data Size: 59392 bytes
Boot Data Size: 256000 bytes
记录了0+0 的读入
记录了0+0 的写出
0字节已复制,0.000133582 s,0.0 kB/s
警告: 所产生的分区没有适当为获得最佳性能而对齐:64s % 2048s != 0s
警告: 所产生的分区没有适当为获得最佳性能而对齐:1024s % 2048s != 0s
记录了620+0 的读入
记录了620+0 的写出
317440字节(317 kB,310 KiB)已复制,0.016783 s,18.9 MB/s
记录了3020+0 的读入
记录了3020+0 的写出
1546240字节(1.5 MB,1.5 MiB)已复制,0.0714901 s,21.6 MB/s
Image Type:   Rockchip RK35 boot image
Init Data Size: 59392 bytes
Boot Data Size: 256000 bytes
[ o.k. ] Building deb [ linux-u-boot-current-orangepi3b_1.0.6_arm64.deb ]

# 编译kernel和生成deb包
[ o.k. ] Started patching process for [ kernel rockchip-rk356x-current ]
[ o.k. ] Looking for user patches in [ userpatches/kernel/rockchip-rk356x-current ]
[ o.k. ] Compiling current kernel [ 6.6.0-rc5 ]
[ o.k. ] Compiler version [ aarch64-none-linux-gnu-gcc 9.2.1 ]
[ o.k. ] Using kernel config file [ /work/sambashare/rk3566/orangepi-build/external/config/kernel/linux-rockchip-rk356x-current.config ]
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/confdata.o
  HOSTCC  scripts/kconfig/expr.o
  LEX     scripts/kconfig/lexer.lex.c
  YACC    scripts/kconfig/parser.tab.[ch]
  HOSTCC  scripts/kconfig/lexer.lex.o
  HOSTCC  scripts/kconfig/menu.o
  HOSTCC  scripts/kconfig/parser.tab.o
  HOSTCC  scripts/kconfig/preprocess.o
  HOSTCC  scripts/kconfig/symbol.o
  HOSTCC  scripts/kconfig/util.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#
  SYNC    include/config/auto.conf.cmd
  HOSTCC  scripts/dtc/flattree.o
  HOSTCC  scripts/dtc/fstree.o
  HOSTCC  scripts/dtc/dtc.o
  HOSTCC  scripts/dtc/livetree.o
  HOSTCC  scripts/dtc/data.o
  HOSTCC  scripts/dtc/treesource.o
  HOSTCC  scripts/dtc/srcpos.o
  HOSTCC  scripts/dtc/util.o
  LEX     scripts/dtc/dtc-lexer.lex.c
  HOSTCC  scripts/dtc/checks.o
......
  CLEAN   .
  CLEAN   modules.builtin modules.builtin.modinfo .vmlinux.export.c
patching file tools/include/tools/be_byteshift.h
patching file tools/include/tools/le_byteshift.h
dpkg-deb: 正在 '../linux-headers-current-rockchip-rk356x_1.0.6_arm64.deb' 中构建软件包 'linux-headers-current-rockchip-rk356x'。
dpkg-genchanges: info: binary-only upload (no source code included)
dpkg-buildpackage: info: binary-only upload (no source included)

# 制作Linux firmware、orangepi-config等的deb包
[ o.k. ] Building deb [ orangepi-config ]
[ o.k. ] Building deb [ orangepi-zsh ]
[ o.k. ] Building deb [ orangepi-plymouth-theme ]
[ o.k. ] Merging and packaging linux firmware [ @host ]
[ o.k. ] Building firmware package [ orangepi-firmware_1.0.6_all ]

# 制作板级支持的deb包
[ o.k. ] Creating board support package for CLI [ orangepi-bsp-cli-orangepi3b ]
[ .... ] Adding files from [ /work/sambashare/rk3566/orangepi-build/external/config/optional/boards/orangepi3b/_packages/bsp-cli ]
[ o.k. ] Starting rootfs and image building process for [ current orangepi3b bullseye null null no ]
[ o.k. ] Extracting bullseye-cli-arm64.0ed...079.tar.lz4 [ 0 days old ]
[ .... ] bullseye-cli-arm64.0ed...079.tar.lz4:  429MiB [ 132MiB/s] [=========================================================>] 100%
[ o.k. ] Applying distribution specific tweaks for [ bullseye ]
[ o.k. ] Applying common tweaks
[ .... ] Cleaning [ package lists ]
[ .... ] Updating [ package lists ]
[ .... ] Temporarily disabling [ initramfs-tools hook for kernel ]

# 安装前面生成的deb包到rootfs中
[ .... ] Installing PACKAGE_LIST_FAMILY packages [ ethtool can-utils ]
[ .... ] Removing PACKAGE_LIST_FAMILY_REMOVE packages [ mpv ]
[ .... ] Installing [ linux-u-boot-current-orangepi3b_1.0.6_arm64.deb ]
[ .... ] Installing [ linux-image-current-rockchip-rk356x_1.0.6_arm64.deb ]
[ .... ] Installing [ linux-dtb-current-rockchip-rk356x_1.0.6_arm64.deb ]
[ .... ] Installing [ orangepi-bsp-cli-orangepi3b_1.0.6_arm64.deb ]
[ .... ] Installing [ orangepi-firmware_1.0.6_all.deb ]
[ .... ] Installing [ orangepi-config_1.0.6_all.deb ]
[ .... ] Installing [ orangepi-zsh_1.0.6_all.deb ]
[ .... ] Installing [ wiringpi_2.53.deb ]
cp: 对 '/work/sambashare/rk3566/orangepi-build/external/cache/sources/wiringOP/next' 调用 stat 失败: 没有那个文件或目录
cp: 对 '/work/sambashare/rk3566/orangepi-build/external/cache/sources/wiringOP-Python/next' 调用 stat 失败: 没有那个文件或目录
[ o.k. ] Enabling serial console [ ttyS2 ]
[ o.k. ] Building kernel splash logo [ bullseye ]
[ .... ] Installing extras-buildpkgs [  hostapd htop ]
[ o.k. ] Calling image customization script [ customize-image.sh ]
[ o.k. ] No longer needed packages [ purge ]
[ o.k. ] Unmounting [ /work/sambashare/rk3566/orangepi-build/.tmp/rootfs-59546f77-d80f-49ca-a7a7-ac71269c56a5 ]
# 制作镜像文件,并格式化分区,rootfs分区类型为ext4,bootfs分区类型为vfat;
[ o.k. ] Preparing image file for rootfs [ orangepi3b bullseye ]
[ o.k. ] Current rootfs size [ 2063 MiB ]
[ o.k. ] Creating blank image for rootfs [ 4056 MiB ]
[ .... ] dd: 3.96GiB [ 126MiB/s] [===========================================================================================>] 100%
[ o.k. ] Creating partitions [ /boot: fat root: ext4 ]
[ .... ] Creating rootfs [ ext4 on /dev/loop18p2 ]
[ .... ] Creating /boot [ fat on /dev/loop18p1 ]
[ .... ] Copying files to [ / ]
[ .... ] Copying files to [ /boot ]
# 更新initramfs
[ .... ] Updating initramfs... [ update-initramfs -uv -k 6.6.0-rc5-rockchip-rk356x ]
[ o.k. ] Updated initramfs. [ for details see: /work/sambashare/rk3566/orangepi-build/output/debug/install.log ]
[ .... ] Re-enabling [ initramfs-tools hook for kernel ]
[ o.k. ] Unmounting [ /work/sambashare/rk3566/orangepi-build/.tmp/mount-59546f77-d80f-49ca-a7a7-ac71269c56a5/ ]
[ o.k. ] Free SD cache [ 24% ]
[ o.k. ] Mount point [ 73% ]
# 将u-boot的bin文件通过dd命令写入到镜像中
[ o.k. ] Writing U-boot bootloader [ /dev/loop18 ]
[ o.k. ] SHA256 calculating [ Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img ]
[ o.k. ] Done building [ /work/sambashare/rk3566/orangepi-build/output/images/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img ]
[ o.k. ] Runtime [ 33 min ]
[ o.k. ] Repeat Build Options [ sudo ./build.sh  BOARD=orangepi3b BRANCH=current BUILD_OPT=image RELEASE=bullseye BUILD_MINIMAL=no BUILD_DESKTOP=no KERNEL_CONFIGURE=no COMPRESS_OUTPUTIMAGE=sha,gpg,img  ]
5.1.4 重复编译

重复编译Linux镜像的命令,使用下面的命令无需通过图形界面选择,可以直接开始编译Linux镜像

[ o.k. ] Repeat Build Options [ sudo ./build.sh  BOARD=orangepi3b BRANCH=current BUILD_OPT=image RELEASE=bullseye BUILD_MINIMAL=no BUILD_DESKTOP=no KERNEL_CONFIGURE=no COMPRESS_OUTPUTIMAGE=sha,gpg,img  ]

5.2 编译输出

查看编译输出目录文件;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ tree output -L 3
output
├── config
├── debs   # 编译生成的deb包
│   ├── bullseye
│   │   └── orangepi-bsp-cli-orangepi3b_1.0.6_arm64.deb         #  板级支持的deb包
│   ├── extra         # 额外包,当前目录为空
│   ├── linux-dtb-current-rockchip-rk356x_1.0.6_arm64.deb       #  内核编译生成
│   ├── linux-headers-current-rockchip-rk356x_1.0.6_arm64.deb   #  内核编译生成
│   ├── linux-image-current-rockchip-rk356x_1.0.6_arm64.deb     #  内核编译生成
│   ├── linux-libc-dev_1.0.6_arm64.deb                          #  内核编译生成 
│   ├── orangepi-config_1.0.6_all.deb          # orangepi-config deb包;
│   ├── orangepi-firmware_1.0.6_all.deb        # Linux firmware deb包
│   ├── orangepi-plymouth-theme_1.0.6_all.deb  # orangepi-plymouth-themedeb包
│   ├── orangepi-zsh_1.0.6_all.deb             # orangepi-zsh deb包
│   ├── test
│   │   ├── boot
│   │   ├── etc
│   │   ├── lib
│   │   └── usr
│   └── u-boot
│       ├── linux-u-boot-current-orangepi3b_1.0.6_arm64.deb    # u-boot编译生成
│       └── usr
├── debug           # 编译日志信息,保留近7天
│   ├── compilation.log
│   ├── compiler.log
│   ├── debootstrap-list.log
│   ├── debootstrap.log
│   ├── extensions.log
│   ├── installed-packages-bullseye.list
│   ├── install.log
│   ├── logs-10_07_2024-17_40_27.tgz
│   ├── logs-10_07_2024-17_45_03.tgz
│   ├── logs-.tgz
│   ├── output.log
│   ├── potential-paths.log
│   └── timestamp
├── images
│   └── Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5   # Linux镜像
│       ├── Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img
│       └── Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img.sha
└── patch

其中:

  • debs目录存放的是编译出来的deb包,有u-boolinux kernelLinux firmwareorangepi-config等;
  • debug:编译过程输出的日志信息;
5.2.1 Linux镜像

编译生成的Linux镜像的存放在output/images/目录下;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ ll output/images/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5/
-rw-rw-r-- 1 root root 4253024256  7月 10 18:30 Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img
-rw-rw-r-- 1 root root        125  7月 10 18:30 Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img.sha

可以看到编译生成的统一镜像大概有4.2GB,这个镜像是可以直接用来制作SD启动卡的。

5.2.2 BSP支持包

output/deb2目录下有大量的deb包,其中有一个比较重要并且我们之前并没有提及到的就是orangepi-bsp-cli-orangepi3b_1.0.6_arm64.deb,解压deb包;

root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/bullseye$ sudo dpkg -x orangepi-bsp-cli-orangepi3b_1.0.6_arm64.deb ./
root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/bullseye$ ll
总计 788
drwxr-xr-x  6 root root   4096  7月 10 18:00 ./
drwxrwsr-x  6 root sudo   4096  7月 10 18:00 ../
drwxr-xr-x 17 root root   4096  7月 10 18:01 etc/
drwxr-xr-x  4 root root   4096  7月 10 13:40 lib/
-rw-r--r--  1 root sudo 781316  7月 10 18:01 orangepi-bsp-cli-orangepi3b_1.0.6_arm64.deb
drwxr-xr-x  8 root root   4096  7月 10 13:40 usr/
drwxr-xr-x  3 root root   4096  7月 10 13:40 var/

etclibusrvar目录下的文件是由<SDK>/external/packages/bsp/commonadb等目录下文件组成的。

zhengyang@ubuntu:/work/sambashare/rk3566/orangepi-build$ ll external/packages/bsp/
-rw-r--r--  1 root root    32  7月 10 13:40 10-no-new-privileges.conf
-rw-r--r--  1 root root   117  7月 10 13:40 99disable-power-management
drwxr-xr-x  2 root root  4096  7月 10 13:40 adb/
drwxr-xr-x  6 root root  4096  7月 10 13:40 common/
-rwxr-xr-x  1 root root 18077  7月 10 13:40 h3consumption*
-rwxr-xr-x  1 root root 15518  7月 10 13:40 h3disp*
drwxr-xr-x  2 root root  4096  7月 10 13:40 h618/
drwxr-xr-x  2 root root  4096  7月 10 13:40 kodi/
drwxr-xr-x  2 root root  4096  7月 10 13:40 mpv/
drwxr-xr-x  4 root root  4096  7月 10 13:40 orangepi5plus/
-rw-r--r--  1 root root  1542  7月 10 13:40 orangepi_first_run.txt.template
drwxr-xr-x  3 root root  4096  7月 10 13:40 orangepimonitor/
drwxr-xr-x  4 root root  4096  7月 10 13:40 overlays_arm64/
drwxr-xr-x  4 root root  4096  7月 10 13:40 overlays_s905d3/
drwxr-xr-x  3 root root  4096  7月 10 13:40 rk3399/
drwxr-xr-x  5 root root  4096  7月 10 13:40 rk356x/
drwxr-xr-x  4 root root  4096  7月 10 13:40 rk3588/
drwxr-xr-x  2 root root  4096  7月 10 13:40 rockchip/
-rwxr-xr-x  1 root root  1416  7月 10 13:40 setsystem*
drwxr-xr-x  2 root root  4096  7月 10 13:40 sunxi/
drwxr-xr-x  2 root root  4096  7月 10 13:40 sunxi-temp/

六、Linux镜像分析

SDK编译出来的Linux镜像有一般有两个分区;

  • 第一个分区为FAT32分区,用于存放内核镜像、dtbuboot变量和脚本;
  • 第二分区为ext4分区,用作真正的rootfs

接下来我们将对该镜像的空间布局进行分析,从而推断出ubootkernelrootfs的地址空间。

6.1 查看分区表

查看Linux镜像的分区表;

root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/images/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5$ sfdisk -J ./Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img
{
   "partitiontable": {
      "label": "gpt",
      "id": "562CABBE-E609-0748-8533-609E63F20DF8",
      "device": "./Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img",
      "unit": "sectors",
      "firstlba": 2048,
      "lastlba": 8306654,
      "sectorsize": 512,
      "partitions": [
         {
            "node": "./Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img1",
            "start": 61440,
            "size": 2097152,
            "type": "BC13C2FF-59E6-4262-A352-B275FD6F7172",
            "uuid": "06DF356B-70C4-BE44-A9AE-EB30EA7FABD3",
            "name": "bootfs"
         },{
            "node": "./Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img2",
            "start": 2158592,
            "size": 6148063,
            "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4",
            "uuid": "AD98C5C4-D76F-2B4A-9948-A9953C5D3BB4",
            "name": "rootfs"
         }
      ]
   }
}

这里采用GUID分区表,GPT存储在磁盘的起始位置(通常是从第一个扇区开始),其结构更加灵活,支持更大的磁盘容量和更多的分区。GPT使用全局唯一标识符(GUID)来标识分区,而不是使用传统的主引导记录(MBR)方式。

如上图所示,Linux镜像只有两个分区:

  • bootfs分区:扇区61440~2158591,大小为1GB,启动引导分区,这个后面我们单独介绍;
  • rootfs分区:扇区2158592~8306654,大小为2.9GB,根文件系统分区。

6.2 查看rootfs分区

通过分区表可以看到rootfsLinux镜像的第二分区,并且偏移量为2158592扇区,所以偏移的字节数为2158592*512=1105199104.

带偏移量挂载:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ mkdir -p /mnt/rootfs
root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo mount -o loop,offset=$((2158592*512)) ./output/images/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img /mnt/rootfs

其中:-o loop 的含义是告诉mount命令将一个文件当作块设备来挂载,通常用于挂载像.img映像文件或其他类似的文件系统镜像文件。

6.2.1 目录结构

这样我们就可以查看根文件系统内容:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$  ll /mnt/rootfs/
lrwxrwxrwx   1 root root     7  7月 10 17:09 bin -> usr/bin/
drwxrwxr-x   2 root root  4096  7月 10 18:28 boot/
drwxr-xr-x   2 root root  4096  7月 10 17:09 dev/
drwxr-xr-x 106 root root  4096  7月 10 18:28 etc/
drwxr-xr-x   3 root root  4096  7月 10 18:04 home/
lrwxrwxrwx   1 root root     7  7月 10 17:09 lib -> usr/lib/
drwx------   2 root root 16384  7月 10 18:28 lost+found/
drwxr-xr-x   2 root root  4096  7月 10 17:09 media/
drwxr-xr-x   2 root root  4096  7月 10 17:09 mnt/
drwxr-xr-x   3 root root  4096  7月 10 13:40 opt/
drwxr-xr-x   2 root root  4096  6月 20 05:20 proc/
drwx------   3 root root  4096  7月 10 18:26 root/
drwxr-xr-x   3 root root  4096  7月 10 18:29 run/
lrwxrwxrwx   1 root root     8  7月 10 17:09 sbin -> usr/sbin/
drwxrwxr-x   2 root root  4096  7月 10 18:01 selinux/
drwxr-xr-x   2 root root  4096  7月 10 17:09 srv/
drwxr-xr-x   2 root root  4096  6月 20 05:20 sys/
drwxrwxrwt   2 root root  4096  7月 10 18:27 tmp/
drwxr-xr-x  11 root root  4096  7月 10 13:40 usr/
drwxr-xr-x  11 root root  4096  7月 10 17:09 var/

在这里我们可以查看各个目录下的文件内容,在这里我们是可以找到前面编译过程中安装的各个deb包的内容,比如linux-image-current-rockchip-rk356x_1.0.6_arm64.deb包的内容;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ ll /mnt/rootfs/lib/modules/6.6.0-rc5-rockchip-rk356x/
总计 3888
drwxr-xr-x  3 root root   4096  7月 10 18:03 ./
drwxr-xr-x  3 root root   4096  7月 10 18:03 ../
drwxr-xr-x 11 root root   4096  7月 10 18:03 kernel/
-rw-r--r--  1 root root 911728  7月 10 17:58 modules.alias
-rw-r--r--  1 root root 933693  7月 10 17:58 modules.alias.bin
-rw-r--r--  1 root root  17950  7月 10 17:58 modules.builtin
-rw-r--r--  1 root root  49397  7月 10 17:58 modules.builtin.alias.bin
-rw-r--r--  1 root root  21758  7月 10 17:58 modules.builtin.bin
-rw-r--r--  1 root root 127113  7月 10 17:58 modules.builtin.modinfo
-rw-r--r--  1 root root 376706  7月 10 17:58 modules.dep
-rw-r--r--  1 root root 531642  7月 10 17:58 modules.dep.bin
-rw-r--r--  1 root root    309  7月 10 17:58 modules.devname
-rw-r--r--  1 root root 143032  7月 10 17:58 modules.order
-rw-r--r--  1 root root    836  7月 10 17:58 modules.softdep
-rw-r--r--  1 root root 370613  7月 10 17:58 modules.symbols
-rw-r--r--  1 root root 458225  7月 10 17:58 modules.symbols.bin

此外boot目录是空的,内核启动后会将第一个分区挂载到该目录下。我们可以查看/etc/fstab文件,其作用是定义系统启动时需要挂载的文件系统及其挂载选项;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ vim /mnt/rootfs/etc/fstab
UUID=eb5b9342-7a1c-4994-91ea-648cf9059720 / ext4 defaults,noatime,commit=600,errors=remount-ro 0 1
UUID=24B4-43E5 /boot vfat defaults 0 2
tmpfs /tmp tmpfs defaults,nosuid 0 0

其中:

  • 第一行表示把UUID=eb5b9342-7a1c-4994-91ea-648cf9059720设备挂载到/目录,文件系统类型为ext4
  • 第二行表示把UUID=24B4-43E5设备挂载到/boot目录,文件系统类型为vfat

当我们把Linux镜像烧录到eMMC起始地址0x00处,内核启动后,将会看到eMMC块设备文件;

  • /dev/mmcblk0:表示的是eMMC这个设备;
  • /dev/mmcblk0p1:对应的是内核镜像分区,其UUIDeb5b9342-7a1c-4994-91ea-648cf9059720
  • /dev/mmcblk0p2:对应的是rootfs分区,其UUID24B4-43E5 ;

我们可以通过如下命令查看指定设备的UUID:

blkid -s UUID -o value /dev/mmcblk0p1
6.2.2 修改根文件系统

如果我们有一些特殊诉求,比如在根文件系统中安装一些软件,那么可以参考《Rockchip RK3399 - 移植ubuntu 20.04.4根文件系统》第一章。

最后,我们需要卸载文件系统:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo umount /mnt/rootfs

6.3 查看bootfs分区

上面我们说过boot目录会挂载Linux镜像的bootfs,那我们想查看该目录内容要怎么做呢,我们创建一个/mnt/boot目录,将第一分区挂载上去;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo mkdir -p /mnt/boot
root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo mount -o loop,offset=$((61440*512)) ./output/images/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img /mnt/boot

我们查看一下boot目录;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ ll /mnt/boot/
-rwxr-xr-x 1 root root   230456  7月 10 18:04 boot.bmp*
-rwxr-xr-x 1 root root     3341  7月 10 18:01 boot.cmd*
-rwxr-xr-x 1 root root     3413  7月 10 18:28 boot.scr*
-rwxr-xr-x 1 root root   247764  7月 10 17:58 config-6.6.0-rc5-rockchip-rk356x*
drwxr-xr-x 3 root root     4096  7月 10 18:03 dtb/
drwxr-xr-x 3 root root     4096  7月 10 18:03 dtb-6.6.0-rc5-rockchip-rk356x/
-rwxr-xr-x 1 root root 31119872  7月 10 17:58 Image*
-rwxr-xr-x 1 root root 15266929  7月 10 18:30 initrd.img-6.6.0-rc5-rockchip-rk356x*
-rwxr-xr-x 1 root root  1152056  7月 10 18:04 logo.bmp*
-rwxr-xr-x 1 root root        0  7月 10 18:03 .next*
-rwxr-xr-x 1 root root      134  7月 10 18:28 orangepiEnv.txt*
-rwxr-xr-x 1 root root     1542  7月 10 18:26 orangepi_first_run.txt.template*
-rwxr-xr-x 1 root root  5133992  7月 10 17:58 System.map-6.6.0-rc5-rockchip-rk356x*
-rwxr-xr-x 1 root root 15266993  7月 10 18:30 uInitrd*
-rwxr-xr-x 1 root root 31119872  7月 10 17:58 vmlinuz-6.6.0-rc5-rockchip-rk356x*

其中:

  • boot.bmp :引导时显示的自定义启动图像文件;
  • boot.cmd:用于生成引导脚本的命令文件;
  • boot.scr :编译后的引导脚本文件,用于uboot distro_boo 引导时执行特定操作;uboot启动后会查找这个文件,然后执行其中的命令;
  • config-6.6.0-rc5-rockchip-rk356x :内核的配置文件,指定了编译内核时的选项和参数;
  • dtbdtb-6.6.0-rc5-rockchip-rk356x:设备树目录,内容相同;
  • Image:内核镜像文件;
  • initrd.img-6.6.0-rc5-rockchip-rk356x:这应该是一个ramdisk格式的rootfs
  • orangepiEnv.txt :是Orange Pi系统的环境变量配置文件;

armbian系统的boot目录结构就是上图所示,里面存放了kerneldtb、以及ramdisk rootfs,至于为啥是这样,后面有时间再深入研究。

6.3.1 boot.cmd

系统启动脚本受到boot.cmd控制,boot.cmd目录内容如下;

# DO NOT EDIT THIS FILE
#
# Please edit /boot/orangepiEnv.txt to set supported parameters
#
# 设置一些环境变量
setenv load_addr "0x9000000"
setenv overlay_error "false"
# default values
setenv rootdev "/dev/mmcblk0p1"
setenv verbosity "1"
setenv console "both"
setenv bootlogo "false"
setenv rootfstype "ext4"
setenv docker_optimizations "on"
setenv earlycon "off"

# devtype为设备类型,比如mmc  dev_num为设备分区编号
echo "Boot script loaded from ${devtype} ${devnum}"

# 检查是否存在orangepiEnv.txt 文件,并加载其中的内容
if test -e ${devtype} ${devnum} ${prefix}orangepiEnv.txt; then
        load ${devtype} ${devnum} ${load_addr} ${prefix}orangepiEnv.txt
        env import -t ${load_addr} ${filesize}
fi

if test "${logo}" = "disabled"; then setenv logo "logo.nologo"; fi

if test "${console}" = "display" || test "${console}" = "both"; then setenv consoleargs "console=tty1"; fi
if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "console=ttyS2,1500000 ${consoleargs}"; fi
if test "${earlycon}" = "on"; then setenv consoleargs "earlycon ${consoleargs}"; fi
if test "${bootlogo}" = "true"; then
        setenv consoleargs "splash plymouth.ignore-serial-consoles ${consoleargs}"
else
        setenv consoleargs "splash=verbose ${consoleargs}"
fi

# get PARTUUID of first partition on SD/eMMC the boot script was loaded from
if test "${devtype}" = "mmc"; then part uuid mmc ${devnum}:1 partuuid; fi

# 设置启动参数
setenv bootargs "root=${rootdev} rootwait rootfstype=${rootfstype} ${consoleargs} consoleblank=0 loglevel=${verbosity} ubootpart=${partuuid} usb-storage.quirks=${usbstoragequirks} ${extraargs} ${extraboardargs}"

if test "${docker_optimizations}" = "on"; then setenv bootargs "${bootargs} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1"; fi
setenv fdtfile rockchip/rk3566-orangepi-3b.dtb

# 将uInitrd加载到地址ramdisk_addr_r
load ${devtype} ${devnum} ${ramdisk_addr_r} ${prefix}uInitrd
# 将Image加载到地址kernel_addr_r
load ${devtype} ${devnum} ${kernel_addr_r} ${prefix}Image
# 将设备树加载到地址fdt_addr_r           
# 设备树文件:/boot/dtb/rockchip/rk3566-orangepi-3b-v2.dtb,如果使用的是linux 6.6该文件不存在,linux 5.10该文件存在
load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}dtb/${fdtfile}
# 设置设备树的起始地址为fdt_addr_r
fdt addr ${fdt_addr_r}
fdt resize 65536

# 加载overlay目录下的设备树文件
for overlay_file in ${overlays}; do
        if load ${devtype} ${devnum} ${load_addr} ${prefix}dtb/rockchip/overlay/${overlay_prefix}-${overlay_file}.dtbo; then
                echo "Applying kernel provided DT overlay ${overlay_prefix}-${overlay_file}.dtbo"
                fdt apply ${load_addr} || setenv overlay_error "true"
        fi
done

for overlay_file in ${user_overlays}; do
        if load ${devtype} ${devnum} ${load_addr} ${prefix}overlay-user/${overlay_file}.dtbo; then
                echo "Applying user provided DT overlay ${overlay_file}.dtbo"
                fdt apply ${load_addr} || setenv overlay_error "true"
        fi
done
if test "${overlay_error}" = "true"; then
        echo "Error applying DT overlays, restoring original DT"
        load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}dtb/${fdtfile}
else
		#  /boot/dtb/rockchip/overlay/rk356x-fixup.scr
        if load ${devtype} ${devnum} ${load_addr} ${prefix}dtb/rockchip/overlay/${overlay_prefix}-fixup.scr; then
                echo "Applying kernel provided DT fixup script (${overlay_prefix}-fixup.scr)"
                source ${load_addr}
        fi
        if test -e ${devtype} ${devnum} ${prefix}fixup.scr; then
                load ${devtype} ${devnum} ${load_addr} ${prefix}fixup.scr
                echo "Applying user provided fixup script (fixup.scr)"
                source ${load_addr}
        fi
fi

if test "${ethernet_phy}" = "rtl8211f"; then
        fdt set /ethernet@ff540000 tx_delay <0x24>
        fdt set /ethernet@ff540000 rx_delay <0x18>
fi

# 启动Image格式内核镜像:参数依次为 内核镜像在内存中地址 ramdisk文件系统在内存中的地址 设备树在内存中的地址
booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}

# Recompile with:
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr

这里使用到了uboot中的setenvtestload等命令,其中:

  • setenv:设置环境变量;
  • load:于从启动设备(如SD卡、eMMC等)指定分区加载文件到内存中,通常用于加载内核、设备树、ramdisk等;
6.3.2 dtb

查看设备树信息:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ tree /mnt/boot/dtb/
/mnt/boot/dtb/
└── rockchip
    ├── overlay
    │   ├── README.rockchip-overlays
    │   ├── rk356x-fixup.scr
    │   ├── rk356x-gpu.dtbo
    │   ├── rk356x-i2c2-m1.dtbo
    │   ├── rk356x-i2c3-m0.dtbo
    │   ├── rk356x-i2c4-m0.dtbo
    │   ├── rk356x-pwm11-m1.dtbo
    │   ├── rk356x-pwm15-m1.dtbo
    │   ├── rk356x-spi3-m0-cs0-spidev.dtbo
    │   ├── rk356x-uart3-m0.dtbo
    │   ├── rk356x-uart7-m2.dtbo
    │   └── rk356x-uart9-m2.dtbo
    └── rk3566-orangepi-3b.dtb
6.3.3 orangepiEnv.txt

查看orangepiEnv.txt

verbosity=1
bootlogo=false
extraargs=cma=128M
overlay_prefix=rk356x
rootdev=UUID=eb5b9342-7a1c-4994-91ea-648cf9059720
rootfstype=ext4

查看完毕,我们需要卸载文件系统:

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo umount /mnt/boot

七、烧录测试

7.1 准备工作

首先我们要对Orange Pi 3B的硬件有一定了解,知道电源在哪里,串口在哪里;下图是官方提供的接口详情图;

Pi3b-img5.png
7.1.1 电源适配器

Orange Pi 3B建议使用5V/3A或者5V/4AType-C电源供电,注意这里输入电源只可以是5V,因为这个5V输入是作为VCC5V0_SYS使用的,具体可以参考官方原理图。

7.1.2 串口连接

使用准备好的USB转串口适配器和连接线,连接开发板;

引脚 开发板接口 USB转串口
1 GND GND
2 RX TX
3 TX RX

这里我使用的串口调试工具是MobaXterm,选择串口端口,设置波特率为1500000,8位数据位,1位停止位。

img

7.2 制作SD启动卡

我们将SD卡插入PC上,在虚拟机ubuntu中运行demsg查看新接入的设备;

[12837.572991] usb 2-1: new high-speed USB device number 2 using ehci-pci
[12837.846049] usb 2-1: New USB device found, idVendor=14cd, idProduct=1212, bcdDevice= 1.00
[12837.846066] usb 2-1: New USB device strings: Mfr=1, Product=3, SerialNumber=2
[12837.846067] usb 2-1: Product: Mass Storage Device
[12837.846070] usb 2-1: Manufacturer: Generic
[12837.846072] usb 2-1: SerialNumber: 121220160204
[12837.931970] usb-storage 2-1:1.0: USB Mass Storage device detected
[12837.939167] scsi host33: usb-storage 2-1:1.0
[12837.942888] usbcore: registered new interface driver usb-storage
[12837.964220] usbcore: registered new interface driver uas
[12838.969026] scsi 33:0:0:0: Direct-Access     Mass     Storage Device   1.00 PQ: 0 ANSI: 0 CCS
[12838.969677] sd 33:0:0:0: Attached scsi generic sg2 type 0
[12839.188528] sd 33:0:0:0: [sdb] 31211520 512-byte logical blocks: (16.0 GB/14.9 GiB)
[12839.192550] sd 33:0:0:0: [sdb] Write Protect is off
[12839.192553] sd 33:0:0:0: [sdb] Mode Sense: 03 00 00 00
[12839.195800] sd 33:0:0:0: [sdb] No Caching mode page found
[12839.195802] sd 33:0:0:0: [sdb] Assuming drive cache: write through
[12839.224982]  sdb: sdb1
[12839.225388] sd 33:0:0:0: [sdb] Attached SCSI removable disk

可以看到SD卡对应的设备节点为/dev/sdb,对应1个分区sdb1

root@ubuntu:~$ ls /dev/sdb*
/dev/sdb  /dev/sdb1

开始制作SD启动卡:

root@ubuntu:~$ cd /work/sambashare/rk3566/orangepi-build
root@ubuntu:/work/sambashare/rk3566/orangepi-build$ dd if=output/images/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img of=/dev/sdb bs=4M status=progress
root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sync

7.3 上电测试

SD卡插入到开发板,并使用准备好的USB转串口适配器和连接线,连接开发板,给开发板上电。

uboot输出日志如下:

U-Boot 2017.09-orangepi (Jul 10 2024 - 17:57:37 +0800)

Model: Orange Pi 3B
PreSerial: 2, raw, 0xfe660000
DRAM:  2 GiB
Sysmem: init
Relocation Offset: 7d233000
Relocation fdt: 7b9f6470 - 7b9fecc0
CR: M/C/I
Using default environment

dwmmc@fe2b0000: 0, dwmmc@fe2c0000: 2, sdhci@fe310000: 1
Bootdev(atags): mmc 0
MMC0: Legacy, 52Mhz
PartType: EFI
DM: v1
boot mode: None
I2c0 speed: 100000Hz
vsel-gpios- not found! Error: -2
vdd_cpu init 900000 uV
PMIC:  RK8090 (on=0x40, off=0x00)
vdd_logic init 900000 uV
vdd_gpu init 900000 uV
vdd_npu init 900000 uV
io-domain: OK
Failed to get scmi clk dev
dmc_fsp failed, ret=-19
Model: Orange Pi 3B
CLK: (sync kernel. arm: enter 816000 KHz, init 816000 KHz, kernel 0N/A)
  apll 816000 KHz
  dpll 528000 KHz
  gpll 1188000 KHz
  cpll 1000000 KHz
  npll 1200000 KHz
  vpll 24000 KHz
  hpll 24000 KHz
  ppll 200000 KHz
  armclk 816000 KHz
  aclk_bus 150000 KHz
  pclk_bus 100000 KHz
  aclk_top_high 300000 KHz
  aclk_top_low 200000 KHz
  hclk_top 150000 KHz
  pclk_top 100000 KHz
  aclk_perimid 300000 KHz
  hclk_perimid 150000 KHz
  pclk_pmu 100000 KHz
Net:   eth1: ethernet@fe010000

在启动过程中按下CTRL+C进入uboot命令行模式,查看内核启动命令;

=> print bootcmd
bootcmd=run distro_bootcmd;boot_android ${devtype} ${devnum};boot_fit;bootrkp;
=>  pri boot_targets
boot_targets=mmc0 mmc1 nvme mtd2 mtd1 mtd0 usb0 pxe dhcp

首先执行的就是distro_bootcmd启动方式,这种启动方式会依次遍历设备mmc0mmc1、....,然后探测内核镜像,并启动内核。

关于uboot引导内核相关内容可以参考:《Rockchip RK3588 - uboot引导方式介绍》。

7.3.1 boot启动日志

输入boot命令启动内核:

=> boot
switch to partitions #0, OK
mmc0 is current device
dwmmc@fe2b0000: 0 (SD)
dwmmc@fe2c0000: 2
sdhci@fe310000: 1
switch to partitions #0, OK
mmc0 is current device
# scan_dev_for_boot:扫描mmc设备编号0,第一个分区,即mmcblk0p1
Scanning mmc 0:1...
# scan_dev_for_scripts:在/目录下查找到boot.scr脚本,加载到scriptaddr=0x00c00000
Found U-Boot script /boot.scr
# 加载/boot.scr脚本,并执行  此时devtype=mmc、devnum=0、distro_bootpart=1
reading /boot.scr
3413 bytes read in 2 ms (1.6 MiB/s)

## Executing script at 00c00000   以下为boot.scr脚本执行输出日志
Boot script loaded from mmc 0

# 将orangepiEnv.txt加载到地址load_addr=0x9000000
reading /orangepiEnv.txt
134 bytes read in 2 ms (65.4 KiB/s)

# 将uInitrd加载到地址ramdisk_addr_r=0x0a200000
reading /uInitrd
15266993 bytes read in 1276 ms (11.4 MiB/s)

# 将Image加载到地址kernel_addr_r=0x00280000
reading /Image
31119872 bytes read in 2596 ms (11.4 MiB/s)

# 将设备树加载到地址fdt_addr_r=0x08300000, fdtfile=rockchip/rk3566-orangepi-3b-v2.dtb
** Unable to read file /dtb/rockchip/rk3566-orangepi-3b-v2.dtb **
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
No FDT memory address configured. Default at 0x7b9f6470

# 加载overlay目录下的设备树文件
reading /dtb/rockchip/overlay/rk356x-fixup.scr
232 bytes read in 6 ms (37.1 KiB/s)
Applying kernel provided DT fixup script (rk356x-fixup.scr)

## Executing script at 09000000 执行booti启动Image格式内核镜像
Fdt Ramdisk skip relocation
## Loading init Ramdisk from Legacy Image at 0a200000 ...
   Image Name:   uInitrd
   Image Type:   AArch64 Linux RAMDisk Image (gzip compressed)
   Data Size:    15266929 Bytes = 14.6 MiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
ERROR: Did not find a cmdline Flattened Device Tree
Could not find a valid device tree
SCRIPT FAILED: continuing...
switch to partitions #0, OK
mmc1(part 0) is current device
dwmmc@fe2b0000: 0 (SD)
dwmmc@fe2c0000: 2
sdhci@fe310000: 1 (eMMC)
switch to partitions #0, OK
mmc1(part 0) is current device
** No partition table - mmc 1 **

Device 0: unknown device
starting USB...
Bus dwc3@fcc00000:

从启动日志中可以看到,在执行boot.cmd加载设备树命令时执行失败了;

# 将设备树加载到地址fdt_addr_r
load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}dtb/${fdtfile}
# 设置设备树的起始地址为fdt_addr_r
fdt addr ${fdt_addr_r}
fdt resize 65536

** Unable to read file /dtb/rockchip/rk3566-orangepi-3b-v2.dtb **
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
No FDT memory address configured. Default at 0x7b9f6470

这主要是因为我们制作内核版本为6.6Linux镜像boot目录下并没有dtb/rockchip/rk3566-orangepi-3b-v2.dtb这个设备树文件;

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ tree /mnt/boot/dtb/
/mnt/boot/dtb/
└── rockchip
    ├── overlay
    │   ├── README.rockchip-overlays
    │   ├── rk356x-fixup.scr
    │   ├── rk356x-gpu.dtbo
    │   ├── rk356x-i2c2-m1.dtbo
    │   ├── rk356x-i2c3-m0.dtbo
    │   ├── rk356x-i2c4-m0.dtbo
    │   ├── rk356x-pwm11-m1.dtbo
    │   ├── rk356x-pwm15-m1.dtbo
    │   ├── rk356x-spi3-m0-cs0-spidev.dtbo
    │   ├── rk356x-uart3-m0.dtbo
    │   ├── rk356x-uart7-m2.dtbo
    │   └── rk356x-uart9-m2.dtbo
    └── rk3566-orangepi-3b.dtb

为此我特意下载编译了legacy版本的内核,在<SDK>/kernel/orange-pi-5.10-rk35xX/arch/arm64/boot/dts/rockchip/目录下是可以看到如下文件的:

rk3566-orangepi-3b.dtb
rk3566-orangepi-3b.dts
rk3566-orangepi-3b-v2.dtb
rk3566-orangepi-3b-v2.dts

为啥在5.10内核下可以看到两个版本的设备树?

在网上搜到的结果是说OrangePi-3B硬件版本v1.1的板子出现过有线网卡无故失灵的故障,为了解决这个问题香橙派推出了硬件版本为V2.1OrangePi-3B。也就是说这两个设备树是分别适配于V1.1V2.1板子的,至于6.6版本为啥没有V2版本的设备树,大概率是官方并没有适配6.6的内核。具体可以参考这个帖子:《香橙派3b有线网卡坏》。

这里我使用的开发板就是v2.1版本的,如果你坚持使用6.6的内核,可以参考下文对u-boot进行调整,个人测试网卡可以正常工作。

需要注意的是如果你使用的是5.10版本的内核,跳过下一小节的修改。

7.3.2 修改默认设备树

这里我们有两种方式修改fdtfile环境变量的值.

7.3.2.1 修改源码

我们在uboot源码include/config.h中找到特定开发板或者硬件平台的配置文件;

#include <configs/evb_rk3568.h>

从而定位到include/configs/evb_rk3568.h -> include/configs/rk3568_common.h文件;

fdtfile这个环境变量就是保存include/configs/rk3568_common.h文件中的;

include/configs/rockchip-common.h:127:#define FDTFILE "rockchip/" CONFIG_DEFAULT_DEVICE_TREE ".dtb" "\0"

// 通过CONFIG_EXTRA_ENV_SETTINGS定义了额外的环境变量。
#define CONFIG_EXTRA_ENV_SETTINGS \
        ENV_MEM_LAYOUT_SETTINGS \
        "fdtfile=" FDTFILE \
        "partitions=" PARTS_RKIMG \
        ROCKCHIP_DEVICE_SETTINGS \
        RKIMG_DET_BOOTDEV \
        BOOTENV
#endif

CONFIG_DEFAULT_DEVICE_TREE可以通过make menuconfig进行配置;

Device Tree Control  --->
	(rk3566-orangepi-3b) Default Device Tree for DT control 

可以在include/generated/autoconf.h中查找到CONFIG_DEFAULT_DEVICE_TREE配置项;

#define CONFIG_DEFAULT_DEVICE_TREE "rk3566-orangepi-3b"
#define CONFIG_BOARD_LATE_INIT 1

那么fdtfile应该为rockchip/rk3566-orangepi-3b.dtb,为啥我们运行uboot看到的是rockchip/rk3566-orangepi-3b-v2.dtb

我们定位到board/rockchip/evb_rk3568/evb_rk3568.c

int rk_board_late_init(void)
{
        int value;
        char dtb_name[32];
        char dtb_ver[10];
        const char *model;

    	// 获取设备树/节点compatible属性值  compatible = "rockchip,rk3566-orangepi-3b", "rockchip,rk3568";
        model = fdt_getprop(gd->fdt_blob, 0, "compatible", NULL);
    	// 匹配3b
        if(!strcmp(model, "rockchip,rk3566-orangepi-3b")) {
                strcpy(dtb_ver, "-v2.dtb");
        } else if(!strcmp(model, "rockchip,rk3566-orangepi-cm4")) {
                strcpy(dtb_ver, "-v1.4.dtb");
        } else
                return 0;

#define GPIO4_BASE      0xfe770000
    	// GPIO控制器寄存器的基地址
        struct rockchip_gpio_regs *regs = (void *)GPIO4_BASE;

    	// 清除swport_ddr寄存器的第20位 用于配置GPIO4_C4引脚为输入方向
        CLRBITS_LE32(&regs->swport_ddr, OFFSET_TO_BIT(20));
        // 读取ext_port寄存器的值,并检查其第20位是否被设置为1 用于检查GPIO4_C4引脚是不是高电平
        value = readl(&regs->ext_port) & OFFSET_TO_BIT(20) ? 1 : 0;

        if(value) {
            	// 获取fdtfile环境变量的值
                char *fdtfile = env_get("fdtfile");
            	// 拷贝到dtb_name
                strcpy(dtb_name, fdtfile);
            	// 在替换.dtb,比如替换成-v2.dtb
                sprintf(dtb_name + strlen(dtb_name) - 4, "%s", dtb_ver);
                env_set("fdtfile", dtb_name);
        }

        return 0;
}

可以看到如果读取到GPIO4_C4引脚为高电平,则使用设备树rockchip/rk3566-orangepi-3b-v2.dtb。那么GPIO4_C4引脚用来做什么的呢?我们可以打开官方的电路原理图,可以看到该引脚连接到了PHY_RESET,该引脚:

  • 一端经过一个10k上的拉电阻连接到3.3V电源;
  • 另一端里连接到了以太网控制器(GMAC1)的PHYRSTB引脚;GMACPHYRSTB引脚通常用于控制以太网PHY(物理层)的复位状态,当PHYRSTB引脚处于逻辑低电平(通常为0V)时,以太网PHY将被复位;

通过上面分分析,因此不难看出GPIO4_C4时钟为高电平。

rk_board_late_init函数的调用链如下:

board_init_r(gd_t,dest_addr)          // arch/arm/lib/crt0.S
    #ifdef CONFIG_BOARD_LATE_INIT
        board_late_init()             // common/board_r.c
			board_late_init()         // arch/arm/mach-rockchip/board.c
    			......
				rk_board_late_init()
	#endif

经过分析,要将fdtfile环境变量的值设置为rockchip/rk3566-orangepi-3b.dtb,我们需要修改rk_board_late_init函数,将value值设置为0即可。

7.3.2.2 修改环境变量

我们需要给开发板复位,重新进入uboot命令行,修改fdtfile,不过这种修改方式只能临时生效,因为代码运行到rk_board_late_init处还是会修改fdtfile的值;

=> setenv fdtfile rockchip/rk3566-orangepi-3b.dtb
=> saveenv
Saving Environment to nowhere...

重新执行boot命令;

点击查看代码
=> boot
switch to partitions #0, OK
mmc0 is current device
dwmmc@fe2b0000: 0 (SD)
dwmmc@fe2c0000: 2
sdhci@fe310000: 1
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
reading /boot.scr
3413 bytes read in 2 ms (1.6 MiB/s)
## Executing script at 00c00000
Boot script loaded from mmc 0
reading /orangepiEnv.txt
134 bytes read in 2 ms (65.4 KiB/s)
reading /uInitrd
15266993 bytes read in 1276 ms (11.4 MiB/s)
reading /Image
31119872 bytes read in 2596 ms (11.4 MiB/s)
reading /dtb/rockchip/rk3566-orangepi-3b.dtb
118563 bytes read in 15 ms (7.5 MiB/s)
reading /dtb/rockchip/overlay/rk356x-fixup.scr
232 bytes read in 5 ms (44.9 KiB/s)
Applying kernel provided DT fixup script (rk356x-fixup.scr)
## Executing script at 09000000
Fdt Ramdisk skip relocation
## Loading init Ramdisk from Legacy Image at 0a200000 ...
   Image Name:   uInitrd
   Image Type:   AArch64 Linux RAMDisk Image (gzip compressed)
   Data Size:    15266929 Bytes = 14.6 MiB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 0x08300000
   Booting using the fdt blob at 0x08300000
   reserving fdt memory region: addr=8300000 size=83000
   Using Device Tree in place at 0000000008300000, end 0000000008385fff
can't found rockchip,drm-logo, use rockchip,fb-logo
WARNING: could not set reg FDT_ERR_BADOFFSET.
failed to reserve fb-loader-logo memory
Adding bank: 0x00200000 - 0x80000000 (size: 0x7fe00000)
== DO RELOCATE == Kernel from 0x00280000 to 0x00400000
Total: 1719337.604 ms

Starting kernel ...

done.
Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done.
Begin: Running /scripts/local-premount ... Scanning for Btrfs filesystems
done.
Begin: Will now check root file system ... fsck from util-linux 2.36.1
[/sbin/fsck.ext4 (1) -- /dev/mmcblk1p2] fsck.ext4 -a -C0 /dev/mmcblk1p2
opi_root: clean, 61817/192384 files, 554687/768507 blocks
done.
done.
Begin: Running /scripts/local-bottom ... done.
Begin: Running /scripts/init-bottom ... done.

Welcome to Orange Pi 1.0.6 Bullseye!

[  OK  ] Created slice system-modprobe.slice.
[  OK  ] Created slice system-serial\x2dgetty.slice.
[  OK  ] Created slice system-systemd\x2dfsck.slice.
[  OK  ] Created slice User and Session Slice.
[  OK  ] Started Forward Password R…uests to Wall Directory Watch.
[  OK  ] Set up automount Arbitrary…s File System Automount Point.
[  OK  ] Reached target Slices.
[  OK  ] Reached target Swap.
[  OK  ] Reached target System Time Set.
[  OK  ] Listening on RPCbind Server Activation Socket.
[  OK  ] Listening on Syslog Socket.
[  OK  ] Listening on fsck to fsckd communication Socket.
[  OK  ] Listening on initctl Compatibility Named Pipe.
[  OK  ] Listening on Journal Audit Socket.
[  OK  ] Listening on Journal Socket (/dev/log).
[  OK  ] Listening on Journal Socket.
[  OK  ] Listening on udev Control Socket.
[  OK  ] Listening on udev Kernel Socket.
         Mounting Huge Pages File System...
         Mounting POSIX Message Queue File System...
         Mounting RPC Pipe File System...
         Mounting Kernel Debug File System...
         Mounting Kernel Trace File System...
         Starting Restore / save the current clock...
         Starting Set the console keyboard layout...
         Starting Create list of st…odes for the current kernel...
         Starting Load Kernel Module configfs...
         Starting Load Kernel Module drm...
         Starting Load Kernel Module fuse...
[  OK  ] Started Nameserver information manager.
[  OK  ] Reached target Network (Pre).
         Starting Load Kernel Modules...
         Starting Remount Root and Kernel File Systems...
         Starting Coldplug All udev Devices...
[  OK  ] Mounted Huge Pages File System.
[  OK  ] Mounted POSIX Message Queue File System.
[  OK  ] Mounted RPC Pipe File System.
[  OK  ] Mounted Kernel Debug File System.
[  OK  ] Mounted Kernel Trace File System.
[  OK  ] Finished Restore / save the current clock.
[  OK  ] Finished Create list of st… nodes for the current kernel.
[  OK  ] Finished Load Kernel Module configfs.
[  OK  ] Finished Load Kernel Module drm.
[  OK  ] Finished Load Kernel Module fuse.
[  OK  ] Finished Load Kernel Modules.
         Mounting FUSE Control File System...
         Mounting Kernel Configuration File System...
         Starting Apply Kernel Variables...
[  OK  ] Finished Remount Root and Kernel File Systems.
[  OK  ] Mounted FUSE Control File System.
[  OK  ] Mounted Kernel Configuration File System.
         Starting Load/Save Random Seed...
         Starting Create System Users...
[  OK  ] Finished Apply Kernel Variables.
[  OK  ] Finished Load/Save Random Seed.
[  OK  ] Finished Create System Users.
         Starting Create Static Device Nodes in /dev...
[  OK  ] Finished Set the console keyboard layout.
[  OK  ] Finished Create Static Device Nodes in /dev.
[  OK  ] Reached target Local File Systems (Pre).
         Mounting /tmp...
         Starting Rule-based Manage…for Device Events and Files...
[  OK  ] Mounted /tmp.
[  OK  ] Started Rule-based Manager for Device Events and Files.
[  OK  ] Finished Coldplug All udev Devices.
         Starting Helper to synchronize boot up for ifupdown...
         Starting Show Plymouth Boot Screen...
[  OK  ] Finished Helper to synchronize boot up for ifupdown.
[  OK  ] Started Show Plymouth Boot Screen.
[  OK  ] Started Forward Password R…s to Plymouth Directory Watch.
[  OK  ] Reached target Local Encrypted Volumes.
[  OK  ] Reached target Paths.
[  OK  ] Found device /dev/ttyS2.
[  OK  ] Found device /dev/disk/by-uuid/24B4-43E5.
[  OK  ] Listening on Load/Save RF …itch Status /dev/rfkill Watch.
         Starting File System Check…/dev/disk/by-uuid/24B4-43E5...
         Starting Load/Save RF Kill Switch Status...
[  OK  ] Started File System Check Daemon to report status.
[  OK  ] Started Load/Save RF Kill Switch Status.
[  OK  ] Finished File System Check…n /dev/disk/by-uuid/24B4-43E5.
         Mounting /boot...
[  OK  ] Mounted /boot.
[  OK  ] Reached target Local File Systems.
         Starting Set console font and keymap...
         Starting Raise network interfaces...
         Starting Preprocess NFS configuration...
         Starting Orange Pi ZRAM config...
         Starting Tell Plymouth To Write Out Runtime Data...
         Starting Manage USB device functions...
[  OK  ] Finished Set console font and keymap.
[  OK  ] Finished Preprocess NFS configuration.
[  OK  ] Reached target NFS client services.
[  OK  ] Finished Tell Plymouth To Write Out Runtime Data.
[  OK  ] Finished Raise network interfaces.
[  OK  ] Finished Orange Pi ZRAM config.
         Starting Orange Pi memory supported logging...
[  OK  ] Started Manage USB device functions.
[  OK  ] Finished Orange Pi memory supported logging.
         Starting Journal Service...
[  OK  ] Started Journal Service.
         Starting Flush Journal to Persistent Storage...
[  OK  ] Finished Flush Journal to Persistent Storage.
         Starting Create Volatile Files and Directories...
[  OK  ] Finished Create Volatile Files and Directories.
[  OK  ] Started Entropy Daemon based on the HAVEGE algorithm.
         Starting RPC bind portmap service...
         Starting Update UTMP about System Boot/Shutdown...
[  OK  ] Finished Update UTMP about System Boot/Shutdown.
[  OK  ] Reached target System Initialization.
[  OK  ] Started Daily Cleanup of Temporary Directories.
[  OK  ] Listening on D-Bus System Message Bus Socket.
[  OK  ] Reached target Sockets.
         Starting Orange Pi hardware monitoring...
         Starting Orange Pi hardware optimization...
         Starting Orange Pi filesystem resize...
[  OK  ] Finished Orange Pi hardware monitoring.
[  OK  ] Started RPC bind portmap service.
[  OK  ] Finished Orange Pi hardware optimization.
[  OK  ] Reached target Remote File Systems (Pre).
[  OK  ] Reached target Remote File Systems.
[  OK  ] Reached target RPC Port Mapper.
[  OK  ] Finished Orange Pi filesystem resize.
[  OK  ] Reached target Basic System.
         Starting Save/Restore Sound Card State...
[  OK  ] Started Regular background program processing daemon.
[  OK  ] Started D-Bus System Message Bus.
         Starting Network Manager...
         Starting Remove Stale Onli…t4 Metadata Check Snapshots...
         Starting Initialize hardware monitoring sensors...
         Starting LSB: Load kernel …d to enable cpufreq scaling...
         Starting Dispatcher daemon for systemd-networkd...
[  OK  ] Started Orange Pi first run tasks.
[  OK  ] Created slice system-getty.slice.
         Starting System Logging Service...
         Starting Self Monitoring a…g Technology (SMART) Daemon...
         Starting Resets System Activity Logs...
         Starting User Login Management...
         Starting WPA supplicant...
[  OK  ] Finished Save/Restore Sound Card State.
[  OK  ] Finished Initialize hardware monitoring sensors.
[  OK  ] Reached target Sound Card.
[  OK  ] Finished Remove Stale Onli…ext4 Metadata Check Snapshots.
[  OK  ] Started LSB: Load kernel m…ded to enable cpufreq scaling.
         Starting LSB: set CPUFreq kernel parameters...
[  OK  ] Finished Resets System Activity Logs.
[  OK  ] Started LSB: set CPUFreq kernel parameters.
         Starting LSB: Set sysfs variables from /etc/sysfs.conf...
[  OK  ] Started LSB: Set sysfs variables from /etc/sysfs.conf.
[  OK  ] Started System Logging Service.
[  OK  ] Started Self Monitoring an…ing Technology (SMART) Daemon.
[  OK  ] Started User Login Management.
[  OK  ] Started WPA supplicant.
[  OK  ] Started Network Manager.
[  OK  ] Reached target Network.
[  OK  ] Reached target Network is Online.
         Starting chrony, an NTP client/server...
         Starting dnsmasq - A light…DHCP and caching DNS server...
         Starting LSB: Advanced IEEE 802.11 management daemon...
         Starting OpenVPN service...
         Starting /etc/rc.local Compatibility...
         Starting OpenBSD Secure Shell server...
         Starting Permit User Sessions...
[  OK  ] Started Unattended Upgrades Shutdown.
[  OK  ] Started vnStat network traffic monitor.
[  OK  ] Started LSB: Advanced IEEE 802.11 management daemon.
[  OK  ] Finished OpenVPN service.
[  OK  ] Started /etc/rc.local Compatibility.
[  OK  ] Finished Permit User Sessions.
         Starting Hold until boot process finishes up...
         Starting Terminate Plymouth Boot Screen...
         Starting Hostname Service...

orangepi3b login: orangepi (automatic login)

  ___  ____ ___   _____ ____
 / _ \|  _ \_ _| |___ /| __ )
| | | | |_) | |    |_ \|  _ \
| |_| |  __/| |   ___) | |_) |
 \___/|_|  |___| |____/|____/

Welcome to Orange Pi 1.0.6 Bullseye with Linux 6.6.0-rc5-rockchip-rk356x

System load:   35%              Up time:       0 min
Memory usage:  7% of 1.87G      IP:            192.168.0.100
CPU temp:      58°C             Usage of /:    16% of 14G

[ General system configuration (beta): orangepi-config ]

Last login: Wed Jul 10 10:02:08 UTC 2024 on tty1
7.3.2.3 保存环境变量

我们在uboot命令行设置了环境变量后,然后执行save保存失败了;

=> saveenv
Saving Environment to nowhere...

看这意思,应该是我们没有设置环境变量的保存位置,参考之前写的这篇文章:《Rockchip RK3399 - TPL/SPL方式加载uboot》,我们执行make menuconfig

root@ubuntu:/work/sambashare/rk3566/orangepi-build/u-boot/v2017.09-rk3588# make menuconfig

配置:

Environment --->
    Select the location of the environment (Environment in an MMC device)  --->    
           (X) Environment in an MMC device    

需要注意的是环境变量默认存储在eMMC地址0x3f8000,大小:0x8000;需要注意的是不要覆盖了其他分区。

CONFIG_ENV_SIZE=0x8000
CONFIG_ENV_OFFSET=0x3f8000

这样配置在使用Linux SDK编译uboot是不会生效的,我们需要修改configs/orangepi-3b-rk3566_defconfig,追加如下配置;

CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_SIZE=0x8000
CONFIG_ENV_OFFSET=0x3f8000
# CONFIG_ENV_IS_NOWHERE is not set     # 用于指定环境变量不被持久化到存储设备中,而仅存在于内存中
7.3.3 uboot编译安装

按照之前的步骤,重新编译ubootLinux镜像。

接下来我们进行测试,使用SD启动卡进入系统后安装新的u-bootdeb包。

7.3.3.1 上传uboot deb

将编译好的u-bootdeb包上传到开发板的Linux系统中;

root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/debs/u-boot$ scp linux-u-boot-current-orangepi3b_1.0.6_arm64.deb root@192.168.0.100:/root
7.3.3.2 卸载旧uboot deb

然后登录到开发板,卸载已安装的u-bootdeb包;

root@orangepi3b:~# apt purge -y linux-u-boot-orangepi3b-current
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
  linux-u-boot-orangepi3b-current*
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 1,024 B disk space will be freed.
7.3.3.3 安装新uboot deb

再安装刚才上传的新的u-bootdeb包;

root@orangepi:~# dpkg -i linux-u-boot-current-orangepi3b_1.0.6_arm64.deb
Selecting previously unselected package linux-u-boot-orangepi3b-current.
(Reading database ... 54666 files and directories currently installed.)
Preparing to unpack linux-u-boot-current-orangepi3b_1.0.6_arm64.deb ...
Unpacking linux-u-boot-orangepi3b-current (1.0.6) ...
Setting up linux-u-boot-orangepi3b-current (1.0.6) ...

由于未指定安装目录, 默认会安装到系统的根目录的各个目录。

然后运行nand-sata-install脚本;

然后选择5 Install/Update the bootloader on SD/eMMC来更新SD/eMMC中的u-boot

7.3.3.4 重启测试

更新完成后,重启系统再次进入uboot命令行,设置环境变量,保存:

=> pri fdtfile
fdtfile=rockchip/rk3566-orangepi-3b.dtb
=> setenv fdtfile rockchip/rk3566-orangepi-3b.dtb
=> saveenv
Saving Environment to MMC...
Writing to MMC(0)... done

7.4 dd命令烧录到eMMC

既然我们通过SD启动卡进入了debian系统,那么如何将该系统烧录到eMMC呢?

7.4.1 上传Linux镜像

将编译好的Linux镜像上传到开发板的Linux系统中;

root@ubuntu:/work/sambashare/rk3566/orangepi-build/output/images/Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5# scp Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img root@192.168.0.100:/root
7.4.2 确认eMMC设备节点

使用mount命令检查当前挂载的根文件系统的设备路径:

root@orangepi3b:~# lsblk
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
mtdblock0     31:0    0    16M  0 disk
mmcblk0      179:0    0  28.9G  0 disk
mmcblk0boot0 179:32   0     4M  1 disk
mmcblk0boot1 179:64   0     4M  1 disk
mmcblk1      179:96   0  14.9G  0 disk
├─mmcblk1p1  179:97   0     1G  0 part /boot
└─mmcblk1p2  179:98   0  13.7G  0 part /
zram0        252:0    0 957.6M  0 disk [SWAP]
zram1        252:1    0    50M  0 disk /var/log

可以看到/dev/mmcblk1p2文件系统挂载到了根路径,那/dev/mmcblk1是什么设备呢?

root@orangepi3b:~# fdisk -l /dev/mmcblk1
Disk /dev/mmcblk1: 14.88 GiB, 15980298240 bytes, 31211520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 562CABBE-E609-0748-8533-609E63F20DF8

Device           Start      End  Sectors  Size Type
/dev/mmcblk1p1   61440  2158591  2097152    1G Linux extended boot
/dev/mmcblk1p2 2158592 30867455 28708864 13.7G Linux filesystem

从设备空间大小可以看出这是我所使用的SD设备了,其大小为14.9G

而另外一个设备/dev/mmcblk0就是eMMC了,大小为28.9G

7.4.3 清空eMMC

然后我们可以使用dd命令清空下eMMC,注意of=参数后面请填入上面确定的eMMC设备节点;

root@orangepi3b:~# dd bs=4M if=/dev/zero of=/dev/mmcblk0 count=1100 status=progress
root@orangepi3b:~# sync
7.4.4 烧录Linux镜像

然后就可以使用dd命令烧录开发板的Linux镜像到eMMC中;

root@orangepi3b:~# ls -l
-rw-r--r-- 1 root root     553496 Jul 27 14:36 linux-u-boot-current-orangepi3b_1.0.6_arm64.deb
-rw-r--r-- 1 root root 4156555264 Jul 27 16:03 Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img
root@orangepi3b:~# dd if=Orangepi3b_1.0.6_debian_bullseye_server_linux6.6.0-rc5.img of=/dev/mmcblk0 bs=4M status=progress
4143972352 bytes (4.1 GB, 3.9 GiB) copied, 182 s, 22.8 MB/s
991+0 records in
991+0 records out
4156555264 bytes (4.2 GB, 3.9 GiB) copied, 185.002 s, 22.5 MB/s
root@orangepi3b:~# sync

当成功烧录开发板的Linux镜像到eMMC后,此时就可以使用poweroff命令关机了。

然后拔出SD卡,再短按电源按键开机,此时就会启动eMMC中的Linux系统了。

八、系统测试

系统默认登录账号和密码:

账号 密码
root orangepi
orangepi orangepi

我们首先查看系统信息;

orangepi@orangepi3b:~$ cat /etc/os-release
PRETTY_NAME="Orange Pi 1.0.6 Bullseye"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
orangepi@orangepi3b:~$ uname -a
Linux orangepi3b 6.6.0-rc5-rockchip-rk356x #1.0.6 SMP PREEMPT Wed Jul 10 17:59:08 CST 2024 aarch64 GNU/Linux

系统为debian,版本为bullseye,内核版本为6.6.0-rc5-rockchip-rk356x

8.1 网络测试

8.1.1 以太网

如果您使用的是以太网有线上网方式,请将网线对准开发板的RJ45端口插入。

通过命令ifconfig检查以太网是否正常,可以看到:

  • 有一个有线网卡ip地址为104,网卡名为eth0
  • 还有一个无线网卡,网卡名为wlan0

具体如下:

root@orangepi3b:~# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.100  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::46fd:1936:1b60:9711  prefixlen 64  scopeid 0x20<link>
        ether 82:c0:4b:d6:9c:de  txqueuelen 1000  (Ethernet)
        RX packets 112  bytes 10413 (10.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 81  bytes 6284 (6.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 76

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 54:78:c9:0d:93:b2  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

此外,使用工具ping判断是否连通网络;

root@orangepi3b:~$ ping wwww.baidu.com
PING ps_other.a.shifen.com (110.242.68.66) 56(84) bytes of data.
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=1 ttl=50 time=34.7 ms
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=2 ttl=50 time=34.4 ms
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=3 ttl=50 time=34.4 ms
8.1.2 wifi

我们使用nmcli device wifi list命令扫描无线网:

root@orangepi3b:~$ nmcli device wifi list
IN-USE  BSSID              SSID          MODE   CHAN  RATE        SIGNAL  BARS >
        8C:A6:DF:6F:E4:41  2202          Infra  6     405 Mbit/s  100     **** >
        9E:A6:DF:6F:E4:41  TPGuest_E441  Infra  6     405 Mbit/s  100     **** >

这里扫描到一个SSID2202的无线网。我们尝试连接它;

root@orangepi3b:~$  nmcli device wifi connect "2202" password "181x1521x112x33"
Device 'wlan0' successfully activated with 'c7bb9144-33dd-43d3-a3bc-296ac9597378'.

我们再次查看网络设备信息,可以发现wlan0ip地址被设置为了192.168.0.100

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.101  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::73a8:4230:190f:7741  prefixlen 64  scopeid 0x20<link>
        ether 54:78:c9:0d:93:b2  txqueuelen 1000  (Ethernet)
        RX packets 6  bytes 1379 (1.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 11  bytes 1422 (1.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

8.2 磁盘测试

8.2.1 查看块设备

查看eMMC块设备文件:

root@orangepi3b:~#  ls /dev/mmc* -l
brw-rw---- 1 root disk 179,  0 Jul 27 16:13 /dev/mmcblk0
brw-rw---- 1 root disk 179, 32 Jul 27 16:13 /dev/mmcblk0boot0
brw-rw---- 1 root disk 179, 64 Jul 27 16:13 /dev/mmcblk0boot1
brw-rw---- 1 root disk 179,  1 Jul 27 16:13 /dev/mmcblk0p1
brw-rw---- 1 root disk 179,  2 Jul 27 16:13 /dev/mmcblk0p2
crw------- 1 root root 242,  0 Jul 27 16:13 /dev/mmcblk0rpmb

这里一共有5个块设备节点和1个字符设备节点;其中:

  • /dev/mmcblk0表示的是eMMC这个设备,其主设备号为179,次设备号为0;
  • mmcblk0boot0mmcblk0boot1对应两个Boot Area Partition;每一个Boot Area Partition大小都是4MB
  • mmcblk0rpmb则为RPMB Partition;大小为4MB
  • mmcblk0pxUser Data Area划分出来的SW Partitions;实际上就是通过解析GPT分区表创建的分区,分区编号依次为1,2;

使用cat /proc/partitions,可以查看全部分区信息:

root@orangepi3b:~$ cat /proc/partitions
major minor  #blocks  name

 179        0   30310400 mmcblk0
 179        1    1048576 mmcblk0p1
 179        2   28919808 mmcblk0p2
 179       32       4096 mmcblk0boot0
 179       64       4096 mmcblk0boot1
  31        0      16384 mtdblock0
 252        0     980584 zram0
 252        1      51200 zram1
 252        2     980584 zram2
 
root@orangepi3b:~# lsblk
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
mtdblock0     31:0    0    16M  0 disk
mmcblk0      179:0    0  28.9G  0 disk
├─mmcblk0p1  179:1    0     1G  0 part /boot
└─mmcblk0p2  179:2    0  27.6G  0 part /
mmcblk0boot0 179:32   0     4M  1 disk
mmcblk0boot1 179:64   0     4M  1 disk
zram0        252:0    0 957.6M  0 disk [SWAP]
zram1        252:1    0    50M  0 disk /var/log
zram2        252:2    0 957.6M  0 disk /tmp

其中blocks表示分区的容量,每个blocks1KB。这里:

  • mtdblock0对应bootfs分区,大小为1GB
  • mmcblk0p2对应rootfs分区,大小为27.6GB
8.2.2 查看磁盘空间

这里我们可以通过df -hT查看磁盘空间信息;

root@orangepi3b:~# df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
udev           devtmpfs  885M     0  885M   0% /dev
tmpfs          tmpfs     192M  512K  192M   1% /run
/dev/mmcblk0p2 ext4       28G  2.0G   25G   8% /
tmpfs          tmpfs     958M     0  958M   0% /dev/shm
tmpfs          tmpfs     5.0M  4.0K  5.0M   1% /run/lock
/dev/zram2     ext4      941M   60K  877M   1% /tmp
/dev/mmcblk0p1 vfat     1022M   96M  927M  10% /boot
/dev/zram1     ext4       49M  6.5M   39M  15% /var/log
tmpfs          tmpfs     192M     0  192M   0% /run/user/1000
tmpfs          tmpfs     192M     0  192M   0% /run/user/0

其中:

  • /dev/mmcblk0p1这个vfat类型的文件系统挂载到了目录/boot
  • /dev/mmcblk0p2这个ext4类型的文件系统挂载到了根目录/
8.2.3 fdisk分区命令

使用fdisk -l查看磁盘/dev/mmcblk0分区情况:

root@orangepi3b:~# fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 28.91 GiB, 31037849600 bytes, 60620800 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: B292985E-0AD5-8344-9762-8985691A3911

Device           Start      End  Sectors  Size Type
/dev/mmcblk0p1   61440  2158591  2097152    1G Linux extended boot
/dev/mmcblk0p2 2158592 59998207 57839616 27.6G Linux filesystem

从上面的内容可以看到:磁盘/dev/mmcblk0大小为28.91 GiB,总容量为31037849600字节。Disklabel type: gpt表示分区表为gpt

/dev/mmcblk0p1的起始扇区是61440/dev/mmcblk0p2的起始扇区是2158592

那么扇区0开始的61440个扇区存放的是什么?存放就是 MiniLoaderAll.binuboot.img

8.2.4 parted分区命令

对于GPT格式的分区,fdisk工具是无能为力的,同时,fdisk工具对分区是有大小限制的,它只能划分小于2T的磁盘。

使用parted命令列出所有可识别的磁盘以及它们的分区信息。

root@orangepi3b:~# parted -l /dev/mmcblk0
Model: MMC A3A551 (sd/mmc)
Disk /dev/mmcblk0: 31.0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name    Flags
 1      31.5MB  1105MB  1074MB  fat32        bootfs  bls_boot
 2      1105MB  30.7GB  29.6GB  ext4

从上面的内容可以看到磁盘/dev/mmcblk0大小为31.0GBPartition Tablete: gpt表示分区表为gpt

参考文章

[1] Orange Pi 3B

[2] openwrt linux rootfs分区表arm盒子快速移植OpenWrt rootfs

[3] Armbian分区优化

[4] 从零开始自定义编译Armbian系统(斐讯N1为例)

[5] R329主线armbian内核,系统,驱动开发方法

[6] OrangePi-3B 折腾笔记 —— 构建 U-Boot

posted @ 2024-07-10 18:16  大奥特曼打小怪兽  阅读(727)  评论(0编辑  收藏  举报
如果有任何技术小问题,欢迎大家交流沟通,共同进步