嵌入式Linux系统中根文件系统构建方式

Posted ST小智

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入式Linux系统中根文件系统构建方式相关的知识,希望对你有一定的参考价值。

1. 根文件系统布局

目录

1. 根文件系统布局

2. 使用BusyBox生成二进制工具

2.1. 获取BusyBox源码

2.2. 配置BusyBox

3. 构建根文件系统

4. 制作根文件系统镜像

 嵌入式 Linux 根文件系统布局,建议还是按照FHS标准来安排,事实上大多数嵌入式Linux都是这样做的。但是,嵌入式系统可能并不需要桌面/服务器那样庞大系统的全部目录,可以酌情对系统进行精简,以简化Linux的使用。如嵌入式Linux文件系统中通常不会放置内核源码,因而存的 常不会放置内核源码,因而存的 常不会放置内核源码,因而存放源码的/usr/src目录是不必要的, 甚至连头文件也不需要,即/usr/include目录也不必要;但是/bin、/dev 、/etc、/lib 、/proc 、/sbin、/usr几个目录是不可或缺的。

所以,允许嵌入式 Linux 对系统目录结构进行精简,以适应具体用场合的需求,一个典型的嵌入式Linux根文件系统目录如下所示:

要构建一个可用的Linux根文件系统,需要的二进制和库都不少,完全从零开始也是不现实的,推荐参考其它现有可用的文件系统,在原基础上按需修改;或者使用文件系统制作工具如 BusyBox 来实现文件系统的生成。

2. 使用BusyBox生成二进制工具

2.1. 获取BusyBox源码

Busybox的官方源码下载路径为:https://busybox.net/downloads/。这里以下载busybox-1.29.3.tar.bz2为例。

2.2. 配置BusyBox

解压源码,进入根目录

$ tar jxvf busybox-1.29.3.tar.bz2
$ cd busybox-1.29.3/

首先,执行:

$ make menuconfig

进入图形化配置界面:

2.2.1.选择编译静态库

进入Settings --->使用空格键选择编译静态库

--- Build Options                                             
[*] Build static binary (no shared libs)  

如图:

2.2.2.选择交叉编译工具链

在Settings ---> 设置项下,填写交叉编译工具链前缀

2-2-3. 选择安装目录

在Settings --->设置项下,找到

--- Installation Options ("make install" behavior) 
    What kind of applet links to install (as soft-links)  --->  
(./_install) Destination path for 'make install' (NEW)  

默认为当前目录下目录,这里我使用默认_install目录:

2-2-4. 编译安装

退出保存后,执行编译make,大概几分钟后编译完成,执行make install,很快就会安装完成:

入_install目录,查看生成的文件

新建一个目录用来存放制作的根文件系统,可以命名为rootfs。将利用BusyBox生成的二进制文件及目录,即_install目录下的所有文件及目录复制到rootfs目录下。

3. 构建根文件系统

使用BusyBox编译后,仅有 bin、sbin、usr这 3个目录和软链接linuxrc,目录里都是二进制命令工具,这还不足以构成 一个可用的根文件系统,必须进行其它完善工作,才能构建一个可用的根文件系统。

3-1. 完善目录结构

根据典型嵌入式Linux根文件系统目录,在rootfs目录中创建其他目录

$ mkdir dev etc lib proc sys tmp var

3-2. 添加C运行库文件

库文件可直接从交叉工具链获取,一般在工具链的libc/lib/目录下。我这里是在ubuntu下安装的Linaro的交叉工具链:

库文件是在/usr/arm-linux-gnueabihf/lib/目录下,拷贝动态链接库文件(.so文件)到新制作的根文件系统根目录下/lib目录里:

$ cp -a  /usr/arm-linux-gnueabihf/lib/*so* ./lib/

这里只是拷贝动态链接库。一般开发程序使用动态编译需要板子上动态库的支持才能运行,所以拷贝动态库。而静态库一般在静态编译的时候用到,由于交叉编译的工作放在了PC上所以板子上不需要静态库,所以没有必要拷贝,这样还可以减小根文件系统的体积。

一般使用gcc编译后的可执行文件、目标文件和动态库都带有调试信息和符号信息,这些在调试的时候用到,但是却增大了文件的大小。通常在PC上调试,或者调试时使用这些带有调试信息和符号信息的库文件,程序发布后使用去掉这些信息的库文件,可以大大缩小根文件系统的体积。这里我们去掉这些信息,方法是使用strip工具:

$ arm-linux-gnueabihf-strip ./*

3-3. 添加初始化配置脚本

初始化配置脚本放在在/etc目录下,用于系统启动所需的初始化配置脚本。BusyBox提供了一些初始化范例脚本,在examples/bootfloppy/etc/目录下。将这些配置文件复制到 ”目录下。将这些配置文件复制到 ”目录下。将这些配置文件复制到新制作的根文件系统etc目录下

cp -a ../busybox/busybox-1.29.3/examples/bootfloppy/etc/* etc/

添加后如图所示:

3-3-1. 修改/etc/inittab文件

/etc/inittab文件是init进程解析的配置文件,通过这个配置文件决定执行哪个进程,何时执行。将文件修改为:

# 系统启动时
::sysinit:/etc/init.d/rcS

# 系统启动按下Enter键时
::askfirst:-/bin/sh

# 按下Ctrl+Alt+Del键时
::ctrlaltdel:/sbin/reboot

# 系统关机时
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r

# 系统重启时
::restart:/sbin/init

以上内容定义了系统启动时,关机时,重启时,按下Ctrl+Alt+Del键时执行的进程。

3-3-2. 修改/etc/init.d/rcS文件

#! /bin/sh

# 挂载 /etc/fstab 中定义的所有文件系统
/bin/mount -a

# 挂载虚拟的devpts文件系统用于用于伪终端设备
/bin/mkdir -p /dev/pts
/bin/mount -t devpts devpts /dev/pts

# 使用mdev动态管理u盘和鼠标等热插拔设备
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug

# 扫描并创建节点
/sbin/mdev -s

3-3-3. 修改/etc/fstab文件

/etc/fstab文件存放的是文件系统信息。在系统启动后执行/etc/init.d/rcS文件里/bin/mount -a命令时,自动挂载这些文件系统。内容如下:

# <file system>    <mount point>    <type>    <options>    <dump>    <pass>     
proc                  /proc          proc     defaults       0         0
sysfs                 /sys           sysfs    defaults       0         0
tmpfs                 /tmp           tmpfs    defaults       0         0
tmpfs                 /dev           tmpfs    defaults       0         0

注:这里我们挂载的文件系统有三个proc、sysfs和tmpfs,在内核中proc和sysfs默认都支持,而tmpfs是没有支持的,我们需要添加tmpfs的支持。

3-3-4. 修改/etc/profile文件

/etc/profile文件作用是设置环境变量,每个用户登录时都会运行它。将文件内容修改为:

# 主机名
export HOSTNAME=zyz

# 用户名
export USER=root

# 用户目录
export HOME=/root

# 终端默认提示符
export PS1="[$USER@$HOSTNAME:\\$PWD]\\# "    

# 环境变量
export PATH=/bin:/sbin:/usr/bin:/usr/sbin

# 动态库路径
export LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH

因为指定了root用户的家目录为/root,所以需要创建该目录,否则执行cd ~时会失败

$ mkdir root

登录系统后效果为:

...
Please press Enter to activate this console.
[root@zyz:/]#
[root@zyz:/]# cd ~
[root@zyz:/root]#
[root@zyz:/root]# echo $PATH
/bin:/sbin:/usr/bin:/usr/sbin

至此,根文件系统就基本构建好了。

4. 制作根文件系统镜像

4-1. 根文件系统类型

如果文件系统已经布局完成, 则可以发到目标中了。通常会制作一个镜像然后通过某种方式固化到目标系统中,具体采用什么样的形发布需要根据资源状况、内核情况和系统需求等方面进行裁决:

(1)硬件方面,至少需要考虑主存储介质的类型和大小如Flash是NOR Flash还是NAND Flash,RAM的大小等。

(2)内核方面, 则需考虑所裁剪后的支持哪些文件系统采用中最合适, 能满足性、速度等要求。

(3)系统需求方面,要考虑运行速度、是否可写压缩等因素。常见的可用于根文件系统类型有ramdisk 、cramfs、jffs2 、yaffs/yaffs2和ubifs等,各类型的特性如表所列。

尽管文件系统固件以某一种文件系统的镜像发布,但是整个文件系统实际上还是并存多种逻辑文件系统的。例如,一个系统根文件系统以ubifs挂载,但是/dev目录却是以tmpfs挂载的、/sys目录挂载的是sysfs文件系统。现在,似乎ubifs是一种趋势。

4-2. 制作UBIFS根文件系统镜像

Linux下制作UBIFS的命令有两个,mkfs.ubifs和ubinize。mkfs.ubifs,将一个目录制作为UBIFS文件系统。使用范例:

$ mkfs.ubifs -m 2048 -e 128KiB -c 4096 -r ./rootfs -o rootfs.ubifs

其中:

-r, -d, --root=DIR       build file system from directory DIR(目录)
-m, --min-io-size=SIZE   minimum I/O unit size(最小输入输出单元大小)
-e, --leb-size=SIZE      logical erase block size(逻辑擦除块大小)
-c, --max-leb-cnt=COUNT  maximum logical erase block count(最大逻辑擦除块数目)
-o, --output=FILE        output to FILE(输出文件)

所以制作ubifs镜像文件,需要知道3个关键参数,即最小输入输出单元大小,逻辑擦除块大小,最大逻辑擦除块数目,其中最大逻辑擦除块数目可由Flash分区大小和逻辑擦除块大小计算出来,这些信息可以通过u-boot命令查看:

=> mtdparts default
=> ubi part rootfs

ubinize,将mkfs.ubifs制作的UBIFS文件系统制作成含有卷标的可以直接烧写在Flash上的镜像。使用范例:

$ ubinize -m 2048 -p 128KiB ubinize.cfg -o rootfs_ubifs.img

其中:

-o, --output=<file name>     output file name(输出文件)
-p, --peb-size=<bytes>       size of the physical eraseblock of the flash(物理擦除块大小)
                             this UBI image is created for in bytes,
                             kilobytes (KiB), or megabytes (MiB)
                             (mandatory parameter)
-m, --min-io-size=<bytes>    minimum input/output unit size of the flash
                             in bytes

这里需要两个参数物理擦除块大小和最小输入输出单元大小。ubinize.cfg是配置文件,内容如下:

[ubifs]
mode=ubi
image=rootfs.ubifs
vol_id=0
vol_size=1024MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize

说明:

[ubifs]
mode=ubi
image=rootfs.ubifs       # mkfs.ubi生成的源镜像 
vol_id=0                 # 卷号
vol_size=1024MiB         # 卷大小,一般要设置的比分区大,防止有坏块
vol_type=dynamic         # 卷类型,动态卷
vol_name=rootfs          # 卷名,rootfs
vol_flags=autoresize     # 自动大小

Yocto2构建嵌入式Linux系统

文章目录


1.定制化嵌入式linux系统

在实际项目中,一款嵌入式产品往往具有不同的硬件平台和软件需求,因此需要对嵌入式Linux系统进行定制,以满足不同的产品需求。之前的章节中基于Freescale官方提供的例程,构建了运行于imx6ull14x14evk硬件平台上的fsl-imx-fb发行版本,以此熟悉了Yocto的基本原理和工作流程。后续我们将基于Freescale官方的imx6ull14x14evk硬件平台的fsl-imx-fb发行版本,定制化自己的嵌入式Linux系统。一个完整的嵌入式Linux发行版包括U-Boot、Linux Kernel、Device Tree、rootfs。因此,定制化嵌入式Linux系统,将分为三个部分:U-Boot移植、Linux Kernel移植、构建rootfs。(Linux Kernel编译过程中,将同时生成Device Tree)。

Yocto是通过Metadata(Layers)的方式,确定构建嵌入式Linux系统的所需要的信息。Yocto和Freescale官方提供了很多的Metadata,在定制嵌入式Linux系统时,一般不会直接更改Yocto或Freescale官方提供的Metadata,而是通过创建新的Metadata,以.bb或.bbappend的方式定制自己的嵌入式Linux系统。采用Metadata的最大好处是使得软件功能模块化,把某一功能使用到的软件包或源码放在同一个Layer中,将使得当需要改变某一功能时,只需要改动相应的Metadata,而不会影响到其他功能。

1.1 创建Metadata

在sources目录下,创建一个文件夹,例如:meta-bird-imx6ull,用于存放自定义的Metadata,所有对于定制化嵌入式Linux系统所需的配置文件、源文件等都将存放在该目录下。在基于Freescale官方提供的fsl-arm-yocto-bsp Yocto项目构建嵌入式Linux系统发行版时,第一步是使用Freescale提供的imx-setup-release.sh初始化构建环境。在使用imx-setup-release.sh脚本时,采用的是如下命令:DISTRO=fsl-imx-fb MACHINE=imx6ull14x14evk source imx-setup-release.sh -b build

其中参数fsl-imx-fb对应Linux发行版,imx6ull14x14evk对应Linux硬件平台。他们分别对应位于/sources/meta-imx路径下的meta-sdk/conf/distro下fsl-imx-fb.conf以及meta-bsp/conf/machine/imx6ull14x14evk.conf。因此需要在这两个文件的基础上,通过修改一定的设置,用于构建定制化的嵌入式Linux系统。在meta-bird-imx6ull文件夹中,需要按照Yocto定义的框架,创建一些文件,用于配置嵌入式Linux发行版的构建过程。教程中将以MACHINE=imx6ull-bird-dk,DISTRO=bird-imx-fb为例,构建系统。

在/sources/meta-bird-imx6ull路径下,创建一个conf文件夹,用于存放配置文件。在conf文件夹下,依次创建distro和machine文件夹。如下图所示:

1.1.1 修改layer.conf文件

在Yocto构建嵌入式Linux系统过程中,通过Layer(meta-xxx文件夹)的方式定义了构建系统所使用的配置文件、源文件等,创建好文件夹(meta-bird-imx6ull)后,通过修改layer.conf文件,将新增加的meta-bird-imx6ull加入到Yocto构建系统过程中。具体来说,将/sources/meta-imx/meta-bsp/conf路径下的layer.conf文件拷贝至/sources/meta-bird-imx6ull/conf路径下,并按照下图所示修改:

修改了BBFILE_xxx变量,用于告诉BitBake构建系统时,采用meta-bird-imx6ull文件夹下的.bb文件。其中,BBFILE_COLLECTIONS += "bird-imx6ull"中的"bird-imx6ull"必须和meta-bird-imx6ull文件夹的后缀bird-imx6ull一致。

对于新创建的Layer(meta-bird-imx6ull文件夹),是通过meta-bird-imx6ull/conf路径下的layer.conf配置文件配置的,在layer.conf文件中,主要定义了一些变量的值,如下:
BBPATH:将当前Layer的路径增加到变量BBPATH中。
BBFILES:在当前Layer(meta-bird-imx6ull)中,有许多的recipes,在recipes中又有各种的.bb或.bbappend文件,这些.bb或.bbappend文件用于定义了参与构建系统过程的软件的基本信息(来源、配置等)。
BBFILE_COLLECTTIONS:该变量用于定义新增加的layer。
BBFILE_PATTERN:该变量用于定义bbFILES所定义的值的匹配路径。
BBFILE_PRIORITY:该变量用于定义Layer的优先级。当有多个相同的recipe存在于多个Layers中时,将用优先级高的那一个。

此外,在layer.coonf文件中还定义了一些其他的变量,用于控制系统的构建过程,在该文件中有许多与mx6不相关的其他型号的配置变量,可以将其移除,同时需要注意的是,目前在我们构建的系统中,去掉了optee相关的功能,因此,需要将layer.conf中与optee相关的部分去掉,去掉后的layer.conf文件如下所示:

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

# We have a packages directory, add to BBFILES
BBFILES += "$LAYERDIR/recipes-*/*/*.bb \\
       $LAYERDIR/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "bird-imx6ull"
BBFILE_PATTERN_bird-imx6ull := "^$LAYERDIR/"
BBFILE_PRIORITY_bird-imx6ull = "9"
LAYERSERIES_COMPAT_bird-imx6ull = "warrior zeus"

HOSTTOOLS_NONFATAL_append = " bc rsync xxd"

# optee is no longer a valid distro feature. Use machine feature to remove, like this:
MACHINE_FEATURES_remove = "optee"
MACHINE_FEATURES_remove = "optee-client"
MACHINE_FEATURES_remove = "optee-os"
MACHINE_FEATURES_remove = "optee-test"
# DEPRECATED: The ability to remove optee from the build is deprecated and
# will be removed in some future release.

DISTRO_FEATURES_FILTER_NATIVESDK += "wayland"

MACHINE_USES_VIVANTE_KERNEL_DRIVER_MODULE ?= "0"

MACHINE_SOCARCH_FILTER_append_imxgpu = " opencv"

MACHINE_SOCARCH_FILTER_remove = " imx-parser alsa-lib gstreamer1.0"

# Use latest SDMA firmware from firmware-imx instead of upstream linux-firmware
MACHINE_FIRMWARE_remove_mx6  = "linux-firmware-imx-sdma-imx6q"
MACHINE_FIRMWARE_append_mx6  = " firmware-imx-sdma firmware-imx-regulatory"

MACHINE_FIRMWARE_append = " $@bb.utils.contains('MACHINE_FEATURES', 'bcm4339', 'linux-firmware-bcm4339', '', d)"
MACHINE_FIRMWARE_append = " $@bb.utils.contains('MACHINE_FEATURES', 'bcm43430', 'linux-firmware-bcm43430', '', d)"
MACHINE_FIRMWARE_append = " $@bb.utils.contains('MACHINE_FEATURES', 'bcm43455', 'linux-firmware-bcm43455', '', d)"
MACHINE_FIRMWARE_append = " $@bb.utils.contains('MACHINE_FEATURES', 'bcm4356', 'linux-firmware-bcm4356-pcie', '', d)"
MACHINE_FIRMWARE_append = " $@bb.utils.contains('MACHINE_FEATURES', 'bcm4359', 'linux-firmware-bcm4359-pcie', '', d)"
MACHINE_FIRMWARE_append = " $@bb.utils.contains('MACHINE_FEATURES', 'nxp8987', 'linux-firmware-nxp8987', '', d)"

# Extra Marvell Wi-Fi & BTE driver and firmware
MACHINE_EXTRA_RRECOMMENDS_append = " $@bb.utils.contains('MACHINE_FEATURES', 'mrvl8997', 'packagegroup-imx-mrvl8997', '', d)"

# Extra NXP Wlan SDK
MACHINE_EXTRA_RRECOMMENDS_append = " $@bb.utils.contains('MACHINE_FEATURES', 'nxp8987', 'nxp-wlan-sdk', '', d)"

MACHINE_GSTREAMER_1_0_PLUGIN_mx6ul ?= "imx-gst1.0-plugin"

PREFERRED_VERSION_weston_mx6 ?= "8.0.0.imx"

PREFERRED_VERSION_wayland-protocols_mx6 = "1.18.imx"

PREFERRED_VERSION_libdrm_mx6 ?= "2.4.99.imx"

PREFERRED_VERSION_isp-imx ?= "4.2.2.2"
PREFERRED_VERSION_basler-camera ?= "4.2.2.2"

SOC_DEFAULT_IMAGE_FSTYPES_remove = "wic.gz"
SOC_DEFAULT_IMAGE_FSTYPES_append = " wic.bz2 tar.bz2"

# Remove from upstream
SDCARD_ROOTFS = "NO_LONGER_USED"

IMAGE_BOOT_FILES_append = " \\
$@bb.utils.contains('COMBINED_FEATURES', 'xen', 'xen', '', d) \\
"

IMAGE_INSTALL_append = " \\
$@bb.utils.contains('COMBINED_FEATURES', 'jailhouse', 'jailhouse', '', d) \\
$@bb.utils.contains('COMBINED_FEATURES', 'xen', 'imx-xen-base imx-xen-hypervisor', '', d) \\
"

MACHINE_FEATURES_append_imx    = " nxp8987"  

1.1.2 创建machine文件

我们是在Freescale官方imx6ull14x14evk硬件平台基础上修改,因此将/sources/meta-imx/meta-bsp/conf/machine路径下的imx6ull14x14evk.conf文件拷贝至/sources/meta-bird-imx6ull/machine路径下,并将其重命名为imx6ull-bird-dk.conf,作为我们构建系统所使用的硬件平台的配置文件。在imx6ull-bird-dk.conf文件中主要由以下几部分构成:

include文件:在imx6ull-bird-dk.conf文件中,通过include关键字引用了imx-base.inc和tune-cortexa7.inc文件,如下图所示:

其中imx-base.inc文件位于/sources/meta-freescale/conf/machine/include路径下,主要定义了一些imx系列CPU的默认配置参数,如U-BOOT的入口地址、默认的Linux内核文件定义等。imx6ull属于cortexA7系列的内核,因此引用了tune-cortexa7.inc文件,该文件位于/sources/poky/meta/conf/machine/include路径下,主要定义了一些与cortexA7架构内核相关的定义,对于tune-cortexa7.inc, 我们不需要进行修改。对于imx-base.inc文件,定义了系统构建过程中使用的一些配置信息,我们需要根据实际使用情况进行相应的修改。复制/sources/meta-freescale/conf/machine/include路径下的imx-base.inc文件,拷贝至/sources/meta-bird-imx6ull/conf/machine/include路径下,将其重命名为imx-bird-base.inc

将imx6ull-bird-dk.conf文件中的include conf/machine/include/imx-base.inc修改为include conf/machine/include/imx-bird-base.inc。同样的在imx-bird-base.inc文件中定义了需要其他芯片imx7等构建过程相关的配置信息,可以将其移除,并且删除imx-bird-base.inc文件中与optee相关的配置信息,修改后的imx-bird-base.inc文件如下所示:

# Provides the i.MX common settings

 include conf/machine/include/fsl-default-settings.inc
 include conf/machine/include/fsl-default-versions.inc

 require conf/machine/include/utilities.inc

 # Set specific make target and binary suffix
 IMX_DEFAULT_BOOTLOADER = "u-boot-fslc"
 IMX_DEFAULT_BOOTLOADER_mx8 = "u-boot-imx"

 PREFERRED_PROVIDER_u-boot ??= "$IMX_DEFAULT_BOOTLOADER"
 PREFERRED_PROVIDER_virtual/bootloader ??= "$IMX_DEFAULT_BOOTLOADER"

 PREFERRED_PROVIDER_u-boot-mxsboot-native ??= "u-boot-fslc-mxsboot-native"

 UBOOT_BINARY ?= "u-boot.$UBOOT_SUFFIX"
 UBOOT_MAKE_TARGET ?= "u-boot.$UBOOT_SUFFIX"

 UBOOT_SUFFIX ?= "imx"

 UBOOT_ENTRYPOINT_mx6ul  = "0x10008000"
 UBOOT_ENTRYPOINT_mx6ull  = "0x10008000"
 UBOOT_ENTRYPOINT_vf = "0x80008000"

 PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg"
 XSERVER_DRIVER                  = "xf86-video-fbdev"
 XSERVER_DRIVER_imxgpu2d         = "xf86-video-imx-vivante"
 XSERVER_DRIVER_vf               = "xf86-video-modesetting"
 XSERVER_DRIVER_append_mx8       = " xf86-video-modesetting"
 XSERVER_DRIVER_use-mainline-bsp = "xf86-video-armada"
 XSERVER = "xserver-xorg \\
           xf86-input-evdev \\
           $XSERVER_DRIVER"

 # Ship kernel modules
 MACHINE_EXTRA_RRECOMMENDS = "kernel-modules"

 # Tunes for hard/soft float-point selection. Note that we allow building for
 # thumb support giving distros the chance to enable thumb by setting
 # ARM_INSTRUCTION_SET = "thumb"
 #
 # handled by software
 # DEFAULTTUNE_mx6 ?= "cortexa9t-neon"
 # handled by hardware
 DEFAULTTUNE_mx6ul  ?= "cortexa7thf-neon"
 DEFAULTTUNE_mx6ull ?= "cortexa7thf-neon"

 INHERIT += "machine-overrides-extender"

 MACHINEOVERRIDES_EXTENDER_mx6ul  = "imxfbdev:imxpxp"
 MACHINEOVERRIDES_EXTENDER_mx6ull = "imxfbdev:imxpxp:imxepdc"

 MACHINEOVERRIDES_EXTENDER_FILTER_OUT_use-mainline-bsp = " \\
    mx6ul \\
    mx6ull \\
 "

 # Sub-architecture support
 MACHINE_SOCARCH_SUFFIX ?= ""
 MACHINE_SOCARCH_SUFFIX_mx6ul  = "-mx6ul"
 MACHINE_SOCARCH_SUFFIX_mx6ull = "-mx6ul"
 MACHINE_SOCARCH_SUFFIX_use-mainline-bsp = "-imx"

 MACHINE_ARCH_FILTER = "virtual/kernel"
 MACHINE_SOCARCH_FILTER_append_imx = " \\
    alsa-lib \\
    gstreamer1.0 \\
    weston \\
 "
 MACHINE_SOCARCH_FILTER_append_imxvpu = " \\
    imx-codec \\
    imx-parser \\
    imx-vpuwrap \\
    libimxvpuapi \\
    virtual/imxvpu \\
 "
 MACHINE_SOCARCH_FILTER_append_imxgpu = " \\
    virtual/egl \\
    virtual/mesa \\
    virtual/libopenvg \\
    libdrm \\
    cairo \\
    libgal-imx \\
    pango \\
 "
 MACHINE_SOCARCH_FILTER_append_imxgpu2d = " \\
    virtual/libg2d \\
 "
 MACHINE_SOCARCH_FILTER_append_imxgpu3d = " \\
    virtual/libgl \\
    virtual/libgles1 \\
    virtual/libgles2 \\
 "
 MACHINE_SOCARCH_FILTER_append_use-mainline-bsp = " \\
    virtual/egl \\
    virtual/libopenvg \\
    virtual/libg2d \\
    virtual/libgl \\
    virtual/libgles1 \\
    virtual/libgles2 \\
    virtual/mesa \\
    cairo \\
    pango \\
    qtbase \\
 "
 MACHINE_SOCARCH_FILTER_append_mx6q = " \\
    virtual/opencl-icd \\
    opencl-headers \\
 "
 MACHINE_SOCARCH_FILTER_append_mx8 = " \\
    virtual/opencl-icd \\
    opencl-headers \\
 "
 MACHINE_SOCARCH_FILTER_append_mx8qm = " \\
    virtual/libopenvx \\
 "

 INHERIT += "fsl-dynamic-packagearch"

 SIGGEN_EXCLUDE_SAFE_RECIPE_DEPS_append = " \\
    imx-gpu-viv->kernel-module-imx-gpu-viv \\
    libimxvpuapi->virtual/imxvpu \\
    imx-vpuwrap->virtual/imxvpu \\
    imx-codec->virtual/imxvpu \\
    imx-test->virtual/imxvpu \\
 "

 # Firmware
 MACHINE_FIRMWARE ?= ""
 MACHINE_FIRMWARE_append_mx6ull = " firmware-imx-epdc"
 MACHINE_FIRMWARE_append_use-mainline-bsp = " linux-firmware-imx-sdma-imx6q linux-firmware-imx-sdma-imx7d firmware-imx-vpu-imx6q firmware-imx-vpu-imx6d"

 # FIXME: Needs addition of firmware-imx of official BSPs
 #MACHINE_FIRMWARE_append_mx27 = " firmware-imx-vpu-imx27"

 MACHINE_EXTRA_RRECOMMENDS += "$MACHINE_FIRMWARE"

 # Extra audio support
 MACHINE_EXTRA_RRECOMMENDS_append_mx6 = " $@bb.utils.contains('DISTRO_FEATURES', 'alsa', 'imx-alsa-plugins', '', d)"

 # Extra QCA Wi-Fi & BTE driver and firmware
 MACHINE_EXTRA_RRECOMMENDS_append = " $@bb.utils.contains('MACHINE_FEATURES', 'qca6174', 'packagegroup-fsl-qca6174', '', d)"
 MACHINE_EXTRA_RRECOMMENDS_append = " $@bb.utils.contains('MACHINE_FEATURES', 'qca9377', 'packagegroup-fsl-qca9377', '', d)"

 # Extra udev rules
 MACHINE_EXTRA_RRECOMMENDS += "udev-rules-imx"

 # GStreamer 1.0 plugins
 MACHINE_GSTREAMER_1_0_PLUGIN ?= ""
 MACHINE_GSTREAMER_1_0_PLUGIN_mx6ul ?= "gstreamer1.0-plugins-imx-meta"
 MACHINE_GSTREAMER_1_0_PLUGIN_mx6ull ?= "gstreamer1.0-plugins-imx-meta"

 # Determines if the SoC has support for Vivante kernel driver
 SOC_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT        = "0"
 SOC_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT_imxgpu = "1"

 # Handle Vivante kernel driver setting:
 #   0 - machine does not have Vivante GPU driver support
 #   1 - machine has Vivante GPU driver support
 MACHINE_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT ?= "$SOC_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT"

 # Graphics libraries
 PREFERRED_PROVIDER_virtual/egl      ?= "mesa"
 PREFERRED_PROVIDER_virtual/libgl    ?= "mesa"
 PREFERRED_PROVIDER_virtual/libgles1 ?= "mesa"
 PREFERRED_PROVIDER_virtual/libgles2 ?= "mesa"

 PREFERRED_PROVIDER_virtual/egl_imxgpu        ?= "imx-gpu-viv"
 PREFERRED_PROVIDER_virtual/libgl_imxgpu3d    ?= "imx-gpu-viv"
 PREFERRED_PROVIDER_virtual/libgles1_imxgpu3d ?= "imx-gpu-viv"
 PREFERRED_PROVIDER_virtual/libgles2_imxgpu3d ?= "imx-gpu-viv"
 PREFERRED_PROVIDER_virtual/libg2d            ?= "imx-gpu-g2d"
 PREFERRED_PROVIDER_virtual/libg2d_imxdpu     ?= "imx-dpu-g2d"

 PREFERRED_VERSION_weston_mx6 ?= "5.0.0.imx"

 PREFERRED_VERSION_wayland-protocols_mx6 ?= "1.17.imx"

 # Use i.MX libdrm Version
 PREFERRED_VERSION_libdrm_mx6 ?= "2.4.91.imx"

 # Handle default kernel
 IMX_DEFAULT_KERNEL = "linux-imx"
 IMX_DEFAULT_KERNEL_mx6ul = "linux-fslc-imx"
 IMX_DEFAULT_KERNEL_mx6ull = "linux-fslc-imx"
 IMX_DEFAULT_KERNEL_use-mainline-bsp = "linux-fslc"

 PREFERRED_PROVIDER_virtual/kernel ??= "$IMX_DEFAULT_KERNEL"

 SOC_DEFAULT_IMAGE_FSTYPES = "wic.bmap wic.gz"
 SOC_DEFAULT_IMAGE_FSTYPES_mxs = "uboot-mxsboot-sdcard wic.gz"

 # Do not update fstab file when using wic images
 WIC_CREATE_EXTRA_ARGS ?= "--no-fstab-update"


 IMAGE_FSTYPES ?= "$SOC_DEFAULT_IMAGE_FSTYPES"

 IMAGE_BOOT_FILES ?= " \\
    $KERNEL_IMAGETYPE \\
    $@make_dtb_boot_files(d) \\
 "

 WKS_FILE_DEPENDS ?= " \\
    virtual/bootloader \\
    \\
    e2fsprogs-native \\
    bmap-tools-native \\
 "

 WKS_FILE_DEPENDS_append_mx8 = " imx-boot "

 SOC_DEFAULT_WKS_FILE ?= "imx-uboot-bootpart.wks.in"

 WKS_FILE ?= "$SOC_DEFAULT_WKS_FILE"

 # Certain machines override the default fsl u-boot with the
 # fslc u-boot. To restore the fsl u-boot, add use-fsl-bsp like this:
 #   MACHINEOVERRIDES_prepend_imx6ulevk = "use-fsl-bsp:"
 UBOOT_MAKE_TARGET_use-fsl-bsp_mx6 = "u-boot.imx"
 UBOOT_SUFFIX_use-fsl-bsp_mx6 = "imx"
 SPL_BINARY_use-fsl-bsp_mx6 = ""
 WKS_FILE_use-fsl-bsp_mx6 = "imx-uboot-bootpart.wks.in"

 SERIAL_CONSOLES = "115200;ttymxc0"
 SERIAL_CONSOLES_mxs = "115200;ttyAMA0"

 KERNEL_IMAGETYPE = "zImage"
 KERNEL_IMAGETYPE_aarch64 = "Image"

 MACHINE_FEATURES = "usbgadget usbhost vfat alsa touchscreen"

 # Add the ability to specify _imx machines
 MACHINEOVERRIDES =. "imx:"  

内核设备树定义文件:在imx6ull-bird-dk.conf文件中,通过变量KERNEL_DEVICETREE定义了Linux内核在编译过程中生成的设备树文件。当需要修改Linux内核在编译过程中生成的设备树文件时,除了需要提供相对于的.dtb文件外,还需要修改KERNEL_DEVICETREE变量值。

U-BOOT的配置:在imx6ull-bird-dk.conf文件中,通过配置UBOOT_CONFIG变量,定义了U-Boot在编译过程中所使用的配置文件。

在imx6ull14x14evk.conf配置文件中,官方支持了optee的功能,关于optee功能的配置,需要修改/sources/meta-freescale/recipes-security/optee-imx路径下的optee-os_3.2.0.imx.bb文件,在目前我们的应用中,暂时用不到optee功能,因此先将其屏蔽,不参与嵌入式Linux系统镜像文件的构建过程,屏蔽optee之后的imx6ull-bird-dk.conf文件如下: 关于imx6ull-bird-dk.conf文件内容修改在后面U-Boot移植、Linux Kernel移植过程中会详细描述。

1.1.3 创建distro文件

distro定义了嵌入式Linux发行版的功能等特性。同样的,我们在官方提供的fsl-imx-fb版本上进行修改。将/sources/meta-imx/meta-sdk/conf/distro下的fsl-imx-fb.conf文件拷贝至/sources/meta-bird-imx6ull/conf/distro/路径下,并将其重命名为bird-imx-fb.conf,并按照下图所示修改:

在bird-imx-fb.conf文件中,通过include conf/distro/include/fsl-imx-base.inc以及include conf/distro/include/fsl-imx-preferred-env.inc包含了fsl-imx-base.inc和fsl-imx-preferred-env.inc两个文件,这两个文件比较重要,定义了对应linux发行版的相关配置。

将/sources/meta-imx/meta-sdk/conf/distro/include/路径下的fsl-imx-base.inc和fsl-imx-preferred-env.inc两个文件拷贝至/sources/meta-bird-imx6ull/conf/distro/include/路径下,并分别将其重命名为:bird-imx-base.inc和bird-imx-preferred-env.inc

同时将bird-imx-fb.conf文件中的include conf/distro/include/fsl-imx-base.inc修改为include conf/distro/include/bird-imx-base.inc;将include conf/distro/include/fsl-imx-preferred-env.inc修改为include conf/distro/include/bird-imx-preferred-env.inc

1.1.4 创建recipe

machine和distro分别定义了定制化嵌入式Linux系统的硬件和发行版特征,除此之外,构建的系统中所需要的软件包、软件源码等还需要在recipes中添加。该小节以recipes-test为例,创建一个recipe,用以描述recipe的过程。后续在实际使用过程中,将根据需求,创建不同的recipe,以实现增减第三方软件包或自己开发的软件,用来构建最终的嵌入式Linux系统。

在/sources/meta-bird-imx6ull路径下,创建文件夹recipes-test,recipes-test文件夹中将用于存放需要使用到的软件包(实际上是一些.bb、.bbappend等文件)。创建文件夹recipes-test后,在/sources/meta-bird-imx6ull/recipes-test路径下创建文件夹test,并在test文件夹中创建printfhello.bb文件。在printfhello.bb文件中,输入以下信息:

# Copyright (C) 2020-2036 XXXX Semiconductor

 DESCRPITION = "Prints Hello World"
 LICENSE = "GPLv2+"
 LIC_FILES_CHKSUM = "file://Licenses/README;md5=a2c678cfd4a4d97135585cad908541c6"

 PN = "printfhello"
 PV = "1"

 addtask TestFun

 python do_TestFun()
   bb.plain("********************");
   bb.plain("* *");
   bb.plain("* Hello, World! *");
   bb.plain("* *");
   bb.plain("********************");
   

在printfhello.bb文件中,提供了recipe的描述,包括:名字、版本,并且重写了do_TestFun任务。在构建过程中,当执行了recipes-test中的printfhello.bb文件时,将会通过执行重写的do_TestFun任务,输出一些打印信息。 至此,创建Metadata基本完成,后面章节将对创建的Metadata进行验证。需要特别注意的是,创建的Metadata整体文件架构有严格的要求,须按照下图所示的文件架构进行创建:

1.2 使能新建的Layers

新创建的Metadata需要在imx-setup-release.sh中将其使能,才能参与到最终的嵌入式Linux发行版的构建。在imx-setup-release.sh脚本中,增加meta-bird-imx6ull即可,如下图所示:

1.3 Metadata测试

在前面小节中,我们创建了以MACHINE=imx6ull-bird-dk,DISTRO=bird-imx-fb为例的Metadata。创建Metadata后,需要对新创建的Metadata进行测试,确定新创建的Metadata是否符合要求。

1.3.1 查看machine

在使用imx-setup-release.sh脚本初始化Yocto构建目录时,imx-setup-release.sh脚本通过调用setup-environment脚本,查找当前支持的machine。因此在/fsl-release-yocto路径下,输入 ./setup-environment -h命令,查看setup-environment脚本帮助信息,该信息列出了Yocto路径下支持的MACHINE。可以看到新增加的machine imx6ull-bird-dk,如下图所示:

1.3.2 imx-setup-release.sh脚本

在/fsl-release-yocto下,运行imx-setup-release.sh脚本。该脚本用于初始化Yocto构建目录,命令如下:DISTRO=bird-imx-fb MACHINE=imx6ull-bird-dk source imx-setup-release.sh -b build,运行该脚本后,将会根据bird-imx-fb和imx6ull-birk-dk找到对用的bird-imx-fb.conf和imx6ull-bird-dk.conf。如下图所示:

查看/fsl-release-yocto/build/conf下的bblayers.conf文件,将看到新增加的bbLAYERS,如下图所示:

查看/fsl-release-yocto/build/conf下的local.conf文件,将看到新增加的machine和distro,如下图所示:

1.3.3 运行BitBake构建系统

运行imx-setup-release.sh脚本后,会自动生成一个build文件夹,并自动进入该文件夹。进入build路径下,运行bitbake命令:bitbake imx-image-multimedia,至此由于我们之前新创建的machine(imx6ull-bird-dk.conf)和distro(bird-imx-fb.conf)都是直接拷贝Freescale官方提供的imx6ull14x14evk.conf和fsl-imx-fb.conf文件,所以将构建出和官方一致的嵌入式Linux发行版。后面将分别对imx6ull-bird-dk.conf、bird-imx-fb.conf以及recipe中的.bb等文件进行修改,真正的构建一个完整的定制化的嵌入式Linux系统。同时在/fsl-release-yocto/build/tmp/deploy/images/imx6ull-bird-dk路径下,可以看到生成了相应的image文件:

此外,我们还需要验证新增加的recipe是否正确。在新增加的recipe中,打印出了相关的测试信息,因此,可以通过该测试信息是否正确打印来确定新增加的recipe是否正确。在/fsl-release-yocto/build路径下,使用如下命令:bitbake printfhello -c TestFun。即可调用recipe printfhello中的TestFun函数,输出如下信息:

1.4 BitBake离线构建系统

在使用bitbake imx-image-multimedia命令开始构建系统时,可以看到将会先通过网络连接至bitbake服务器做一些验证准备工作,同时,在Bitbake构建系统过程中,会根据.bb文件中定义的资源路径下载相关的源码,进行系统构建。通常来说,构建嵌入式Linux系统是一个不断修改不断迭代的过程,要是每次构建系统都重新连接bitbake服务器、下载一些相关源码,对于开发效率来说影响很大,特别是网络条件不好时。

因此当通过bitbake imx-image-multimedia命令完成一次系统构建后,构建系统所需要的软件源码等都已经下载至本地的/Yocto/fsl-yocto-release/downloads路径下,也就是说所有参与构建嵌入式系统所需的资源都已经下载至了本地,我们要做的只是在对本地资源进行修改的情况下,可以采用离线构建系统的方式,具体来说通过修改imx-setup-release.sh文件,设置BB_NO_NETWORK变量为1即可,如下所示:

2.U-Boot移植

一个完整的嵌入式Linux发行版包括U-BootLinux KernelDevice Tree(Linux Kernel编译时相应的Device Tree也会编译出来)以及Rootfs。Linux系统的启动,需要一个BootLoader程序。U-Boot就是BootLoader的一种。通常来说,CPU芯片上电以后先运行一段BootLoader程序。这段bootloader程序会先初始化DDR等外设,然后将Linux内核从flash(NAND,NOR FLASH, SD, MMC 等)拷贝到 DDR 中,最后启动Linux内核。 一般来说对于U-Boot的移植,主要会涉及到:DDR初始化,以太网功能。

2.1 U-Boot源码下载

U-Boot是一个遵循GPL协议的开源软件,官方提供了针对不同厂家CPU不同版本的U-Boot。各个CPU厂家从U-Boot官方下载某一特定版本的U-Boot,CPU厂商(如NXP)根据自己的CPU芯片基于该版本维护一个版本的U-Boot。然后基于各厂商CPU的开发板或自己设计的板卡,需要根据CPU厂商维护的U-Boot做相应的修改,以适应自己的板卡。具体关系如下:

在实际项目中,我们通常会参考半导体厂商针对所使用CPU的评估板进行相关的修改(硬件/软件)制作自己产品所使用的硬件平台。因此对于U-Boot,大多数情况下是在基于半导体厂商维护的U-Boot代码,进行相应的调整(适配),使其能够在产品使用的硬件平台上正确的运行。

对于imx6ull,教程中采用的是NXP官方维护的U-Boot版本是imx_v2020.04_5.4.47_2.2.0,所以我们将在imx_v2020.04_5.4.47_2.2.0版本上进行修改。其下载地址为git://source.codeaurora.org/external/imx/uboot-imx.git,分支为imx_v2020.04_5.4.47_2.2.0。

U-Boot的最主要目的是启动Linux内核,但除此之外,还可以集成一些其他基础功能,目前的U-Boot已经支持液晶屏、网络、 USB 等高级功能。 就像PC上的BIOS一样,可以直接进入BIOS进行一些配置操作。因此U-Boot中也会涉及到一些外设驱动,这也就是U-Boot移植过程中需要涉及到的工作。

2.2 增加U-Boot Recipe

在U-Boot移植(硬件适配)过程中,需要修改相应的U-Boot源码,同样我们不会直接在Yocto中提供的recipe中直接修改,而是在我们新创建的metadata中创建新的recipe的方式来对U-Boot软件编译过程进行配置。

U-Boot的配置属于distro中的内容。在/sources/meta-bird-imx6ull/conf/distro路径下的bird-imx-fb.conf中,通过include conf/distro/include/bird-imx-preferred-env.inc的方式,引用了bird-imx-preferred-env.inc文件,在该文件中,通过PREFERRED_PROVIDER_virtual/bootloader_imx = "u-boot-imx"变量定义了U-Boot的provider。

可以看出imx6ull的provider是u-boot-imx,实际上对应的是/sources/meta-imx/meta-bsp/recipes-bsp/u-boot/路径下的u-boot-imx_2020.04.bb文件。因此创建如下路径:/fsl-release-yocto/sources/meta-bird-imx6ull/recipes-bsp/u-boot/,并将/sources/meta-imx/meta-bsp/recipes-bsp/u-boot/路径下的u-boot-imx_2020.04.bb文件及该路径下的其他文件拷贝至/fsl-release-yocto/sources/meta-bird-imx6ull/recipes-bsp/u-boot/路径下,将其重命名为:u-boot-bird_2020.04.bb。

同时将/sources/meta-bird-imx6ull/conf/distro/include/路径下的bird-imx-preferred-env.inc中的PREFERRED_PROVIDER_virtual/bootloader_imx = "u-boot-imx"修改为PREFERRED_PROVIDER_virtual/bootloader_imx = “u-boot-bird”,修改后的bird-imx-preferred-env.inc如下:

修改后用命令bitbake imx-image-multimedia重新编译,可以看到如下编译过程:

如下两个文件是可直接下载到开发板上运行的文件:

2.3 修改U-Boot Recipe

对于U-Boot的移植或者说是硬件平台的适配,更多的是需要修改U-Boot源码(相关驱动代码:如EMMC、SD、网口、LCD等),使其能工作于我们自己设计的硬件平台。理论上来说,不同的硬件平台所对应的相关驱动是不一样的,这也导致了不同的硬件平台所使用的U-Boot也是不一样的。

但是实际过程中,往往在设计硬件平台的时候会参考NXP官方提供的EVK开发板,同时,对于一个CPU,所使用的硬件外设接口相差不大,因此,我们可以在基于官方平台提供的U-Boot版本上做相应的修改即可得到适合自己设计硬件平台的U-Boot。

同样的,在修改U-Boot源码之前,我们需要将从NXP官方下载的U-Boot源码放在本地,并且将OpenEmbedded编译所使用的U-Boot软件包源码指向我们本地存放的U-Boot,这样,就可以实现只更改本地存储的U-Boot代码,而不至于影响到其他项目。将从NXP官网下载的imx_v2020.04_5.4.47_2.2.0版本解压至/Linux/fsl-release-yocto/bird-imx-uboot路径下,如下图所示:

uboot源码已经下载到本地,在构建的路径下进行相应编译。

将U-Boot源码存放在/Linux/fsl-release-yocto/bird-imx-uboot路径之后,同样的,在本地采用Git管理U-Boot源码,同时,修改/fsl-release-yocto/sources/meta-bird-imx6ull/recipes-bsp/u-boot/u-boot-bird_2020.04.bb文件,将其中的SRC_URI指向本地存放U-Boot的路径。

LICENSE = "GPLv2+"
LIC_FILES_CHKSUM = "file://Licenses/gpl-2.0.txt;md5=b234ee4d69f5fce4486a80fdaf4a4263"

SRCBRANCH = "master"
UBOOT_SRC ?= "git:$BSPDIR/bird-imx-uboot;protocol=file"
SRC_URI = "$UBOOT_SRC;branch=$SRCBRANCH"
SRCREV = "$AUTOREV"

#LICENSE = "GPLv2+"
#LIC_FILES_CHKSUM = "file://Licenses/gpl-2.0.txt;md5=b234ee4d69f5fce4486a80fdaf4a4263"

#NXP_REPO_MIRROR ?= "nxp/"
#SRCBRANCH = "$NXP_REPO_MIRRORimx_v2016.03_4.1.15_2.0.0_ga"
#UBOOT_SRC ?= "git://source.codeaurora.org/external/imx/uboot-imx.git;protocol=https"
#SRC_URI = "$UBOOT_SRC;branch=$SRCBRANCH"
#SRCREV = "a57b13b942d59719e3621179e98bd8a0ab235088"  


其中,LIC_FILES_CHKSUM的md5值和SRCREV的值需要根据实际情况修改,LIC_FILES_CHKSUM的md5值在编译过程中会自动计算,如果出现LIC_FILES_CHKSUM的md5值不匹配的错误,根据错误信息中提供的新的md5值修改LIC_FILES_CHKSUM的md5值即可。

SRCREV的值指定了所使用代码分支下的版本,可以通过bird-imx-uboot下使用git log查看(commit id),也可以将SRCREV设置为SRCREV="$AUTOREV"使用代码分支下的最新版本。

u-boot-bird_2020.04.bb文件用于配置在bird-imx-fb发行版中u-boot的配置。在u-boot-bird_2020.04.bb文件中,通过require u-boot-common.inc引用了u-boot-common.inc文件,在u-boot-common.inc文件中,定义了u-boot的获取地址等,但是在实际编译过程中,会在u-boot-bird_2020.04.bb文件中对u-boot获取的地址及版本号对应的变量UBOOT_SRC、SRCBRANCH重新赋值,因此,u-boot-common.inc文件中的内容,保持原样即可。

同样的在u-boot-bird_2020.04.bb文件中,同样通过require recipes-bsp/u-boot/u-boot.inc引用了u-boot.inc文件,该文件实际上对应的是/sources/poky/meta/recipes-bsp/u-boot路径下的u-boot.inc文件,在u-boot.inc文件中定义了些与u-boot编译相关的变量值,我们不需要修改,保持原样即可。

如下之前编译过了,直接用source。

2.4 编译U-Boot

通过修改U-Boot recipe,将OpenEmbedded构建系统使用的U-Boot源码指向了本地U-Boot存放地址,因此编译过程中将编译本地存

以上是关于嵌入式Linux系统中根文件系统构建方式的主要内容,如果未能解决你的问题,请参考以下文章

Yocto2构建嵌入式Linux系统

迅为iTop开发板使用buildroot构建opencv文件系统

嵌入式LINUXbusybox-1.32.0 交叉编译构建文件系统会出现的问题以及解决方案

嵌入式LINUXbusybox-1.32.0 交叉编译构建文件系统会出现的问题以及解决方案

嵌入式LINUXbusybox-1.32.0 交叉编译构建文件系统会出现的问题以及解决方案

嵌入式linux与物联网进阶之路三:根文件系统制作