在官方U-Boot 中添加自己的开发板

官方 uboot 中默认都是官方自己的开发板,所以借鉴官方 6ULL EVK 开发板在uboot中添加

建议请先浏览博主的“NXP的uboot编译\烧写体验”篇

一、添加开发板默认配置文件

在“uboot_myuboot4.1”根目录开始,复制一份官方的开发板默认配置文件,改名为自己设置的名字

代码如下:

cd configs 
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_my_defconfig

1、因为文件在configs目录下,所以先进入该目录

2、使用cp,把文件改成自己的名字

接着修改该文件内容,按文件名字修改后如下图

CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_my/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_MY=y
CONFIG_CMD_GPIO=y

二、添加开发板对应的头文件

在“uboot_myuboot4.1”根目录开始,也是复制一份官方的头 文 件,再修改成自己开发板的头文件,文件在include/configs目录下

cp include/configs/mx6ullevk.h include/configs/mx6ull_my.h

打开mx6ull_my.h,按文件名字修改后如图(改名为自己设置的名字后"_CONFIG_H")

#ifndef __MX6ULL_MY_CONFIG_H
#define __MX6ULL_MY_CONFIG_H

mx6ull_my.h 文件的主要功能就是配置或者裁剪 uboot。如果需要某个功能的话就在里面添加这个功能对应的 CONFIG_XXX 宏即可,如果不需要某个功能的话就删除掉对应的宏即可

三、 添加开发板对应的板级文件夹

uboot 中每个板子都有一个对应的文件夹来存放板级文件,比如开发板上外设驱动文件等等

NXP 的 I.MX 系列芯片的所有板级文件夹都存放在 board/freescale 目录下,在这个目录下有个名为 mx6ullevk 的文件夹,这个文件夹就是 NXP 官方 I.MX6ULL EVK 开发板的板级文件夹

在“uboot_myuboot4.1”根目录开始,复制 mx6ullevk目录,将其重命名为 mx6ull_my

cd board/freescale/
cp mx6ullevk/ -r mx6ull_my

 然后进入mx6ull_my目录,把mx6ullevk.c 文 件 重 命 名 为mx6ull_my.c

cd mx6ull_my
mv mx6ullevk.c mx6ull_my.c

下面在mx6ull_my目录作修改

1、修改mx6ull_my目录下的 Makefile 文件,修改如下

修改这个才会编译上面修改的“mx6ull_my.c”

2、修改mx6ull_my目录下的 imximage.cfg 文件,修改如下

3、修改mx6ull_my目录下的Kconfig 文件,修改如下

 4、修改mx6ull_my目录下的MAINTAINERS 文件,修改如下 

 四、修改 U-Boot 图形界面配置文件

uboot 是支持图形界面配置

在“uboot_myuboot4.1”根目录开始,修改文件arch/arm/cpu/armv7/mx6/Kconfig

在207行添加下面的内容(改名为自己设置的名字)

config TARGET_MX6ULL_MY
    bool "Support mx6ull_my"
    select MX6ULL
    select DM
    select DM_THERMAL

在最后一行的 endif 前一行添加下面内容(改名为自己设置的名字)

source "board/freescale/mx6ull_my/Kconfig"

 到此, 本I.MX6ULL开发板就已经添加到 uboot 中了,接下来就是编译这个新添加的开发板

五、使用新添加的板子配置编译 uboot

在“uboot_myuboot4.1”根目录开始

复制之前编译的shell脚本,修改(改为自己设置的名字)默认配置文件(或者新建一个.sh文件)

cp mx6ull_nxp_emmc.sh mx6ull_my_emmc.sh

把里面的默认配置文件改成现在修改的名字,修完如下图

然后给权限新的shell文件

chmod 777 mx6ull_my_emmc.sh 

最后执行编译脚本

./mx6ull_my_emmc.sh 

看一下编译过程,输入下面代码

grep -nR "mx6ull_my.h"

 如果有很多文件都引用了mx6ull_my.h这个头文件,那就说明新板子添加成功

 编译完成以后就使用 imxdownload 将新编译出来的 u-boot.bin 烧写到 SD 卡中测试

打开SecureCRT 看输出结果,如下图

