NXP LSDK(Layerscape SDK)是NXP提供的一套适用于NXP Layerscape 和 QorIQ 系列处理器的下一代Linux开发套件,可以用于从引导程序、固件、内核、文件系统到应用程的全流程软件开发,可以从Linux Software and Development Tools页面点击SDKs for Layerscape
进行下载。目前最新版本是21.08,本文基于20.12,但是基本用法差别不大。
-
1. 环境搭建
- 1.1 搭建流程
- 1.2 帮助信息获取
- 1.3 Docker编译环境搭建
-
2. 固件编译
- 2.1 基本流程
- 2.2 单独编译
-
3. 内核编译
- 3.1 基本流程
- 3.2 内核配置
- 3.3 单独编译
-
4. 文件系统编译
- 4.1 初始文件系统编译
- 4.2 正式文件系统编译
- 5. 应用编译
-
6. 镜像创建和使用
- 6.1 FIT格式内核镜像创建
- 6.2 Legacy格式内核镜像创建
- 6.3 文件系统镜像创建
- 6.4 镜像烧写位置
1. 环境搭建
1.1 搭建流程
-
解压缩下载的
flexbuild_lsdkXXX.tgz
压缩包:$ tar xvf flexbuild_lsdk2012.tgz $ cd flexbuild_lsdk2012
注意:
该文件夹是一个git仓库,可以通过git命令进行修改、生成和应用patch等
-
Bootloader、内核、文件系统等默认不存在,只能在首次编译时自动克隆,如下所示:
flexbuild_lsdk2012$ tree packages/ -L 2 packages/ ├── apps ... ├── firmware │ ├── atf.mk │ ├── Makefile │ └── u-boot.mk ├── linux │ └── Makefile ├── Makefile └── rfs └── misc
-
设置环境变量:
flexbuild_lsdk2012$ source setup.env
注意:LSDK需要从github.com
和source.codeaurora.org
下载源码和镜像,因此建议修改flexbuild_lsdk2012/configs/build_lsdk.cfg
文件,将这两个软件源分别替换为hub.fastgit.org
和source.codeaurora.cn
,从而加快下载速度;替换后如果个别软件包下载失败,可以单独恢复为原始软件源。
1.2 帮助信息获取
LSDK20.12的帮助信息可以通过LSDK 20.12 User Guide获取,也可以通过如下命令获取:
flexbuild_lsdk2012$ flex-builder --help
Usage: flex-builder -m <machine>
or flex-builder -c <component> [-m <machine>] [-a <arch>] [-b <boottype>] [-f cfg-file]
or flex-builder -i <instruction> [-m <machine>] [-a <arch>] [-r <distro_type>:<distro_scale>] [-f cfg-file]
Most used example with automated build:
flex-builder -m ls1046ardb # automatically build all firmware, linux, apps components and distro userland for ls1046ardb
flex-builder -i auto -a arm64 # automatically build all firmware, linux, apps components and distro userland for all arm64 machines
Most used example with separate command:
flex-builder -i mkrfs # generate Ubuntu main arm64 userland, '-r ubuntu:main -a arm64' by default
flex-builder -i mkrfs -r ubuntu:lite # generate Ubuntu lite arm64 userland
flex-builder -i mkrfs -r yocto:tiny # generate Yocto-based arm64 tiny userland
flex-builder -i mkrfs -r buildroot:tiny # generate Buildroot-based arm64 tiny userland
flex-builder -i mkrfs -r centos # generate CentOS arm64 userland
flex-builder -i mkitb -r yocto:tiny # generate lsdk_yocto_tiny_LS_arm64.itb including rootfs_lsdk_yocto_tiny_arm64.cpio.gz
flex-builder -c linux -a arm64 # build linux kernel as per the default linux repo and branch/tag for all arm64 machines
flex-builder -c atf -m ls1046ardb -b sd # build ATF images for SD boot on LS1046ardb
flex-builder -i mkfw -m ls1046ardb -b sd # generate composite firmware for SD boot on ls1046ardb
flex-builder -i mkboot -a arm64 # generate boot partition tarball bootpartition_LS_arm64_lts.tgz for deployment
flex-builder -c apps # build all apps components(dpdk, fmc, restool, tsntool, optee_os, openssl, secure_obj, etc)
flex-builder -i merge-component # merge component packages into target arm64 userland
flex-builder -i packrfs # pack and compress target rootfs as rootfs_lsdk2012_ubuntu_main.tgz
flex-builder -i packapp # pack and compress target app components as app_components_LS_arm64.tgz
flex-builder -i download -m ls1043ardb # download prebuilt distro images for specific machine
flex-builder -c eiq # build eIQ AI/ML components (armnn,tensorflow,tflite,caffe,opencv,armcl,flatbuffer,protobuf,onnx,etc)
flex-builder -i repo-fetch # fetch all git repositories of components from remote repos if not exist locally
flex-builder -i repo-update # update all components to the latest TOP commmits of current branches
flex-builder -i mkdistroscr # generate distro boot script
flex-builder docker # create or attach Ubuntu docker container to run flex-builder in docker
flex-builder clean # clean all obsolete firmware/linux/apps image except distro rootfs
flex-builder clean-rfs # clean distro rootfs, '-r ubuntu:main -a arm64' by default
flex-builder clean-firmware # clean obsolete firmware image
flex-builder clean-linux # clean obsolete linux image
Most used options:
-m, --machine target machine, supports ls1012afrwy,ls1021atwr,ls1028ardb,ls1043ardb,ls1046ardb,ls1088ardb_pb,ls2088ardb,lx2160ardb_rev2,lx2162aqds,etc
-a, --arch target arch of processor, valid argument: arm64, arm64:be, arm32, arm32:be, ppc64, ppc32, arm64 by default
-b, --boottype type of boot media, valid argument: nor, sd, emmc, qspi, xspi, nand, default all types if unspecified
-c, --component component to be built, valid argument: firmware, apps, linux, atf, rcw, multimedia, networking, security, eiq,
weston, fmc, tsntool, openssl, vpp, dpdk, ovs_dpdk, pktgen_dpdk, openssl, optee_os, libpkcs11, secure_obj, etc
-r, --rootfs specify flavor of target rootfs, valid argument: ubuntu|yocto|centos:main|devel|lite|tiny
-i, --instruction instruction to do for dedicated function
-s, --secure enable security feature in case of secure boot
See docs/flexbuild_usage.txt and docs/build_and_deploy_distro.md for more information about the available commands.
1.3 Docker编译环境搭建
LSDK20.12要求使用Ubuntu18.04,如果没有,可以采用docker环境,命令如下所示:
flexbuild_lsdk2012$ flex-builder docker
执行上述命令后,将自动进入ubuntu18.04 docker镜像的shell,并可以在此基础上进行编译和开发。注意:
退出docker环境可以用
exit
命令;-
需要安装
docker.io
,具体命令如下所示:$ sudo apt install docker.io $ sudo usermod -aG docker xxx # 将当前用户加入docker群组,避免使用sudo执行
dockerhub官网比较慢,可以去aliyun申请个人容器镜像托管服务也就是专属容器镜像仓库,并使用
sudo docker login --username=XXX registry.cn-hangzhou.aliyuncs.com
登录,从而加速docker创建;-
容器中默认为root用户,需要为Yocto创建普通用户,添加到sudo列表中,并切换到新用户:
$ adduser yocto $ chmod +w /etc/sudoers $ vim /etc/sudoers # "root ALL=(ALL:ALL) ALL"的下一行插入"yocto ALL=(ALL:ALL) ALL" $ chmod -w /etc/sudoers $ su yocto
2. 固件编译
2.1 基本流程
内核编译流程可以参考LSDK 20.12 User Guide: 4.3.6 How to build Linux kernel with flex-builder,执行如下命令,克隆相关代码并进行编译:
flexbuild_lsdk2012$ flex-builder -c firmware -m lx2160ardb_rev2 -b <boot mode>
COMPONENT: firmware
MACHINE: lx2160ardb_rev2
BOOTTYPE: emmc
...
Building uboot for lx2160ardb_rev2 ...
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
Building UEFI_BIN ...
Build UEFI_BIN [Done]
Building RCW ...
...
Building ATF ...
...
Building mc_utils ...
...
Build fm_ucode [Done]
...
Build qe_ucode [Done]
...
Build mc_bin [Done]
Build phy_cortina [Done]
Build phy_inphi [Done]
...
Build pfe_bin [Done]
Build ddr_phy_bin [Done]
...
Build dp_firmware_cadence [Done]
...
其中,<boot mode>为启动介质类型,例如emmc,sd, qspi等。
2.2 单独编译
第一次编译完成之后,固件目录代码结构如下所示:
flexbuild_lsdk2012$ tree -L 1 packages/firmware/
packages/firmware/
├── atf
├── atf.mk
├── ddr_phy_bin
├── dp_firmware_cadence
├── fm_ucode
├── Makefile
├── mbedtls
├── mc_bin
├── mc_utils
├── pfe_bin
├── phy_cortina
├── phy_inphi
├── qe_ucode
├── rcw
├── u-boot
├── u-boot.mk
└── uefi_bin
其中,每个目录都可以单独编译,如下所示:
flexbuild_lsdk2012/packages/firmware$ export CROSS_COMPILE=aarch64-linux-gnu- # 设置交叉编译工具链
flexbuild_lsdk2012/packages/firmware$ export ARCH=arm64 # 设置ARCH
flexbuild_lsdk2012/packages/firmware$
flexbuild_lsdk2012/packages/firmware$ cd rcw/<board>
flexbuild_lsdk2012/packages/firmware/rcw/<board>$ make clean # 清理之前的编译结果
flexbuild_lsdk2012/packages/firmware/rcw/<board>$ make # 编译RCW
flexbuild_lsdk2012/packages/firmware/rcw/<board>$
flexbuild_lsdk2012/packages/firmware/rcw/<board>$ cd ../../atf
flexbuild_lsdk2012/packages/firmware/atf$ make help # 获取ATF编译帮助信息
usage: make [PLAT=<platform>] [OPTIONS] [TARGET]
PLAT is used to specify which platform you wish to build.
If no platform is specified, PLAT defaults to: fvp
platform = a3700|a5ds|a70x0|a70x0_amc|a80x0|a80x0_mcbin|agilex|arm_fpga|axg|corstone700|fvp|fvp_ve|g12a|gxbb|gxl|hikey|hikey960|
...
flexbuild_lsdk2012/packages/firmware/atf$ make clean PLAT=<board> # 清理之前的编译结果
flexbuild_lsdk2012/packages/firmware/atf$ make bl2 pbl PLAT=<platform> BOOT_MODE=<boot mode> RCW=<RCW file path> # 编译并生成包含PBL和BL2的bl2_<boot mode>.pbl文件
flexbuild_lsdk2012/packages/firmware/atf$
flexbuild_lsdk2012/packages/firmware/atf$ cd ../u-boot
flexbuild_lsdk2012/packages/firmware/u-boot$ make help # 获取U-Boot编译帮助信息
flexbuild_lsdk2012/packages/firmware/u-boot$ make distclean # 清理之前的编译结果
flexbuild_lsdk2012/packages/firmware/u-boot$ make <XXX_defconfig> # 使用<configs>目录下的配置文件生成编译配置信息
flexbuild_lsdk2012/packages/firmware/u-boot$ make # 编译U-Boot
flexbuild_lsdk2012/packages/firmware/u-boot$
flexbuild_lsdk2012/packages/firmware/u-boot$ cd ../atf
flexbuild_lsdk2012/packages/firmware/atf$ make PLAT=<platform> fip BL33=../u-boot/u-boot.bin # 编译BL31并与u-boot.bin组装生成fip.bin
3. 内核编译
3.1 基本流程
内核编译流程可以参考LSDK 20.12 User Guide: 4.3.6 How to build Linux kernel with flex-builder,执行如下命令,克隆Linux内核代码并进行编译:
flexbuild_lsdk2012$ flex-builder -m lx2160ardb_rev2 -c linux -a arm64
MACHINE: lx2160ardb_rev2
COMPONENT: linux
DESTARCH: arm64
...
注意:
* 上述命令将会下载和安装必须的库和编译工具,并使用git
将Linux内核克隆到flexbuild_lsdk2012/packages/linux/linux
目录,从而使得后续内核相关开发可以基于此git仓库进行;
-
根据
flexbuild_lsdk2012/configs/build_lsdk.cfg
,Linux内核相关配置如下所示,其中内核编译默认使用分支为LSDK-20.12-V5.4
:# kernel and linux modules git repositories linux_repo_url=https://source.codeaurora.cn/external/qoriq/qoriq-components/linux.git linux_repo_branch=linux-5.4 linux_repo_tag=LSDK-20.12-V5.4
编译出来的image位于
flexbuild_lsdk2012/build/linux/kernel/arm64/LS
目录下;可以使用
flex-builder -m lx2160ardb_rev2 -i clean-linux -a arm64
清理编译出来的image。
3.2 内核配置
LSDK支持使用如下命令对内核进行配置并编译:
$ flex-builder -m lx2160ardb_rev2 -c linux:custom -a arm64 # 配置内核
$ flex-builder -m lx2160ardb_rev2 -c linux -a arm64 # 编译内核
根据flexbuild_lsdk2012/configs/build_lsdk.cfg
,Linux内核默认配置文件为defconfig和lsdk.config:
# default linux config list
linux_config_list_arm64_ls="defconfig lsdk.config"
因此也可以通过直接修改flexbuild_lsdk2012/packages/linux/linux/arch/arm64/configs
目录下的defconfig
和lsdk.config
文件来配置内核。
3.3 单独编译
内核代码可以使用如下命令单独编译:
flexbuild_lsdk2012/packages/linux/linux$ export OUTPUT=../../../build/linux/linux/arm64/LS/output/LSDK-20.12-V5.4 # 设置输出目录
flexbuild_lsdk2012/packages/linux/linux$ export CROSS_COMPILE=aarch64-linux-gnu- # 设置交叉编译工具链
flexbuild_lsdk2012/packages/linux/linux$ export ARCH=arm64 # 设置ARCH
flexbuild_lsdk2012/packages/linux/linux$ make defconfig lsdk.config O=$OUTPUT # 创建配置文件
flexbuild_lsdk2012/packages/linux/linux$ make -j5 Image.gz O=$OUTPUT # 编译内核镜像
flexbuild_lsdk2012/packages/linux/linux$ make -j5 dtbs # 编译设备树
flexbuild_lsdk2012/packages/linux/linux$
flexbuild_lsdk2012/packages/linux/linux$
flexbuild_lsdk2012/packages/linux/linux$ cp -f $OUTPUT/arch/arm64/boot/Image.gz ../../../build/linux/kernel/arm64/LS/ # 拷贝内核镜像到LSDK要求的目录
flexbuild_lsdk2012/packages/linux/linux$ cp -f $OUTPUT/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dtb ../../../build/linux/kernel/arm64/LS/ # 拷贝设备树到LSDK要求的目录
flexbuild_lsdk2012/packages/linux/linux$
flexbuild_lsdk2012/packages/linux/linux$
flexbuild_lsdk2012/packages/linux/linux$ make distclean O=$OUTPUT # 清理编译
flexbuild_lsdk2012/packages/linux/linux$ make menuconfig O=$OUTPUT # 配置内核
flexbuild_lsdk2012/packages/linux/linux$ make savedefconfig O=$OUTPUT # 保存配置
注意:
- 内核编译使用
defconfig
和lsdk.config
作为配置文件,其中lsdk.config
用于对defconfig
进行调整; - 如果需要编译FIT格式镜像,需要将
Image.gz
和fsl-lx2160a-rdb.dtb
拷贝到1.6 FIT格式镜像编译描述的位置 -
distclean
用于清理编译目录;menucconfig
用于对内核进行配置;savedefconfig
用于将menucconfig
或者flex-builder -m lx2160ardb_rev2 -c linux:custom -a arm64
修改后的配置保存为目的文件夹下的defconfig
文件,覆盖内核源码目录下的arch/arm64/configs/defconfig
,做为下次编译的配置文件; - 编译完成后,
Image.gz
和fsl-lx2160a-rdb.dtb
分别位于输出目录的arch/arm64/boot/
和arch/arm64/boot/dts/freescale/
目录下。
4. 文件系统编译
4.1 初始文件系统编译
初始文件系统用作initrd
,可以参考LSDK 20.12 User Guide: 4.3.13 How to build various userland with custom packages,执行如下命令:
flexbuild_lsdk2012$ flex-builder -m lx2160ardb_rev2 -a arm64 -i mkrfs -r yocto:tiny # 编译Yocto:tiny根文件系统
MACHINE: lx2160ardb_rev2
DESTARCH: arm64
INSTRUCTION: mkrfs
DISTRO TYPE: yocto
DISTRO SCALE: tiny
...
flexbuild_lsdk2012$ flex-builder -m lx2160ardb_rev2 -a arm64 -i clean-rfs -r yocto:tiny # 清理Yocto:tiny根文件系统
...
注意:
- 上述命令将会下载和安装必须的库和编译工具,并使用
git
将Yocto克隆到flexbuild_lsdk2012/packages/rfs/yocto-poky
目录,从而使得后续用户空间相关开发可以基于此git仓库进行; - 编译出来的image为
rootfs_lsdk2012_yocto_tiny_arm64.cpio.gz
,在flexbuild_lsdk2012/build/images/
和flexbuild_lsdk2012/packages/rfs/initrd/
目录下各有一份,内容一致,可以作为初始文件系统,对应目录为'flexbuild_lsdk2012/build/rfs/rootfs_lsdk2012_yocto_tiny_arm64/target'; - 可以使用
flex-builder -m lx2160ardb_rev2 -a arm64 -i clean-rfs -r yocto:tiny
清理编译出来的image。
4.2 正式文件系统编译
正式文件系统包含更多组件,适用于应用开发,对应的配置文件位于flexbuild_lsdk2012/configs
目录中,可以根据需要使用和修改:
flexbuild_lsdk2012$ tree configs/
configs/
├── android
│ ├── build_imx8.cfg
│ └── build_layerscape.cfg
...
├── buildroot
...
│ ├── qoriq_arm32_be_devel_defconfig
│ ├── qoriq_arm32_be_tiny_defconfig
...
│ └── sec_imaevm.sh
├── centos
│ ├── CentOS-Base.repo
│ └── distro.cfg
├── linux
│ ├── android_kernel_fragment.config
│ ├── edgescale_demo_kernel.config
│ ├── ima_evm_arm32.config
│ ├── ima_evm_arm64.config
...
│ └── lttng.config
├── lsdk
│ ├── legal
│ └── README.LSDK
├── ubuntu
│ ├── additional_packages_list
│ ├── build.cfg
│ └── reconfigpkg.sh
└── yocto
├── local_arm32_devel.conf
├── local_arm32_tiny.conf
...
└── reconfig.sh
其中,yocto:devel
文件系统编译指令如下所示:
flexbuild_lsdk2012$ flex-builder -m lx2160ardb_rev2 -a arm64 -i mkrfs -r yocto:devel
MACHINE: lx2160ardb_rev2
DESTARCH: arm64
INSTRUCTION: mkrfs
DISTRO TYPE: yocto
DISTRO SCALE: devel
...
编译出来的image为flexbuild_lsdk2012/build/images/rootfs_lsdk2012_yocto_devel_arm64.cpio.gz
,对应目录为'flexbuild_lsdk2012/build/rfs/rootfs_lsdk2012_yocto_devel_arm64/target'。
5. 应用编译
根据LSDK 20.12 User Guide: 4.3.9 How to build application components in Flexbuild,可以采用如下方法单独编译指定的应用并合并到根文件系统中,以网络相关应用为例:
flexbuild_lsdk2012$ flex-builder -m lx2160ardb_rev2 -a arm64 -c networking -r yocto:tiny
flexbuild_lsdk2012$ flex-builder -m lx2160ardb_rev2 -a arm64 -c openssl -r yocto:tiny
flexbuild_lsdk2012$ flex-builder -m lx2160ardb_rev2 -a arm64 -i merge-component -r yocto:tiny
flexbuild_lsdk2012$ flex-builder -m lx2160ardb_rev2 -a arm64 -i packrfs -r yocto:tiny
根据LSDK 20.12 User Guide: 4.3.12 How to add new app component in Flexbuild,采用如下步骤创建, 以cJSON
为例:
-
修改
flexbuild_lsdk2012/configs/build_lsdk.cfg
,增加CONFIG_APP_<component>=y
,<component>_repo_url
和<component>_repo_branch
或<component>_repo_tag
,如下所示:# set default components for autobuild ... CONFIG_APP_CJSON=y ... # App component git repositories ... cjson_repo_url=https://github.com/DaveGamble/cJSON.git cjson_repo_tag=v1.7.10
-
修改
flexbuild_lsdk2012/packages/apps/generic/generic.mk
,参考其他应用,增加如下编译命令:.PHONY: cjson cjson: ifeq ($(CONFIG_APP_CJSON), y) ifeq ($(DESTARCH),arm64) @[ $(DISTROTYPE) != ubuntu -a $(DISTROTYPE) != yocto ] && exit || \ $(call fbprint_b,"cjson") && $(call fetch-git-tree,cjson,apps/generic) && \ cd $(GENDIR)/cjson && export CC=$(CROSS_COMPILE)gcc && \ mkdir -p build && cd build && cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. && \ $(MAKE) && sudo $(MAKE) install DESTDIR=$(RFSDIR) && $(call fbprint_d,"cjson") endif endif
6. 镜像创建和使用
6.1 FIT格式内核镜像创建
LS2160内核镜像采用FIT(扁平镜像树)格式,将内核、设备树和根文件系统打包成一个lsdk2012_yocto_tiny_LS_arm64.itb
文件。
根据LSDK 20.12 User Guide: 4.3.7 How to build linux itb based on custom kernel and various distros,以yocto:tiny
文件系统为例,打包命令如下所示:
flexbuild_lsdk2012$ flex-builder -m lx2160ardb_rev2 -a arm64 -i mkitb -r yocto:tiny
...
Configuration 15 (lx2160aqds)
Description: config for lx2160aqds
Kernel: kernel
Init Ramdisk: initrd
FDT: lx2160aqds-dtb
...
/home/xxx/work/lx2080/flexbuild_lsdk2012/build/images/lsdk2012_yocto_tiny_LS_arm64.itb [Done]
FIT格式镜像对应的配置文件为flexbuild_lsdk2012/configs/linux/linux_arm64_LS.its
,指定了对应镜像的相关信息:
/ {
description = "arm64 kernel, ramdisk and FDT blob";
#address-cells = <1>;
images {
kernel {
description = "ARM64 Kernel";
data = /incbin/("../../build/linux/kernel/arm64/LS/Image.gz");
type = "kernel";
arch = "arm64";
os = "linux";
compression = "gzip";
load = <0x84080000>;
entry = <0x84080000>;
hash {
algo = "sha1";
};
signature {
algo = "sha1,rsa2048";
key-name-hint = "dev";
};
};
initrd {
description = "initrd for arm64";
data = /incbin/("../../packages/rfs/initrd/rootfs_yocto_arm64_tiny.cpio.gz");
type = "ramdisk";
arch = "arm64";
os = "linux";
compression = "none";
load = <0x00000000>;
entry = <0x00000000>;
hash {
algo = "sha1";
};
signature {
algo = "sha1,rsa2048";
key-name-hint = "dev";
};
};
...
lx2160ardb-dtb {
description = "lx2160ardb-dtb";
data = /incbin/("../../build/linux/kernel/arm64fsl-lx2160a-rdb.dtb");
type = "flat_dt";
arch = "arm64";
os = "linux";
compression = "none";
load = <0x90000000>;
hash {
algo = "sha1";
};
signature {
algo = "sha1,rsa2048";
key-name-hint = "dev";
};
};
...
};
configurations {
...
lx2160ardb {
description = "config for lx2160ardb";
kernel = "kernel";
ramdisk = "initrd";
fdt = "lx2160ardb-dtb";
signature {
algo = "sha1,rsa2048";
key-name-hint = "dev";
sign-images = "kernel", "fdt","ramdisk";
};
};
...
};
};
由此可见,所使用的镜像分别是:
- flexbuild_lsdk2012/build/linux/kernel/arm64/LS/Image.gz;
- flexbuild_lsdk2012/packages/rfs/initrd/rootfs_lsdk2012_yocto_tiny_arm64.cpio.gz(编译过程中由
rootfs_yocto_arm64_tiny.cpio.gz
替换而来); - flexbuild_lsdk2012/build/linux/kernel/arm64/LS/fsl-lx2160a-rdb.dtb。
FIT格式镜像可以通过如下命令加载,其中a0000000
为镜像在内存中的位置:
=> bootm a0000000#$BOARD
6.2 Legacy格式内核镜像创建
Legacy格式镜像需要根据flexbuild_lsdk2012/configs/linux/linux_arm64_LS.its
中的配置信息,为内核和根文件系统加载U-Boot头部,然后与DTB一起加载:
- 为内核镜像添加U-Boot头:
flexbuild_lsdk2012$ mkimage -A arm64 -O linux -T kernel -C gzip -a 0x84080000 -e 0x84080000 -d build/linux/kernel/arm64/LS/Image.gz uImage
- 为文件系统镜像添加U-Boot头:
flexbuild_lsdk2012$ mkimage -A arm64 -O linux -T ramdisk -C none -a 0 -e 0 -d packages/rfs/initrd/rootfs_lsdk2012_yocto_tiny_arm64.cpio.gz uRamDisk
Legacy格式镜像可以通过如下命令加载:
=> bootm a0000000 a4000000 af000000
其中,a0000000
、a4000000
和af000000
分别为内核镜像uImage
、根文件系统镜像uRamDisk
和DTB文件的内存地址。
6.3 文件系统镜像创建
此处以EXT4
格式的yocto:devel
文件系统为例:
-
确认Yocto:devel版本文件系统真是位置和大小:
lx2080/fs$ ll ../flexbuild_lsdk2012/build/rfs/rootfs_lsdk2012_yocto_devel_arm64/ total 92 drwxrwxr-x 4 XXX XXX 4096 2月 22 15:09 ./ drwxrwxr-x 4 XXX XXX 4096 2月 22 11:57 ../ ... lrwxrwxrwx 1 XXX XXX 80 2月 22 14:56 target -> /home/XXX/yoctobuild/tmp/work/qemuarm64-poky-linux/core-image-sato/1.0-r0/rootfs/ lx2080/fs$ sudo du -d 1 -B 1024 /home/XXX/yoctobuild/tmp/work/qemuarm64-poky-linux/core-image-sato/1.0-r0/ ... 1111244 /home/XXX/yoctobuild/tmp/work/qemuarm64-poky-linux/core-image-sato/1.0-r0/rootfs ...
-
根据上一步骤得到的文件系统大小创建空白文件系统,例如当前文件系统为
1,111,244Kb
,因此创建一个1.2G
的EXT4
文件系统:lx2080/fs$ dd if=/dev/zero of=fs_user.ext4 bs=1024 count=1200000 lx2080/fs$ mkfs.ext4 -F fs_user.ext4
-
向空白文件系统中拷贝内容:
lx2080/fs$ mkdir tmpfs lx2080/fs$ sudo mount -o loop fs_user.ext4 tmpfs/ lx2080/fs$ sudo cp -a /home/XXX/yoctobuild/tmp/work/qemuarm64-poky-linux/core-image-sato/1.0-r0/rootfs/* tmpfs/ lx2080/fs$ sudo umount tmpfs
创建出来的文件系统镜像烧写到存储介质上之后,只需要修改内核启动参数bootargs
,使得根文件系统指向相应分区即可:
=> setenv bootargs 'console=ttyAMA0,115200 root=/dev/mmcblk1p5 earlycon=pl011,mmio32,0x21c0000 default_hugepagesz=1024mhugepagesz=1024m hugepages=2'
其中,mmcblk1p5
意为MMC设备1的分区5。
6.4 镜像烧写位置
镜像需要根据启动方式的不同烧写到Flash、SD/eMMC等启动介质的不同位置中,这些位置可以从flexbuild_lsdk2012/docs/memory_layout.txt
中查看:
+-----------------------------+---------|--------------|-----------------+
|Firmware Definition | MaxSize | Flash Offset | SD Start Block# |
|-----------------------------|---------|--------------|-----------------|
|RCW + PBI + BL2 (bl2.pbl) | 1MB | 0x00000000 | 0x00008 |
|-----------------------------|---------|--------------|-----------------|
|ATF FIP Image (fip.bin) | 4MB | 0x00100000 | 0x00800 |
|BL31 + BL32 + BL33 | | | |
|-----------------------------|---------|--------------|-----------------|
|Bootloader environment | 1MB | 0x00500000 | 0x02800 |
|-----------------------------|---------|--------------|-----------------|
|Secure boot headers | 2MB | 0x00600000 | 0x03000 |
|-----------------------------|---------|--------------|-----------------|
|DDR PHY FW or reserved | 512KB | 0x00800000 | 0x04000 |
|-----------------------------|---------|--------------|-----------------|
|Fuse provisioning header | 512KB | 0x00880000 | 0x04400 |
|-----------------------------|---------|--------------|-----------------|
|DPAA1 FMAN ucode | 256KB | 0x00900000 | 0x04800 |
|-----------------------------|---------|--------------|-----------------|
|QE firmware or DP firmware | 256KB | 0x00940000 | 0x04A00 |
|-----------------------------|---------|--------------|-----------------|
|Ethernet PHY firmware | 256KB | 0x00980000 | 0x04C00 |
|-----------------------------|---------|--------------|-----------------|
|Script for flashing image | 256KB | 0x009C0000 | 0x04E00 |
|-----------------------------|---------|--------------|-----------------|
|DPAA2-MC or PFE firmware | 3MB | 0x00A00000 | 0x05000 |
|-----------------------------|---------|--------------|-----------------|
|DPAA2 DPL | 1MB | 0x00D00000 | 0x06800 |
|-----------------------------|---------|--------------|-----------------|
|DPAA2 DPC | 1MB | 0x00E00000 | 0x07000 |
|-----------------------------|---------|--------------|-----------------|
|Device tree(needed by uefi) | 1MB | 0x00F00000 | 0x07800 |
|-------------+---------------|---------|--------------|-----------------|
|Kernel | | 16MB | 0x01000000 | 0x08000 |
|-------------|sdk_linux.itb |---------|--------------|-----------------|
|initrd rfs | | 30MB | 0x02000000 | 0x10000 |
|-----------------------------|---------|--------------|-----------------|
|CA or other uses | 2MB | 0x03e00000 | 0x1F000 |
+-----------------------------+---------+--------------+-----------------+
注意:
- Flash使用字节地址,eMMC卡使用SD卡块地址;
- 表格只包含存储介质最开始的若干M字节,其余空间用户可以自行分配。