Uboot的移植 首先从官方下载一个Uboot,之后在此上面进行移植,可以进行使用脚本进行编译一下。
1 2 3 make ARCH=arm CORSS_COMPILE=arm-linux-gnueabihf- distclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
在Uboot中添加使用的开发板 添加开发板默认配置文件 将cofigs目录下复制原有的mx6ull_14x14_evk_emmc_defconfig进行修改
1 cp mx6ull_14x14_evk_emmc_defconfig mx6ull_alientek_emmc_defconfig
修改mx6ull_alientek_emmc_defconfig文件,将原有的替换成mx6ull_alientek_emmc
1 2 3 4 5 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_alientek_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK" CONFIG_ARM=y CONFIG_ARCH_MX6=y CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC=y CONFIG_CMD_GPIO=y
添加开发板对应的头文件 在 目 录 include/configs 下 添 加 I.MX6ULL-ALPHA 开 发 板 对 应 的 头 文 件 , 复 制include/configs/mx6ullevk.h,并重命名为 mx6ull_alientek_emmc.h,命令如下:
1 cp include/configs/mx6ullevk.h mx6ull_alientek_emmc.h
拷贝完成以后将:
1 2 #ifndef __MX6ULLEVK_CONFIG_H #define __MX6ULLEVK_CONFIG_H
改为:
1 2 #ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H #define __MX6ULL_ALIENTEK_EMMC_CONFIG_H
此头文件主要功能就是配置或者裁剪 uboot。如果需要某个功能的话就在里面添加这个功能对应的 CONFIG_XXX 宏即可,如果不需要某个功能的话就删除掉对应的宏即可。
添加开发板对应的板级文件夹 NXP 的 I.MX 系列芯片的所有板级文件夹都存放在 board/freescale 目录下,在这个目录下有个名为 mx6ullevk 的文件夹,这个文件夹就是 NXP 官方 I.MX6ULL EVK 开发板的板级文件夹。
1 2 3 4 cd board/freescale/ cp mx6ullevk/ -r mx6ull_alientek_emmc cd mx6ull_alientek_emmc mv mx6ullevk.c mx6ull_alientek_emmc.c
分别需要修改Makefile文件、imximage.cfg 文件、Kconfig 文件 、MAINTAINERS 文件
Makefile要改编译的.o的文件名字。
imximage.cfg 需要修改PLUGIN 后面的板载二进制文件所在路径。
Kconfig 文件 需要改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 if TARGET_MX6ULL_ALIENTEK_EMMC config SYS_BOARD default "mx6ull_alientek_emmc" config SYS_VENDOR default "freescale" config SYS_SOC default "mx6" config SYS_CONFIG_NAME default "mx6ull_alientek_emmc" endif
MAINTAINERS 文件需改
1 2 3 4 5 MX6ULL_ALIENTEK_EMMC BOARD M: Peng Fan <peng.fan@nxp.com> S: Maintained F: board/freescale/mx6ull_alientek_emmc/ F: include/configs/mx6ull_alientek_emmc.h
修改U-boot图形化配置文件 修改文件arch/arm/cpu/armv7/mx6/Kconfig ,207行加入
1 2 3 4 5 config TARGET_MX6ULL_ALIENTEK_EMMC bool "Support mx6ull_alientek_emmc" select MX6ULL select DM select DM_THERMAL
endif前加入
1 source "board/freescale/mx6ull_alientek_emmc/Kconfig"
LCD驱动修改 一般 uboot 中修改驱动基本都是在 xxx.h 和 xxx.c 这两个文件中进行的, xxx 为板子名称,比如 mx6ull_alientek_emmc.h 和 mx6ull_alientek_emmc.c 这两个文件。 一般修改 LCD 驱动重点注意以下几点: ①、 LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。 ②、 LCD 背光引脚 GPIO 的配置。 ③、 LCD 配置参数是否正确。
基于使用的lcd设置参数为
1 2 3 4 5 6 7 8 9 10 11 12 13 .mode = { .name = "TFT4384", .xres = 800, .yres = 480, .pixclock = 31746, .left_margin = 88, .right_margin = 40, .upper_margin = 32, .lower_margin = 13, .hsync_len = 48, .vsync_len = 3, .sync = 0, .vmode = FB_VMODE_NONINTERLACED
将mx6ull_alientek_emmc.h中的panel进行修改
之后就可以编译烧录。正常显示出现以下东西。
如果没有出现效果,修改环境变量
1 2 setenv panel TFT7016 saveenv
如果只显示NXP没有uboot的版本号,并且报错no valid bmp image at 88000000 ,使用uboot命令清除一下环境变量。
网络驱动修改 更换 PHY 芯片以后如何调整网络驱动
修改 ENET1 网络驱动的话重点就三点: ①、 ENET1 复位引脚初始化。 ②、 LAN8720A 的器件 ID。 ③、 LAN8720 驱动
ENET2 网络驱动的修改也注意一下三点: ①、 ENET2 的复位引脚,从图 33.2.7.2 可以看出, ENET2 的复位引脚 ENET2_RST 接到了 I.MX6ULL 的 SNVS_TAMPER8 上。 ②、 ENET2 所使用的 PHY 芯片器件地址,从图 33.2.7.2 可以看出, PHY 器件地址为 0X1。 ③、 LAN8720 驱动, ENET1 和 ENET2 都使用的 LAN8720,所以驱动肯定是一样的。
网络PHY地址修改 修改ENETI和ENET2的PHY地址和驱动,ENET1和ENET2的PHY的地址存在mx6ull_alientek_emmc.h中
1 2 3 4 5 #if (CONFIG_FEC_ENET_DEV == 0) #define CONFIG_FEC_MXC_PHYADDR 0x2 //ENET1的地址改为0x0 #elif (CONFIG_FEC_ENET_DEV == 1) #define CONFIG_FEC_MXC_PHYADDR 0x1 //ENET2的地址相同不用改 #define CONFIG_PHY_MICREL //使用 LAN8720A则改为CONFIG_PHY_SMSC
因为两个板子的复位引脚不同。删除之前为了复位的扩展IO的代码,在mx6ull_alientek_emmc.c中
1 2 3 4 #define IOX_SDI IMX_GPIO_NR(5, 10) #define IOX_STCP IMX_GPIO_NR(5, 7) #define IOX_SHCP IMX_GPIO_NR(5, 11) #define IOX_OE IMX_GPIO_NR(5, 8)
替换为自己使用板子的网络复位IO
1 2 #define ENET1_RESET IMX_GPIO_NR(5, 7) #define ENET2_RESET IMX_GPIO_NR(5, 8)
删除原有结构体和函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 static iomux_v3_cfg_t const iox_pads[] = { MX6_PAD_BOOT_MODE0__GPIO5_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), MX6_PAD_BOOT_MODE1__GPIO5_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL), }; static void iox74lv_init (void ) { int i;gpio_direction_output(IOX_OE, 0 ); for (i = 7 ; i >= 0 ; i--) {gpio_direction_output(IOX_SHCP, 0 ); gpio_direction_output(IOX_SDI, seq[qn_output[i]][0 ]); udelay(500 ); gpio_direction_output(IOX_SHCP, 1 ); udelay(500 ); } ...... gpio_direction_output(IOX_STCP, 1 ); }; void iox74lv_set (int index) { int i;for (i = 7 ; i >= 0 ; i--) {gpio_direction_output(IOX_SHCP, 0 ); if (i == index)gpio_direction_output(IOX_SDI, seq[qn_output[i]][0 ]); else gpio_direction_output(IOX_SDI, seq[qn_output[i]][1 ]); udelay(500 ); gpio_direction_output(IOX_SHCP, 1 ); udelay(500 ); } ...... gpio_direction_output(IOX_STCP, 1 ); };
删掉板子初始化函数中的相关程序
1 2 3 4 5 6 7 8 int board_init (void ) { ...... imx_iomux_v3_setup_multiple_pads(iox_pads, ARRAY_SIZE(iox_pads)); iox74lv_init(); ...... return 0 ;}
添加自己开发板的网络复位引脚驱动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 static iomux_v3_cfg_t const fec1_pads[] = { MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL), MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), ... MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), }; static iomux_v3_cfg_t const fec2_pads[] = { MX6_PAD_GPIO1_IO06__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL), MX6_PAD_GPIO1_IO07__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), ... MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL), };
修改初始化网络IO的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 static void setup_iomux_fec (int fec_id) { if (fec_id == 0 ) { imx_iomux_v3_setup_multiple_pads(fec1_pads,ARRAY_SIZE(fec1_pads)); gpio_direction_output(ENET1_RESET, 1 ); gpio_set_value(ENET1_RESET, 0 ); mdelay(20 ); gpio_set_value(ENET1_RESET, 1 ); } else { imx_iomux_v3_setup_multiple_pads(fec2_pads,ARRAY_SIZE(fec2_pads)); gpio_direction_output(ENET2_RESET, 1 ); gpio_set_value(ENET2_RESET, 0 ); mdelay(20 ); gpio_set_value(ENET2_RESET, 1 ); } }
修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); ...... return 0 ; }
之后就在Uboot中设置环境变量网址就可以应用了。