I.MX6ULL 移植U-boot
1. 添加开发板默认配置文件
-
在 configs 目录下创建默认配置文件,复制 mx6ull_14x14_evk_emmc_defconfig,然后重
命名为 mx6ull_alientek_emmc_defconfig 。cd configs cp mx6ull_14x14_evk_emmc_defconfig mx6ull_alientek_emmc_defconfig
-
修改mx6ull_alientek_emmc_defconfig的内容为:
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
2. 添加开发板对应的头文件
-
在 目 录 include/configs 下 添 加 I.MX6ULL-ALPHA 开 发 板 对 应 的 头 文 件 , 复 制
include/configs/mx6ullevk.h,并重命名为 mx6ull_alientek_emmc.h :cp mx6ullevk.h mx6ull_alientek_emmc.h
-
修改mx6ull_alientek_emmc.h文件中头文件声明改为:
#ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H #define __MX6ULL_ALIENTEK_EMMC_CONFIG_H
3. 添加开发板对应的板级文件夹
-
uboot 中每个板子都有一个对应的文件夹来存放板级文件,比如开发板上外设驱动文件等
等。 NXP 的 I.MX 系列芯片的所有板级文件夹都存放在 board/freescale 目录下,在这个目录下
有个名为 mx6ullevk 的文件夹,这个文件夹就是 NXP 官方 I.MX6ULL EVK 开发板的板级文件
夹。复制 mx6ullevk,将其重命名为 mx6ull_alientek_emmc ,cd board/freescale/ cp -r mx6ullevk/ mx6ull_alientek_emmc
-
进 入 mx6ull_alientek_emmc 目 录 中 , 将 其 中 的 mx6ullevk.c 文 件 重 命 名 为
mx6ull_alientek_emmc.ccd mx6ull_alientek_emmc/ mv mx6ullevk.c mx6ull_alientek_emmc.c
-
修改 mx6ull_alientek_emmc 目录下的 Makefile 文件
# (C) Copyright 2015 Freescale Semiconductor, Inc. # # SPDX-License-Identifier: GPL-2.0+ # obj-y := mx6ull_alientek_emmc.o extra-$(CONFIG_USE_PLUGIN) := plugin.bin $(obj)/plugin.bin: $(obj)/plugin.o $(OBJCOPY) -O binary --gap-fill 0xff $< $@
-
修改 mx6ull_alientek_emmc 目录下的 imximage.cfg 文件
PLUGIN board/freescale/mx6ull_alientek_emmc/plugin.bin 0x00907000
-
修改 mx6ull_alientek_emmc 目录下的 Kconfig 文件
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
-
修改 mx6ull_alientek_emmc 目录下的 MAINTAINERS 文件
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
4. 修改 U-Boot 图形界面配置文件
-
修改文件arch/arm/cpu/armv7/mx6/Kconfig ,
- 207行
config TARGET_MX6ULL_ALIENTEK_EMMC bool "Support mx6ull_alientek_emmc" select MX6ULL select DM select DM_THERMAL
- 在endif 前面加上
source "board/freescale/mx6ull_alientek_emmc/Kconfig"
5. 使用新添加的板子配置编译 uboot
-
在 uboot 根目录下新建一个名为 mx6ull_alientek_emmc.sh 的 shell 脚本,在这个 shell 脚本
里面输入如下内容:#!/bin/bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- diskclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8
-
给 mx6ull_alientek_emmc.sh 运行权限,并运行脚本,
chmod 777 mx6ull_alientek_emmc.sh ./mx6ull_alientek_emmc.sh
6. 烧录到SD卡测试
-
烧录:
chmod 777 imxdownload ./imxdownload u-boot.bin /dev/sdb #SD卡
7. 修改LCD 驱动
一般 uboot 中修改驱动基本都是在 xxx.h 和 xxx.c 这两个文件中进行的, xxx 为板子名称,
比如 mx6ull_alientek_emmc.h 和 mx6ull_alientek_emmc.c 这两个文件。
一般修改 LCD 驱动重点注意以下几点:
①、 LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。
②、 LCD 背光引脚 GPIO 的配置。
③、 LCD 配置参数是否正确。
正点原子的 I.MX6U-ALPHA 开发板 LCD 原理图和 NXP 官方 I.MX6ULL 开发板一致,也
就是 LCD 的 IO 和背光 IO 都一样的,所以 IO 部分就不用修改了。需要修改的之后 LCD 参数,
-
修改 LCD 参数,
- 打开文件 mx6ull_alientek_emmc.c,找到如下所示内容:
cd board/freescale/mx6ull_alientek_emmc/ vim mx6ull_alientek_emmc.c
struct display_info_t const displays[] = {{ .bus = MX6UL_LCDIF1_BASE_ADDR, .addr = 0, .pixfmt = 24, .detect = NULL, .enable = do_enable_parallel_lcd, .mode = { .name = "TFT7016", .xres = 1024, .yres = 600, .pixclock = 19531, .left_margin = 140, .right_margin = 160, .upper_margin = 20, .lower_margin = 12, .hsync_len = 20, .vsync_len = 3, .sync = 0, .vmode = FB_VMODE_NONINTERLACED } } };
- 打开文件mx6ull_alientek_emmc.h ,将所有的panel=TFT43AB ,改成panel=TFT7016
cd include/configs/ vim mx6ull_alientek_emmc.h
-
编译再烧录尝试
8. 网络驱动修改
-
网络 PHY 地址修改 ,首先修改 uboot 中的 ENET1 和 ENET2 的 PHY 地址和驱动,打开 mx6ull_alientek_emmc.h
这个文件,vim ./include/configs/mx6ull_alientek_emmc.h
有三处要修改:
①、修改 ENET1 网络 PHY 的地址。
②、修改 ENET2 网络 PHY 的地址。
③、使能 SMSC 公司的 PHY 驱动#ifdef CONFIG_CMD_NET #define CONFIG_CMD_PING #define CONFIG_CMD_DHCP #define CONFIG_CMD_MII #define CONFIG_FEC_MXC #define CONFIG_MII #define CONFIG_FEC_ENET_DEV 1 #if (CONFIG_FEC_ENET_DEV == 0) #define IMX_FEC_BASE ENET_BASE_ADDR #define CONFIG_FEC_MXC_PHYADDR 0x0 #define CONFIG_FEC_XCV_TYPE RMII #elif (CONFIG_FEC_ENET_DEV == 1) #define IMX_FEC_BASE ENET2_BASE_ADDR #define CONFIG_FEC_MXC_PHYADDR 0x1 #define CONFIG_FEC_XCV_TYPE RMII #endif #define CONFIG_ETHPRIME "FEC" #define CONFIG_PHYLIB #define CONFIG_PHY_SMSC #endif
-
删除 uboot 中 74LV595 的驱动代码
- 打开mx6ull_alientek_emmc.c,将下面代码删除并换成
#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) 换成下面的: #define ENET1_RESET IMX_GPIO_NR(5, 7) #define ENET2_RESET IMX_GPIO_NR(5, 8)
- 删除以下代码
删除这个数组: static iomux_v3_cfg_t const iox_pads[] = { /* IOX_SDI */ MX6_PAD_BOOT_MODE0__GPIO5_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), /* IOX_SHCP */ MX6_PAD_BOOT_MODE1__GPIO5_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), /* IOX_STCP */ MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), /* IOX_nOE */ MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL), };
删掉这两个函数: static void iox74lv_init(void) { ... } void iox74lv_set(int index) { ... }
int board_init(void) { ... imx_iomux_v3_setup_multiple_pads(iox_pads, ARRAY_SIZE(iox_pads)); //删除这一行 iox74lv_init(); //删除这一行 ... return 0; }
-
添加 I.MX6U-ALPHA 开发板网络复位引脚驱动
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_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL), MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | 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_TX_DATA0__ENET2_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET2_TX_DATA1__ENET2_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL), MX6_PAD_ENET2_TX_EN__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET2_RX_DATA0__ENET2_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL), MX6_PAD_ENET2_RX_DATA1__ENET2_RDATA01 | 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),//添加这一句 };
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
-
打开文件drivers/net/phy/phy.c,找到函数 genphy_update_link,这是个通用 PHY 驱动函数,此函数用于更新 PHY 的连接状态和速度。使用 LAN8720A 的时候需要在此函数中添加一些代码,修改后的函数 genphy_update_link 如下所示 :
(加个条件编译)
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 /* * Wait if the link is up, and autonegotiation is in progress * (ie - we're capable and it's not done) */ mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); ... }
-
-
编译并烧录到板子,在终端输入:
- 配置网络地址
setenv ipaddr 192.168.3.10 //开发板 IP 地址 setenv ethaddr 00:04:9f:04:d2:35 //开发板网卡 MAC 地址 setenv gatewayip 192.168.3.1 //开发板默认网关 setenv netmask 255.255.255.0 //开发板子网掩码 setenv serverip 192.168.3.9 //服务器地址,也就是 Ubuntu 地址 saveenv //保存环境变量
- 测试网络
ping 192.168.3.9
9. 其他需要修改的
-
在 uboot 启动信息中会有“Board: MX6ULL 14x14 EVK”这一句,也就是说板子名字为
“ MX6ULL 14x14 EVK”,要将其改为我们所使用的板子名字,比如“ MX6ULL ALIENTEK
EMMC”或者“MX6ULL ALIENTEK NAND”。打开文件 mx6ull_alientek_emmc.c,找到函数
checkboard,将其改为如下所示内容int checkboard(void) { if (is_mx6ull_9x9_evk()) puts("Board: MX6ULL 9x9 EVK\n"); else puts("Board: MX6ULL ALIENTEK EMMC\n"); return 0; }
10. 测试从网络启动linux
-
在ubuntu的tftpboot文件夹存放 zImage 和 imx6ull-14x14-nand-7-1024x600-c.dtb文件,如果是从windows传过来的,需要给777权限。
chmod 777 zImage chmod 777 imx6ull-14x14-nand-7-1024x600-c.dtb
-
在uboot命令行中使用tftp下载,并启动内核:
tftp 80800000 zImage tftp 83000000 imx6ull-14x14-nand-7-1024x600-c.dtb bootz 80800000 - 83000000 或者使用bootargs和bootcmd环境变量输入上述的命令: setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw' setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000' saveenv