STM32MP157 Linux系統(tǒng)移植開發(fā)篇5:Trusted Firmware-A移植
本文章為《STM32MP157 Linux系統(tǒng)移植開發(fā)篇》系列中的一篇,筆者使用的開發(fā)平臺(tái)為華清遠(yuǎn)見FS-MP1A開發(fā)板(STM32MP157開發(fā)板)。stm32mp157是ARM雙核,2個(gè)A7核,1個(gè)M4核,A7核上可以跑Linux操作系統(tǒng),M4核上可以跑FreeRTOS、RT-Thread等實(shí)時(shí)操作系統(tǒng),STM32MP157開發(fā)板所以既可以學(xué)嵌入式linux,也可以學(xué)stm32單片機(jī)。
針對(duì)FS-MP1A開發(fā)板,除了Linux系統(tǒng)移植篇外,還包括其他多系列教程,包括Cortex-A7開發(fā)篇、Cortex-M4開發(fā)篇、擴(kuò)展板驅(qū)動(dòng)移植篇、Linux應(yīng)用開發(fā)篇、FreeRTOS系統(tǒng)移植篇、Linux驅(qū)動(dòng)開發(fā)篇、硬件設(shè)計(jì)篇、人工智能機(jī)器視覺篇、Qt應(yīng)用編程篇、Qt綜合項(xiàng)目實(shí)戰(zhàn)篇等。歡迎關(guān)注,更多stm32mp157開發(fā)教程及視頻,可加技術(shù)交流Q群459754978,感謝關(guān)注。
關(guān)于FS-MP1A開發(fā)板:
手機(jī)淘寶分享碼:復(fù)制本行文字打開手淘?T4FPXn3YYJ2?
鏈接:https://item.taobao.com/item.htm?id=622457259672
Trusted Firmware-A移植
Trusted Firmware-A簡介
嵌入式高速發(fā)展的今天,大量的嵌入式設(shè)備使用了Arm為核心的芯片。我們會(huì)接觸到越來越多的嵌入式設(shè)備,一個(gè)問題油然而生:數(shù)量如此巨大的嵌入式設(shè)備的安全性如何?目前針對(duì)嵌入式安全的技術(shù)和標(biāo)準(zhǔn)可謂千姿百態(tài),除了必要的硬件安全技術(shù),與之配套的安全軟件也是必不可少的一部分。今天我們要介紹的是基于Arm 的可信固件Trusted Firmware-A,簡稱TF-A。它是一個(gè)開源軟件,運(yùn)行在一個(gè)硬件隔離的安全環(huán)境中并提供安全服務(wù)。
實(shí)驗(yàn)?zāi)康?/h1>
完成TF-A的基本功能實(shí)現(xiàn)TF-A引導(dǎo)u-boot啟動(dòng)。
實(shí)驗(yàn)平臺(tái)
華清遠(yuǎn)見開發(fā)環(huán)境,F(xiàn)S-MP1A平臺(tái)
實(shí)驗(yàn)步驟
本實(shí)驗(yàn)基于tf-a-stm32mp-2.2版本,然后添加意法半導(dǎo)體提供的補(bǔ)丁文件。在意法半導(dǎo)體官方的tf-a中移植我們自己的tf-a。
導(dǎo)入源碼
如果之前已經(jīng)建立了源碼目錄,并且導(dǎo)入了源碼包,即可跳過本小節(jié)。
建立源碼目錄
linux@ubuntu:$ cd ~
linux@ubuntu:$ mkdir FS-MP1A
將【華清遠(yuǎn)見-FS-MP1A開發(fā)資料\02-程序源碼\04-Linux系統(tǒng)移植\01-官方源碼】下的
en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz壓縮包,導(dǎo)入到ubuntu下的${HOME}/FS-MP1A目錄下。

解壓縮源碼包
linux@ubuntu:$ tar xvf en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz
解壓完成后得到“
stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24”目錄

進(jìn)入tf-a目錄下
linux@ubuntu:$ cd ~/FS-MP1A/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/tf-a-stm32mp-2.2.r1-r0

