第13章 uboot移植

编译ST官方U-boot

ST官方uboot源码打补丁

获取ST官方uboot

u-boot-stm32mp-2020.01-r0 可以理解为是之前解压ST官方源码得到的uboot的SDK工具包(PS:里面有个README.HOW_TO.txt的帮助手册可以看下)
cd ~/linux/atk-mp1/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/u-boot-stm32mp-2020.01-r0
解压uboot源码包
tar -vxf u-boot-stm32mp-2020.01-r0.tar.gz
进入解压得到的 u-boot-stm32mp-2020.01 ,进行打补丁的操作
cd u-boot-stm32mp-2020.01
for p in `ls -1 ../*.patch`;do patch -p1 < $p;done    
新建目录 my_uboot,将打好补丁的ST官方uboot源码拷贝到 my_uboot 目录(方便阅读)
mkdir ~/linux/atk-mp1/uboot/my_uboot
cp * ~/linux/atk-mp1/uboot/my_uboot/ -rf

编译ST官方uboot

进入到my_uboot目录下
cd ~/linux/atk-mp1/uboot/my_uboot
在Makefile中添加ARCH和CROSS_COMPILE变量值
编译uboot
make stm32mp15_trusted_defconfig
make DEVICE_TREE=stm32mp157d-ev1 all -j8
编译成功得到uboot可执行文件
(u-boot.bin:包含设备树和uboot镜像)(u-boot.stm32:u-boot.bin添加了256字节头部信息的可执行文件)

烧写

STM23CubeProgrammer 烧写原理:先向DDR烧写完整的uboot来启动板子再烧写完整的系统(uboot、内核、设备树、文件系统等等)
因此要确保uboot是完整的,但刚刚编译ST官方的uboot对于原子开发板来说是不完整的,所以我们要保留烧录工具里原有的uboot(烧给DDR),添加刚刚编译得到的ST的uboot(烧给EMMC)
重命名编译得到的u-boot.stm32为my-u-boot.stm32
my-u-boot.stm32拷贝到 images 文件夹,修改烧录脚本为如下
烧写完成后,启动开发板,uboot会不断复位且蜂鸣器会响,uboot时间为刚刚编译uboot的时间
ST的uboot能运行但有错,因此需要移植

在uboot添加开发板

创建默认配置文件

拷贝uboot源码configs目录下的 stm32mp15_trusted_defconfig 并重命名为 stm32mp15_atk_trusted_defconfig
cd ~/linux/atk-mp1/uboot/my_uboot/configs
cp stm32mp15_trusted_defconfig stm32mp15_atk_trusted_defconfig 

创建默认配置设备树

在 arch/arm/dts目录下复制ST官方设备树为自己的
cd ~/linux/atk-mp1/uboot/my_uboot/arch/arm/dts
cp stm32mp157d-ed1.dts stm32mp157d-atk.dts 
cp stm32mp15xx-edx.dtsi stm32mp157d-atk.dtsi 
cp stm32mp157a-ed1-u-boot.dtsi stm32mp157d-atk-u-boot.dtsi 
修改 stm32mp157d-atk.dts 文件里的头文件引用,修改内容如下

修改电源管理设置

修改 stm32mp157d-atk-u-boot.dtsi 文件,屏蔽掉以下圈着的内容

修改 stm32mp157d-atk.dtsi 内容
删除掉adc节点(90~104行)、dac节点(114~125行)、i2c4节点(143~298行)
删除led节点和sd_switch节点信息
在/根节点下添加电源管理配置(vin节点前)
	vddcore: regulator-vddcore {
		compatible = "regulator-fixed";
		regulator-name = "vddcore";
		regulator-min-microvolt = <1200000>;
		regulator-max-microvolt = <1350000>;
		regulator-always-on;
		regulator-boot-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;
	};

	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;
	};

修改TF卡和EMMC配置

 修改sdmmc1和sdmmc2成内容如下
