STM32MP157A系统移植--内核移植与根文件系统的制作

  • Linux内核移植步骤

Linux 内核源代码非常庞大,随着版本的发展不断增加。它使用目录树结构,并且使用Makefile 组织配置编译

3.1》导入源码

1)打开系统源码,进入linux的源码目录下,该目录下以 patch 结尾的文件为 ST 官方提供的补丁文件;linux-5.4.31.tar.xz为标准linux源码包。

/home/linux/fs_mp157a/kernel/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.4.31-r0

 

 

  1. 解压linux内核源码,并且进入解压后的源码目录下

  tar -xvf linux-5.4.31.tar.xz

cd linux-5.4.31/

(********注意:接下来所有的操作都将在此目录下,不要走错了地方。

3.2》添加 STMicroelectronics 官方补丁

  1. 解压 linux 内核源码后得到的是 Linux 社区的标准内核源码,接下来需要将 ST 官方提供的源码补丁添加到标准内核中。

for p in `ls -1 ../*.patch`; do patch -p1 < $p; done

3.3》生成标准板配置文件

1)生成 multi_v7_defconfig 默认配置

make ARCH=arm multi_v7_defconfig "fragment*.config"

2)在默认 multi_v7_defconfig 配置中加入 ST 官方提供的 fragment config

//执行以下两条指令

for f in `ls -1 ../fragment*.config`; do scripts/kconfig/merge_config.sh -m -r .config $f; done

yes '' | make ARCH=arm oldconfig

3)生成自己的默认配置文件

cp .config arch/arm/configs/stm32_fsmp1a_defconfig

4)取消 git 中的 SHA1

echo "" > .scmversion  /* echo命令的功能是写内容到标准输出。SHA1---哈希算法功能 */

//标准版基本配置已经配置好,在编译前如果需要编译额外的功能或者驱动,可以使用make meunconfig 来对内核进行配置

3.4》生成设备树文件

  1. 以参考板 DK1 设备树文件 stm32mp15xx-dkx.dtsi 和 stm32mp157a-dk1.dts 为参考,增加 stm32mp15xx-fsmp1x.dtsi 和 stm32mp157a-fsmp1a.dts:

在 arch/arm/boot/dts/ 目录下新建 stm32mp15xx-fsmp1x.dtsi:

vim arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi

增加以下内容:

#include "stm32mp157-m4-srm.dtsi"

#include "stm32mp157-m4-srm-pinctrl.dtsi"

#include <dt-bindings/mfd/st,stpmic1.h>

/ {

 memory@c0000000 {

 device_type = "memory";

 reg = <0xc0000000 0x20000000>;

 };

reserved-memory {

 #address-cells = <1>;

 #size-cells = <1>;

 ranges;

 mcuram2: mcuram2@10000000 {

 compatible = "shared-dma-pool";

 reg = <0x10000000 0x40000>;

 no-map;

 };

 vdev0vring0: vdev0vring0@10040000 {

 compatible = "shared-dma-pool";

 reg = <0x10040000 0x1000>;

 no-map;

 };

 vdev0vring1: vdev0vring1@10041000 {

 compatible = "shared-dma-pool";

 reg = <0x10041000 0x1000>;

 no-map;

 };

 vdev0buffer: vdev0buffer@10042000 {

 compatible = "shared-dma-pool";

 reg = <0x10042000 0x4000>;

 no-map;

 };

 mcuram: mcuram@30000000 {

 compatible = "shared-dma-pool";

 reg = <0x30000000 0x40000>;

 no-map;

 };

 retram: retram@38000000 {

 compatible = "shared-dma-pool";

 reg = <0x38000000 0x10000>;

 no-map;

 };

 };

 vin: vin {

 compatible = "regulator-fixed";

 regulator-name = "vin";

 regulator-min-microvolt = <5000000>;

 regulator-max-microvolt = <5000000>;

 regulator-always-on;

 };

 v3v3: regulator-3p3v {

 compatible = "regulator-fixed";

 regulator-name = "v3v3";

 regulator-min-microvolt = <3300000>;

 regulator-max-microvolt = <3300000>;

 regulator-always-on;

 regulator-boot-on;

 };

 vdd: regulator-vdd {

 compatible = "regulator-fixed";

 regulator-name = "vdd";

 regulator-min-microvolt = <3300000>;

 regulator-max-microvolt = <3300000>;

 regulator-always-on;

 regulator-boot-on;

 };

 };

 /*HDMI CEC 控制器*/

 &cec {

 pinctrl-names = "default", "sleep";

 pinctrl-0 = <&cec_pins_b>;

 pinctrl-1 = <&cec_pins_sleep_b>;

 status = "okay";

 };

 /*循环冗余校验计算单元*/

 &crc1 {

status = "okay";

 };

 &dma1 {

sram = <&dma_pool>;

 };

 &dma2 {

sram = <&dma_pool>;

 };