第一行括号里面的编译的时间是对的上的,说明这次添加开发板板编译烧录成功了

 但是Board 还是“MX6ULL 14x14 EVK”,因为参考的 NXP官方的 I.MX6ULL 开发板来添加自己的开发板。如果接了 LCD 屏幕的话会发现 LCD 屏幕并没有显示 NXP 的 logo,而且从图可以看出此时的网络同样也没识别出来。默认 uboot 中的 LCD 驱动和网络驱动在I.MX6ULL开发板上是有问题的,需要修改,下面开始修改

1、LCD 驱动修改

一般 uboot 中修改驱动基本都是在 xxx.h 和 xxx.c 这两个文件中进行的, xxx 为开发板名称,
比如 mx6ull_14x14_evk_emmc.h 和 mx6ull_14x14_evk_emmc.c 这两个文件

对于修改 LCD 驱动一般重点注意以下几点:
①、 LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确
②、 LCD 背光引脚 GPIO 的配置
③、 LCD 配置参数是否正确

因为这里使用的开发板和 NXP 官方 I.MX6ULL 开发板一致,也就是 LCD 的 IO 和背光 IO 都一样所以 IO 部分就不用修改了
需要修改的之后 LCD配置参数,打开文件 mx6ull_my.c,找到如下图所示内容

 定义了一个变量 displays,类型为 display_info_t,这个结构体是 LCD信息结构体,其中包括了 LCD 的分辨率,像素格式, LCD 的各个参数等。 display_info_t 定义
在文件 arch/arm/include/asm/imx-common/video.h 中,定义如下

 pixfmt 是像素格式,也就是一个像素点是多少位,如果是 RGB565 的话就是 16 位,如果
是 888 的话就是 24 位,一般使用 RGB888。结构体 display_info_t 还有个 mode 成员变量,此
成员变量也是个结构体,为 fb_videomode,定义在文件 include/linux/fb.h 中,定义如下图

结构体 fb_videomode 里面的成员变量为 LCD 的参数,这些成员变量函数如下:
name: LCD 名字,要和环境变量中的 panel 相等。
xres、 yres: LCD X 轴和 Y 轴像素数量。
pixclock:像素时钟,每个像素时钟周期的长度,单位为皮秒。
left_margin: HBP,水平同步后肩。
right_margin: HFP,水平同步前肩。
upper_margin: VBP,垂直同步后肩。
lower_margin: VFP,垂直同步前肩。
hsync_len: HSPW,行同步脉宽。
vsync_len: VSPW,垂直同步脉宽。
vmode: 大多数使用 FB_VMODE_NONINTERLACED,也就是不使用隔行扫描
以开发板 7 寸 1024*600 分辨率的屏幕(ATK7016)为例,屏幕要求的像素时钟为 51.2MHz

因此:pixclock=(1/51200000)*10^12=19531
在根据其他的屏幕参数,可以得出 ATK7016 屏幕的配置参数,修改如下:

4.3寸屏幕的修改如下

 打开 mx6ull_my.h,找到所有语句:panel=TFT43AB
将其改为:panel=TFT7016

panel 的值要与上图中的.name 成员变量的值一致

到这一般 LCD 上会显示 NXP 的 logo,但是有可能会遇到LCD 还是黑屏因为之前有将环境变量保存到 EMMC 中, uboot 启动以后会先从 EMMC 中读取环境变量,如果 EMMC 中没有环境变量的话才会使用 mx6ull_my.h 中的默认环境变量。如果 EMMC 中的环境变量 panel 不等于 TFT7016,LCD 显示肯定不正常,只需要在uboot 中修改 panel 的值为 TFT7016 即可

输入print看一下环境变量panel,如下图

可以看到这是需要吧修改panel的值

输入下面命令

 setenv panel TFT7016

 saveenv

第一句为修改环境变量,第二句为保存,修改为在打印检查即可

重启 uboot,此时 LCD 驱动就工作正常了

如果 LCD 还是没有正常工作的,那就要检查自己哪里有没有改错,或者还有哪里没有修改

2、网络驱动修改

 I.MX6UL/ULL 内部有个以太网 MAC 外设,也就是 ENET,需要外接一个 PHY 芯片来实现网络通信功能,也就是内部 MAC+外部 PHY 芯片的方案。I.MX6UL/ULL 有两个网络接口 ENET1 和 ENET2,开发板提供了这两个网络接口,其中 ENET1 和 ENET2 都使用 LAN8720A 作为 PHY 芯片。

