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下的imagessdk目录下。

补充: 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代码和本文并非完全一样,本文修改&ethernet0节点不同之处如下所示:

&ethernet0 {
	......
	pinctrl-1 = <&ethernet0_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接口后需要修改一些配置文件,系统启动后才能正常挂载文件系统。需要修改如下几个文件:

  1. 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
    
    
  2. 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
    
    
  3. 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
posted @ 2022-07-24 14:29  树·哥  阅读(919)  评论(0编辑  收藏  举报