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

Rockchip RK3566 - orangepi-build编译

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

开发板 :Orange Pi 3B开发板
eMMC32GB
LPDDR48GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot2017.09
linux5.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:具体作用不太了解,看名字应该是SPI相关的;
  • 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的。

这里我们看一下这个脚本:

# 这里是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脚本;

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
  • 编译使用的dts文件为:<SDK>/kernel/orange-pi-5.10-rk35xx/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.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
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) 制作镜像文件;

  • 制作镜像文件,并格式化分区,默认类型为ext4
  • 再将配置好的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 ]
# 制作镜像文件,并格式化分区,默认类型为ext4
[ 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
5.2.2 BSP支持包

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

5.2 Linux镜像分析

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

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

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

5.3.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镜像只有两个分区:

  • 分区1:扇区61440~2158591,大小为1GB
  • 分区2:扇区2158592~8306654,大小为2.9GB

前文我们说了第一个分区用来存放内核镜像,起始地址转换成16进制为0xF000扇区,我们在介绍rk3399的时候内核都是烧录到0x8000扇区的,这里为啥变了呢?

5.3.2 查看rootfs内容

通过分区表可以看到rootfs为第二分区,并且偏移量为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映像文件或其他类似的文件系统镜像文件。

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

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

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

root@ubuntu:/work/sambashare/rk3566/orangepi-build$ sudo umount /mnt/rootfs
5.3.3 查看boot目录

上面我们说过boot目录会挂载Linux镜像的第一个分区,那我们想查看该目录内容要怎么做呢,我们创建一个/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,至于为啥是这样,后面有时间再深入研究。

5.3.1.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


# 将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
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
        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等;
5.3.1.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
5.3.1.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

参考文章

[1] Orange Pi 3B

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

[3] Armbian分区优化

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

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

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