/*数字钟温度传感器*/

 &dts {

status = "okay";

 };

 /*图像处理单元*/

 &gpu {

 contiguous-area = <&gpu_reserved>;

 status = "okay";

 };

 /*哈希处理器*/

 &hash1 {

status = "okay";

 };

/*处理器间通信控制器*/

 &ipcc {

status = "okay";

 };

 /*看门狗*/

 &iwdg2 {

 timeout-sec = <32>;

 status = "okay";

 };

 /*随机数发生器*/

 &rng1 {

status = "okay";

 };

 /*实时时钟*/

 &rtc {

status = "okay";

 };

 /*sdmmc1 TF 卡*/

 &sdmmc1 {

 pinctrl-names = "default", "opendrain", "sleep";

 pinctrl-0 = <&sdmmc1_b4_pins_a>;

 pinctrl-1 = <&sdmmc1_b4_od_pins_a>;

 pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;

 cd-gpios = <&gpioh 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;

 disable-wp;

 st,neg-edge;

 bus-width = <4>;

 vmmc-supply = <&v3v3>;

 status = "okay";

 };

 &sram {

 dma_pool: dma_pool@0 {

 reg = <0x50000 0x10000>;

 pool;

 };

 };

 /*命令行终端*/

 &uart4 {

 pinctrl-names = "default", "sleep", "idle";

 pinctrl-0 = <&uart4_pins_a>;

 pinctrl-1 = <&uart4_sleep_pins_a>;

 pinctrl-2 = <&uart4_idle_pins_a>;

 pinctrl-3 = <&uart4_pins_a>;

 /delete-property/dmas;

 /delete-property/dma-names;

 status = "okay";

};

/*电源基准缓冲器*/

&vrefbuf {

 regulator-min-microvolt = <2500000>;

 regulator-max-microvolt = <2500000>;

 vdda-supply = <&vdd>;

 status = "okay";

};

  1. 在 arch/arm/boot/dts/ 目录下新建 stm32mp157a-fsmp1a.dts:

vim arch/arm/boot/dts/stm32mp157a-fsmp1a.dts

增加以下内容:

/dts-v1/;

#include "stm32mp157.dtsi"

#include "stm32mp15xa.dtsi"

#include "stm32mp15-pinctrl.dtsi"

#include "stm32mp15xxaa-pinctrl.dtsi"

#include "stm32mp15xx-fsmp1x.dtsi"

/ {

 model = "HQYJ STM32MP157 FSMP1A Discovery Board";

 compatible = "st,stm32mp157a-dk1", "st,stm32mp157";

aliases {

serial0 = &uart4;

 };

chosen {

stdout-path = "serial0:115200n8";

 };

reserved-memory {

 gpu_reserved: gpu@da000000 {

 reg = <0xda000000 0x4000000>;

 no-map;

 };

optee_memory: optee@0xde000000 {

 reg = <0xde000000 0x02000000>;

 no-map;

 };

 };

};

&optee {

 status = "okay";

};

  1. 由于添加了新文件需修改 Makefile 才能编译,修改 arch/arm/boot/dts/Makefile,添加 stm32mp157a-fsmp1a.dts 的编译选项(红色字体部分为添加内容)

vim arch/arm/boot/dts/Makefile

  1. 在Makefile中增加红色内容

stm32mp157a-dk1.dtb \

stm32mp157a-fsmp1a.dtb \

stm32mp157d-dk1.dtb \

3.5》编译内核及设备树

  1. 导入交叉编译器