該目錄下以patch結(jié)尾的文件為ST官方提供的補(bǔ)丁文件;
tf-a-stm32mp-2.2.r1-r0.tar.gz為標(biāo)準(zhǔn)tf-a源碼包。
解壓標(biāo)準(zhǔn)tf-a源碼包
linux@ubuntu:$ tar -xvf tf-a-stm32mp-2.2.r1-r0.tar.gz
解壓完成后得到tf-a-stm32mp-2.2.r1目錄

進(jìn)入tf-a源碼目錄下:
linux@ubuntu:$ cd tf-a-stm32mp-2.2.r1

將ST官方補(bǔ)丁文件打到tf-a源碼中:
linux@ubuntu:$ for p in `ls -1 ../*.patch`; do patch -p1 < $p; done
TF卡分區(qū)
要對(duì)TF卡進(jìn)行燒錄,需要先將TF接入到ubuntu系統(tǒng)中。
查看TF卡分區(qū)
linux@ubuntu:$ ls /dev/sd*

由上圖所示只有“/dev/sdb1”一個(gè)分區(qū)則需要重新進(jìn)行分區(qū)。
首先刪除原有分區(qū)
linux@ubuntu:$ sudo parted -s /dev/sdb mklabel msdos
如果顯示如下內(nèi)容,則表示設(shè)備已經(jīng)被掛載,需要卸載掉設(shè)備再刪除分區(qū)。

卸載設(shè)備
linux@ubuntu:$ umount /dev/sdb1
卸載完成后重新執(zhí)行刪除分區(qū)命令
linux@ubuntu:$ sudo parted -s /dev/sdb mklabel msdos
對(duì)tf進(jìn)行重新分區(qū)
linux@ubuntu:$ sudo sgdisk --resize-table=128 -a 1 -n 1:34:545 -c 1:fsbl1 -n 2:546:1057 -c 2:fsbl2 -n 3:1058:5153 -c 3:ssbl -n 4:5154:136225 -c 4:bootfs -n 5:136226 -c 5:rootfs -A 4:set:2 -p /dev/sdb -g

注意:最后-p /dev/sdb參數(shù)中的/dev/sdb需要按照實(shí)際ubuntu中的tf節(jié)點(diǎn)為準(zhǔn),否則可能發(fā)生不可預(yù)料的后果。
建立自己的平臺(tái)
配置工具鏈
導(dǎo)入交叉編譯工具鏈(如果還未安裝SDK可參考《SDK工具鏈安裝》章節(jié)進(jìn)行安裝)
linux@ubuntu:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
驗(yàn)證開發(fā)工具是否安裝正確,顯示版本信息如下圖所示。
linux@ubuntu:$ $CC --version

增加板級(jí)相關(guān)文件
進(jìn)入到tf-a源碼目錄
linux@ubuntu:$ cd ~/FS-MP1A/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/tf-a-stm32mp-2.2.r1-r0/tf-a-stm32mp-2.2.r1
添加設(shè)備樹文件
linux@ubuntu:$ cp fdts/stm32mp15xx-dkx.dtsi fdts/stm32mp15xx-fsmp1x.dtsi
linux@ubuntu:$ cp fdts/stm32mp157a-dk1.dts fdts/stm32mp157a-fsmp1a.dts
修改上層目錄下的Makefile.sdk編譯腳本在TFA_DEVICETREE配置項(xiàng)中添加stm32mp157a-fsmp1a
TFA_DEVICETREE ?=?stm32mp157a-fsmp1a?stm32mp157a-dk1 stm32mp157d-dk1 stm32mp157c-dk2 stm32mp157f-dk2 stm32mp157c-ed1 stm32mp157f-ed1 stm32mp157a-ev1 stm32mp157c-ev1 stm32mp157d-ev1 stm32mp157f-ev1
修改
fdts/stm32mp157a-fsmp1a.dts將
#include "stm32mp15xx-dkx.dtsi"
修改為
#include "stm32mp15xx-fsmp1x.dtsi"
編譯源碼
執(zhí)行如下指令編譯trusted:
linux@ubuntu:$ make -f $PWD/../Makefile.sdk TFA_DEVICETREE=stm32mp157a-fsmp1a TF_A_CONFIG=trusted ELF_DEBUG_ENABLE='1' all
編譯成功后,最后顯示內(nèi)容(部分截圖)如下:

