使用的开发板:正点原子ALPHA V2.2
- Uboot简介
在学习STM32的过程中使用过IAP在线升级就会知道,有引导程序+APP程序,即bootloader程序+APP。在学习嵌入式Linux的时候也一样,这个引导程序就是Uboot.
uboot移植主要是根据原厂的uboot移植:芯片厂商通常会做一块自己的评估板并发布BSP,我们使用的就是NXP官方的评估板的Uboot进行裁剪,修改得来我们自己板子的程序。
本次使用的是NXP
官方原版的
uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
首先把文件原版的Uboot文件拷贝到Ubuntu下并且解压
tar xf uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2 -C ./
解压了之后我们需要看一下配置文件,需要再配置文件里面配置我们的Uboot,这个配置文件就在configs目录下,我们进入configs目录下。
在这一个目录下我们可以看到有很多defconfig结尾的文件,这些就是Uboot每对应一个板子的一个配置文件。由于使用的是正点原子的开发板,使用的是mx6ull_14x14_evk_emmc_defconfig这一个配置文件。找到我们这个配置文件后我们就可以对他进行编译了。
首先清理一下工程
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
对目标的配置进行编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4
然后make进行编译
在这里我们可以看到生成了u-boot.bin和 u-boot.imx文件。
下面我们烧录进开发板里面看看。
我们使用 imxdownload 软件将 u-boot.bin烧写到 SD 卡中
把SD卡插上电脑
查找自己的设备,我这里是/dev/sdb ,切记烧录的时候不可以用/dev/sda 否则Ubuntu就开不了机了!!!
chmod 777 imxdownload
./imxdownload u-boot.bin /dev/sdb //切记不可以使用/dev/sda
然后插SD卡到板子上。
用xshell连接板子。可以看到Uboot已经成功启动了。
但是启动是启动了,但是这时候屏幕和网络无法使用,因为我使用的这款正点原子的开发板驱动和uboot默认的屏幕不一样,因此我们需要修改驱动。
下面开始移植我们自己板子的uboot
首先就是配置文件,我们打开uboot的配置文件目录
在configs 目录下有很多配置文件,可想而知,每一个配置文件就对应一块开发板。
我们找到 mx6ull_14x14_evk_emmc_defconfig, 这是nxp官方的配置文件,我们就是参考它做修改。
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_myuboot_emmc_defconfig
然后复 制
include/configs/mx6ullevk.h,并重命名为 mx6ull_myuboot_emmc.h:
cp mx6ullevk.h mx6ull_myuboot_emmc.h
把mx6ull_myuboot_emmc.h文件的相关配置改成我们自己的。
文件中基本都是“CONFIG_”开头的宏定义,这也说明这个文件的主要功能就是配置或者裁剪 uboot。如果需要某个功能的话就在里面添加这个功能对应的 CONFIG_XXX 宏即可,如果不需要某个功能的话就删除掉对应的宏即可。
添加开发板对应的板级文件夹
进入board/freescale/目录下
cp mx6ullevk/ -r mx6ull_myuboot_emmc
然后进入mx6ull_myuboot_emmc目录修改相应文件的名字
mv mx6ullevk.c mx6ull_myuboot_emmc.c
我们改了c文件后,我们需要更改Mainfile文件
同时修改 imximage.cfg 中的下面一句改成自己的目录
修改Kconfig文件
if TARGET_MX6ULL_MYUBOOT_EMMC
config SYS_BOARD
default "mx6ull_myuboot_emmc"
config SYS_VENDOR
default "freescale"
config SYS_SOC
default "mx6"
config SYS_CONFIG_NAME
default "mx6ull_myuboot_emmc"
endif
修改 MAINTAINERS 文件
MX6ULLEVK BOARD
M: Peng Fan <peng.fan@nxp.com>
S: Maintained
F: board/freescale/mx6ull_myuboot_emmc/
F: include/configs/mx6ull_myuboot_emmc.h
uboot 是支持图形界面配置,修改 U-Boot 图形界面配置文件
到此,已经移植好了,下面我们还需要修改LCD驱动和网络驱动。
打开mx6ull_myuboot_emmc.c文件
修改LCD驱动
找到mx6ull_myuboot_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 = "ATK4384",
.xres = 800,
.yres = 480,
.pixclock = 32258,
.left_margin = 88,
.right_margin = 40,
.upper_margin = 32,
.lower_margin = 13,
.hsync_len = 48,
.vsync_len = 3,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED
} } };
下一步注释掉lcd_pads里面的LCD复位
找到do_enable_parallel_lcd函数注释啊掉复位的相关代码
然后找到 mx6ull_myuboot_emmc.h里面的
"panel=AFT43AN\0"改为
“panel=ATK4384\0”
修改网络驱动
网络 PHY 地址修改
修改mx6ull_myuboot_emmc.h 的代码
#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
更改好网络PHY芯片地址后我们修改复位引脚,因为官方的Uboot使用74LV595进行扩展IO但是我们的开发板并没有这东西。而是直接接到了IO口,因此我们需要修改驱动
找到以下代码注释掉这是芯片 74LV595的芯片引脚IO
然后加入我们自己的
#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)
同时删掉 74LV595 的 IO 配置参数结构体,将其删除掉。
接着删掉74LV595的初始化函数
void iox74lv_init(void)
void iox74lv_set(int index)
找到 board_init 函数,此函数是板子初始化函数,会被
board_init_r 调用,board_init 函数内容如下:
删掉 以下代码
imx_iomux_v3_setup_multiple_pads(iox_pads, ARRAY_SIZE(iox_pads));
iox74lv_init();
在这里插入图片描述
接下来就是添加 I.MX6U-ALPHA 开发板两个网络复位引脚了
找到fec1_pads 和 fec2_pads
MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)
MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
修改setup_iomux_fec为如下
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
在函数加入以下代码
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;
}
在此LCD驱动和网络驱动已经修改完成了
我们来编译验证一下!!
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_myuboot_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4
编译完成。
最后烧录进行SD卡
./imxdownload u-boot.bin /dev/sdb
屏幕亮起,说明屏幕驱动OK
然后设置板子的网络参数
setenv ipaddr 192.168.1.55 //开发板 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.250 //服务器地址,也就是 Ubuntu 地址
saveenv //保存环境变量
最后测试网络连接
网络时通的!!说明网络驱动OK。