嵌入式Linux系统开发笔记(十)

U-Boot移植

下载NXP官方维护的uboot-imx-rel_imx_4.1.15_2.1.0_ga版本

git clone -b rel_imx_4.1.15_2.1.0_ga --single-branch git://source.codeaurora.org/external/imx/uboot-imx.git

如果下载速度过慢,也可以从以下国内的gitee仓库下载

git clone https://gitee.com/SudekiMing/uboot-imx-rel_imx_4.1.15_2.1.0_ga.git

在移植之前,我们需要先编译一下 NXP 官方 I.MX6ULL EVK 开发板对应的 uboot,首先是配置uboot, configs 目录下有很多跟 I.MX6UL/6ULL 有关的配置如图:
在这里插入图片描述

其中以 mx6ul 开头的是 I.MX6UL 芯片的,mx6ull 开头的是 I.MX6ULL 开发板的。 I.MX6UL/6ULL 有 9x9mm 和 14x14mm 两种尺寸的,所以我们可以看到会有mx6ull_9x9和mx6ull_14x14开头的默认配置文件。我们使用的是14x14mm的芯片,所以关注 mx6ull_14x14 开头的默认配置文件。

我的开发板是EMMC版本,因此我只 需 要 关 注 mx6ull_14x14_evk_emmc_defconfig ,使用 mx6ull_14x14_evk_emmc_defconfig 作为默认配置文件。

1.1 编译 NXP 官方开发板对应的 uboot

找到 NXP 官方 I.MX6ULL EVK 开发板对应的默认配置文件以后就可以编译一下,使用如下命令编译 uboot:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4

编译完成以后结果如图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n7JRCCyy-1675178748810)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.1-1-uboot初次编译完成.png)]

我们在编译的时候需要输入 ARCH 和 CORSS_COMPILE这两个变量的值,这样太麻烦了。我们可以直接在顶层 Makefile 中直接给 ARCH 和CORSS_COMPILE 赋值,修改如图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ksgkyGcp-1675178748811)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.1-2-uboot修改makefile.png)]

这样我们就可以使用如下简短的命令来编译 uboot 了:

make mx6ull_14x14_evk_emmc_defconfig
make V=1 -j4

编译完成以后会生成 u-boot.bin、 u-boot.imx 等文件,但是这些文件是 适配的NXP 官方 I.MX6ULLEVK 开发板。

1.2 在 U-Boot 中添加自己的开发板
1.2.1 添加开发板默认配置文件

先在 configs 目录下创建默认配置文件,复制 mx6ull_14x14_evk_emmc_defconfig,然后重命名为 mx6ull_alientek_emmc_defconfig,命令如下:

cd configs
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_14x14_atk_emmc_defconfig

然后将文件 mx6ull_14x14_atk_emmc_defconfig 中的内容改成下面的(只是第 1 行和第 4 行做了修改 ):

CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_14x14_atk_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_14X14_ATK_EMMC=y
CONFIG_CMD_GPIO=y
1.2.2 添加开发板对应的头文件

在 目 录 include/configs 下 添 加 I.MX6ULL-ALPHA 开 发 板 对 应 的 头 文 件 , 复 制include/configs/mx6ullevk.h,并重命名为 mx6ullatk.h,命令如下:

cp include/configs/mx6ullevk.h include/configs/mx6ullatk.h

拷贝完成以后将:

#ifndef __MX6ULLEVK_CONFIG_H
#define __MX6ULLEVK_CONFIG_H

改为:

#ifndef __MX6ULLATK_CONFIG_H
#define __MX6ULLATK_CONFIG_H

mx6ullatk.h里面有很多宏定义,这些宏定义基本用于配置 uboot,也有一些I.MX6ULL 的配置项目。 文件中基本都是“CONFIG_”开头
的宏定义,这也说明 mx6ullatk.h 文件的主要功能就是配置或者裁剪 uboot。如果需要某个功能的话就在里面添加这个功能对应的 CONFIG_XXX 宏即可,如果不需要某个功能的话就删除掉对应的宏即可。

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

uboot 中每个板子都有一个对应的文件夹来存放板级文件,比如开发板上外设驱动文件等等。 NXP 的 I.MX 系列芯片的所有板级文件夹都存放在 board/freescale 目录下,在这个目录下有个名为 mx6ullevk 的文件夹,这个文件夹就是 NXP 官方 I.MX6ULL EVK 开发板的板级文件夹。复制 mx6ullevk,将其重命名为 mx6ullatk,命令如下:

cd board/freescale/
cp mx6ullevk/ -r mx6ullatk

进 入 mx6ullatk 目 录 中 , 将 其 中 的 mx6ullevk.c 文 件 重 命 名 为mx6ullatk.c,命令如下:

cd mx6ullatk
mv mx6ullevk.c mx6ullatk.c

我们还需要对 mx6ullatk 目录下的文件做一些修改:

1、修改 mx6ull_alientek_emmc 目录下的 Makefile 文件

# (C) Copyright 2015 Freescale Semiconductor, Inc.
#
# SPDX-License-Identifier: GPL-2.0+
#

obj-y := mx6ullatk.o

extra-$(CONFIG_USE_PLUGIN) := plugin.bin
$(obj)/plugin.bin: $(obj)/plugin.o
$(OBJCOPY) -O binary --gap-fill 0xff $< $@

重点是第 6 行的 obj-y,改为 mx6ullatk.o,这样才会编译 mx6ullatk.c这个文件

2、修改 mx6ullatk目录下的 imximage.cfg 文件

将 imximage.cfg 中的下面一句:

PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000

改为:

PLUGIN board/freescale/mx6ullatk/plugin.bin 0x00907000

3、修改 mx6ullatk目录下的 Kconfig 文件

修改 Kconfig 文件,修改后的内容如下:

if TARGET_MX6ULL_14X14_ATK_EMMC

config SYS_BOARD
	default "mx6ullatk"

config SYS_VENDOR
	default "freescale"

config SYS_SOC
	default "mx6"

config SYS_CONFIG_NAME
	default "mx6ullatk"

endif

4、修改 mx6ullatk目录下的 MAINTAINERS 文件

修改 MAINTAINERS 文件,修改后的内容如下:

MX6ULLATK BOARD
M:	Peng Fan <peng.fan@nxp.com>
S:	Maintained
F:	board/freescale/mx6ullatk/
F:	include/configs/mx6ullatk.h
F:	configs/mx6ull_14x14_atk_defconfig
1.3 修改 U-Boot 图形界面配置文件

uboot 是支持图形界面配置的,修改文件arch/arm/cpu/armv7/mx6/Kconfig(如果用的 I.MX6UL 的话,应该修改 arch/arm/Kconfig 这个文件),在 207 行前加入如下内容:

config TARGET_MX6ULL_14X14_ATK_EMMC
	bool "Support mx6ull_14x14_atk_emmc"
	select MX6ULL
	select DM
	select DM_THERMAL

在最后一行的 endif 的前一行添加如下内容:

source "board/freescale/mx6ullatk/Kconfig"

添加完成以后的 Kconfig 文件的改动如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lDQ4ZFyu-1675178748812)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.3-1-修改uboot图形界面配置文件.png)]

到此为止, I.MX6U-ALPHA 开发板就已经添加到 uboot 中了,接下来就是编译这个新添加的开发板。

1.4 使用新添加的板子配置编译 uboot
# 清理工程
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
# 配置 uboot 
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_atk_emmc_defconfig
# 编译
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4

# 在顶层Makefile中配置修改过ARCH和CORSS_COMPILE,可直接使用下面简化的指令编译

# 清理工程
make distclean
# 配置 uboot 
make mx6ull_14x14_atk_emmc_defconfig
# 编译
make -j4

等 待 编 译 完 成 , 编 译 完成 以 后 输 入 如 下命 令, 查 看 一 下 添加 的mx6ullatk.h 这个头文件有没有被引用。如果有很多文件都引用了mx6ull_alientek_emmc.h这个头文件,那就说明新板子添加成功。

grep -nR "mx6ullatk.h"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HXDwAV4v-1675178748812)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.4-1-uboot添加新板子编译验证.png)]

1.5 LCD 驱动修改

如果你用的不是正点原子的 4.3 寸 480x272 分辨率的屏幕的话,那么 LCD 就不会显示 以上logo 界面。因为 NXP 官方 I.MX6ULL 开发板的屏幕就是 4.3 寸 480x272 分辨率的,所以 uboot 默认 LCD 驱动是 4.3 寸 480x272 分辨率的。如果使用其他分辨率的 LCD 就需要修改 LCD 驱动。(因为我本次试验用就是正点原子 4.3 寸 480x272 分辨率的屏幕,故NXP logo正常显示,驱动不用做修改)