&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>;
	st,neg-edge;
	broken-cd;
	bus-width = <4>;
	vmmc-supply = <&v3v3>;
	status = "okay";
};

&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;
	st,neg-edge;
	bus-width = <8>;
	vmmc-supply = <&v3v3>;
	keep-power-in-suspend;
	status = "okay";
};

编译uboot

这里只验证uboot能否运行,因此先屏蔽掉 stm32mp157d-atk.dtsi 文件中的 &usbotg_hs 节点。此节点是ST官方板的USB_OTG电源配置。
设置要编译的配置文件项,打开 arch/arm/dts/Makefile,添加如下
制作编译脚本,在uboot源码根目录下创建 stm32mp157d_alientek.sh 的脚本文件,内容如下
#!/bin/bash
make distclean
make stm32mp15_atk_trusted_defconfig
make CROSS_COMPILE=arm-none-linux-gnueabihf- DEVICE_TREE=stm32mp157d-atk all -j12
赋予脚本可执行权限后,执行脚本即可编译uboot
编译得到u-boot.stm32,重命名为my-u-boot.stm32,再烧录到板子,启动信息如下
网络、USB_OTG仍不正常,继续修改

网络设备树修改

打开 stm32mp157d-atk.dtsi 文件,在最后添加 ethernet0 节点,内容如下
&ethernet0  {
	status = "okay";
	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
	pinctrl-1 = <&ethernet0_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>;
				};
	};
};
保存,重新编译uboot,将生成的u-boot.stm32重命名为my-u-boot.stm32再烧录,启动后信息如下
网络修改完成,继续修改

USB OTG设备树修改

添加 usb_phy_tuning 子节点

继续修改 stm32mp157d-atk.dtsi ,在/节点下添加 usb_phy_tuning 的子节点,内容如下
	usb_phy_tuning: usb-phy-tuning  {
		st,hs-dc-level = <2>;
		st,fs-rftime-tuning;
		st,hs-rftime-reduction;
		st,hs-current-trim = <15>;
		st,hs-impedance-trim = <1>;
		st,squelch-level = <3>;
		st,hs-rx-offset = <2>;
		st,no-lsfs-sc;
	};

添加STUSB1600 I2C 子节点

原子板子用的是 STUSB1600 芯片的 type-C接口,挂靠在I2C接口,因此添加 &i2c1 节点,内容如下:
&i2c1  {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&i2c1_pins_a>;
	pinctrl-1 = <&i2c1_pins_sleep_a>;
	i2c-scl-rising-time-ns = <100>;
	i2c-scl-falling-time-ns = <7>;
	status = "okay";
	/delete-property/dmas;
	/delete-property/dma-names;

	stusb1600@28 {
		compatible = "st,stusb1600";
		reg = <0x28>;
		interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
		interrupt-parent = <&gpiog>;
		pinctrl-names = "default";
		pinctrl-0 = <&stusb1600_pins_a>;
		status = "okay";
		vdd-supply = <&vin>;

		connector {
			compatible = "usb-c-connector";
			label = "USB-C";
			power-role = "dual";
			power-opmode = "default";

			port {
				con_usbotg_hs_ep: endpoint {
						remote-endpoint = <&usbotg_hs_ep>;
					};
				};
			};
		};
};

添加USB接口相关节点

继续在stm32mp157d-atk.dtsi添加,内容如下
&usbh_ehci  {
	phys = <&usbphyc_port0>;
	status = "okay";
};

&usbotg_hs  {
	phys = <&usbphyc_port1 0>;
	phy-names = "usb2-phy";
	usb-role-switch;
	status = "okay";

	port {
		usbotg_hs_ep: endpoint {
			remote-endpoint = <&con_usbotg_hs_ep>;
			};
	};
};

&usbphyc {
	status = "okay";
};

stm32mp157d-atk-u-boot.dtsi 文件中添加usbotg_hs 节点

