【Yocto Transplantation】Technology Sharing


foreword

Generally speaking, a complete embedded Linux system mainly includes U-Boot, Linux kernel, and root file system. Building an embedded Linux system is actually to transplant U-Boot, Linux kernel, and root file system to the hardware platform used, and according to actual project needs, it may involve adding software provided by a third party to the built embedded system. In the Linux system, so that the application program can realize the product requirements quickly, conveniently and reliably. There are many ways and tools to build an embedded Linux system. This article uses Yocto to build an embedded Linux system running on NXP's imx8mm platform. The Yocto Project is well known in the embedded Linux world for its flexibility and ease of use. The purpose of the Yocto project is to create a Linux distribution for embedded hardware and software manufacturers. Many core board manufacturers use Yocto to build the corresponding embedded Linux distribution. This sharing serves as a basic introduction to Yocto to help you understand the basic process and method of building an embedded Linux system based on Yocto.


1. Get Yocto software source code

Switch to the Yocto working path /opt/work/yocto-kirkstone, and then use the following repo command to get the Yocto project (clone the imx-linux-kirkstone branch of the NXP official imx-manifest.git project):

repo init -u https://source.codeaurora.org/external/imx/imx-manifest -b imx-linux-kirkstone -m imx-5.15.32-2.0.0.xml

Note: Before executing the above instructions, you need to install Python3 in the ubuntu environment

After the cloning is completed, /opt/work/yocto-kirkstonethere are files in the directory /.repo/manifests/imx-5.15.32-2.0.0.xml, which define which Git libraries used under the imx-linux-kirkstone branch. Finally, in /opt/work/yocto-kirkstonethe directory, run repo syncthe command to get the Yocto project.

After successfully obtaining the source code of the Yocto project, you will /opt/work/yocto-kirkstone/get imx-setup-release.sh, setup-environment, sourcesand other files under the Yocto working path.
insert image description here
in:

  • imx-setup-release.sh: This script is used to initialize Yocto to build the embedded Linux system working environment.
  • setup-environment: This script sets up the Yocto working environment according to imx-setup-release.shthe parameters entered when running the script MACHINE, DISTROand .-b <build_dir>
  • sources folder: many files are stored under this folder, including some source codes and compilation tools, which are used to build embedded Linux systems.
    insert image description here
  • base: This folder mainly stores bblayers.conf and setup-environment, which are used when building the Yocto working environment.
  • meta-advantech : Project development uses this layer.
  • meta-clang: C language family frontend and LLVM compiler backend.
  • meta-browser : provides several browsers, such as gnome, mozilla.
  • meta-freescale : Provides some basic support software based on the Freescale ARM official reference board.
  • meta-imx
    • meta-bspIncluding the configuration information of uboot and kernel, the directories are
      sources/meta-imx/meta-bsp/recipes-bsp/u-boot
      sources/meta-imx/meta-bsp/recipes-kernel
    • meta-sdkIncluding some updated software, such as the bbappend file of Google Chrome is in this directory
      sources/meta-imx/meta-sdk/dynamic-layers/chromium-browser-layer/recipes-browser/chromium
    • meta-ml: Software related to machine learning.
  • meta-freescalse-distro: some official embedded Linux distributions.
  • meta-freescalse-3rdparty: Third-party board support software.
  • meta-nxp-demo-experience: Some demos officially provided by NXP NXP.
  • meta-openembedded: Some collections of OE kernels, which define some tool software used to build Yocto.
  • meta-qt6: QT6 related software.
  • poky: The basic distribution of Yocto , based on this version, build your own embedded Linux distribution.

It should be noted that i.MXthe configuration of the board is mainly defined in meta-imxand , including the kernel and some board-level hardware configuration information.meta-freescaleLinuxU-Boot

2. Initialize the Yocto build directory

After obtaining the Yocto project source code through repo, you also need to initialize the Yocto build directory, which is used for Yocto to build the working environment of the embedded Linux system (actually create some folders, initialize some variable values, and obtain configuration files for building specific embedded Linux distributions). Under the Yocto project source path (/opt/work/yocto-kirkstone/) obtained by repo, Freescales provides the imx-setup-release.sh script.

2.1.imx-setup-release.sh script running

Enter the following command in the path where imx-setup-release.sh is located to execute the imx-setup-release.sh script

MACHINE=imx8mmeamb9918a1 DISTRO=fsl-imx-xwayland source  imx-setup-release.sh -b eamb9918a1

imx-setup-release.shAfter the script runs, it will first read some EULA licenses. After the reading is completed, the initialization of the Yocto build directory is completed.
After the script finishes running, eamb9918a1a folder will be automatically generated and switched to eamb9918a1the path. The subsequent system construction process is completed under this folder. At the same time, under the eamb9918a1 folder, a conf folder will be generated:
insert image description here
there are two important files in the conf folder: bblayers.confand local.conftwo configuration files:

  • eamb9918a1/conf/bblayer.conf: This configuration file defines the meta-layers needed to build the embedded Linux system distribution.
  • eamb9918a1/conf/local.conf: This configuration file defines the configuration items of MACHINE and DISTRO .

2.2.imx-setup-release.sh script analysis

When the imx-setup-release.sh script is running, three main parameters need to be input:

  • MACHINE=imx8mmeamb9918a1
  • DISTRO=fsl-imx-xwayland
  • -b eamb9918a1