1.6 网络驱动修改

注意!正点原子I.MX6U-ALPHA开发板V2.4版本以前的底板使用的网络PHY为LAN8720,V2.4 及其以后的版本使用的网络 PHY 为 SR8201F,而且网络 PHY 地址有改变,大家一定要看准自己所使用的底板版本号!(我的底板版本为V1.7)

1.6.1 I.MX6U-ALPHA 开发板网络简介

I.MX6UL/ULL 内部有个以太网 MAC 外设,也就是 ENET,需要外接一个 PHY 芯片来实现网络通信功能,也就是内部 MAC+外部 PHY 芯片的方案。

I.MX6UL/ULL 有两个网络接口 ENET1 和 ENET2,正点原子的 I.MX6U-ALPHA 开发板提供了这两个网络接口,其中 ENET1 和 ENET2 都使用 LAN8720A 作为 PHY 芯片(注:正点原子Mini LinuxI.MX6ULL只有一个网络接口ENET2,我这里使用的是Mini LinuxI.MX6ULL开发板)。

NXP 官方的I.MX6ULL EVK 开发板使用 KSZ8081 这颗 PHY 芯片, LAN8720A 相比 KSZ8081 具有体积小、外围器件少、价格便宜等优点。直接使用 KSZ8081 固然可以,但是我们在实际的产品中不一定会使用 KSZ8081,有时候为了降低成本会选择其他的 PHY 芯片。

1.6.2 网络 PHY 地址修改

首先修改 uboot 中的 ENET1 和 ENET2 的 PHY 地址和驱动,打开 mx6ullatk.h这个文件,找到如下代码:

第 331 行的宏 CONFIG_FEC_ENET_DEV 用于选择使用哪个网口,默认为 1,也就是选择ENET2(建议大家将ENET2 设置为 uboot 的默认网卡!也就是将宏 CONFIG_FEC_ENET_DEV 设置为 1)。

第 335 行为 ENET1 的 PHY 地址,默认是 0X2,第 339 行为 ENET2 的 PHY 地址,默认为 0x1。根据前面的分析可知,正点原子的 I.MX6U-ALPHA 开发板 ENET1 的 PHY 地址为0X0, ENET2 的 PHY 地址为 0X1,所以需要将第 335 行的宏 CONFIG_FEC_MXC_PHYADDR改为 0x0。第 345 行定了一个宏 CONFIG_PHY_MICREL,此宏用于使能 uboot 中 Micrel 公司的 PHY驱动, KSZ8081 这颗 PHY 芯片就是 Micrel 公司生产的,不过 Micrel 已经被 Microchip 收购了。

如果要使用 LAN8720A,那么就得将 CONFIG_PHY_MICREL 改为 CONFIG_PHY_SMSC,也就是使能 uboot 中的 SMSC 公司中的 PHY 驱动,因为 LAN8720A 就是 SMSC 公司生产的。

所以示例代码有三处要修改:

①、修改 ENET1 网络 PHY 的地址。
②、修改 ENET2 网络 PHY 的地址。
③、使能 SMSC 公司的 PHY 驱动。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vVQWKcTE-1675178748813)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.6.2-1-uboot修改网络phy地址.png)]

1.6.3 删除 uboot 中 74LV595 的驱动代码

uboot 中网络 PHY 芯片地址修改完成以后就是网络复位引脚的驱动修改了,打开mx6ullatk.c,找到如下代码:

示例代码中以 IOX 开头的宏定义是 74LV595 的相关 GPIO,因为 NXP 官方I.MX6ULL EVK 开发板使用 74LV595 来扩展 IO,两个网络的复位引脚就是由 74LV595 来控制的。正点原子的 I.MX6U-ALPHA 开发板并没有使用 74LV595,因此我们将示例代码中的代码删除掉,

ENET1 的复位引脚连接到 SNVS_TAMPER7 上,对应 GPIO5_IO07, ENET2 的复位引脚连接到 SNVS_TAMPER8 上,对应 GPIO5_IO08。

继续在 mx6ullatk.c 中找到如下代码:

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

同理,示例代码是 74LV595 的 IO 配置参数结构体,将其删除掉。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f9WkLa88-1675178748814)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.6.3-1-删除 uboot 中 74LV595 的驱动代码.png)]

