STM32MP157构建OpenSTLinux的QT镜像和SDK
作者:zzssdd2
E-mail:zzssdd2@foxmail.com
记录下整个过程以及在该过程中遇到的问题和解决方法。
一、获取软件仓库
$ mkdir -p openstlinux-5.4-dunfell-mp1-21-12-22
$ cd openstlinux-5.4-dunfell-mp1-21-12-22
$ repo init -u https://github.com/STMicroelectronics/oe-manifest.git -b refs/tags/openstlinux-5.4-dunfell-mp1-21-12-22
执行第3条命令时报错如下:
$ repo init -u https://github.com/STMicroelectronics/oe-manifest.git -b refs/tags/openstlinux-5.4-dunfell-mp1-21-12-22
Command 'repo' not found, but can be installed with:
sudo snap install git-repo
按照提示安装git-repo
后重新执行命令,报错如下:
$ repo init -u https://github.com/STMicroelectronics/oe-manifest.git -b refs/tags/openstlinux-5.4-dunfell-mp1-21-12-22
warning: gpg (GnuPG) is not available.
warning: Installing it is strongly encouraged.
warning: templates not found /build/git-repo-publish/parts/git/install/usr/share/git-core/templates
......
File "/home/admin/samba/stm32mp157/STM32MP15-Ecosystem-v2.1.0/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/.repo/repo/main.py", line 79
file=sys.stderr)
^
SyntaxError: invalid syntax
按照如下步骤解决上述错误:
$ sudo apt-get install gpg
$ rm -rf ~/.repoconfig
$ mkdir -p ~/bin
$ curl https://storage.googleapis.com/git-repo-downloads/repo-1 > ~/bin/repo
$ chmod a+x ~/bin/repo
然后执行如下命令获取仓库:
$ python3 ~/bin/repo init -u https://github.com/STMicroelectronics/oe-manifest.git -b refs/tags/openstlinux-5.4-dunfell-mp1-21-12-22
如果出现如下警告,按照提示执行命令即可:
... A new version of repo (2.21) is available.
... You should upgrade soon:
cp /home/admin/samba/stm32mp157/STM32MP15-Ecosystem-v2.1.0/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/.repo/repo/repo /home/admin/bin/repo
如果执行命令出现如下错误提示:
Downloading Repo source from https://gerrit.googlesource.com/git-repo
fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle
fatal: error [Errno 110] Connection timed out
fatal: double check your --repo-rev setting.
fatal: cloning the git-repo repository failed, will remove '.repo/repo'
执行如下命令使用国内镜像源:
$ export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
然后再重新执行命令。成功执行命令的话提示如下:
$ python3 ~/bin/repo init -u https://github.com/STMicroelectronics/oe-manifest.git -b refs/tags/openstlinux-5.4-dunfell-mp1-21-12-22
Downloading Repo source from https://mirrors.tuna.tsinghua.edu.cn/git/git-repo
remote: Enumerating objects: 7259, done.
remote: Counting objects: 100% (7259/7259), done.
remote: Compressing objects: 100% (3847/3847), done.
remote: Total 7259 (delta 4683), reused 5526 (delta 3338)
接收对象中: 100% (7259/7259), 3.21 MiB | 3.41 MiB/s, 完成.
处理 delta 中: 100% (4683/4683), 完成.
Downloading manifest from https://github.com/STMicroelectronics/oe-manifest.git
remote: Enumerating objects: 61, done.
remote: Counting objects: 100% (27/27), done.
remote: Compressing objects: 100% (18/18), done.
remote: Total 61 (delta 15), reused 20 (delta 9), pack-reused 34
展开对象中: 100% (61/61), 9.76 KiB | 713.00 KiB/s, 完成.
Your identity is: zzssdd2 <zzssdd2@foxmail.com>
If you want to change this, please re-run 'repo init' with --config-name
repo has been initialized in /home/admin/samba/stm32mp157/STM32MP15-Ecosystem-v2.1.0/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22
接着执行同步仓库的命令:
$ python3 ~/bin/repo sync
Fetching: 100% (9/9), done in 3m27.864s
Garbage collecting: 100% (9/9), done in 0.040s
repo sync has finished successfully.
执行完上面命令后仓库就同步完成了,如果在同步过程中由于下载出错等原因导致中断,重新执行同步命令即可。同步完成后目录结构如下所示:
openstlinux-5.4-dunfell-mp1-21-12-22
├── .repo
│ ├── copy-link-files.json
│ ├── manifests
│ ├── manifests.git
│ ├── manifest.xml
│ ├── project.list
│ ├── project-objects
│ ├── projects
│ └── repo
└── layers
├── meta-openembedded
├── meta-qt5
├── meta-st
├── meta-timesys
└── openembedded-core
接下来进行构建环境的初始化。
二、初始化构建环境
我选择的镜像是QT image and SDK with weston/wayland,因此执行如下命令来初始化构建环境:
$ DISTRO=openstlinux-weston MACHINE=stm32mp1 source layers/meta-st/scripts/envsetup.sh
由于我的主机缺少相关软件包提示如下:
[HOST DISTRIB check]
Linux Distrib: Ubuntu
Linux Release: 20.04
Required packages for Linux Distrib:
build-essential chrpath cpio debianutils diffstat gawk gcc-multilib git iputils-ping libegl1-mesa libsdl1.2-dev libssl-dev pylint python3 python3-git python3-jinja2 python3-pexpect python3-pip socat texinfo unzip wget xterm xz-utils
Missing required packages detected:
chrpath diffstat gawk gcc-multilib libegl1-mesa libsdl1.2-dev pylint python3-git python3-jinja2 python3-pip socat texinfo xterm
To update your Linux Distribution packages, two proposals:
1) run again envsetup.sh script with '--pkg-update' option
OR
2) before running envsetup.sh script, launch first in your Linux console:
sudo apt-get update
sudo apt-get install chrpath diffstat gawk gcc-multilib libegl1-mesa libsdl1.2-dev pylint python3-git python3-jinja2 python3-pip socat texinfo xterm
Check aborted: exiting now...
根据提示执行如下命令:
$ sudo apt-get update
$ sudo apt-get install chrpath diffstat gawk gcc-multilib libegl1-mesa libsdl1.2-dev pylint python3-git python3-jinja2 python3-pip socat texinfo xterm
然后在我的主机上会出现如下错误:
下列软件包有未满足的依赖关系:
libsdl1.2-dev : 依赖: libglu1-mesa-dev 但是它将不会被安装 或
libglu-dev
依赖: libx11-dev 但是它将不会被安装
依赖: libxext-dev 但是它将不会被安装
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。
解决错误过程如下:
$ sudo apt install aptitude
$ sudo aptitude install libsdl1.2-dev
......
libx11-dev : 依赖: libx11-6 (= 2:1.6.9-2ubuntu1.2) 但是 2:1.6.9-2ubuntu1.3 已安装
下列动作将解决这些依赖关系:
保持 下列软件包于其当前版本:
1) libegl-dev [未安装的]
2) libgl-dev [未安装的]
3) libgl1-mesa-dev [未安装的]
4) libgles-dev [未安装的]
5) libglu1-mesa-dev [未安装的]
6) libglvnd-dev [未安装的]
7) libglx-dev [未安装的]
8) libsdl1.2-dev [未安装的]
9) libx11-dev [未安装的]
10) libxext-dev [未安装的]
是否接受该解决方案?[Y/n/q/?] n
下列动作将解决这些依赖关系:
降级 下列软件包:
1) libx11-6 [2:1.6.9-2ubuntu1.3 (now) -> 2:1.6.9-2ubuntu1.2 (focal-security,
是否接受该解决方案?[Y/n/q/?] Y
......
解决该错误后重新执行安装所缺少软件包的那条命令即可。安装完成后再次执行初始化构建环境的命令,如下:
$ DISTRO=openstlinux-weston MACHINE=stm32mp1 source layers/meta-st/scripts/envsetup.sh
[HOST DISTRIB check]
Linux Distrib: Ubuntu
Linux Release: 20.04
Required packages for Linux Distrib:
build-essential chrpath cpio debianutils diffstat gawk gcc-multilib git iputils-ping libegl1-mesa libsdl1.2-dev libssl-dev pylint python3 python3-git python3-jinja2 python3-pexpect python3-pip socat texinfo unzip wget xterm xz-utils
Check OK: all required packages are installed on host.
[source layers/openembedded-core/oe-init-build-env][from nothing]
[EULA configuration]
[Configure *.conf files]
[INFO] No 'site.conf.sample' file available at /home/admin/samba/stm32mp157/STM32MP15-Ecosystem-v2.1.0/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/layers/meta-st/scripts. Create default one...
===========================================================================
Configuration files have been created for the following configuration:
DISTRO : openstlinux-weston
DISTRO_CODENAME : dunfell
MACHINE : stm32mp1
BB_NUMBER_THREADS : <no-custom-config-set>
PARALLEL_MAKE : <no-custom-config-set>
BUILDDIR : build-openstlinuxweston-stm32mp1
DOWNLOAD_DIR : <disable>
SSTATE_DIR : <disable>
SOURCE_MIRROR_URL : <no-custom-config-set>
SSTATE_MIRRORS : <disable>
WITH_EULA_ACCEPTED: YES
===========================================================================
Available images for OpenSTLinux layers are:
- Official OpenSTLinux images:
st-image-weston - OpenSTLinux weston image with basic Wayland support (if enable in distro)
- Other OpenSTLinux images:
- Supported images:
st-image-core - OpenSTLinux core image
You can now run 'bitbake <image>'
The OpenEmbedded environment setup script must be run once in each new working terminal in which you use the BitBake or devtool tools
The BSP for STM32MP1 depends on packages and firmwares which are covered by a software license agreement (SLA). You will be asked to read and to accept this EULA.
至此,构建环境初始化完成,接下来开始构建镜像和SDK。
三、构建镜像和SDK
温馨提示:在执行下面的构建命令前建议查看下磁盘容量以确保有足够的磁盘空间,否则在构建过程中因磁盘空间不足也会导致失败,如果磁盘空间不够需要先进行扩容再来进行构建工作。
镜像和SDK构建完成后的磁盘占用情况如下:
$ du -h -d 1 134M ./layers 330M ./.repo 70G ./build-openstlinuxweston-stm32mp1
执行如下命令开始构建镜像:
$ bitbake st-example-image-qtwayland
然后就是耐心等待构建完成。如果在该过程中由于下载出错等原因导致中断,重新执行构建命令即可。
################################### 2000 years later...... ################################################
构建成功后如下所示:
NOTE: Started PRServer with DBfile: /home/admin/samba/stm32mp157/STM32MP15-Ecosystem-v2.1.0/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/cache/prserv.sqlite3, IP: 127.0.0.1, PORT: 42375, PID: 502452
Loading cache: 100% |#############################################################################| Time: 0:00:02
Loaded 3751 entries from dependency cache.
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION = "1.46.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "universal"
TARGET_SYS = "arm-ostl-linux-gnueabi"
MACHINE = "stm32mp1"
DISTRO = "openstlinux-weston"
DISTRO_VERSION = "3.1.11-snapshot-20220507"
TUNE_FEATURES = "arm vfp cortexa7 neon vfpv4 thumb callconvention-hard"
TARGET_FPU = "hard"
DISTRO_CODENAME = "dunfell"
ACCEPT_EULA_stm32mp1 = "1"
GCCVERSION = "9.%"
PREFERRED_PROVIDER_virtual/kernel = "linux-stm32mp"
meta-python
meta-oe
meta-gnome
meta-initramfs
meta-multimedia
meta-networking
meta-webserver
meta-filesystems
meta-perl = "HEAD:2e7e98cd0cb82db214b13224c71134b9335a719b"
meta-st-stm32mp = "HEAD:bd643ba8654010628fbcf093666fe3d184a9df34"
meta-qt5 = "HEAD:b4d24d70aca75791902df5cd59a4f4a54aa4a125"
meta-st-openstlinux = "HEAD:2dc988821b19d2eb75cfad4d543b674cdadd77bb"
meta = "HEAD:c7d2281eb6cda9c1637c20b3540b142073bca235"
Initialising tasks: 100% |########################################################################| Time: 0:00:28
Sstate summary: Wanted 432 Found 432 Missed 0 Current 2996 (100% match, 100% complete)
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 9391 tasks of which 9373 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 2 seconds
接下来构建SDK,执行如下命令:
$ bitbake st-example-image-qtwayland -c populate_sdk
如果在该过程中因为出错导致中断,重新执行构建命令即可。构建完成后如下所示:
NOTE: Started PRServer with DBfile: /home/admin/samba/stm32mp157/STM32MP15-Ecosystem-v2.1.0/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/cache/prserv.sqlite3, IP: 127.0.0.1, PORT: 46791, PID: 1730318
Loading cache: 100% |#############################################################################| Time: 0:02:32
Loaded 3751 entries from dependency cache.
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION = "1.46.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "universal"
TARGET_SYS = "arm-ostl-linux-gnueabi"
MACHINE = "stm32mp1"
DISTRO = "openstlinux-weston"
DISTRO_VERSION = "3.1.11-snapshot-20220507"
TUNE_FEATURES = "arm vfp cortexa7 neon vfpv4 thumb callconvention-hard"
TARGET_FPU = "hard"
DISTRO_CODENAME = "dunfell"
ACCEPT_EULA_stm32mp1 = "1"
GCCVERSION = "9.%"
PREFERRED_PROVIDER_virtual/kernel = "linux-stm32mp"
meta-python
meta-oe
meta-gnome
meta-initramfs
meta-multimedia
meta-networking
meta-webserver
meta-filesystems
meta-perl = "HEAD:2e7e98cd0cb82db214b13224c71134b9335a719b"
meta-st-stm32mp = "HEAD:bd643ba8654010628fbcf093666fe3d184a9df34"
meta-qt5 = "HEAD:b4d24d70aca75791902df5cd59a4f4a54aa4a125"
meta-st-openstlinux = "HEAD:2dc988821b19d2eb75cfad4d543b674cdadd77bb"
meta = "HEAD:c7d2281eb6cda9c1637c20b3540b142073bca235"
Initialising tasks: 100% |########################################################################| Time: 0:00:21
Sstate summary: Wanted 405 Found 405 Missed 0 Current 2363 (100% match, 100% complete)
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 7689 tasks of which 7689 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 2 seconds
镜像和SDK构建完成后分别存放在目录openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/tmp-glibc/deploy
下的images
和sdk
目录下。
补充: OpenSTLinux提供了两种基于QT的镜像和SDK,这两种镜像和SDK的构建命令如下:
-
QT image and SDK with EGLFS
# Initialize the OpenEmbedded build environment for the openstlinux-eglfs distro: $ DISTRO=openstlinux-eglfs MACHINE=stm32mp1 source layers/meta-st/scripts/envsetup.sh # Build the image and the SDK: $ bitbake st-example-image-qt $ bitbake st-example-image-qt -c populate_sdk
-
QT image and SDK with weston/wayland
# Initialize the OpenEmbedded build environment for the openstlinux-weston distro: $ DISTRO=openstlinux-weston MACHINE=stm32mp1 source layers/meta-st/scripts/envsetup.sh # Build the image and the SDK: $ bitbake st-example-image-qtwayland $ bitbake st-example-image-qtwayland -c populate_sdk
四、适配开发板
前面已经编译完成镜像和SDK,已经确保整个过程是没有问题的。接下来就可以修改tf-a、u-boot和linux适配自己的开发板了,这些工作均在编译目录openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1
进行。
4.1 修改TF-A
执行如下命令查找TF-A recipe:
$ devtool search tf-a*
结果如下:
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
NOTE: Started PRServer with DBfile: /home/admin/samba/stm32mp157/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/cache/prserv.sqlite3, IP: 127.0.0.1, PORT: 34083, PID: 252954
Loading cache: 100% |#############################################################################| Time: 0:00:01
Loaded 3751 entries from dependency cache.
......
tf-a-stm32mp Trusted Firmware-A for STM32MP1
......
tf-a-stm32mp-serialboot Trusted Firmware-A for STM32MP1 as serial boot loader
......
tf-a-stm32mp-ssp Trusted Firmware-A SSP for STM32MP1
......
如果出现如下错误:
ERROR: Unable to start bitbake server (None) ERROR: Server log for this session ...... ERROR: The following layer directories do not exist ...... ERROR: Please check BBLAYERS in ......
解决方法:
$ source ../layers/openembedded-core/oe-init-build-env
然后根据查找到的recipe名称执行如下命令:
$ devtool modify tf-a-stm32mp
命令执行完成后会生成workspace
目录,然后进入目录workspace/sources/tf-a-stm32mp
对tf-a源码进行修改,参考STM32MP157系统移植(TF-A,U-Boot,Linux)文章的TF-A移植部分。
这里需要注意的是,如果是要创建自己的开发板设备树文件则需要修改配置文件,否则无法编译出对应的固件。例如我需要添加自己的开发板stm32mp157d-custom
,需要做如下修改:
修改openstlinux-5.4-dunfell-mp1-21-12-22/layers/meta-st/meta-st-stm32mp/conf/machine/stm32mp1.conf
文件如下内容,在其中添加自己的开发板:
# =========================================================================
# Machine settings
# =========================================================================
# Define list of devicetree per board
STM32MP_DT_FILES_DK += "stm32mp157a-dk1 stm32mp157d-dk1"
STM32MP_DT_FILES_DK += "stm32mp157c-dk2 stm32mp157f-dk2"
STM32MP_DT_FILES_ED += "stm32mp157c-ed1 stm32mp157f-ed1"
STM32MP_DT_FILES_EV += "stm32mp157a-ev1 stm32mp157c-ev1 stm32mp157d-ev1 stm32mp157f-ev1 stm32mp157d-custom"
当然直接修改源码中现有的设备树文件是最方便的,就无需再去修改配置文件了。例如我手中的开发板是参考stm32mp157d-ev1
设计,那就直接修改源码中stm32mp157d-ev1.dts
及其相关文件就行了(个人更推荐这种做法,维持非自己创建的layer完整性)。
修改完成后执行如下命令进行编译:
$ devtool build tf-a-stm32mp
编译成功后在目录workspace/sources/tf-a-stm32mp/oe-workdir/deploy-tf-a-stm32mp
下就是编译出的固件。然后执行如下命令部署:
$ bitbake tf-a-stm32mp -c deploy
部署后在/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/tmp-glibc/deploy/images/stm32mp1/arm-trusted-firmware
目录下可以看到更新固件。
接下来对tf-a-stm32mp-serialboot
进行修改,和上面步骤一样:
$ devtool modify tf-a-stm32mp-serialboot
$ devtool build tf-a-stm32mp-serialboot
$ bitbake tf-a-stm32mp-serialboot -c deploy
4.2 修改U-Boot
执行如下命令查找U-boot recipe:
$ devtool search u-boot*
结果如下:
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
NOTE: Started PRServer with DBfile: /home/admin/samba/stm32mp157/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/cache/prserv.sqlite3, IP: 127.0.0.1, PORT: 36991, PID: 371338
Loading cache: 100% |#############################################################################| Time: 0:00:01
Loaded 3749 entries from dependency cache.
Parsing recipes: 100% |###########################################################################| Time: 0:00:01
Parsing of 2546 .bb files complete (2544 cached, 2 parsed). 3751 targets, 107 skipped, 0 masked, 0 errors.
u-boot-stm32mp-extlinux Provide 'extlinux.conf' file for U-Boot
u-boot-stm32mp Universal Boot Loader for embedded devices for stm32mp
u-boot-stm32mp-splash Universal Boot Loader Splash Screen for stm32mp embedded devices
u-boot-fw-config-stm32mp U-Boot bootloader fw_printenv/setenv utilities
......
然后根据查找到的recipe名称执行如下命令:
$ devtool modify u-boot-stm32mp
命令执行完成后进入目录workspace/sources/u-boot-stm32mp
对u-boot源码进行修改,参考STM32MP157系统移植(TF-A,U-Boot,Linux)文章的U-BOOT移植部分。
注意:《STM32MP157系统移植(TF-A,U-Boot,Linux)》文章的u-boot代码和本文并非完全一样,本文修改
ðernet0
节点不同之处如下所示:
ðernet0 {
......
pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>;
......
};
修改完成后执行如下命令进行编译:
$ devtool build u-boot-stm32mp
如果编译报错就看下输出日志里面有没如下提示文本:
/home/admin/samba/stm32mp157/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/workspace/sources/u-boot-stm32mp is not clean, please run 'make mrproper' in the '/home/admin/samba/stm32mp157/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/workspace/sources/u-boot-stm32mp' directory.
若有就按提示进入
u-boot-stm32mp
目录下执行make mrproper
命令:$ make mrproper CLEAN u-boot.cfg.tmp CLEAN scripts/basic CLEAN scripts/kconfig CLEAN include/config include/generated
然后回到
build-openstlinuxweston-stm32mp1
目录重新执行编译指令。同样,若重新构建image过程中遇到uboot报错在
openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/tmp-glibc/work-shared/stm32mp1/uboot-source
目录执行make mrproper
命令然后回到build-openstlinuxweston-stm32mp1
目录重新执行构建指令
编译成功后在目录workspace/sources/u-boot-stm32mp/oe-workdir/deploy-u-boot-stm32mp
下就是编译出的固件。然后执行如下命令部署:
$ bitbake u-boot-stm32mp -c deploy
部署后在/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/tmp-glibc/deploy/images/stm32mp1/bootloader
目录下可以看到更新固件。
4.3 修改Linux
首先执行如下命令进行初始化:
$ devtool modify virtual/kernel
提示如下所示:
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
NOTE: Started PRServer with DBfile: /home/admin/samba/stm32mp157/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/cache/prserv.sqlite3, IP: 127.0.0.1, PORT: 33507, PID: 1054423
Loading cache: 100% |############################################| Time: 0:00:01
Loaded 3748 entries from dependency cache.
Parsing recipes: 100% |##########################################| Time: 0:00:01
Parsing of 2546 .bb files complete (2543 cached, 3 parsed). 3751 targets, 107 skipped, 0 masked, 0 errors.
INFO: Mapping virtual/kernel to linux-stm32mp
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION = "1.46.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "universal"
TARGET_SYS = "arm-ostl-linux-gnueabi"
MACHINE = "stm32mp1"
DISTRO = "openstlinux-weston"
DISTRO_VERSION = "3.1.11-snapshot-20220512"
TUNE_FEATURES = "arm vfp cortexa7 neon vfpv4 thumb callconvention-hard"
TARGET_FPU = "hard"
DISTRO_CODENAME = "dunfell"
ACCEPT_EULA_stm32mp1 = "1"
GCCVERSION = "9.%"
PREFERRED_PROVIDER_virtual/kernel = "linux-stm32mp"
meta-python
meta-oe
meta-gnome
meta-initramfs
meta-multimedia
meta-networking
meta-webserver
meta-filesystems
meta-perl = "HEAD:2e7e98cd0cb82db214b13224c71134b9335a719b"
meta-st-stm32mp = "HEAD:bd643ba8654010628fbcf093666fe3d184a9df34"
meta-qt5 = "HEAD:b4d24d70aca75791902df5cd59a4f4a54aa4a125"
meta-st-openstlinux = "HEAD:2dc988821b19d2eb75cfad4d543b674cdadd77bb"
meta = "HEAD:c7d2281eb6cda9c1637c20b3540b142073bca235"
workspace = "<unknown>:<unknown>"
Initialising tasks: 100% |#######################################| Time: 0:00:05
Sstate summary: Wanted 0 Found 0 Missed 0 Current 22 (0% match, 100% complete)
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 102 tasks of which 99 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 2 seconds
INFO: Adding local source files to srctree...
INFO: Source tree extracted to /home/admin/samba/stm32mp157/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/workspace/sources/linux-stm32mp
INFO: Recipe linux-stm32mp now set up to build from /home/admin/samba/stm32mp157/Distribution-Package/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/workspace/sources/linux-stm32mp
命令执行完成后进入目录workspace/sources/linux-stm32mp
对linux源码进行修改,参考STM32MP157系统移植(TF-A,U-Boot,Linux)文章的LINUX移植部分。
如果需要执行menuconfig
对内核配置进行更改则执行如下命令:
$ bitbake virtual/kernel -c menuconfig
修改完成后执行如下命令进行编译:
# devtool build linux-stm32mp
# bitbake linux-stm32mp -c deploy
$ bitbake virtual/kernel -C compile
编译完成后在/openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/tmp-glibc/deploy/images/stm32mp1/kernel
目录下可以看到新的固件。
上面命令会执行configure、compile、package、deploy等一系列命令,比较耗时间,如果只是想单纯编译可以执行如下命令:
$ bitbake virtual/kernel -c compile
编译后固件在openstlinux-5.4-dunfell-mp1-21-12-22/build-openstlinuxweston-stm32mp1/workspace/sources/linux-stm32mp/oe-workdir/build
目录。
最后,将这些固件更新到开发板后就可以搭配编译出来的带Qt的文件系统进行验证3D-GPU等功能了。
五、补充
5.1 关于SDMMC3
The SDMMC instances are ordered by address in the device tree arch/arm/boot/dts/stm32mp151.dtsi file:
sdmmc3: sdmmc@48004000 { ... sdmmc1: sdmmc@58005000 { ... sdmmc2: sdmmc@58007000 {
By default, in OpenSTLinux distribution, sdmmc3 is disabled so the sdmmc1 (SD card on Evaluation boards and Discovery kits) and sdmmc2 (eMMC on Evaluation boards and Wifi on Discovery kits) are respectively aliased to mmc0 and mmc1.
If you enable sdmmc3, it will take the mmc0 alias and the aliases above will shift, so don't forget to update the Linux kernel boot command accordingly!
For instance, 'root=/dev/mmcblk0p6' will become 'root=/dev/mmcblk1p6' to mount the rootfs from the sdmmc1 (SD card) when sdmmc3 is enabled.
STM32MP157拥有三个SDMMC接口,在芯片中的内存映射地址如下:
Peripheral | Boundary address | Size (Bytes) |
---|---|---|
SDMMC1 | 0x58005000 - 0x58005FFF | 4 KB |
SDMMC2 | 0x58007000 - 0x58007FFF | 4 KB |
SDMMC3 | 0x48004000 - 0x480043FF | 1 KB |
根据地址分配可知它们的初始化顺序是SDMMC3 --> SDMMC1 --> SDMMC2。
三个接口都启用后在Linux中对应的操作文件如下:
SDMMC1 | SDMMC2 | SDMMC3 |
---|---|---|
/dev/mmcblk1 | /dev/mmcblk2 | /dev/mmcblk0 |
我手上的开发板对这3个接口分配如下:
SDMMC1 | SDMMC2 | SDMMC3 |
---|---|---|
SD卡 | EMMC | WIFI |
在Linux设备树中启用sdmmc3接口前后sd卡和emmc设备号的变化如下:
设备 | 设备号(不使用SDMMC3) | 设备号(使用SDMMC3) |
---|---|---|
SD卡 | mmc0 | mmc1 |
EMMC | mmc1 | mmc2 |
st提供的yocto源码中没有使用sdmmc3,所以启用了sdmmc3接口后需要修改一些配置文件,系统启动后才能正常挂载文件系统。需要修改如下几个文件:
-
mount-partitions.sh
OpenSTLinux源码中的位置:
openstlinux-5.4-dunfell-mp1-21-12-22/layers/meta-st/meta-st-openstlinux/recipes-core/systemd/systemd-mount-partitions/mount-partitions.sh
烧录后在文件系统中的位置:
/sbin/mount-partitions.sh
修改后内容如下,主要增加了mmcblk2的内容:
#!/bin/sh - #=============================================================================== # # FILE: mount-partitions.sh # # USAGE: ./mount-partitions.sh [start|stop] # # DESCRIPTION: mount partitions # ORGANIZATION: STMicroelectronics # COPYRIGHT: Copyright (C) 2018, STMicroelectronics - All Rights Reserved # CREATED: 01/09/2018 13:36 # REVISION: --- #=============================================================================== MOUNT_PARTITIONS_LIST="" get_type() { local __resultvar=$1 ROOT_TYPE="unknown" if [ -f /usr/bin/findmnt ]; then ROOT_DEVICE=$(findmnt --noheadings --output=SOURCE / | cut -d'[' -f1) case $ROOT_DEVICE in ubi*) ROOT_TYPE="nand" ;; /dev/mmcblk0*) ROOT_TYPE="sdmmc" ;; /dev/mmcblk1*) ROOT_TYPE="mmc" ;; /dev/mmcblk2*) ROOT_TYPE="mmc" ;; /dev/disk/by-*) LINK=$(/usr/bin/readlink $ROOT_DEVICE | tr '/' ' ' | tr '.' ' ' | sed "s/ //g") case $LINK in ubi*) ROOT_TYPE="nand" ;; mmcblk0*) ROOT_TYPE="sdmmc" ;; mmcblk1*) ROOT_TYPE="mmc" ;; mmcblk2*) ROOT_TYPE="mmc" ;; esac ;; esac else if [ `cat /proc/cmdline | sed "s/.*mmcblk0.*/mmcblk0/" ` == "mmcblk0" ]; then ROOT_TYPE="sdmmc" elif [ `cat /proc/cmdline | sed "s/.*mmcblk1.*/mmcblk1/" ` == "mmcblk1" ]; then ROOT_TYPE="mmc" elif [ `cat /proc/cmdline | sed "s/.*mmcblk2.*/mmcblk2/" ` == "mmcblk2" ]; then ROOT_TYPE="mmc" elif [ `cat /proc/cmdline | sed "s/.*ubi0.*/ubi0/" ` == "ubi0" ]; then ROOT_TYPE="nand" fi fi eval $__resultvar="'$ROOT_TYPE'" } found_devices() { local __resultvar=$1 local __resultopt=$2 local _type=$3 local _search=$4 local _device="unknown" local _option=" " case $_type in nand) local ubi_volumes=$(ls -1 -d /sys/class/ubi/ubi0_*) for f in $ubi_volumes; do if [ -r $f/name ]; then cat $f/name | grep -sq "^${_search}" if [ "$?" -eq 0 ]; then _device="/dev/$(basename $f)" _option="-t ubifs" break; fi fi done ;; sdmmc) local sdmmc_parts=$(ls -1 -d /sys/block/mmcblk0/mmcblk0p*) for f in $sdmmc_parts; do if [ -r $f/uevent ]; then cat $f/uevent | grep PARTNAME | sed "s/PARTNAME=//" | grep -sq "^${_search}" if [ "$?" -eq 0 ]; then _device="/dev/$(basename $f)" break; fi fi done ;; mmc) local mmc_parts=$(ls -1 -d /sys/block/mmcblk1/mmcblk1p*) if [ ! $mmc_parts]; then mmc_parts=$(ls -1 -d /sys/block/mmcblk2/mmcblk2p*) fi for f in $mmc_parts; do if [ -r $f/uevent ]; then cat $f/uevent | grep PARTNAME | sed "s/PARTNAME=//" | grep -sq "^${_search}" if [ "$?" -eq 0 ]; then _device="/dev/$(basename $f)" break; fi fi done ;; esac eval $__resultvar="'$_device'" eval $__resultopt="'$_option'" } case "$1" in start) # mount partitions echo "mount-partitions start!" get_type TYPE echo "TYPE of support detected: $TYPE" for part in $MOUNT_PARTITIONS_LIST do part_label=$(echo $part | cut -d',' -f1) mountpoint=$(echo $part | cut -d',' -f2) found_devices DEVICE DEVICE_OPTION $TYPE $part_label echo "$part_label device: $DEVICE" [ -d $mountpoint ] || mkdir -p $mountpoint [ -e $DEVICE ] && mount $DEVICE_OPTION $DEVICE $mountpoint done ;; stop) # umount partitions echo "mount-partitions stop!" for part in $MOUNT_PARTITIONS_LIST do mountpoint=$(echo $part | cut -d',' -f2) umount $mountpoint done ;; *) echo "Usage: $0 [start|stop]" ;; esac
-
userfs-cleanup-package.sh
OpenSTLinux源码中的位置:
openstlinux-5.4-dunfell-mp1-21-12-22/layers/meta-st/meta-st-openstlinux/recipes-support/userfs/userfs-cleanup-package/userfs-cleanup-package.sh
烧录后在文件系统中的位置:
/sbin/userfs-cleanup-package.sh
修改后内容如下,主要增加了mmcblk2的内容:
#! /bin/sh ### BEGIN INIT INFO # remove package which are present on the database but not present on userfs ### END INIT INFO DESC="cleanup apt database" get_type() { local __resultvar=$1 ROOT_TYPE="unknown" if [ -f /usr/bin/findmnt ]; then ROOT_DEVICE=$(findmnt --noheadings --output=SOURCE / | cut -d'[' -f1) case $ROOT_DEVICE in ubi*) ROOT_TYPE="nand" ;; /dev/mmcblk0*) ROOT_TYPE="sdmmc" ;; /dev/mmcblk1*) ROOT_TYPE="mmc" ;; /dev/mmcblk2*) ROOT_TYPE="mmc" ;; /dev/disk/by-*) LINK=$(/usr/bin/readlink $ROOT_DEVICE | tr '/' ' ' | tr '.' ' ' | sed "s/ //g") case $LINK in ubi*) ROOT_TYPE="nand" ;; mmcblk0*) ROOT_TYPE="sdmmc" ;; mmcblk1*) ROOT_TYPE="mmc" ;; mmcblk2*) ROOT_TYPE="mmc" ;; esac ;; esac else if [ `cat /proc/cmdline | sed "s/.*mmcblk0.*/mmcblk0/" ` == "mmcblk0" ]; then ROOT_TYPE="sdmmc" elif [ `cat /proc/cmdline | sed "s/.*mmcblk1.*/mmcblk1/" ` == "mmcblk1" ]; then ROOT_TYPE="mmc" elif [ `cat /proc/cmdline | sed "s/.*mmcblk2.*/mmcblk2/" ` == "mmcblk2" ]; then ROOT_TYPE="mmc" elif [ `cat /proc/cmdline | sed "s/.*ubi0.*/ubi0/" ` == "ubi0" ]; then ROOT_TYPE="nand" elif [ `cat /proc/cmdline | sed "s/.*nfsroot.*/nfs/" ` == "nfs" ]; then ROOT_TYPE="nfs" fi fi eval $__resultvar="'$ROOT_TYPE'" } found_devices() { local __resultvar=$1 local __resultopt=$2 local _type=$3 local _search=$4 local _device="unknown" local _option=" " case $_type in nand) local ubi_volumes=$(ls -1 -d /sys/class/ubi/ubi0_*) for f in $ubi_volumes; do if [ -r $f/name ]; then cat $f/name | grep -sq "^${_search}" if [ "$?" -eq 0 ]; then _device="/dev/$(basename $f)" _option="-t ubifs" break; fi fi done ;; sdmmc) local sdmmc_parts=$(ls -1 -d /sys/block/mmcblk0/mmcblk0p*) for f in $sdmmc_parts; do if [ -r $f/uevent ]; then cat $f/uevent | grep PARTNAME | sed "s/PARTNAME=//" | grep -sq "^${_search}" if [ "$?" -eq 0 ]; then _device="/dev/$(basename $f)" break; fi fi done ;; mmc) local mmc_parts=$(ls -1 -d /sys/block/mmcblk1/mmcblk1p*) if [ ! $mmc_parts]; then mmc_parts=$(ls -1 -d /sys/block/mmcblk2/mmcblk2p*) fi for f in $mmc_parts; do if [ -r $f/uevent ]; then cat $f/uevent | grep PARTNAME | sed "s/PARTNAME=//" | grep -sq "^${_search}" if [ "$?" -eq 0 ]; then _device="/dev/$(basename $f)" break; fi fi done ;; nfs) $_device="/dev/nfs" ;; esac eval $__resultvar="'$_device'" eval $__resultopt="'$_option'" } case $1 in start) echo "Starting $DESC" get_type TYPE found_devices DEVICE DEVICE_OPTION $TYPE userfs if [ "$DEVICE" = "/dev/null" ]; then # nfs file system, do nothing exit 0 fi case $DEVICE in unknown) # userfs partition are not present # we need to cleanup apt database grep -l "^/usr/local/" /var/lib/dpkg/info/* | sed -e "s|/var/lib/dpkg/info/\(.*\).list|\1|" | xargs apt-get purge -y echo "USERFS NOT PRESENT: CLEAN DPKG DATABASE" > /dev/kmsg ;; /dev/nfs) # nfs file system, do nothing exit 0 ;; /dev/*) # userfs are present, do nothing ;; esac ;; *) echo "Usage: @sysconfdir@/init.d/userfs-cleanup-package.sh {start}" >&2 exit 1 ;; esac exit 0 # vim:noet
-
init-resize.sh
OpenSTLinux源码中的位置:
openstlinux-5.4-dunfell-mp1-21-12-22/layers/meta-st/meta-st-openstlinux/recipes-st/initrd/files/init-resize.sh
烧录后在文件系统中的位置:
/boot/uInitrd/init.d/95-resize
修改后内容如下,主要增加了mmcblk2的内容:
#!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin resize_enabled() { return 0 } resize_run() { ln -s /proc/mounts /etc/mtab if [ -n "$ROOTFS_DIR" ]; then if [ ! -e $ROOTFS_DIR/etc/.resized ] then # sdmmc0/1/2 for j in 0 1 2; do for i in 4 5 6 7 8 9 10; do DEVICE="/dev/mmcblk"$j"p"$i if [ -e $DEVICE ]; then label=$(/sbin/e2label $DEVICE 2> /dev/null) if [ $? -eq 0 ]; then case $label in user*) echo "RESIZE USERFS [$DEVICE]" /sbin/e2fsck -f -y -c -C 0 $DEVICE && /sbin/resize2fs $DEVICE ;; root*) echo "RESIZE ROOTFS [$DEVICE]" /sbin/resize2fs $DEVICE ;; vendor*) echo "RESIZE VENDORFS [$DEVICE]" /sbin/e2fsck -f -y -c -C 0 $DEVICE && /sbin/resize2fs $DEVICE ;; boot*) echo "RESIZE BOOTFS [$DEVICE]" /sbin/e2fsck -f -y -c -C 0 $DEVICE && /sbin/resize2fs $DEVICE ;; *) ;; esac fi fi done done touch $ROOTFS_DIR/etc/.resized fi fi }
5.2 关于bootfs
st-image-bootfs-openstlinux-weston-stm32mp1.ext4
镜像内容如下:
.
├── boot.scr.uimg
├── lost+found [error opening dir]
├── mmc0_extlinux
│ └── stm32mp157d-custom_extlinux.conf
├── mmc1_extlinux
│ └── stm32mp157d-custom_extlinux.conf
├── splash.bmp
├── stm32mp157d-custom.dtb
├── uImage
└── uInitrd
stm32mp157d-custom_extlinux.conf
文件内容如下:
$ cat mmc0_extlinux/stm32mp157d-custom_extlinux.conf
# Generic Distro Configuration file generated by OpenEmbedded
menu title Select the boot mode
MENU BACKGROUND /splash.bmp
TIMEOUT 20
DEFAULT stm32mp157d-custom
LABEL stm32mp157d-custom
KERNEL /uImage
FDT /stm32mp157d-custom.dtb
INITRD /uInitrd
APPEND root=PARTUUID=e91c4e10-16e6-4c0e-bd0e-77becf4a3582 rootwait rw console=ttySTM0,115200
$ cat mmc1_extlinux/stm32mp157d-custom_extlinux.conf
# Generic Distro Configuration file generated by OpenEmbedded
menu title Select the boot mode
MENU BACKGROUND /splash.bmp
TIMEOUT 20
DEFAULT stm32mp157d-custom
LABEL stm32mp157d-custom
KERNEL /uImage
FDT /stm32mp157d-custom.dtb
INITRD /uInitrd
APPEND root=PARTUUID=491f6117-415d-4f53-88c9-6e0de54deac6 rootwait rw console=ttySTM0,115200