在正式修改uboot之前我们先创建vscode工程,方便修改。
uboot2020和以前的uboot不一样,uboot2020与linux的内核类似,使用设备树描述设备。这里就不分析源码。重点就是快速移植,所以根据uboot输出的调试信息,在源码中找到并修改。
从调试信息看,我第一个应该修改的是Model:的内容,我们复制这个内容“i.MX6 ULL 14x14 EVK Board”到源码中搜索,发现在设备树imx6ull-14x14-evk.dts中,我们肯定最好不要修改这个文件,不影响包含他的其他板子。这个文件的内容比较少,我们可以把他的内容复制到imx6ull-alpha-emmc.dts中,再修改,修改后:
/*
* Copyright 2019 NXP
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*/
/dts-v1/;
#include "imx6ull.dtsi"
#include "imx6ul-14x14-evk.dtsi"
#include "imx6ul-14x14-evk-u-boot.dtsi"
/ {
model = "i.MX6 ULL ALPHA EMMC Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
};
&clks {
assigned-clocks = <&clks IMX6UL_CLK_PLL3_PFD2>;
assigned-clock-rates = <320000000>;
};
&usdhc2 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc2_8bit>;
pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
bus-width = <8>;
non-removable;
status = "okay";
};
编译下载运行看看结果:
发现已经改变了。
接下来看调试信息,返现显示设备不对,需要修改
这个能够输出显示设备的信息,说明设备的驱动没有问题,输出的信息和实际的显示屏不对,说明是设备树中的描述的设备有问题,所以我们去修改设备树,打开imx6ull-alpha-emmc.dts发现,并没有关于lcd的节点描述。不过包含了imx6ull.dtsi,imx6ul-14x14-evk.dtsi,imx6ul-14x14-evk-u-boot.dtsi
#include "imx6ull.dtsi"
#include "imx6ul-14x14-evk.dtsi"
#include "imx6ul-14x14-evk-u-boot.dtsi"
我们去查看这几个文件,发现在imx6ul-14x14-evk.dtsi这个文件中有关于lcd的描述
&lcdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl>;
display = <&display0>;
status = "okay";
display0: display@0 {
bits-per-pixel = <24>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <9200000>;
hactive = <480>;
vactive = <272>;
hfront-porch = <8>;
hback-porch = <4>;
hsync-len = <41>;
vback-porch = <2>;
vfront-porch = <4>;
vsync-len = <10>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
从描述信息可以看出来LCD的尺寸为480x272与uboot启动信息输出符合。所以我们就修改这个节点的内容,将自己的显示屏的内容添加进去。
&lcdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl>;
display = <&display1>;
status = "okay";
display0: display@0 {
bits-per-pixel = <24>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <9200000>;
hactive = <480>;
vactive = <272>;
hfront-porch = <8>;
hback-porch = <4>;
hsync-len = <41>;
vback-porch = <2>;
vfront-porch = <4>;
vsync-len = <10>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
display1: display@1 {
bits-per-pixel = <24>;
bus-width = <24>;
display-timings {
native-mode = <&timing1>;
timing1: timing1 {
clock-frequency = <51200000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <160>;
hback-porch = <140>;
hsync-len = <20>;
vback-porch = <20>;
vfront-porch = <12>;
vsync-len = <3>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
编译下载运行看看结果:
调试信息已经改变,同时显示屏也显示了LOG,
接下来继续看调试信息的输出
可以看出,网口驱动还需要修改,网口,原子哥的开发板使用的LAN8720a,属于SMSC公司生产的,所以我们先要在make menuconfig配置中,选择网口芯片。
Device Drivers --->
Ethernet PHY (physical media interface) support --->
修改设备树,关于网络的部分;可以参考Linux的设备树
pinctrl_enet1: enet1grp {
fsl,pins = <
MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
/* reset */
MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0X10B0
>;
};
pinctrl_enet2: enet2grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
/* reset */
MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0X10B0
>;
};
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
phy-mode = "rmii";
phy-handle = <ðphy0>;
phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
phy-reset-duration = <26>;
status = "okay";
};
&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2>;
phy-mode = "rmii";
phy-handle = <ðphy1>;
phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
phy-reset-duration = <26>;
status = "okay";
mdio {
#address-cells = <1>;
#size-cells = <0>;
ethphy0: ethernet-phy@0 {
reg = <0>;
micrel,led-mode = <1>;
clocks = <&clks IMX6UL_CLK_ENET_REF>;
clock-names = "rmii-ref";
};
ethphy1: ethernet-phy@1 {
reg = <1>;
micrel,led-mode = <1>;
clocks = <&clks IMX6UL_CLK_ENET2_REF>;
clock-names = "rmii-ref";
};
};
};
添加原子哥收的LAN8720A的原厂驱动BUG.在/drivers/net/phy/phy.c中
int genphy_update_link(struct phy_device *phydev)
{
unsigned int mii_reg;
#ifdef CONFIG_PHY_SMSC
static int lan8720_flag = 0;
int bmcr_reg = 0;
if (lan8720_flag == 0) {
bmcr_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
while(phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR) & 0X8000) {
udelay(100);
}
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg);
lan8720_flag = 1;
}
#endif
编译下载运行试一试。
可以发现网络通畅了。从服务器下载zImage和设备树,看看能不能正常引导内核。
内核是可以成功引导的。
从调试信息看,还需要修改一下 Board的内容,原来Board: MX6ULL 14x14 EVK
,我们希望是Board: MX6ULL ALPHA
这个我们首先需要修改mx6ull_alpha_emmc.h中添加
#define is_mx6ull_alpha_emmc() CONFIG_IS_ENABLED(TARGET_MX6ULL_ALPHA_EMMC)
然后修改mx6ull_alpha_emmc.c
int checkboard(void)
{
if (is_mx6ull_alpha_emmc())
puts("Board: MX6ULL ALPHA\n");
else if (is_cpu_type(MXC_CPU_MX6ULZ))
puts("Board: MX6ULZ 14x14 EVK\n");
else
puts("Board: MX6ULL 14x14 EVK\n");
return 0;
}
编译下载运行
至此,整个移植过程结束!