继续在mx6ullatk.c 中找到函数 iox74lv_init,iox74lv_init 函数是 74LV595 的初始化函数, iox74lv_set 函数用于控制 74LV595 的 IO 输出电平,将这两个函数全部删除掉!

在 mx6ullatk.c 中找到 board_init 函数,此函数是板子初始化函数,会被board_init_r 调用

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v2esUdm9-1675178748814)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.6.3-2-删除 uboot 中 74LV595 的驱动代码.png)]

至此, mx6ullatk.c 中关于 74LV595 芯片的驱动代码都删除掉了,接下来就是添加 I.MX6U-ALPHA 开发板两个网络复位引脚了。

1.6.4 添加 I.MX6U-ALPHA 开发板网络复位引脚驱动

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

结构体数组 fec1_pads 和 fec2_pads 是 ENET1 和 ENET2 这两个网口的 IO 配置参数,在这两个数组中添加两个网口的复位 IO 配置参数,完成以后如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H0krzdtf-1675178748815)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.6.4-1-添加 I.MX6U-ALPHA 开发板网络复位引脚驱动.png)]

示例代码中,第 651 行和 667 行分别是 ENET1 和 ENET2 的复位 IO 配置参数。继续在文件 mx6ullatk.c 中找到函数 setup_iomux_fec,

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L88XFlmP-1675178748816)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.6.4-2-添加 I.MX6U-ALPHA 开发板网络复位引脚驱动.png)]

示例代码中第 676 行~679 行和第 685 行~688 行分别对应 ENET1 和 ENET2 的复位 IO 初始化,将这两个 IO 设置为输出并且硬件复位一下 LAN8720A,这个硬件复位很重要!否则可能导致 uboot 无法识别 LAN8720A。

1.6.5 修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link

大功基本上告成,还差最后一步, uboot 中的 LAN8720A 驱动有点问题,打开文件drivers/net/phy/phy.c,找到函数 genphy_update_link,这是个通用 PHY 驱动函数,此函数用于更新 PHY 的连接状态和速度。使用 LAN8720A 的时候需要在此函数中添加一些代码,修改后的函数 genphy_update_link 如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XNb4vNgD-1675178748816)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.6.5-1-修改函数 genphy_update_link.png)]

225 行~237 行就是新添加的代码,为条件编译代码段,只有使用 SMSC 公司的 PHY 这段代码才会执行(目前只测试了 LAN8720A, SMSC 公司其他的芯片还未测试)。第 229 行读取LAN8720A 的 BMCR 寄存器(寄存器地址为 0),此寄存器为 LAN8720A 的配置寄存器,这里先读取此寄存器的默认值并保存起来。 230 行向寄存器 BMCR 寄存器写入 BMCR_RESET(值为0X8000),因为 BMCR 的 bit15 是软件复位控制位,因此 230 行就是软件复位 LAN8720A,复位完成以后此位会自动清零。第 231~233 行等待 LAN8720A 软件复位完成,也就是判断 BMCR的 bit15 位是否为 1,为 1 的话表示还没有复位完成。第 234 行重新向 BMCR 寄存器写入以前的值,也就是 229 行读出的那个值。至此网络的复位引脚驱动修改完成,重新编译 uboot,然后将 u-boot.bin 烧写到 SD 卡中并启动。

1.7 修改uboot 启动信息 Board名字

在 uboot 启动信息中会有“Board: MX6ULL 14x14 EVK”这一句,也就是说板子名字为“ MX6ULL 14x14 EVK”,要将其改为我们所使用的板子名字,比如“ MX6ULL 14x14 ATK” 。打开文件 mx6ullatk.c,找到函数checkboard,将其做如下修改:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bOR4T2UK-1675178748817)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.7-1-uboot修改启动Board名字.png)]

修改完成以后重新编译 uboot 并烧写到 SD 卡中验证, uboot 启动信息如图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r0CLzfTX-1675178748818)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-1.7-2-uboot修改启动Board名字启动.png)]

可以看出, Board 变成了“MX6ULL ALIENTEK EMMC”。至此 uboot 的驱动部分就修改完成了, uboot 移植也完成了。

总结:一般 uboot 中需要解决串口、 NAND、 EMMC 或 SD 卡、网络和 LCD 驱动,因为 uboot的主要目的就是启动 Linux 内核,所以不需要考虑太多的外设驱动。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值