内容如下
&usbotg_hs  {
	u-boot,force-b-session-valid;
	hnp-srp-disable;
	/* TEMP: force peripheral for USB OTG */
	dr_mode = "peripheral";
};

使能boot和bootd命令

ST官方uboot没有使能boot和bootd命令,指令源文件为cmd/bootm.c
打开 include/configs/stm32mp1.h,在后面添加如下定义

LCD驱动修改

打开 stm32mp157d-atk.dts 文件,在/根节点下添加panel_backlight 和panel_rgb 这两个节点,内容如下
	panel_backlight: panel-backlight {
		compatible = "gpio-backlight";
		gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>;
		default-on;
		status = "okay";
		};

	panel_rgb: panel-rgb {
		compatible = "simple-panel";
		pinctrl-names = "default", "sleep";
		pinctrl-0 = <&ltdc_pins_b>;
		pinctrl-1 = <&ltdc_pins_sleep_b>;
		backlight = <&panel_backlight>;
		status = "okay";

		port {
			panel_in_rgb: endpoint {
				remote-endpoint = <&ltdc_ep0_out>;
			};
		};

		display-timings {
			native-mode = <&timing0>; 					/* 时序信息*/
			timing0: timing0 { 										/* 7 寸1024*600 分辨率*/
				clock-frequency = <51200000>; 		/* LCD 像素时钟,单位Hz */
				hactive = <1024>; 									/* LCD X 轴像素个数*/
				vactive = <600>; 										/* LCD Y 轴像素个数*/
				hfront-porch = <160>; 							/* LCD hfp 参数*/
				hback-porch = <140>; 							/* LCD hbp 参数*/
				hsync-len = <20>; 										/* LCD hspw 参数*/
				vback-porch = <20>; 								/* LCD vbp 参数*/
				vfront-porch = <12>; 								/* LCD vfp 参数*/
				vsync-len = <3>; 										/* LCD vspw 参数*/
			};
		};
	};
追加 ltdc 节点,内容如下
&ltdc {
	status = "okay";
	pinctrl-names = "default";
	port {
		#address-cells = <1>;
		#size-cells = <0>;

		ltdc_ep0_out: endpoint@0 {
			reg = <0>;
			remote-endpoint = <&panel_in_rgb>;
		};
	};
};

自烧写测试

这里和前面的烧写不同,直接烧写编译好的u-boot.stm32,不需要重命名(改名)
将编译得到的u-boot.stm32替换掉 images 目录下的原文件,修改脚本成如下

从EMMC启动Linux

STM32CubeProgrammer的烧录要求 uImage 和 .dtb打包在一起成 ext4 格式的文件
这里添加烧录正点原子出厂的内核镜像,将网盘的内核镜像拷贝到 images 文件夹
网盘路径:开发板光盘A-基础资料\8、系统镜像\2、出厂系统镜像\1、STM32CubeProg烧录固件包\atk-image-bootfs.ext4
修改烧录脚本成如下
烧写完启动板子,执行 ext4ls mmc 1:2
设置bootcmd环境变量从EMMC读取系统文件并启动
setenv bootcmd 'ext4load mmc 1:2 c2000000 uImage;ext4load mmc 1:2 c4000000 stm32mp157d-atk.dtb;bootm c2000000 - c4000000'
saveenv
boot
系统内核启动成功

从网络启动Linux系统

设置板子网络的相关信息
setenv ipaddr 192.168.1.250
setenv ethaddr 00:04:9f:04:d2:35
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.208
saveenv

ping 192.168.1.208
设置bootcmd环境变量
setenv bootcmd 'tftp c2000000 uImage;tftp c4000000 stm32mp157d-atk.dtb;bootm c2000000 - c4000000'
saveenv
boot

uboot下的LCD测试

bootcmd 和bootargs 环境变量

bootcmd 环境变量

bootcmd 所在位置 include/env_default.h

bootargs 环境变量






posted @ 2021-02-19 17:15  orangebear  阅读(294)  评论(0)    收藏  举报