1. aw-image-build介绍

aw-image-build是野火科技基于armbian镜像构建脚本修改并定制的一套专用于LubanCat-AW系列板卡的镜像构建工具, 可以实现对LubanCat-AW系列板卡镜像的一键式构建,保证了镜像构建过程的一致性、快捷性和完整性。

本镜像构建工具支持Debian和Ubuntu系统,不同release版本和不同桌面环境镜像的构建, 并支持自定义预安装软件包,可实现板卡镜像的即装即用。

1.1. 初始目录文件介绍

aw-image-build工具实质上是一些用于镜像构建或辅助构建的脚本和配置文件的合集,本身内容并不多。

我们使用git命令拉取aw-image-build工具所在的git仓库

1
2
3
4
5
# Github
git clone https://github.com/LubanCat/aw-image-build

# Gitee
git clone https://gitee.com/LubanCat/aw-image-build

拉取完成后,我们进入aw-image-build目录中,对其中的文件进行简单分析。

以下是aw-image-build仓库被拉取后的初始目录结构

1
2
3
4
5
6
7
# aw-image-build根目录下的文件及目录如下所示
.
├── build.sh
├── external
├── LICENSE
├── README.md
└── scripts
  • README.md :aw-image-build的快速使用说明,讲解了aw-image-build的基本使用方法

  • build.sh:整个aw-image-build工具的入口,我们可以通过 ./build.sh 命令来选择aw-image-build工具的功能,从而调用并执行对应功能的脚本

  • scripts:保存用于镜像构建相关脚本的目录

  • external:保存镜像构建过程中使用到的一些配置文件、二进制文件及工具的目录

1.2. 拉取源码

aw-image-build工具并不包含用于构建LubanCat板卡所需的源码,所以当我们拉取了aw-image-build工具仓库后, 还需要借助aw-image-build工具来拉取构建所需的源代码。

在aw-image-build根目录下运行 ./build.sh

当我们第一次运行 ./build.sh 时,会自动安装一些用于系统镜像构建的依赖工具,请耐心等待安装完成。

安装完成后会进入aw-image-build功能的选择页面。

menu

点击键盘上下按键选中 update source repository ,再按Enter键进入下一步

choose-board

选择我们要拉取源码的板卡,如 lubancat-a1 Allwinner H618 ,再按Enter键进入下一步

source-mirror

选择我们要拉取源码仓库的地址,可选项有Github和Gitlab。Gitlab地址用于野火内部开发使用, 用户可选Github地址,后续还会添加Gitee地址加速国内用户下载。这里以Gitlab地址为例,选中后按Enter键进入下一步

aw-image-build工具开始自动拉取相关板卡源码仓库。

如果是第一次拉取源码仓库,还会在拉取源码仓库之前下载后续构建所需的交叉编译工具链,下载时间与网络环境有关。

source

拉取完成以后我们再来看一下新增了哪些目录和文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 拉取源码以后的文件及目录如下所示
.
├── build
│   └── debug
├── build.sh
├── external
│   ├── cache
│   ├── config
│   ├── extensions
│   └── packages
├── LICENSE
├── README.md
├── scripts
├── source
│   ├── kernel
│   │   └── linux-5.4-h618
│   ├── lbc-firmware
│   └── u-boot
│       └── v2018.07-h618
└── toolchains
    ├── gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu
    ├── gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu
    └── gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi

可以看到在根目录下新增了build、source和toolchains三个目录

  • build:存放编译过程中的中间文件以及脚本的执行日志文件

  • toolchains:存放刚刚下载的,用于编译使用的交叉编译工具链

  • source:存放构建过程中使用的源代码,如kernel、u-boot源码,一些deb软件包的源码

1.3. 镜像构建

1.3.1. 一键构建镜像

可以在aw-image-build根目录运行 ./build.sh 来进入交互式构建界面

menu

可以看到,在我们的功能选择界面,总共有7个选项

  • Build all step :构建完整镜像,自动执行step1到step4

  • step1.Build Kernel:单独编译内核

  • step2.Build U-boot:单独编译u-boot

  • step3.Build base-rootfs and deb packages:构建根文件系统镜像并打包自定义deb软件包

  • step4.Pack image:将系统镜像的各个部分按规则打包成一个完整的用于烧录的镜像

  • update source repository:下载或更新软件源码

  • clean source/build/out files:清理拉取的源代码、构建过程中产生的文件、最终输出的镜像

如果我们只是需要构建一个用于板卡启动的镜像,选择 Build all step 再按Enter键进入下一步

choose-board

选择我们要构建镜像的板卡,如 lubancat-a1 Allwinner H618

choose-release

选择我们要构建的根文件系统的发行版和release版本,如 Debian 11 Bullseye

choose-type

选择我们要构建的根文件系统是否为桌面版,如 desktop

choose-desktop

选择我们要构建的根文件系统的桌面环境,如 Xfce

choose-configuration

选择我们要构建的根文件系统的桌面环境的配置文件,默认是 base configuration

choose-app

选择我们要构建的根文件系统预装的软件包,使用空格键选中,再按Enter键开始构建过程