In general, the imx-setup-release.sh script determines the build environment through these three parameters, among which, an eamb9918a1 folder is -b eamb9918a1generated to store the temporary files, build logs and final Generated installation files, etc. At the same time, Yocto finds the corresponding configuration files (.conf) according to these two parameters, and these configuration files define the functions and status of the embedded Linux system to be built. For example:DISTROMACHINE

  • The imx-setup-release.sh script will find the .conf file corresponding to the value of DISTRO under the source path according to the value of DISTRO, for example: , it willDISTRO= fsl-imx-xwayland find the file sources/meta-imx/meta-sdk/conf/distrounder the path fsl-imx-xwayland.conf, in which some variables are defined, use For configuring embedded Linux distributions. At the same time, it is found that sources/meta-imx/meta-bsp/conf/machineunder the path, the hardware platform that supports the configuration of the embedded Linux system is defined.
  • imx-setup-release.sh will find the .conf file corresponding to the MACHINE value under the source path according to the value of MACHINE, for example: , it will find the file under the path , in which some variables are defined for Configure the hardware platform on which embedded Linux runs.MACHINE= imx8mmeamb9918a1sources/meta-advantech/meta-adv-imx/conf/machineimx8mmeamb9918a1.conf

2.3. The setup-environment script runs

In the imx-setup-release.sh script, the setup-environment script will be DISTRO=$FSLDISTRO MACHINE=$MACHINE . ./$PROGNAME $BUILD_DIRcalled .

# Set up the basic yocto environment
if [ -z "$DISTRO" ]; then
   DISTRO=$FSLDISTRO MACHINE=$MACHINE . ./$PROGNAME $BUILD_DIR
else
   MACHINE=$MACHINE . ./$PROGNAME $BUILD_DIR
fi

View the help information of the setup-environment script, which lists the supported MACHINEs under the Yocto path , and also explains how to use the setup-environment script.