开发板 ENET1 的网络原理图如下图
 

ENET1 的网络原理图

 

ENET1 引脚与 NXP 官方的 I.MX6ULL EVK 开发板基本一样,唯独复位引脚不同 

修改 ENET1 网络驱动的话重点就三点:
①、 ENET1 复位引脚初始化
②、 LAN8720A 的器件 ID,从图可以看出, PHY 器件地址为 0X1
③、 LAN8720 驱动

开发板 ENET2 的网络原理图如下图

ENET2 的网络原理图

 

ENET2 网络驱动的修改也注意一下三点:
①、 ENET2 的复位引脚,从图可以看出, ENET2 的复位引脚 ENET2_RST 接到了I.MX6ULL 的 SNVS_TAMPER8 上
②、 ENET2 所使用的 PHY 芯片器件地址,从图可以看出, PHY 器件地址为 0X1
③、 LAN8720 驱动, ENET1 和 ENET2 都使用的 LAN8720,所以驱动肯定是一样的

下面开始网络 PHY 地址修改
修改 uboot 中的 ENET1 和 ENET2 的 PHY 地址和驱动,打开 mx6ull_my.h文件,找到如下代码:

 331 行的宏 CONFIG_FEC_ENET_DEV 用于选择使用哪个网口,默认为 1,也就是选择ENET2

335 行为 ENET1 的 PHY 地址,默认是 0X2

339 行为 ENET2 的 PHY 地址,默认为 0x1

345 行定了一个宏 CONFIG_PHY_MICREL,此宏用于使能 uboot 中 Micrel 公司的 PHY驱动,不过 Micrel 已经被 Microchip 收购了,如果要使用 LAN8720A,那么就得将 CONFIG_PHY_MICREL 改为 CONFIG_PHY_SMSC,也就是使能 uboot 中的 SMSC 公司中的 PHY 驱动,因为 LAN8720A 就是 SMSC 公司生产的

所以有三处需要修改:
①、修改 ENET1 网络 PHY 的地址。
②、修改 ENET2 网络 PHY 的地址。
③、使能 SMSC 公司的 PHY 驱动。
修改如下图

然后删除 uboot 中 74LV595 的驱动代码

uboot 中网络 PHY 芯片地址修改后就是网络复位引脚的驱动修改,在mx6ull_my.c,找到如下代码

 以 IOX 开头的宏定义是 74LV595 的相关 GPIO,因为 NXP 官方I.MX6ULL EVK 开发板使用 74LV595 来扩展 IO,两个网络的复位引脚就是由 74LV595 来控制的。本开发板并没有使用 74LV595,因此将图中的代码删除掉,替换为如下所示代码

#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)

 ENET1 的复位引脚连接到 SNVS_TAMPER7 上,对应 GPIO5_IO07

 ENET2 的复位引脚连接到 SNVS_TAMPER8 上,对应 GPIO5_IO08

继续在本文件中找到如下代码:

这个是 74LV595 的 IO 配置参数结构体,将其删除掉

继续在mx6ull_my.c 中找到函数 iox74lv_init和 iox74lv_set

 iox74lv_init 函数是 74LV595 的初始化函数, iox74lv_set 函数用于控制 74LV595 的 IO 输出电平,将这两个函数全部删除掉

继续找 board_init 函数,这是开发板初始化函数,会被board_init_r 调用, 函数部分内容如下:

 board_init 会调用 726 和728这两个函数来初始化74lv595 的 GPIO,将这两行删除掉。

 关于 74LV595 芯片的驱动代码都删除掉了

添加两个网络复位引脚

在 mx6ull_my.c 中找到如下所示代码

在561行后面加下面代码

MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),

在576行后面加下面代码

 MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),

结构体数组 fec1_pads 和 fec2_pads 是 ENET1 和 ENET2 这两个网口的 IO 配置参数,在这两个数组中添加两个网口的复位 IO 配置参数

继续找到函数 setup_iomux_fec,此函数默认代码如下:

 函数 setup_iomux_fec 就是根据 fec1_pads 和 fec2_pads 这两个网络 IO 配置数组来初始化