source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

2)编译内核及设备树

make -j4 uImage dtbs LOADADDR=0xC2000040

 

 

 

内核文件在arch/arm/boot/ 目录下

 

设备树文件在arch/arm/boot/ dts 目录下

 

3)编译内核模块-----这一步暂时可以不做,时间太久了,暂时还不会使用模块,等需要再编译

make ARCH=arm modules 

该操作会将内核中配置为模块的源码进行编译,最终得到 ko 文件。

 

 

4)将编译好的设备树文件与内核的 uImage文件,复制到 ubuntu 主机的/tftpboot 文件夹下,

当使用 tftp 方式下载内核与设备树文件时会用到。

cp arch/arm/boot/uImage /tftpboot/

cp arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb /tftpboot/

3.6》通过TFTP下载内核

在 linux 系统移植中,我们使用 tftp 下载的方式来验证结果。为什么使用TFTP下载内核?因为Linux系统非常庞大,如果直接去构建系统,可能需要5个小时的时间,而在开发阶段,我们通常使用TFTP下载的方式,因为内核配置经常需要更改,不可能改一下,去构建一次系统。所以用TFTP下载内核。

使用 tftp 下载需要构建 pxelinux 相关的目录。

  1. 需要将 ubuntu 主机中的/tftpboot/pxelinux.cfg/01-00-80-e1-42-60-17 文件内容,暂时替换为如下内容,在后续的移植过程中会根据不同的需求进行修改。

sudo mkdir /tftpboot/pxelinux.cfg

sudo vim /tftpboot/pxelinux.cfg/01-00-80-e1-42-60-17

添加的内容如下:

# Generic Distro Configuration file generated by OpenEmbedded

menu title Select the boot mode

TIMEOUT 20

DEFAULT stm32mp157a-fsmp1a-emmc

LABEL stm32mp157a-fsmp1a-emmc

 KERNEL /uImage

 FDT /stm32mp157a-fsmp1a.dtb

 APPEND root=/dev/mmcblk1p4 rootwait rw console=ttySTM0,115200

  1. 打开开发板

下面这种方式:是电脑和开发板接同一个交换机的方式

在uboot中设置以下内容

env set -f ethaddr 00:80:E1:42:60:17  //这就是MAC

env set serverip 192.168.10.2   //Ubuntu的IP

env save //保存

下面这种方式:是电脑和开发板直连的方式(就是电脑的网口和开发板的网口用一根网线连接)

在uboot中设置以下内容

env set -f ethaddr 00:80:E1:42:60:17  //这就是MAC

env set serverip 192.168.10.2   //Ubuntu的IP

env set gatewayip 192.168.10.1  //网关

env set ipaddr 192.168.10.3  //给板子设置的IP

env save //保存

