NXP LSDK简明实用手册

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. 解压缩下载的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
      
  2. 设置环境变量:

    flexbuild_lsdk2012$ source setup.env
    

注意LSDK需要从github.comsource.codeaurora.org下载源码和镜像,因此建议修改flexbuild_lsdk2012/configs/build_lsdk.cfg文件,将这两个软件源分别替换为hub.fastgit.orgsource.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内核默认配置文件为defconfiglsdk.config

# default linux config list
linux_config_list_arm64_ls="defconfig lsdk.config"

因此也可以通过直接修改flexbuild_lsdk2012/packages/linux/linux/arch/arm64/configs目录下的defconfiglsdk.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   # 保存配置

注意

  • 内核编译使用defconfiglsdk.config作为配置文件,其中lsdk.config用于对defconfig进行调整;
  • 如果需要编译FIT格式镜像,需要将Image.gzfsl-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.gzfsl-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根文件系统
...

注意

  • 上述命令将会下载和安装必须的库和编译工具,并使用gitYocto克隆到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一起加载:

  1. 为内核镜像添加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
    
  2. 为文件系统镜像添加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

其中,a0000000a4000000af000000分别为内核镜像uImage、根文件系统镜像uRamDisk和DTB文件的内存地址。

6.3 文件系统镜像创建

此处以EXT4格式的yocto:devel文件系统为例:

  1. 确认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
    ...
    
  2. 根据上一步骤得到的文件系统大小创建空白文件系统,例如当前文件系统为1,111,244Kb,因此创建一个1.2GEXT4文件系统:

    lx2080/fs$ dd if=/dev/zero of=fs_user.ext4 bs=1024 count=1200000
    lx2080/fs$ mkfs.ext4 -F fs_user.ext4
    
  3. 向空白文件系统中拷贝内容:

    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字节,其余空间用户可以自行分配。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容