构建完成后镜像保存在out/images目录下

1.3.2. 单步构建镜像

对用户而言,如果要对LubanCat-AW系列板卡进行二次开发,需要预装应用、修改调试内核等,可能就涉及到了根文件系统或内核的单独构建, 此时就可以选择单步构建的方式。

在aw-image-build根目录运行 ./build.sh 来进入交互式构建界面

menu

可以看到,除了使用 Build all step 进行一键构建以外,还有step1到step4的单步构建选项, 实际上一键构建的过程,就是顺序调用这四部分脚本的过程。

注意

由于全志某些版本的u-boot对内核生成的部分内容有依赖关系,所以在构建u-boot之前必须先构建kernel,相关内容在下面的u-boot小节进行详细说明。

1.3.2.1. step1.Build Kernel

这一步是单独编译内核源码并生成内核deb包

运行 ./build.sh 进入交互式构建界面,选择 step1.Build Kernel 再按Enter键进入下一步

choose-board

选择我们要编译内核的板卡,如 lubancat-a1 Allwinner H618

choose-branch

如果我们的板卡支持多种版本的内核,这时还会有编译分支版本的选择,如果仅支持一个版本的话,将会使用默认版本,不会弹出选择页面。

接下来就进入了内核的构建过程,在构建过程中,会有一些内核构建的提示信息

kernel-build
  • Compiler kernel info:编译的内核版本

  • Compiler kernel path:编译的内核保存路径

  • Copy kernel config:使用的内核配置文件

  • Compiler kernel command:内核构建命令

  • Compiler kernel deb:内核deb包的构建命令

在构建结束后还会打印一些辅助信息

kernel-buildinfo
  • Kernel deb path:构建生成的内核deb文件保存路径

  • Kernel deb name:构建生成的内核deb包名称

如果我们对内核内容做了修改,此时将生成的内核deb包传输到正在运行的板卡中, 使用dpkg -i linux-xxx.deb,然后重启板卡,就可以更新升级内核了

警告

LubanCat-A1板卡使用的5.4.125版本的内核使用了打包在u-boot镜像中的设备描述文件,所以更新内核deb包时无法更新设备树。当我们在内核源码中修改了设备树后,需要先编译内核,再编译u-boot,最后将u-boot镜像更新到我们的板卡中。

如果我们想要修改内核配置文件来开启或关闭内核的某项功能,应该如何操作,以LubanCat-A1板卡为例:

首先我们需要进入内核所在的目录,可以查看构建时的提示信息 Compiler kernel path 进入对应的目录

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 进入内核源码目录
cd /home/jiawen/Allwinner/H618/aw-image-build/source/kernel/linux-5.4-h618

# 修改内核配置文件
make ARCH=arm64 menuconfig

# 修改完成后保存并退出menuconfig配置页面,此时修改的配置保存在.config中,我们还需要将修改 同步到板卡的内核配置文件中
# 保存defconfig配置文件
make ARCH=arm64 savedefconfig

# 使用生成的defconfig文件替换板卡配置文件
cp defconfig arch/arm64/configs/linux_h618_defconfig

# 查看板卡配置文件修改的内容
git diff arch/arm64/configs/linux_h618_defconfig

至此,板卡的内核配置文件的修改就完成了,我们可以通过构建工具来重新编译内核

1.3.2.2. step2.Build U-boot

这一步是单独编译u-boot并将生成的u-boot镜像打包为deb

运行 ./build.sh 进入交互式构建界面,选择 step2.Build U-boot 再按Enter键进入下一步

choose-board

选择我们要编译u-boot的板卡,如 lubancat-a1 Allwinner H618

choose-branch

如果我们的板卡支持多种版本的内核,为了配合内核的启动,就会有不同版本的u-boot, 这一步还会有编译分支版本的选择,选择与内核分支一致的版本,如果仅支持一个版本的话,将会使用默认版本,不会弹出选择页面。

接下来就进入了u-boot的编译过程,在编译时会有一些构建的提示信息

uboot-build
  • Compiler uboot info:编译的u-boot版本

  • Compiler uboot path:编译的u-boot保存路径

  • Compiler uboot config:使用的u-boot配置文件

  • Compiler uboot command:u-boot构建命令

结束后还会打印一些辅助信息

uboot-buildinfo
  • Target directory:构建生成的u-boot deb文件保存路径

  • File name:构建生成的u-boot deb包名称

如果我们对u-boot内容做了修改,此时将生成的u-boot deb包传输到正在运行的板卡中, 使用dpkg -i lubancat-a1-uboot-xxx.deb将u-boot镜像解压到板卡根文件系统中, 最后还需要使用脚本将u-boot镜像写入进我们存储设备的指定位置覆盖原来的u-boot。

1
2
# 使用管理员权限运行脚本
sudo nand-sata-install
uboot-install

选择选项 5 Install/Update the bootloader on SD/EMMC

warning

确认警告信息

warting

提示写入完成,完成后我们重启板卡即可使用更新后的u-boot

警告