編譯完成后會(huì)在上級(jí)build/trusted目錄得到如下文件:
linux@ubuntu:$ ls ../ build/trusted

linux@ubuntu:$ cd ../ build/trusted
固件燒寫
由于在移植過程中會(huì)多次燒寫固件并且會(huì)導(dǎo)致正常tf-a無法啟動(dòng),因此推薦使用TF卡啟動(dòng)的方式來驗(yàn)證。
tf-a需要使用trusted 格式的u-boot鏡像啟動(dòng),具體的編譯方法可參考《U-boot移植》章節(jié)中的“生成Trusted鏡像”小節(jié)。
將TF接入ubuntu系統(tǒng)后,查看TF卡分區(qū)
linux@ubuntu:$ ls /dev/sd*

/dev/sdb為TF卡設(shè)備。如果該設(shè)備下只有/dev/sdb1一個(gè)分區(qū)則重新分區(qū)。
執(zhí)行如下指令燒寫u-boot:
linux@ubuntu:$ sudo dd if=tf-a-stm32mp157a-fsmp1a-trusted.stm32 of=/dev/sdb1 conv=fdatasync
linux@ubuntu:$ sudo dd if=tf-a-stm32mp157a-fsmp1a-trusted.stm32 of=/dev/sdb2 conv=fdatasync
linux@ubuntu:$ sudo dd if=u-boot-stm32mp157a-fsmp1a-trusted.stm32 of=/dev/sdb3 conv=fdatasync
其中前兩條命令“
tf-a-stm32mp157a-fsmp1a-trusted.stm32”為本章節(jié)編譯得到的,第三條命令中的“u-boot-stm32mp157a-fsmp1a-trusted.stm32”則為《U-boot移植》章節(jié)中的“生成Trusted鏡像”小節(jié)得到。
啟動(dòng)開發(fā)板
將撥碼開關(guān)設(shè)置為SD卡啟動(dòng)方式:
Boot mode
BOOT2
BOOT1
BOOT0
Engineering boot
1
0
0
Forced USB bootfor flashing
0
0
0
eMMC
0
1
0
SDCARD
1
0
1
將制作好的TF卡插入開發(fā)板,上電后會(huì)出現(xiàn)如下錯(cuò)誤提示:

這個(gè)錯(cuò)誤產(chǎn)生的原因是電源初始化錯(cuò)誤,需重新調(diào)整電源相關(guān)配置
調(diào)整設(shè)備樹電源配置
由于官方參考板DK1采用電源管理芯片做電源管理,而FS-MP1A采用分離電路作為電源管理,本例需要將文件中原有電源管理芯片相關(guān)內(nèi)容去掉,增加上固定電源相關(guān)內(nèi)容
去掉原有電源管理內(nèi)容
DK1參考板電源管理芯片掛在I2C4上,而FS-MP1A并未使用I2C4總線,所以直接將I2C4相關(guān)內(nèi)容完全刪除即可。
修改
fdts/stm32mp15xx-fsmp1x.dtsi文件
將文件中i2c4節(jié)點(diǎn)相關(guān)內(nèi)容整體刪除,刪除內(nèi)容如下:
&i2c4 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c4_pins_a>;
pinctrl-1 = <&i2c4_pins_sleep_a>;
i2c-scl-rising-time-ns = <185>;
i2c-scl-falling-time-ns = <20>;
clock-frequency = <400000>;
status = " okay";
secure-status = "okay";
/*內(nèi)容太長此處省略*/
watchdog {
compatible = "st,stpmic1-wdt";
status = "disabled";
};
};
};
修改
fdts/stm32mp15xx-fsmp1x.dtsi文件,刪除如下內(nèi)容:
&cpu0{
cpu-supply = <&vddcore>;
};
&cpu1{
cpu-supply = <&vddcore>;
};
添加固定電源配置
修改fdts/:文件
固定電源配置通常添加在根節(jié)點(diǎn)下,在根節(jié)點(diǎn)末尾位置添加如下內(nèi)容(紅色字體為需要添加的內(nèi)容):
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;
};
v1v8_audio: regulator-v1v8-audio {
compatible = "regulator-fixed";
regulator-name = "v1v8_audio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
v3v3_hdmi: regulator-v3v3-hdmi {
compatible = "regulator-fixed";
regulator-name = "v3v3_hdmi";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
v1v2_hdmi: regulator-v1v2-hdmi {
compatible = "regulator-fixed";
regulator-name = "v1v2_hdmi";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
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;
};
vdd_usb: regulator-vdd-usb {
compatible = "regulator-fixed";
regulator-name = "vdd_usb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
};
重新編譯源碼
linux@ubuntu:$ make -f $PWD/../Makefile.sdk TFA_DEVICETREE=stm32mp157a-fsmp1a TF_A_CONFIG=trusted ELF_DEBUG_ENABLE='1' all
燒寫后啟動(dòng)
重新燒寫后啟動(dòng)現(xiàn)象如下:

可以看到現(xiàn)在已經(jīng)可以啟動(dòng)到u-boot了
eMMC移植
參考原理圖可知eMMC使用的是SDMMC2總線,當(dāng)前所使用的設(shè)備樹文件中沒有SDMMC2的支持,所以需要增加相關(guān)內(nèi)容才能正常驅(qū)動(dòng)eMMC。

由于在使STM32MP1芯片很多管腳為多功能復(fù)用管腳,且很多管腳具備同樣的功能,所以移植eMMC時(shí)需要確認(rèn)硬件設(shè)計(jì)是使用的是那些管腳,根據(jù)原理圖確認(rèn)后管腳對(duì)應(yīng)關(guān)系為:
原理圖網(wǎng)絡(luò)編號(hào)
對(duì)應(yīng)管腳
管腳功能
管腳功能碼
SD2_DATA0
PB14
SDMMC2_D0
AF9
SD2_DATA1
PB15
SDMMC2_D1
AF9
SD2_DATA2
PB3
SDMMC2_D2
AF9
SD2_DATA3
PB4
SDMMC2_D3
AF9
SD2_DATA4
PA8
SDMMC2_D4
AF9
SD2_DATA5
PA9
SDMMC2_D5
AF10
SD2_DATA6
PE5
SDMMC2_D6
AF9
SD2_DATA7
PD3
SDMMC2_D7
AF9
SD2_CLK
PE3
SDMMC2_CK
AF9
SD2_CMD
PG6
SDMMC2_CMD
AF10
管腳定義
在u-boot中STM32MP1默認(rèn)管腳定義在文件
arch/arm/dts/stm32mp15-pinctrl.dtsi中,查看文件中是否有需要的管腳定義:
查看后確認(rèn)有SDMMC2的管腳定義,且與FS-MP1A硬件使用情況一致,定義如下:
sdmmc2_b4_pins_a: sdmmc2-b4-0 {
pins1 {
pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
<STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
<STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
<STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
<STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
slew-rate = <1>;
drive-push-pull;
bias-pull-up;
};
pins2 {
pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
slew-rate = <2>;
drive-push-pull;
bias-pull-up;
};
};
增加SDMMC2節(jié)點(diǎn)信息
修改
fdts/stm32mp15xx-fsmp1x.dtsi增加SDMMC2的信息
在原有sdmmc1節(jié)點(diǎn)下增加sdmmc2的內(nèi)容,添加內(nèi)容可參考
arch/arm/dts/stm32mp15xx-edx.dtsi中sdmmc2的寫法,內(nèi)容如下:
&sdmmc2 {
pinctrl-names = "default";
pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
non-removable;
st,neg-edge;
bus-width = <8>;
vmmc-supply = <&v3v3>;
vqmmc-supply = <&v3v3>;
status = "okay";
};
測(cè)試
重新編譯燒寫后可以通過ums或者scp的方式更新eMMC中的u-boot即可。具體可參考《通過linux更新eMMC中的u-boot》章節(jié)。