1、打补丁
cd linux-5.4.31
for p in `ls -1 ../*.patch`; do patch -p1 < $p; done
该命令会将上层目录下所有的 patch 补丁文件应用到当前的内核中
2、生成标准版配置文件
生成 multi_v7_defconfig 默认配置
make ARCH=arm multi_v7_defconfig "fragment*.config"
会生成 .config文件
在默认 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
生成自己的配置文件
cp .config arch/arm/configs/stm32_fsmp1a_defconfig
取消 git 中的 SHA1
echo "" > .scmversion
3、配置内核
-
安装交叉编译工具链
$CC --version
若未安装请看uboot移植文章中安装工具链步骤
-
导入交叉编译工具链
source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
- 测试make menuconfi
-
编译内核
make -j4 ARCH=arm uImage vmlinux LOADADDR=0xC2000040 -j4 线程数 ARCH=arm 指定编译平台 uImage 内核镜像名称 vmlinux 内核调试镜像 LOADADDR 内核程序连接的地址
- 编译内核模块
make ARCH=arm modules
该操作会将内核中配置为模块的源码进行编译,最终得到 ko 文件。
4、生成设备树文件
arch/arm/boot/dts/
cp stm32mp15xx-dkx.dtsi stm32mp15xx-fsmp1x.dtsi
cp stm32mp157a-dk1.dts stm32mp157a-fsmp1a.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";
};
创建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";
};
由于添加了新文件需修改 Makefile 才能编译,修改 arch/arm/boot/dts/Makefile,添加stm32mp157a-fsmp1a.dts 的编译选项
重新编译设备树:
make ARCH=arm dtbs
编译完成后会在 arch/arm/boot/dts/目录下生成 stm32mp157a-fsmp1a.dtb 文件
将编译好的设备树文件与内核的 uImage 文件,复制到 ubuntu 主机的/tftpboot 文件夹下,当使用 tftp 方式下载内核与设备树文件时会用到。
cp arch/arm/boot/uImage /tftpboot/
cp arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb /tftpboot/
cp arch/arm/boot/dts/stm32mp157a-fsmp1a*.dtb /tftpboot/
5、配置tftp
注意 uboot启动内核只能以安全模式启动
cd /tftpboot
mkdir pxelinux.cfg
vi 01-00-80-e1-42-60-17
写入内容:
EMMC启动:
# 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
SDCARD启动
# Generic Distro Configuration file generated by OpenEmbedded
menu title Select the boot mode
TIMEOUT 20
DEFAULT stm32mp157a-fsmp1a-sdcard
LABEL stm32mp157a-fsmp1a-sdcard
KERNEL /uImage
FDT /stm32mp157a-fsmp1a.dtb
APPEND root=/dev/mmcblk1p6 rootwait rw console=ttySTM0,115200
查看连接
开发板连接网线
开发板需要和主机同一网段:
串口连接开发板
开发板复位进入uboot命令行
env set -f ethaddr 00:80:E1:42:60:17
dhcp 查找ip
ping主机
ping 192.168.40.115
开发板可以ping通主机
指定server IP
env set serverip 192.168.40.155
输入:env save 作用:保存环境变量到emmc,下次启动就不需要再配置了
使用 run bootcmd_pxe 开始下载 linux 内核与设备树文件。看到如下提示后选择您对应的启动选项即可。\
后续会通过对系统源码的修改,逐渐完成整个系统的启动和对外围设备的驱动
错误:卡在这儿了