usage()
{
    
    
    echo -e "
Usage: MACHINE=<machine> DISTRO=<distro> source $PROGNAME <build-dir>
Usage:                                   source $PROGNAME <build-dir>
    <machine>    machine name
    <distro>     distro name
    <build-dir>  build directory

The first usage is for creating a new build directory. In this case, the
script creates the build directory <build-dir>, configures it for the
specified <machine> and <distro>, and prepares the calling shell for running
bitbake on the build directory.

The second usage is for using an existing build directory. In this case,
the script prepares the calling shell for running bitbake on the build
directory <build-dir>. The build directory configuration is unchanged.
"

    ls sources/meta-advantech/*/conf/machine/*.conf > /dev/null 2>&1
    ls sources/meta-freescale-distro/conf/distro/fslc-*.conf > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo -e "
Supported machines: `echo; ls sources/meta-advantech/*/conf/machine/*.conf \
| sed s/\.conf//g | sed -r 's/^.+\///' | xargs -I% echo -e "\t%"`

Supported Freescale's distros: `echo; ls sources/meta-freescale-distro/conf/distro/fslc-*.conf \
| sed s/\.conf//g | sed -r 's/^.+\///' | xargs -I% echo -e "\t%"`

Available Poky's distros: `echo; ls sources/poky/meta-poky/conf/distro/*.conf \
| sed s/\.conf//g | sed -r 's/^.+\///' | xargs -I% echo -e "\t%"`

Examples:

- To create a new Yocto build directory:
  $ MACHINE=imx8mmeamb9918a1 DISTRO=fsl-imx-xwayland source imx-setup-release.sh -b imx8mmeamb9918a1

- To use an existing Yocto build directory:
  $ source $PROGNAME build
"
    fi
}

By comparing the imx-setup-release.sh and setup-environment scripts, the imx-setup-release.sh script mainly completes EULA licensing related operations and writes layer, machine, distro and other information into configuration files; in setup- In the environment script, complete the creation of the build directory emab9918 and find the configuration file in the corresponding path according to the two parameters of DISTRO and MACHINE, and prepare the environment for calling the shell to run the bitbake build tool in the build directory.


3. Build an embedded Linux system

3.1. Brief analysis of BitBake build system process

The first step in a Bitbake build is to parse the metedata base configuration files that determine some of the capabilities and characteristics of the embedded Linux system distribution being built.
Let's first understand a few concepts
of metadata : After obtaining the yocto project through repo, there are some folders in the source directory, and these folders are metadata one by one . When using bitbake to build the system, which metadata will be used is imx-setup-release.shdetermined when the script is initialized. Under the build/conf/ path, a bblayers.conf configuration file is generated , and the bitbake tool will be based on the bblayers.conf file The definition in determines which metadata to use.
insert image description here
recipes : In metadata, there are many files stored in the source/meta-xxx folder,
insert image description here
of which:
classes: the bbclass file under this folder, the bbclass file saves the general function or variable, It can be referenced by the inherit keyword in other recipes . A bit similar to the concept of classes in C++.
conf: The layer.conf file under the conf folder defines which .bb and .bbappend files used in the metadata participate in building the embedded Linux system.
recipes-xxx: There are many .bb or .bbappend files in this folder, which define the software packages or source codes needed to build the embedded Linux system, mainly including:

  • Basic information of the software package: author, home page, license, etc.
  • Version Information
  • dependent file
  • Where and how to download packages
  • Software package patch information: whether a patch is required, patch download address and method, etc.
  • How to configure, how to compile the software package, installation location, etc.
    Take the bb file of package u-boot as an example:
qing@Qing:/opt/work/yocto-kirkstone/sources/meta-imx/meta-bsp/recipes-bsp/u-boot$ cat u-boot-imx_2022.04.bb 
# Copyright (C) 2013-2016 Freescale Semiconductor
# Copyright 2018 (C) O.S. Systems Software LTDA.
# Copyright 2017-2022 NXP

require recipes-bsp/u-boot/u-boot.inc
###############################################################
########### For upstream u-boot-imx-common_2022.04.inc ########
DESCRIPTION = "i.MX U-Boot suppporting i.MX reference boards."

LICENSE = "GPL-2.0-or-later"
LIC_FILES_CHKSUM = "file://Licenses/gpl-2.0.txt;md5=b234ee4d69f5fce4486a80fdaf4a4263"

UBOOT_SRC ?= "git://source.codeaurora.org/external/imx/uboot-imx.git;protocol=https"
SRCBRANCH = "lf_v2022.04"
SRC_URI = "${UBOOT_SRC};branch=${SRCBRANCH}"
SRCREV = "1c881f4da83cc05bee50f352fa183263d7e2622b"
LOCALVERSION = "-${SRCBRANCH}"

DEPENDS += "flex-native bison-native bc-native dtc-native gnutls-native"

S = "${WORKDIR}/git"
B = "${WORKDIR}/build"

inherit fsl-u-boot-localversion

BOOT_TOOLS = "imx-boot-tools"

###############################################################
# require recipes-bsp/u-boot/u-boot-imx-common_${
      
      PV}.inc

PROVIDES += "u-boot"

inherit uuu_bootloader_tag

UUU_BOOTLOADER            = ""
UUU_BOOTLOADER:mx6-nxp-bsp        = "${UBOOT_BINARY}"
UUU_BOOTLOADER:mx7-nxp-bsp        = "${UBOOT_BINARY}"
UUU_BOOTLOADER_TAGGED     = ""
UUU_BOOTLOADER_TAGGED:mx6-nxp-bsp = "u-boot-tagged.${UBOOT_SUFFIX}"
UUU_BOOTLOADER_TAGGED:mx7-nxp-bsp = "u-boot-tagged.${UBOOT_SUFFIX}"

do_deploy:append:mx8m-nxp-bsp() {
    
    
    # Deploy u-boot-nodtb.bin and fsl-imx8m*-XX.dtb for mkimage to generate boot binary
    if [ -n "${UBOOT_CONFIG}" ]
    then
        for config in ${
    
    UBOOT_MACHINE}; do
            i=$(expr $i + 1);
            for type in ${
    
    UBOOT_CONFIG}; do
                j=$(expr $j + 1);
                if [ $j -eq $i ]
                then
                    install -d ${
    
    DEPLOYDIR}/${
    
    BOOT_TOOLS}
                    install -m 0777 ${
    
    B}/${
    
    config}/arch/arm/dts/${
    
    UBOOT_DTB_NAME}  ${
    
    DEPLOYDIR}/${
    
    BOOT_TOOLS}
                    install -m 0777 ${
    
    B}/${
    
    config}/u-boot-nodtb.bin  ${
    
    DEPLOYDIR}/${
    
    BOOT_TOOLS}/u-boot-nodtb.bin-${
    
    MACHINE}-${
    
    type}
                fi
            done
            unset  j
        done
        unset  i
    fi
}

PACKAGE_ARCH = "${MACHINE_ARCH}"
COMPATIBLE_MACHINE = "(mx6-generic-bsp|mx7-generic-bsp|mx8-generic-bsp)"

bbappendFiles: .bbappend files are used to extend or override recipe file information. Each bbappend file has a corresponding recipe file, the two files use the same file name, but the suffix is ​​different. For example u-boot-imx_2022.04.bband u-boot-imx_2022.04.bbappend. Can also be %used to wildcard recipe file names. For example, an busybox_1.21.%.bbappendappend file named can extend and overwrite any recipe file named busybox_1.21.x.bb, and the x in the file name can be any string, such as busybox_1.21.1.bb, busybox_1.21.2. bb ... Usually use the percent sign to wildcard the version number.

After the above concepts are clarified, let's talk about the construction process of bitbake.
In general , bitbake finds the corresponding meta-layers/conf directory according to the enabled meta-layers defined in build/conf/bblayers.conf layer.conf. In layer.conf, the recipes used under the current layer are specified by bbFILESand . bbPATHThat is, through bbPATH, tell bitbake in which paths, which .bb and .bbappend files to find, and tell bitbake through these files which software packages or source codes will be used to build the embedded Linux distribution. When the recipe is parsed, a " task list " will be generated, and you can use bitbake -scommands to list all buildable tasks in the current project. The next step is that bitbake builds the system according to the " task list" . In fact, in the process of building the system, it is carried out in the form of tasks.

3.2. Brief analysis of BitBake build system tasks

When executing the simplest method of building a package bitbake <package_name>, bitbake will search for the recipe file of this package, parse the configuration options in the recipe after finding it, and then perform the following tasks in sequence:

  • do_fetch download source code
  • do_unpack decompresses the source code
  • do_patch to patch the source code
  • do_configure configuration
  • do_compile compile
  • do_install installation, copy the file to the target directory
  • do_package generates the installation package
    , and can also execute individual tasks through the **-c** parameter, for example, only downloading the source code can execute bitbake -c fetch .

3.2.1 Get the source code

The process of obtaining the source code is completed by the do_fetch task, which is mainly controlled by the SRC_URI variable, which can specify the location of the source code, the protocol for obtaining the source code, etc. There are three sources of source code: upstream project releases , local project files , and code version managers such as git/svn .
Upstream project releases exist in the form of archive files, such as: zip, tar packages, etc.
The source code released through the version control manager is usually downloaded using the git/svn protocol. For example, if you use this method to specify the source code, when bitbake executes the do_fetch task in the process of building the Linux system , it will clone the source code to participate in building the system according to the SRC_URI and SRCREV variables defined in the recipe . In addition, if the source code is obtained as an archive file, the do_unpack task will release the source code to the path pointed to by the ${S} variable. The default value of S is ${WORKDIR} / ${BPN} - ${PV} , if the source code compressed package is downloaded, and the internal structure of the compressed package conforms to the convention of the top-level subdirectory ${BPN} - ${PV}, Then there is no need to set S. However, if the compressed package does not conform to this convention, or the source code is cloned from a version management server such as git, you must manually set S. For example, git will clone the source code to the ${WORKDIR}/git path, so this value must be set in the recipe.
The following picture is a schematic diagram of obtaining and releasing the source code:
insert image description here
as in the linux-imx_5.15.bb file, you need to manually set the value of S:

KERNEL_SRC = "git://github.com/Advantech-IIoT/linux-imx.git;protocol=https;branch=${SRCBRANCH}"
SRC_URI = "${KERNEL_SRC}"
SRCREV = "065aa1f91e58e1108720dc701a074760be878962"

S = "${WORKDIR}/git"

The final source code will be downloaded to eamb9918a1/tmp/work/imx8mmeamb9918a1-poky-linux/linux-imx/5.10.72+gitAUTOINC+b8bb4918e6-r0/gitthe path.

3.2.2 Patching

After the software obtains the source code, it needs to be patched. In SRC_URI, patch, .diff or the compressed package diff.gz with these suffixes are all patch codes. The patch is automatically applied when the do_patch task is executed. Usually, we put the patch files in a folder named ${BP} ${BPN} or files next to the recipe file.
Among them, the patch files are placed under the files directory.

root@ning-QiTianM620-N000:sources/meta-advantech/meta-adv-imx/recipes-extended/cpio# ls
cpio_%.bbappend  files
root@ning-QiTianM620-N000:sources/meta-advantech/meta-adv-imx/recipes-extended/cpio/files$ ls
0001-Wrong-CRC-with-ASCII-CRC-for-large-files.patch

Among them, the patch file is placed under the chromium-ozone-wayland directory, which is a folder created with the recipe name ${BPN} of the build package.

root@ning-QiTianM620-N000:/recipes-browser/chromium/chromium-ozone-wayland# ls
0001-Add-knob-for-imx-gpu.patch                        

3.2.3 Configuration

Most software needs to be configured before compiling, usually in the following three ways:

  1. Autotools: If there is a configure.ac file in the source file, then the software is built using Autotools, and the recipes file needs to inherit the autotools class (inherit autotools). In this case, there is no need to include the do_configure task. You may need to set EXTRA_OECONF or PACKAGE_CONFARGS to pass the required configuration options.
  2. CMake: If there is a CMakeLists file in the source file, then your software is built with CMake, the recipes file needs to inherit the cmake class (inherit cmake), and does not have to contain the do_configure task, you can make some adjustments by setting EXTRA_OECMAKE.
  3. Others; in other cases, you need to provide a do_configure task in the recipe for configuration.

3.2.4 Compile

After the configuration is successful, the system will automatically call the do_compile task to compile.

3.2.5 Installation

During installation, the file and directory structure generated by the system call do_install task is copied to the mirror location on the target device. The files in the ${S} ${B} and ${WORKDIR} directories will be copied into the ${D} directory to create the structure on the target system. For software packages built with autotools and cmake, the system will call their install commands to perform installation tasks. In other cases, you need to modify or manually write the do_install task. We can define a do_install function in the recipe, and then add installation instructions.
If you want to install manually, you must first use install -d in the do_install function to create a directory under ${D}. Once these directories exist, you can use install to manually install files into these directories.
Take the do_install function in a .bb file as an example to illustrate the following:

do_install() {
    
    	
	install -d ${
    
    D}/usr/bin/
    install -m 755 ${
    
    S}/bin/gester ${
    
    D}/usr/bin/
}

3.2.6 Packaging

If you use cmake or Autotools, this step is also automatic, otherwise you need to write a do_package function.


4. Customized embedded Linux system

The Yocto system organizes and manages the software packages, source code, configuration information, etc. used by the build system in the form of metadata. To a certain extent, metadata can be understood as layers, which are actually folders one by one (these folders are usually named in the form of meta-xxx).
Using layers to manage source data is conducive to maintaining a modular design method. A layer contains source data required by some specific functions, and each layer does not interfere with each other. When the functions required by the built system change, only It is only necessary to modify the layer corresponding to this function, which maintains the independence and modular design of the function.

4.1. Create meta-mylayer

There are two ways to create a meta-layer, one is to create it manually, and the other is to use the bitbake-layers command to create it. It should be noted that before creating a layer, you can http://layers.openembedded.org/layerindex/layers/check the existing layer in . If the layer to be created already exists, you can use it directly. If not, you will need to create it yourself.

4.1.1 Automatic creation

bitbake-layers create-layer meta-mylayer

4.1.2 Manual creation

1. Create a folder to store the data in the layer, usually named meta-xxx. For example: meta-mylayer.
2. Create a layer configuration file. Create a conf/layer.conf file under the newly created layer folder (for example: meta-mylayer). The basic framework of the layer.conf file is as follows:

# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
   ${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "mylayer"
BBFILE_PATTERN_mylayer = "^${LAYERDIR}/"
BBFILE_PRIORITY_mylayer = "5"

Among them, the meanings of each variable are as follows:
(1). BBPATH: Add the newly added layer path to the global variable BBPATH, and bitbake will find the corresponding layer according to this variable when building the system.
(2). BBFILES: Add the recipe file (ie: .bb or .bbappend file) in the newly added layer to the global variable BBFILES, and bitbake will find the corresponding recipe file according to this variable when building the system.
(3). BBFILE_COLLECTIONS: Add the layer name to the bbFILE_COLLECTIONS variable, that is, assign xxx in the layer folder name meta-xxx to BBFILE_COLLECTIONS.
(4). BBFILE_PATTERN: The BBFILE_PATTERN variable is a regular expression, which is used to match the files defined in BBFILES in a specific layer. This variable must be prefixed with the name of the specific layer.
(5). BBFILE_PRIORITY: The priority of the layer. When the same recipe is defined in different layers, the corresponding recipe file will be used according to the high priority corresponding to BBFILE_PRIORITY.
3. Add content. According to the type of layer, some layers will add machine and distro configurations. Therefore, you need to add machine configurations in the conf/machine/ file under the Layer, and add distribution configurations in the conf/distro/ file in this layer.

4.2. Enable meta-mylayer

After creating a new layer, it needs to be enabled before it can participate in the system construction process. The layers used by the participating build system are defined in eamb9918a1/config/bblayers.conf. Freescale officially provides the imx-setup-release.sh script to modify the eamb9918a1/conf/bblayers.conf file. When initializing the Yocto build directory, call the imx-setup-release.sh script. Therefore, just modify the imx-setup-release.sh script, and the modification method is as follows:
insert image description here
You can also bitbake-layers add-layer meta-mylayeradd meta-mylayer to the bblayers.conf file by executing the relative directory of meta-mylayer.

cd /opt/work/yocto-kirkstone/eamb9918a1
bitbake-layers add-layer ./sources/meta-mylayer

4.3. Create recipes

Recipes (.bb files) are the basic components in the Yocto project environment. There are two relatively simple ways to create new recipes:

  • recipetool: A tool provided by Yocto to automatically create recipes based on source files
  • exiting recipes: Modify an existing recipe with similar functional requirements. There are many community-maintained recipes in http://layers.openembedded.org/layerindex/branch/master/layers/ , you can find the ones that meet your needs and get them directly to use.
recipetool create -o example/example_0.1.bb  ../../meta-mylayer/

The following is the recipe created by executing the above instructions

# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
# No information for SRC_URI yet (only an external source tree was specified)
SRC_URI = ""

# NOTE: no Makefile found, unable to determine what needs to be done
do_configure () {
    
    
	# Specify any needed configure commands here
	:
}
do_compile () {
    
    
	# Specify compilation commands here
	:
}
do_install () {
    
    
	# Specify install commands here
	:
}

In the above file, the copyright license of the recipe, the checksum of the license file, and the URI of the source code are provided, and the rewriting interface for tasks such as do_configure is provided.

4.4. Compile recipes

After using the imx-setup-release script to initialize the Yocto build directory, it will automatically enter the build directory. In this path, execute the following command to compile

bitbake example

Among them, example is the name of the recipe. During the compilation process, the OpenEmbedded compilation system will create a temporary folder for each recipe to store decompressed files, log files, etc. The temporary files for each recipe are organized as follows:

BASE_WORKDIR ?= "${TMPDIR}/work"
WORKDIR = "${BASE_WORKDIR}/${MULTIMACH_TARGET_SYS}/${PN}/${EXTENDPE}${PV}-${PR}" 

For example: imx8mmeamb9918a1-poky-linux is the system architecture, the recipe file is rs9116nb0_git.bb, and the generated file path is as follows:

eamb9918a1/tmp/work/imx8mmeamb9918a1-poky-linux/rs9116nb0/2022.06_git-r0

In addition, we can use the following command to locate the working directory when building a package:

bitbake -e linux-imx | grep ^WORKDIR=  //定位linux-imx工作目录
bitbake -e linux-imx | grep ^S=        //定位源码解压后的位置
bitbake -e linux-imx | grep ^B=        //定位源码编译目录
bitbake -e linux-imx | grep -E "^PN=|^PV=|^PR="  //定位构建包的配方名称、配方版本和构建包的配方的修订版

There are several important folders under the above file directory:

  • image : Store the files to be installed on the target system, and store them according to the installation path.
  • deploy : store installation packages in rpm/deb format.
  • temp : stores all task instructions executed during the build process, and logs of the executed process.
    The order in which BitBake executes tasks is controlled by its task scheduler. ${WORKDIR}/temp/Under the directory, run_the files starting with record the detailed content of each task after parsing, log_the files starting with record the log when the task is executed, and log.task_orderthe files record the tasks executed by the current target in order.
    insert image description here

4.5. Create Machine file

In general, the custom hardware platform will refer to the imx8mmevk hardware platform settings officially provided by Freescale. We need to modify the imx8mmevk hardware platform based on the custom hardware interface design to ensure that our hardware interface drivers work normally. Therefore, we need to refer to the files sources/meta-imx/meta-bsp/conf/machineunder the path imx8mmevk.confas the configuration files for the hardware platform we use to build the system. imx8mmevk.confThe file mainly consists of the following parts:

  • include file In the imx8mmevk.conf file, the file
    is referenced by the require keyword , and in the file, the file is referenced by the require keyword .sources/meta-freescale/conf/machine/imx8mm-lpddr4-evk.confimx8mm-lpddr4-evk.confimx8mm-evk.inc
qing@Qing:sources$ cat meta-freescale/conf/machine/imx8mm-lpddr4-evk.conf
......
require include/imx8mm-evk.inc
......

imx8mm-evk.increferenced in the file

require conf/machine/include/imx-base.inc
require conf/machine/include/arm/armv8a/tune-cortexa53.inc

Among them, imx8mm belongs to the coretexa53 series core, so the coretexa53.inc file is referenced. This file is located sources/poky/meta/conf/machine/include/arm/armv8a/tune-cortexa53.incunder the path and mainly defines some definitions related to the coretexa53 architecture core. For coretexa53.inc, we do not need to modify it. In addition, the imx-base.inc file is located sources/meta-freescale/conf/machine/include/imx-base.incunder the path, which mainly defines some default parameters of the imx series CPU, such as the entry address of uboot, the default kernel definition, etc.

  • Kernel device tree definition
    In the imx8mmevk.conf file, the device tree file generated by the Linux kernel during compilation is defined through the variable KERNEL_DEVICETREE . When you need to modify the device tree file generated by the Linux kernel during compilation, you need to modify the value of the KERNEL_DEVICETREE variable.
# Include device trees for other boards for internal test
KERNEL_DEVICETREE += " \
    freescale/imx8mm-ddr4-evk.dtb \
    freescale/imx8mm-ddr4-evk-pcie-ep.dtb \
    freescale/imx8mm-ddr4-evk-rm67191.dtb \
    freescale/imx8mm-ddr4-evk-rm67191-cmd-ram.dtb \
    freescale/imx8mm-ddr4-evk-rm67199.dtb \
    freescale/imx8mm-ddr4-evk-rm67199-cmd-ram.dtb \
    freescale/imx8mm-ddr4-evk-revb.dtb \
    freescale/imx8mm-ddr4-evk-revb-rm67191.dtb \
    freescale/imx8mm-ddr4-evk-revb-rm67191-cmd-ram.dtb \
    freescale/imx8mm-ddr4-evk-revb-rm67199.dtb \
    freescale/imx8mm-ddr4-evk-revb-rm67199-cmd-ram.dtb \
"
  • U-BOOT configuration
    In the imx8mm-lpddr4-evk.conf file, the corresponding U-Boot default configuration file is added for the custom hardware platform, and it is enabled by setting the UBOOT_CONFIG variable, as shown below:
UBOOT_CONFIG ??= "sd"
UBOOT_CONFIG_BASENAME = "imx8mm_evk"
UBOOT_CONFIG[sd]      = "${UBOOT_CONFIG_BASENAME}_defconfig,sdcard"
UBOOT_CONFIG[mfgtool] = "${UBOOT_CONFIG_BASENAME}_defconfig"
UBOOT_CONFIG[fspi]    = "${UBOOT_CONFIG_BASENAME}_fspi_defconfig"

In the imx8mm-evk.inc file, the device tree file used by uboot in compilation is defined by the variable UBOOT_DTB_NAME .

# Set u-boot DTB
UBOOT_DTB_NAME = "${KERNEL_DEVICETREE_BASENAME}.dtb"
  • DDR FIRMWARE configuration
    In the imx8mm-lpddr4-evk.conf file, the bin file used by DDR during compilation is defined by the variable DDR_FIRMWARE_NAME .
# Set DDR FIRMWARE
DDR_FIRMWARE_NAME = " \
 lpddr4_pmu_train_1d_imem.bin \
 lpddr4_pmu_train_1d_dmem.bin \
 lpddr4_pmu_train_2d_imem.bin \
 lpddr4_pmu_train_2d_dmem.bin \
"

4.6. Customize system image

4.6.1 Using the IMAGE_INSTALL method

By modifying the existing system image file. For example: If you want to build a imx-image-fullsystem image file based on the system, but you need to add an additional strace package, you can add the strace package by creating a file and adding the following code in the imx-image-full.bbappendnew file:.bbappend

IMAGE_INSTALL:append = "strace"

In addition, the file can also be modified conf/local.conf, but the modification here is global and will cause all built image files to take effect, which is not conducive to project management. The best way is to create a new bbappend file corresponding to the image for modification, and only install a certain package in a specific image file.

The above method of adding packages is to add or delete packages to the target image system by setting the IMAGE_INSTALL variable. You can use the :append syntax to add a package, and the :remove syntax to delete a package. Packages and package groups are generally installed to the target image through the IMAGE_INSTALL variable setting. A package group is a collection of packages, which are generally defined by .bb files.

4.6.1 Using the IMAGE_FEATURES method

In addition to using the IMAGE_INSTALL variable, you can also use the IMAGE_FEATURES variable to set the characteristics of the target image. This variable is not limited to packages and package groups, and users can define it by themselves. We can also modify the contents of the IMAGE_FEATURES variable with :append and :remove syntax. As used in the project:

IMAGE_FEATURES:remove = " ssh-server-dropbear"
IMAGE_FEATURES:append = " ssh-server-openssh"

Above, through the IMAGE_FEATURES variable, the package: ssh-server-openssh was added to the fsl-image-multimedia image, and the package: ssh-server-dropbear was deleted. In addition, by executing the following command, we can know that the above additions and deletions through IMAGE_FEATURES:remove and IMAGE_FEATURES:append are also package groups.

$ bitbake -e fsl-image-multimedia | grep ^FEATURE_PACKAGES
FEATURE_PACKAGES_ssh-server-dropbear="packagegroup-core-ssh-dropbear"
FEATURE_PACKAGES_ssh-server-openssh="packagegroup-core-ssh-openssh"

The defined ssh-server-opensshmeans that packagegroup-core-ssh-opensshthe defined ssh-server-dropbearmeans that packagegroup-core-ssh-dropbearthe .bb files of the above two package groups can be directly searched in the source code directory:

$ find ./ -name "packagegroup-core-ssh-openssh*"
./poky/meta/recipes-core/packagegroups/packagegroup-core-ssh-openssh.bb

4.6.3 Using PACKAGE_EXCLUDE

Finally, if the package we want to delete is not displayed in the definition of IMAGE_INSTALL and IMAGE_FEATURES , it is usually encapsulated in the package group. At this time, it can be set with the PACKAGE_EXCLUDE variable:

PACKAGE_EXCLUDE = "package_name package_name package_name ..."

None of the listed packages will be installed into the target image. There may be a problem here, if some other package depends on the package listed here (ie listed in the RDEPENDS variable), it will report an error when building, and the corresponding dependency must be touched. Take the removal of connman as an example:

PACKAGE_EXCLUDE = "connman"

The following error occurs when building:

$ bitbake fsl-image-machine-test
...
Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 packagegroup-core-tools-testapps : Depends: connman-client but it is not going to be installed
                                    Depends: connman-tools but it is not going to be installed
E: Unable to correct problems, you have held broken packages.
...

Both connman-client and connman-tools in the packagegroup-core-tools-testapps package group depend on connman, which can be seen in the packagegroup-core-tools-testapps.bb file:

RDEPENDS_${
    
    PN} = "\
    blktool \
    ${KEXECTOOLS} \
    alsa-utils-amixer \
    alsa-utils-aplay \
    ltp \
    connman-tools \
    connman-tests \
    connman-client \
    ${@bb.utils.contains('DISTRO_FEATURES', 'x11', "${
    
    X11TOOLS}", "", d)} \
    ${@bb.utils.contains('DISTRO_FEATURES', 'x11 opengl', "${
    
    X11GLTOOLS}", "", d)} \
    ${@bb.utils.contains('DISTRO_FEATURES', '3g', "${
    
    3GTOOLS}", "", d)} \
    "

You can create a new packagegroup-core-tools-testapps.bbappend file and delete it using the _remove syntax:

RDEPENDS_${
    
    PN}_remove = "connman-tools connman-tests connman-client"

Five, uboot transplant

5.1.u-boot source code modification

During the U-Boot porting process, the corresponding uboot source code needs to be modified. We will not directly modify the recipe provided by Yocto, but configure the U-Boot software compilation process by creating a bbappend file with the same name recipe in our newly created meta-advantech layer. The uboot provider is defined by
the PREFERRED_PROVIDER_virtual/bootloader_imx = "u-boot-imx" variable, as follows:

PREFERRED_PROVIDER_virtual/bootloader_imx = "u-boot-imx"

It can be seen that the provider of imx8mm is u-boot-imx, in fact, it corresponds to u-boot-imx_2022.04 under the path of /sources/meta-imx/meta-bsp/recipes-bsp/u-boot/ .bb files. Therefore, we created the following path: sources/meta-advantech/meta-adv-imx/recipes-bsp/u-boot/, and created u-boot-imx_2022.04.bbappend file. The content of the file is as follows:

FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

UBOOT_SRC = "git://github.com/Advantech-IIoT/uboot-imx.git;protocol=https"
SRCBRANCH = "lf_v2022.04"
SRC_URI = "${UBOOT_SRC};branch=${SRCBRANCH}"
SRCREV = "642b7925a0bcfc145e5ef51214b008afe472cc6d"
LOCALVERSION = "-${SRCBRANCH}"

From the above bbappend file, specify the location of the uboot source code participating in the build system by using the SRC_URI and SRCREV variables.

5.2.u-boot device tree file

When creating the machine.conf file earlier, it was mentioned that the variable UBOOT_DTB_NAME needs to be set to define the device tree file used by uboot in compilation. The settings for other configurations of uboot are also set in the machine.conf file.

5.3.u-boot source code construction

After the Yocto working environment is loaded through the command MACHINE=imx8mmeamb9918a1 DISTRO=fsl-imx-xwayland source imx-setup-release.sh -b eamb9918a1, the kernel can be compiled in the following two ways:
Execute command: bitbake imx-image-fullcompile the entire system
Execute command: bitbake u-boot-imxcompile uboot alone
For the command to compile the entire system in mode 1, the embedded Linux distribution version will be completed at one time U-Boot, Linux kernel, device tree files, root file system compilation, package installation and other processes will directly generate the final target file; while using method 2, only uboot will be compiled separately, and after compilation, it will be generated under the road eamb9918a1/tmp/work/imx8mmeamb9918a1-poky-linux/u-boot-imx/2022.04-r0/image/bootforce u-boot.bin file.

eamb9918a1/tmp/work/imx8mmeamb9918a1-poky-linux/u-boot-imx/2022.04-r0/image/boot$ ls
u-boot.bin  u-boot.bin-sd  u-boot-sd-2022.04-r0.bin  u-boot-spl.bin  u-boot-spl.bin-sd  u-boot-spl.bin-sd-2022.04-r0

6. Kernel transplantation

6.1. Linux kernel source code modification

During the Linux kernel porting process, the corresponding Linux kernel source code needs to be modified. Similarly, we will not directly modify the recipe provided in Yocto, but create a new recipe in the meta-advantech we created before. Configure the Linux kernel compilation process.
The provider of the Linux kernel is defined by the PREFERRED_PROVIDER_virtual/kernel_imx variable, as follows:

PREFERRED_PROVIDER_virtual/kernel_imx = "linux-imx"

It can be seen that the provider of the imx8mm Linux kernel is linux-imx, in fact, it corresponds to the linux-imx_5.15.bb file under the /sources/meta-imx/meta-bsp/recipes-kernel/linux/ path. Therefore, we created paths like this: sources/meta-advantech/meta-adv-imx/recipes-kernel/linux/,并创建linux-imx_5.15.bbappendfile. The content of the file is as follows:

sources/meta-advantech/meta-adv-imx/recipes-kernel/linux$ cat linux-imx_5.15.bbappend 
SRCBRANCH = "lf-5.15.y"
LOCALVERSION = "-lts-5.15.y"
KERNEL_SRC = "git://github.com/Advantech-IIoT/linux-imx.git;protocol=https;branch=${SRCBRANCH}"
SRC_URI = "${KERNEL_SRC}"
SRCREV = "065aa1f91e58e1108720dc701a074760be878962"

Similarly, we specify the location of the kernel source code participating in the build system by using the SRC_URI and SRCREV variables.

6.2 Linux kernel device tree file

When creating the machine.conf file earlier, it was mentioned that the variable KERNEL_DEVICETREE needs to be set. The device tree file used in the Linux kernel compilation process is defined by the variable KERNEL_DEVICETREE.

6.3. Linux kernel making and obtaining patch files

During the Linux kernel porting process, obtaining or making patch files will be involved. The simpler way is to use the git command to submit changes and generate patch files.

$ git add init/calibrate.c
$ git commit -m "calibrate.c - Added some printk statements"
$ git format-patch -1
0001-calibrate.c-Added-some-printk-statements.patch

Put the generated patch file in the meta-mylayer/recipes-kernel/linux/linux-imx/ path, and add in the .bbappend file:

SRC_URI:append = " file://0001-calibrate.c-Added-some-printk-statements.patch"

Execute the following command to clear the kernel compilation directory first, and then apply the patch again:

$ bitbake linux-imx -c clean
$ bitbake linux-imx -c patch

Then check the patched source code, confirm that the patch has taken effect, and compile it:

$ bitbake linux-imx

Another way to modify the kernel configuration is to open bitbake linux-imx -c menuconfigan interactive interface and modify the configuration here:
insert image description here
the configuration here comes from the .config file in the compilation directory. If it is the first compilation, this file is the arch/arm of the kernel source code A copy of a defconfig file in the /conifg directory, which file it is, usually specified in the do_config task of the recipe file.
After modifying in menuconfig, save and exit. An updated .config file will be generated under the compilation directory tmp/work/imx8mmeamb9918a1-poky-linux/linux-imx/5.15.32+gitAUTOINC+065aa1f91e-r0/build/, and the original .config will be renamed to .config .old. Then call the diffconfig option to generate a configuration snippet:

bitbake linux-imx -c diffconfig

This step is to compare the difference between .config and .config.old, determine the modified content, and generate a patch file, which is called a configuration fragment. The generated file is located in fragment.cfg in the kernel build directory . We can copy this file to the meta-advantech/meta-adv-imx/recipes-kernel/linux/linux-imx/ directory, and then add in the linux-imx_5.10.72.bbappend file:

SRC_URI += "file://fragment.cfg"

It's a good idea to change the fragment.cfg to a meaningful file name, as multiple configuration fragments are often used to add different types of modifications. Before compiling, you can call kernel_configcheckthe option to check whether the kernel configuration is correct:

bitbake linux-imx -c kernel_configcheck

6.4. Linux kernel source code construction

After the Yocto working environment is loaded through the command MACHINE=imx8mmeamb9918a1 DISTRO=fsl-imx-xwayland source imx-setup-release.sh -b eamb9918a1, the kernel can be compiled in the following two ways:
Execute command: bitbake imx-image-fullcompile the entire system
Execute command: bitbake linux-imxcompile the Linux kernel separately
For the command to compile the entire system in method 1, the embedded Linux distribution version will be completed at one time U-Boot, Linux kernel, device tree files, root file system compilation, package installation and other processes will directly generate the final target file; while using method 2, only the Linux kernel and device tree files will be compiled separately. After compilation, The image file will be generated under eamb9918a1/tmp/work/imx8mmeamb9918a1-poky-linux/linux-imx/5.15.32+gitAUTOINC+065aa1f91e-r0/build/arch/arm64/boot, and the file will be generated under road dtsstrength dtb;

eamb9918a1/tmp/work/imx8mmeamb9918a1-poky-linux/linux-imx/5.15.32+gitAUTOINC+065aa1f91e-r0/build/arch/arm64/boot/dts/freescale$ ls
imx8mm-adv-eamb9918-a1.dtb  imx8mm-evk.dtb

The above dtb file is the device tree file generated during the Linux kernel compilation process. Correspondingly, in the sources/meta-advantech/meta-adv-imx/conf/machine/imx8mmeamb9918a1.conf file, the defined variable KERNEL_DEVICETREE just corresponds to the generated device tree file.
If you need to deploy the compiled Linux kernel image, you can use the following command:

bitbake -c deploy -f linux-imx                    //部署内核镜像到deploy目录

This command will deploy the generated Linux kernel image file to the /tmp/deploy/images path.


Seven. Build the root file system

When building an embedded Linux system distribution, the entire complete embedded Linux system is built through the bitbake imx-image-multimedia command. Among them, Freescale provides several target image files to choose from. It should be noted that the more functions supported by the image file, the larger the root file system will be:
insert image description here
here, imx-image-full is selected. In fact, by running the bitbake imx-image-full command, bitbake will find the files /sources/meta-imx/meta-sdk/dynamic-layers/qt6-layer/recipes-fsl/imagesin the path imx-image-full.bband build the system according to the configuration in the imx-image-full.bb file. At the same time, /sources/meta-imx/meta-sdk/recipes-fsl/imagesyou can also see fsl-image-multimedia.bbother files under the path, which correspond to the mirror files mentioned in the above table.
In addition, when building the file system, we need to install and configure new functional software by creating the corresponding bbppend file according to the needs of the actual project. Finally, we can start using the bitbake tool to build an embedded Linux system by running the bitbake imx-image-full command. After the file system is built, the imx-image-full-xxx.xxx file will be eamb9918a1/tmp/deploy/images/imx8mmeamb9918a1output under the path , which corresponds to the Yocto file system. At the same time, under this path, a manifest file is also output, which contains the software packages installed in the corresponding file system. View the manifest file by executing the following command, and query whether the installed software package in the built root file system contains the chromium browser
insert image description here

eamb9918a1/tmp/deploy/images/imx8mmeamb9918a1$ cat imx-image-full-imx8mmeamb9918a1.manifest | grep chromium
chromium-ozone-wayland armv8a-mx8mm 96.0.4664.110-r0

In addition, when building the root file system, you often encounter some errors such as fetch/request. Generally speaking, it is a network problem, and you can perform the corresponding operation again. For example, if the error message prompts that an error is reported during fetch, then we can execute the do_fetch task alone. After the do_fetch task is successful, we re-execute the construction of the file system. If a problem occurs repeatedly when building the root file system, you can try to delete the contents of the build folder and run the command to build the file system again.

Summarize

For example: the above is what I will talk about today. This article only briefly introduces the introduction and use of the Yocto system to help you quickly and easily understand the system transplantation process of the Yocto system.

Guess you like

Origin blog.csdn.net/weixin_53860846/article/details/127381127