STM32MP157 optee3.16移植
参考母板是STM32MP157D-DK1开发板,移植开发板为100ASK_STM32MP157_V11。
- STM32MP157 tf-a2.6 optee3.16 u-boot2021.10 linux5.15移植
- STM32MP157启动流程
- STM32MP157 tf-a2.6移植
- STM32MP157 optee3.16移植
- STM32MP157 u-boot2021.10移植
- STM32MP157 linux5.15移植
- STM32MP157 buildroot-2022.02.5构建根文件系统
1. 初次编译
这个过程和TF-A基本类似,解压之前准备好的源码,并打好补丁文件。可以参考README.HOW_TO.txt
文件,里面说了怎么解压和打补丁,并且还说了如何编译。
#解压源码
$ tar -xvf optee-os-stm32mp-3.16.0-stm32mp1-r1-r0.tar.xz
#进入源码目录
$ cd optee-os-stm32mp-3.16.0-stm32mp1-r1/
#打补丁
$ tar -xvf ../fonts.tar.gz
$ for p in `ls -1 ../*.patch`; do patch -p1 < $p; done
解压好源码,我们在源码目录执行以下命令完成编译。DEPLOYDIR=$FIP_DEPLOYDIR_ROOT/optee
是OPTEE编译结果存放的目录,如果不设置就会在上一级产生deploy目录存放编译结果,同级目录下生成的build目录存放编译中间文件。
#设置编译器
$ source ../../../../toolchain/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
#设置FIP目录
$ export FIP_DEPLOYDIR_ROOT=$PWD/../../FIP_artifacts
#编译
$ make -f $PWD/../Makefile.sdk DEPLOYDIR=$FIP_DEPLOYDIR_ROOT/optee -j12 all
$ make -f $PWD/../Makefile.sdk -j12 all
编译有错误因为我们在移植TF-A的时候删除了一些开发板,同样修改Makefile.sdk
文件,让其只编译STM32MP157D-DK1。删除CFG_EMBED_DTB_SOURCE_FILE
变量中的其他开发板,然后删除FIP_artifacts/optee
目录下的所有文件从新编译。
2. 移植
2.1 添加自己的板子
执行下列命令添加自己板子设备树的创建,复制stm32mp15xx-dkx.dtsi
和stm32mp157d-dk1.dts
为自己板子的设备树。
$ cd core/arch/arm/dts/
$ cp stm32mp15xx-dkx.dtsi stm32mp15xx-100ask.dtsi
$ cp stm32mp157d-dk1.dts stm32mp157d-100ask.dts
修改stm32mp157d-100ask.dts
文件
13 #include "stm32mp15xx-dkx.dtsi"
//改为
13 #include "stm32mp15xx-100ask.dtsi"
17 model = "STMicroelectronics STM32MP157D-DK1 Discovery Board";
18 compatible = "st,stm32mp157d-dk1", "st,stm32mp157";
//改为
17 model = "STMicroelectronics STM32MP157D-100ASK Discovery Board";
18 compatible = "st,stm32mp157d-100ask", "st,stm32mp157";
在Makefile.sdk
文件中添加自己的板子,在CFG_EMBED_DTB_SOURCE_FILE
变量中添加自己的板子stm32mp157d-100ask
,同时搜索stm32mp157d-dk1
有三处列出了所有开发板,把自己的板子添进去,然后编译。
2.2 修改设备树
前面已经移植了TF-A,OPTEE和TF-A要改的设备树基本相同。
2.2.1 修改串口Uart
100ASK_STM32MP157_V11开发板的串口和参考母板的串口都使用的是uart4,但是用的引脚不同。在stm32mp157d-100ask.dts
文件中引用pinctrl
节点,在其下追加uart4_pins_d
整个节点。
//在stm32mp157d-100ask.dts文件最后追加如下代码
&pinctrl {
uart4_pins_d: uart4-3 {
pins1 {
pinmux = <STM32_PINMUX('A', 11, AF6)>; /* UART4_RX */
bias-disable;
};
pins2 {
pinmux = <STM32_PINMUX('A', 12, AF6)>; /* UART4_TX */
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
};
};
修改uart4对引脚的配置,把uart4_pins_a
改为uart4_pins_d
。
//修改stm32mp15xx-100ask.dtsi文件
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
status = "okay";
};
//改为
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_d>;
status = "okay";
};
2.2.2 修改时钟
由于我们参考的官方母板采用的是有源晶振,100ASK_STM32MP157_V11开发板采用了无源晶振。上图是官方晶振原理图,下图为100ASK_STM32MP157_V11开发板原理图。
//删除stm32mp15xx-100ask.dtsi文件如下代码
&clk_hse {
st,digbypass;
};
2.2.3 修改电源
由于我们参考的官方母板使用了STPMIC1电源管理芯片,但是100ASK_STM32MP157_V11开发板没有使用电源管理芯片,使用的是固定电源。我们需要删除STPMIC1相关的东西,然后添加一些固定电源域完善设备树。
//修改stm32mp15xx-100ask.dtsi文件
/ {
memory@c0000000 {
device_type = "memory";
reg = <0xc0000000 0x20000000>;
};
vin: vin {
compatible = "regulator-fixed";
regulator-name = "vin";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-always-on;
};
//此处添加以下这些固定电源域
vddcore: regulator-vddcore {
compatible = "regulator-fixed";
regulator-name = "vddcore";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1350000>;
regulator-off-in-suspend;
regulator-always-on;
};
vdd: regulator-vdd {
compatible = "regulator-fixed";
regulator-name = "vdd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-off-in-suspend;
regulator-always-on;
};
v3v3: regulator-v3v3 {
compatible = "regulator-fixed";
regulator-name = "v3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-off-in-suspend;
regulator-always-on;
};
vdd_usb: regulator-vdd-usb {
compatible = "regulator-fixed";
regulator-name = "vdd_usb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-off-in-suspend;
regulator-always-on;
};
};
&i2c4 {
compatible = "st,stm32mp15-i2c-non-secure";
pinctrl-names = "default";
pinctrl-0 = <&i2c4_pins_a>;
i2c-scl-rising-time-ns = <185>;
i2c-scl-falling-time-ns = <20>;
clock-frequency = <400000>;
status = "okay";
/* 删除这部分注释代码
pmic: stpmic@33 {
compatible = "st,stpmic1";
reg = <0x33>;
interrupt-controller;
#interrupt-cells = <2>;
status = "okay";
regulators {
// 此次代码已省略
};
};
*/
};
/* 删除以下这些节点
&v1v2_hdmi {
// 此次代码已省略
};
&v1v8_audio {
// 此次代码已省略
};
&v3v3 {
// 此次代码已省略
};
&v3v3_hdmi {
// 此次代码已省略
};
&vdd {
// 此次代码已省略
};
&vdda {
// 此次代码已省略
};
&vddcore {
// 此次代码已省略
};
&vdd_ddr {
// 此次代码已省略
};
&vdd_usb {
// 此次代码已省略
};
&vref_ddr {
// 此次代码已省略
};
&vtt_ddr {
// 此次代码已省略
};
*/
修改完电源,我们需要修改源码,因为我们固定电源域regulator-vddcore
和regulator-vdd-usb
的名字超过了16字节(名字长度要加一个字节的结束符),所以将名字长度改为20字节。
//修改core/drivers/regulator/regulator_fixed.c
19 #define FIXED_REGULATOR_NAME_LEN 16
//改为
19 #define FIXED_REGULATOR_NAME_LEN 20
3. 编译下载
3.1 编译
编译前需要编译TF-A,并且编译结果要存放到arm-trusted-firmware
目录中。我们需要复制一份U-Boot改成自己的开发板,如果TF-A已经做了下面这些可以不做。
#进入FIP目录下的u-boot目录
$ cd ../../FIP_artifacts/u-boot/
#复制U-boot
$ cp u-boot-stm32mp157d-dk1-trusted.dtb u-boot-stm32mp157d-100ask-trusted.dtb
#返回OP-TEE源码目录
$ cd ../../optee-os-stm32mp-3.16.0-stm32mp1-r1-r0/optee-os-stm32mp-3.16.0-stm32mp1-r1/
#编译
$ make -f $PWD/../Makefile.sdk DEPLOYDIR=$FIP_DEPLOYDIR_ROOT/optee -j12 all
在FIP_artifacts/fip
目录中生成了fip-stm32mp157d-100ask-optee.bin
。
3.2 下载
新建FlashLayout_emmc_stm32mp157d-100ask-optee.tsv
脚本,内容如下。
#Opt Id Name Type IP Offset Binary
- 0x01 fsbl-boot Binary none 0x0 arm-trusted-firmware/tf-a-stm32mp157d-100ask-usb.stm32
- 0x03 fip-boot FIP none 0x0 fip/fip-stm32mp157d-100ask-optee.bin
用STM32CubeProg打开烧写脚本,进行烧写。板子一直重启,那是因为U-boot不对。从串口打印信息上可以看到BL2启动BL32后,OPTEE就运行起来了,最终U-Boot启动。
4. 总结
可以看到OPTEE的移植比TF-A的移植简单了许多,这是因为移植的差异主要体现在底层,越是往上层平台的差异就会变小移植的难度就会降低。但是如果在上层开发一个驱动,将是非常复杂的一件事,比如Linux驱动开发。这些代码只启动板子,其他功能问题并没有解决。
学习笔记仅供参考,欢迎指正错误,如有侵权请及时联系。移植源码获取:
git clone https://github.com/Sonboy97/arm-ostl-linux-gnueabi.git
版本:9ae04fa8dbea4c984243179d1faa6e39cd18d2dd