(注意如果使用直连方式,需要做以下步骤:

  1. 打开ubuntu,点击编辑------>虚拟网络编辑器

 

 

  1. 选择你的网卡,将网卡切换到ubuntu,让ubuntu使用你的网卡

 

 

  1. 将电脑和开发板之间的网线连接好

  1. 启动

静态IP启动或者电脑和开发板直连的方式

if pxe get; then pxe boot; fi

自动获取IP启动

run bootcmd_pxe

 

 

由于目前还未对源码进行任何修改,在内核启动过程中会停留在如下地方。

3.7》Linux 内核 eMMC 驱动移植

参考原理图可知 eMMC 使用的是 sdmmc2 总线,当前所使用的设备树文件中没有 sdmmc2 的支持,所以需要增加相关内容才能正常驱动 eMMC。

注意:还是在linux的内核源码下

  1. 导入交叉编译器

source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

  1. 添加 eMMC 设备树配置,修改 arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi 文件

vim arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi

添加以下内容:

 &sdmmc2 {

pinctrl-names = "default", "opendrain", "sleep";

pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;

pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>;

pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>;

non-removable;

no-sd;

no-sdio;

st,neg-edge;

bus-width = <8>;

vmmc-supply = <&v3v3>;

vqmmc-supply = <&vdd>;

mmc-ddr-3_3v;

status = "okay";

};

  1. 配置内核,由于内核源码默认配置已经支持 eMMC,本节列出主要选项,如下

make menuconfig

Device Drivers --->

<*> MMC/SD/SDIO card support --->

[*] STMicroelectronics STM32 SDMMC Controller

  1. 编译内核级设备树

make -j4 uImage dtbs LOADADDR=0xC2000040

  1. 将编译好的设备树文件与内核的 uImage文件,复制到 ubuntu 主机的/tftpboot 文件夹下, 当使用 tftp 方式下载内核与设备树文件时会用到。

cp arch/arm/boot/uImage /tftpboot/

cp arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb /tftpboot/

  1. 重新启动开发板

 

3.8》Linux 内核网卡驱动移植

还是在linux的内核源码下

  1. 导入交叉编译工具链

source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

  1. 添加网卡设备树配置。

修改 arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi 文件

vim arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi

在文件末尾添加如下内容: 

ðernet0 {

status = "okay";

pinctrl-0 = <ðernet0_rgmii_pins_a>;

pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>;

pinctrl-names = "default", "sleep";

phy-mode = "rgmii-id";

max-speed = <1000>;

phy-handle = <&phy0>;

mdio0 {

#address-cells = <1>;

#size-cells = <0>;

compatible = "snps,dwmac-mdio";

phy0: ethernet-phy@0 {

reg = <0>;

};

};

};

  1. 编译内核及设备树

make -j4 uImage dtbs LOADADDR=0xC2000040

4)将编译好的设备树文件与内核的 uImage文件,复制到 ubuntu 主机的/tftpboot 文件夹下, 当使用 tftp 方式下载内核与设备树文件时会用到。

cp arch/arm/boot/uImage /tftpboot/

cp arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb /tftpboot/

  1. 重新启动开发板

 

 

可以ping通主机就行,说明网络是通的。

  • 根文件系统的制作与挂载

4.1》配置制作文件系统的交叉编译工具链。

  1. 安装交叉编译器

linux@ubuntu:$ sudo apt-get install gcc-arm-linux-gnueabihf

linux@ubuntu:$ sudo apt-get install g++-arm-linux-gnueabihf

  1. 验证开发工具是否安装正确,显示版本信息如下图所示

linux@ubuntu:$ arm-linux-gnueabihf-gcc -v

 

 

4.2》导入busybox源码

1)拷贝制作文件系统的工具源码:源码:E:\春\系统移植\系统移植工具\制作文件系统的源码\busybox-1.29.3.tar.bz2

拷贝到Ubuntu中的/home/linux/fs_mp157a/kernel/下

2)解压源码:busybox-1.29.3.tar.bz2 ,进入源码目录

tar -xvf busybox-1.29.3.tar.bz2

cd busybox-1.29.3

*******注意:后面的操作均在这个目录下。

  1. 配置 busybox 源码:

将顶层目录下的 Makefile 文件中的 CROSS_COMPILE 字段修改为“arm-linux-gnueabihf-” ,后面不要有空格哟,否则编译有问题

vim Makefile 

 

 

  1. 可以使用如下命令配置源码:

make menuconfig

必须执行,可以不改变任何内容,并且要保存,才会生成 .config的配置文件

4.3》创建文件系统

  1. 编译busybox源码

make

 

 

2)安装: busybox 默认安装路径为源码目录下的_install

make install

 

 

3)进入安装目录

cd _install

4)创建其他需要的目录

mkdir dev etc mnt proc var tmp sys root

  1. 添加库: 将工具链中的库拷贝到_install 目录下:

cp /usr/arm-linux-gnueabihf/lib/ . -a 

  1. 删除静态库:

rm lib/*.a

7)添加系统启动文件: 在 etc 下添加文件 inittab,文件内容如下: 注意:修改文件均为_install 目录下

vim etc/inittab

增加以下内容:

#this is run first except when booting in single-user mode.

::sysinit:/etc/init.d/rcS

# /bin/sh invocations on selected ttys

# start an "askfirst" shell on the console (whatever that may be)

::askfirst:-/bin/sh

# stuff to do when restarting the init process

::restart:/sbin/init

# stuff to do before rebooting

::ctrlaltdel:/sbin/reboot

  1. 在 etc 下添加文件 fstab,文件内容如下:

vim etc/fstab

添加以下内容:

#device mount-point type options dump fsck order

proc /proc proc defaults 0 0

tmpfs /tmp tmpfs defaults 0 0

sysfs /sys sysfs defaults 0 0

tmpfs /dev tmpfs defaults 0 0

  1. 在 etc 下创建 init.d 目录,并在 init.d 下创建 rcS 文件,rcS 文件内容为:

mkdir etc/init.d

vim etc/init.d/rcS

添加以下内容:

#!/bin/sh

# This is the first script called by init process

/bin/mount -a

/sbin/mdev -s

  1. 为 rcS 添加可执行权限:

chmod a+x etc/init.d/rcS

  1. 在 etc 下添加 profile 文件,文件内容为:

vim etc/profile

添加以下内容:

#!/bin/sh

 export HOSTNAME=fsmp1a

 export USER=root

 export HOME=root

 export PS1="[$USER@$HOSTNAME \W]\# "

 PATH=/bin:/sbin:/usr/bin:/usr/sbin

 LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH

 export PATH LD_LIBRARY_PATH

4.3》测试------这里用NFS挂载的方式

  1. 删除原先的/opt/rootfs:

sudo rm -rf /opt/rootfs

  1. 将我们新建的根文件系统拷贝到/opt/rootfs 目录下

sudo mkdir /opt/rootfs

sudo cp ./* /opt/rootfs -a

  1. 修改 ubuntu 主机中的/tftpboot/pxelinux.cfg/01-00-80-e1-42-60-17 文件添加 nfs 启动选项

sudo vim /tftpboot/pxelinux.cfg/01-00-80-e1-42-60-17

替换成以下内容:

# Generic Distro Configuration file generated by OpenEmbedded

menu title Select the boot mode

MENU BACKGROUND /splash.bmp

TIMEOUT 20

DEFAULT stm32mp157a-fsmp1a-emmc

LABEL stm32mp157a-fsmp1a-emmc

 KERNEL /uImage

 FDT /stm32mp157a-fsmp1a.dtb

 APPEND root=/dev/mmcblk1p4 rootwait rw console=ttySTM0,115200

LABEL stm32mp157a-fsmp1a-nfs

 KERNEL /uImage

 FDT /stm32mp157a-fsmp1a.dtb

 APPEND root=/dev/nfs nfsroot=192.168.1.5:/opt/rootfs ip=dhcp rootwait rw earlyprintk console=ttySTM0,115200

  1. 打开开发板

回车输入启动指令 run bootcmd_pxe

 

 

选择nfs挂载方式启动 输入2

 

 

可以用ls查看一下是否进入开发板成功

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于STM32MP157系统移植,以下是一个大致的步骤: 1. 了解硬件平台:熟悉STM32MP157的硬件特性和主要组件,包括处理器核心、外设、存储器等。 2. 准备开发环境:安装交叉编译工具链和相关开发工具,例如GCC编译器、Make工具等。 3. 获取源代码:从STMicroelectronics官方网站下载适用于STM32MP157Linux发行版源代码。这些源代码包含了内核、设备树、驱动程序等。 4. 配置内核据目标应用需求,对内核进行配置。可以通过make menuconfig命令进入配置界面,选择所需的内核功能和驱动程序。 5. 编译内核:使用交叉编译工具链编译内核源代码。可以通过make命令进行编译,并生成内核镜像文件。 6. 配置设备树:设备树描述了硬件平台的信息,包括外设的连接和配置。据实际硬件情况,编辑设备树文件。 7. 编译设备树:使用设备树编译器(DTC)将设备树文件编译为二进制格式。 8. 准备启动介质:准备启动介质,例如SD卡或eMMC闪存。将编译好的内核镜像和设备树文件拷贝到启动介质中。 9. 配置启动参数:通过在启动介质的引导配置文件中指定内核镜像和设备树文件的路径,配置启动参数。 10. 启动系统:将启动介质插入目标硬件平台,启动系统系统会加载内核镜像和设备树文件,完成系统初始化。 以上是一个简要的步骤概述,实际的系统移植过程中可能还涉及到其他细节和配置。具体步骤和操作可以参考STMicroelectronics官方提供的文档和开发者社区。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值