I.MX6ULL 的网络 IO。需要在其中添加网络复位 IO 的初始化代码,并且复位一下 PHY 芯片,修改后的 setup_iomux_fec 函数如下:

         gpio_direction_output(ENET1_RESET, 1);
        gpio_set_value(ENET1_RESET, 0);
        mdelay(20);
        gpio_set_value(ENET1_RESET, 1);

        gpio_direction_output(ENET2_RESET, 1);
        gpio_set_value(ENET2_RESET, 0);
        mdelay(20);
        gpio_set_value(ENET2_RESET, 1);

587行~590 行和 596 行~599 行分别对应 ENET1 和 ENET2 的复位 IO 初始化,将这两个 IO 设置为输出并硬件复位一下 LAN8720A,这个复位很重要,否则可能导致 uboot 无法识别 LAN8720A

修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link
还差最后一步, uboot 中的 LAN8720A 驱动有点问题,打开文件drivers/net/phy/phy.c

找到函数 genphy_update_link,这是个通用 PHY 驱动函数,此函数用于更新 PHY 的连接状态和速度。使用 LAN8720A 的时候需要在此函数中添加一些代码,修改后的函数 genphy_update_link 如下所示:

#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

225 行~237 行就是新添加的代码,为条件编译代码段,只有使用 SMSC 公司的 PHY 这段
代码才会执行

230 行读取LAN8720A 的 BMCR 寄存器(寄存器地址为 0),此寄存器为 LAN8720A 的配置寄存器,这里先读取此寄存器的默认值并保存起来

231 行向寄存器 BMCR 寄存器写入 BMCR_RESET(值为0X8000),因为 BMCR 的 bit15 是软件复位控制位,因此 230 行就是软件复位 LAN8720A,复位完成以后此位会自动清零

 232~235 行等待 LAN8720A 软件复位完成,也就是判断 BMCR的 bit15 位是否为 1,为 1 的话表示还没有复位完成

第 236 行重新向 BMCR 寄存器写入以前的值,也就是 230 行读出的那个值。
至此网络的复位引脚驱动修改完成,重新编译 uboot,然后将 u-boot.bin 烧写到 SD 卡中

 

进入uboot,可以看到“Net: FEC1”这一行,提示当前使用的 FEC1 这个网口,也就
是 ENET2。在 uboot 中使用网络之前要先设置几个环境变量,命令如下:

setenv ipaddr 192.168.1.221                  //开发板 IP 地址
setenv ethaddr b8:ae:1d:01:00:00        //开发板网卡 MAC 地址
setenv gatewayip 192.168.1.1              //开发板默认网关
setenv netmask 255.255.255.0            //开发板子网掩码
setenv serverip 192.168.1.222            //服务器地址,也就是 Ubuntu 地址
saveenv                                               //保存环境变量

这里的网段需要根据你实际情况修改

设置好环境变量以后就可以在 uboot 中使用网络了,用网线将 开发板上的 ENET2与电脑或者路由器连接起来,保证开发板和电脑在同一个网段内,通过 ping 命令测试一下网络连接,命令如下:

ping 192.168.1.222 

可以看出, ping 主机也成功,说明 ENET2 网络也工作正常

自行测试一下ENET1 网络,只需要把mx6ull_my.h文件331 行的宏 CONFIG_FEC_ENET_DEV (用于选择使用哪个网口,默认为 1,也就是选择ENET2)修改为0,也就是选择ENET1即可

其他需要修改的地方
 uboot 启动信息中会有“Board: MX6ULL 14x14 EVK”这一句,也就是说板子名字为“ MX6ULL 14x14 EVK”,将其改为自己名字,打开文件 mx6ull_my.c,找到函数checkboard,将其改为如下所示内容:

修改完成以后重新编译 uboot 并烧写到 SD 卡中验证
 

 Board 变成了“MX6ULL MY EMMC”。至此 uboot 的驱动部分就修改完成了

 uboot 移植也完成了, uboot 的最终目的就是启动 Linux 内核

所以需要通过启动 Linux 内核来判断 uboot 移植是否成功

在启动 Linux 内核之前可以了解两个重要的环境变量 bootcmd 和 bootargs
减少篇幅,新内容在下一章

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值