由于LubanCat-A1板卡使用的全志v2018.07版本的u-boot需要使用内核设备树文件和全志的硬件配置文件sys_config.fex来共同生成系统的设备描述文件并打包到u-boot镜像中,并且u-boot和内核都使用这一设备描述文件,所以当我们在内核源码中修改了设备树文件后,需要先编译内核,再编译u-boot,最后将u-boot镜像更新到我们的板卡中。

1.3.2.3. step3.Build base-rootfs and deb packages

这一步是单独构建基础根文件系统及本地自定义的deb软件包

运行 ./build.sh 进入交互式构建界面,选择 step3.Build base-rootfs and deb packages 再按Enter键进入下一步

choose-board

选择我们要构建镜像的板卡,如 lubancat-a1 Allwinner H618

choose-branch

如果我们的板卡支持多种版本的内核,为了适配不同内核的些许差异,这一步还会有编译分支版本的选择, 选择与内核分支一致的版本,如果仅支持一个版本的话,将会使用默认版本,不会弹出选择页面。

os-release

选择我们要构建的发行版和release版本,目前aw-image-build支持构建Debian系统和Ubuntu系统, 并且根据内核版本的不同,还可以选择不同的release版本,如Debian系:Bullseye、bookworm等; Ubuntu系统:focal、jammy等

image-type

然后就是选择我们要构建的根文件系统的类别,server版是不带桌面的版本,适合小内存,小存储,对性能要求高的用户, desktop是带桌面的版本,安装了一些常用的桌面应用,占用资源较多,但是操作较为便利,和桌面PC操作方式类似。

如果选择的是server版,接下来就进入了根文件系统的构建过程;如果选择的是desktop版本,还需要进一步的配置。

desktop-env

选择要安装的桌面套件的版本,我们根据板卡资源配置的多少,已经筛选出了适合安装的版本

desktop-config

选择桌面套件的配置文件,一般默认 base configuration

desktop-app

选择额外的预装软件包,这些软件包都是可选的。出于对发布镜像体积的考虑,在随板卡发布的镜像中默认未安装这些额外的软件包

接下来就进入了根文件系统及部分本地deb软件包的构建过程,构建时间与网络性能和磁盘性能密切相关。

由于根文件系统的构建很耗费时间,为了减少相同内容根文件系统的重复构建,我们通过对比需要安装的软件包名称字符的哈希值来判断根文件系统是否需要重新构建。

首次构建的基础根文件系统压缩包保存在 aw-image-build/build/rootfs-base 目录下, 其命名规则是 系统release版本-桌面套件版本-处理器架构.软件包字符串哈希值.压缩格式 , 当我们需要二次构建根文件系统时,首先计算出所有要安装的软件包的名称的字符串哈希值, 然后在存放基础根文件系统压缩包的目录下寻找是否存在对应的压缩包,如果存在的话就跳过构建过程, 直接进行下一步骤,如果不存在,就构建新的基础根文件系统并压缩保存。

完成了根文件系统的构建后,还会继续使用本地源码去预先构建要在stop4中安装到系统中的自定义deb软件包以及和保存板卡间差异内容的deb包等。

rootfs-base

有时候也会遇到基础根文件系统内容损坏,需要强制重新构建的情况,这时将build/rootfs-base目录下的对应名称的所有文件都删除再重新编译即可。

1.3.2.4. step4.Pack image

这一步是将step1-step3生成的内容进行安装和打包,生成一个完整的用于板卡烧录的镜像。

运行 ./build.sh 进入交互式构建界面,选择 step3.Build base-rootfs and deb packages 再按Enter键进入下一步

choose-board

选择我们要构建镜像的板卡,如 lubancat-a1 Allwinner H618

choose-branch

如果我们的板卡支持多种版本的内核,为了统一版本分支,这一步还会有编译分支版本的选择, 选择与内核分支一致的版本,如果仅支持一个版本的话,将会使用默认版本,不会弹出选择页面。

os-release

选择我们要打包的根文件系统的发行版和release版本,后续的内容与第三步中的步骤相同,不再赘述,选择完所有的选项后进入了正式的打包流程。

install-deb

首先解压基础根文件系统并挂载到工作目录,然后使用chroot命令对根文件系统中的内容进行操作, 如更新根文件系统软件包列表,将软件包更新到最新版本, 安装u-boot的deb包和内核deb包

install-bsp

除此之外,还需要安装本地自定义deb软件包、硬件差异相关的bsp包、桌面环境差异相关的deb包等

img-dd

处理完根文件系统中的内容后,解除根文件系统的挂载。

根据根文件系统的大小来计算出整个系统镜像所需的空间,然后使用dd命令创建一个同样大小的空的、没有内容的镜像文件。 按照各部分的大小对镜像文件分区和格式化。

img-sync

将刚刚格式化的镜像文件分区挂载,把前面生成的完整的根文件系统中的所有内容同步到挂载的分区中,然后取消挂载

img-gz

在镜像文件前端的固定位置写入u-boot,用于启动镜像。 整个系统镜像的打包就结束了,后续是一些镜像的压缩过程,主要是为了便于文件的传输和发布