1.在U-Boot中驱动LCD和网络
在U-Boot 移植初探一文中介绍了如何修改 NXP官方uboot,使得 uboot能匹配我们自己的开发板,但是匹配完成后 LCD驱动和网络驱动还是不正常的,所以下面将介绍如何修改 LCD驱动和网络驱动等
1.1 LCD驱动修改
uboot 中修改驱动都是在对应板子的 .c文件和 .h文件中进行,即下面两个文件中:mx6ull_andyxi_emmc.c 和 mx6ull_andyxi_emmc.h
修改 LCD驱动重点注意以下几点:
- LCD的 IO配置是否正确
- LCD背光引脚 GPIO的配置
- LCD配置参数是否正确
我们使用的 I.MX6ULL开发板的 LCD原理图和 NXP官方的开发板一致,也就是LCD的IO和背光IO都是一样的, 所以IO部分就不用修改了,只需修改 LCD配置参数即可
mx6ull_andyxi_emmc.c 文件中修改下面内容:
/*######### 原始内容 ###############################*/
/*该代码定义了一个变量displays,类型为display_info_t,这个结构体
是LCD信息结构体,其中包括了LCD的分辨率,像素格式,LCD的各个参数等*/
struct display_info_t const displays[] = {{
.bus = MX6UL_LCDIF1_BASE_ADDR,
.addr = 0,
.pixfmt = 24,
.detect = NULL,
.enable = do_enable_parallel_lcd,
.mode = {
.name = "TFT43AB",
.xres = 480,
.yres = 272,
.pixclock = 108695,
.left_margin = 8,
.right_margin = 4,
.upper_margin = 2,
.lower_margin = 4,
.hsync_len = 41,
.vsync_len = 10,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED
} } };
/*######### 修改后的内容 ###########################*/
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, //HBPD
.right_margin = 160, //HFPD
.upper_margin = 20, //VBPD
.lower_margin = 12, //VFPD
.hsync_len = 20, //HSPW
.vsync_len = 3, //VSPW
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED
} } };
mx6ull_andyxi_emmc.h 文件中修改 panel值
panel=TFT7016 #根据具体使用型号修改
重新编译 uboot并烧写到 SD中启动后,若 LCD仍不能显示,则需要在uboot命令模式下,检查环境变量 panel的值,确保与 LCD参数里的 name一致
panel=TFT7016 #与mx6ull_andyxi_emmc.c中修改的名称保持一致
1.2 网络驱动修改
I.MX6UL/ULL 内部有个以太网 MAC外设,需要外接一个 PHY芯片来实现网络通信功能。 我们使用的 I.MX6U 开发板提供了这两个网络接口,都使用 LAN8720A 作为 PHY 芯片。 NXP 官方的I.MX6ULL EVK 开发板使用 KSZ8081 的 PHY 芯片。 下面将介绍更换了PHY 芯片以后如何调整网络驱动,使网络工作正常。
开发板 ENET1/ENET2的原理图如下示:
网络 PHY芯片LAN8720A,通过 RMII接口与 I.MX6ULL相连,引脚与 NXP官方的 I.MX6ULL EVK 开发板基本一样,只是复位引脚不同。 从上图可以看出,复位引脚ENET1_RST 接到了 I.M6ULL 的 SNVS_TAMPER7 引脚上,复位引脚 ENET2_RST 接到了 SNVS_TAMPER8 引脚上
修改网络驱动重点注意以下几点:
- LAN8720A复位引脚初始化
- LAN8720A的器件ID
- LAN8720A驱动
在 mx6ull_andyxi_emmc.c中添加复位引脚驱动
/* 结构体数组fec1_pads和fec2_pads是ENET1和ENET2这两个网口的IO
* 配置参数,在这两个数组中添加两个网口的复位 IO 配置参数 */
/*######### 原始内容 ###############################*/
staticiomux_v3_cfg_tconst 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),
};
staticiomux_v3_cfg_tconst 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),
};
/*######### 修改后的内容 ###########################*/
staticiomux_v3_cfg_tconst 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),//添加此行
};
staticiomux_v3_cfg_tconst 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),//添加此行
};
/* 函数 setup_iomux_fec 就是根据 fec1_pads 和 fec2_pads 这两个网络IO配置
数组来初始化I.MX6ULL的网络IO,此处需要在其中添加网络复位IO的初始化代码,
并且复位一下 PHY 芯片
*/
/*######### 原始内容 ###############################*/
staticvoidsetup_iomux_fec(int fec_id)
{
if(fec_id ==0)
imx_iomux_v3_setup_multiple_pads(fec1_pads,ARRAY_SIZE(fec1_pads));
else
imx_iomux_v3_setup_multiple_pads(fec2_pads, ARRAY_SIZE(fec2_pads));
}
/*######### 修改后的内容 ###########################*/
staticvoidsetup_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);
}
}
在 mx6ull_andyxi_emmc.h中修改 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 //用于选择使用哪个网卡,默认为1(ENET2)
#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x2 //ENET1的PHY地址,默认为0x2
#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 //ENET2的PHY地址,默认为0x1
#define CONFIG_FEC_XCV_TYPE RMII
#endif
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_PHYLIB
#define CONFIG_PHY_MICREL //用于使能Micrel公司的PHY驱动(KSZ8081芯片)
#endif
/*######### 修改后的内容 ###########################*/
#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 //修改ENET1的PHY地址为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 //修改ENET2的PHY地址为为0x1
#define CONFIG_FEC_XCV_TYPE RMII
#endif
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_PHYLIB
#define CONFIG_PHY_SMSC //使能SMSC公司的PHY驱动(LAN8720A是SMSC生产的)
#endif
在 mx6ull_andyxi_emmc.c中删除 74LV595的驱动代码
/* NXP 官方I.MX6ULL EVK 开发板使用74LV595来扩展 IO,两个网络的复位引脚
* 就是由74LV595来控制的,I.MX6U-ALPHA开发板并没有使用74LV595,因此删除掉
*/
/*######### 原始内容 ###############################*/
#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)
/*##### 修改后的内容:以上四行替换为以下两行 #######*/
/* ENET1 的复位引脚连接到 SNVS_TAMPER7 上,对应 GPIO5_IO07
* ENET2 的复位引脚连接到 SNVS_TAMPER8 上,对应 GPIO5_IO08
*/
#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)
//删除74LV595的IO配置参数结构体
/*######### 删除以下内容 ###############################*/
staticiomux_v3_cfg_tconst 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的初始化函数
/*######### 删除以下内容 ###############################*/
staticvoidiox74lv_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);
}
......
/*
* shift register will be output to pins
*/
gpio_direction_output(IOX_STCP,1);
};
//删除iox74lv_set函数(用于控制74LV595的IO输出电平)
/*######### 删除以下内容 ###############################*/
voidiox74lv_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);
}
......
/*
* shift register will be output to pins
*/
gpio_direction_output(IOX_STCP,1);
};
/* 删除板子初始化函数 board_init 中的74lv595 的GPIO初始化代码 */
/*######### 删除部分代码 ###############################*/
intboard_init(void)
{
......
imx_iomux_v3_setup_multiple_pads(iox_pads,ARRAY_SIZE(iox_pads));//删除此行
iox74lv_init(); //删除此行
......
return0;
}
在drivers/net/phy/phy.c 中的 genphy_update_link函数里,添加 SMSC的 PHY芯片条件编译代码段
/*######### 修改后的内容 ###########################*/
intgenphy_update_link(structphy_device*phydev){
unsignedint mii_reg;
//以下为添加的SMSC的PHY芯片条件编译代码段,只有使用SMSC的PHY才会执行
#ifdef CONFIG_PHY_SMSC
staticint 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);
......
return0;
}
至此网络的复位引脚驱动修改完成,重新编译 uboot,然后将 u-boot.bin 烧写到 SD 卡中并启动,uboot 启动信息如下图所示:
由上图可见当前使用FEC1这个网口(ENET2),但此时网络地址还没有设置。 在uboot使用网络之前还要先设置以下几个网络环境变量
setenv ipaddr 192.168.10.50 //开发板 IP 地址
setenv ethaddr b8:ae:1d:01:00:00 //开发板网卡 MAC 地址
setenv gatewayip 192.168.10.1 //开发板默认网关
setenv netmask 255.255.255.0 //开发板子网掩码
setenv serverip 192.168.10.100 //服务器地址,也就是 Ubuntu 地址
saveenv //保存环境变量
设置好环境变量以后就可以在 uboot 中使用网络了,用网线将开发板上的 ENET2与电脑连接起来,保证开发板和电脑在同一个网段内,通过 ping 命令来测试网络连接,命令如下:
ping 192.168.1.100
结果如下图示,说明ping 主机成功,至此说明ENET2网络工作正常
将 mx6ull_andyxi_emmc.h中的CONFIG_FEC_ENET_DEV参数改为 0,然后重新编译 uboot 并烧写到 SD 卡中重启,按以上步骤可以测试 ENET1 的网络是否正常工作
1.3 其他修改
在 uboot启动信息中会有“Board: MX6ULL 14x14 EVK”这一句,即板子名字为“ MX6ULL 14x14 EVK”,可将其改为我们自已的名字“ MX6ULL ANDYXI EMMC”
在mx6ull_andyxi_emmc.c中的checkboard函数里,做如下修改
/*######### 修改后的内容 ###########################*/
intcheckboard(void)
{
if(is_mx6ull_9x9_evk())
puts("Board: MX6ULL 9x9 EVK\\n");
else
puts("Board: MX6ULL ANDYXI EMMC\\n");
return0;
}
修改完成以后重新编译 uboot 并烧写到 SD 卡中验证,uboot 启动信息如下图,可见名字已经修改过来了
2.bootcmd和bootargs环境变量
uboot 中有两个非常重要的环境变量 bootcmd 和 bootargs,是采用类似 shell 脚本语言编写的,里面有很多 NXP自己定义的的环境变量引用
文件 mx6ull_andyxi_emmc.h中的
宏CONFIG_EXTRA_ENV_SETTINGS 保存着这些环境变量的默认值,其内容如下:
#if defined(CONFIG_SYS_BOOT_NAND)
#defineCONFIG_EXTRA_ENV_SETTINGS\\
CONFIG_MFG_ENV_SETTINGS \\
"panel=TFT43AB\\0"\\
"fdt_addr=0x83000000\\0"\\
"fdt_high=0xffffffff\\0"\\
......
"bootz ${loadaddr} - ${fdt_addr}\\0"
#else
#defineCONFIG_EXTRA_ENV_SETTINGS\\
CONFIG_MFG_ENV_SETTINGS \\
"script=boot.scr\\0"\\
"image=zImage\\0"\\
"console=ttymxc0\\0"\\
"fdt_high=0xffffffff\\0"\\
"initrd_high=0xffffffff\\0"\\
"fdt_file=undefined\\0"\\
......
"findfdt="\\
"if test $fdt_file = undefined; then " \\
"if test $board_name = EVK && test $board_rev = 9X9; then " \\
"setenv fdt_file imx6ull-9x9-evk.dtb; fi; " \\
"if test $board_name = EVK && test $board_rev = 14X14; then " \\
"setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \\
"if test $fdt_file = undefined; then " \\
"echo WARNING: Could not determine dtb to use; fi; " \\
"fi;\\0" \\
2.1 bootcmd环境变量
bootcmd 保存着 uboot 默认命令, uboot 倒计时结束后就会执行其中的命令。 一般是用来启动内核的,比如读取 EMMC或 NAND Flash中的内核镜像文件和设备树文件到 DRAM中,然后启动内核
可在 uboot启动后进入命令行设置 bootcmd环境变量的值。 如果 EMMC或者 NAND中没有保存 bootcmd的值,那么 uboot就会使用默认值,板子第一次运行 uboot 时都会使用默认值来设置 bootcmd 环境变量
打开文件 include/env_default.h,在此文件中有如下所示内容:
......
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS "\\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND "\\0"
#endif
......
env_default.h中指定了很多环境变量的默认值,比如 bootcmd 的默认值是CONFIG_BOOTCOMMAND,bootargs的是 CONFIG_BOOTARGS。 我们可在mx6ull_andyxi_emmc.h 文件中通过设置宏 CONFIG_BOOTCOMMAND来设置 bootcmd 的默认值, NXP官方设置的 CONFIG_BOOTCOMMAND 值如下:
#defineCONFIG_BOOTCOMMAND\\
"run findfdt;"\\
"mmc dev ${mmcdev};"\\
"mmc dev ${mmcdev}; if mmc rescan; then "\\
"if run loadbootscript; then "\\
"run bootscript; "\\
"else "\\
"if run loadimage; then "\\
"run mmcboot; "\\
"else run netboot; "\\
"fi; "\\
"fi; "\\
"else run netboot; fi"
2.2 bootargs环境变量
bootargs 保存着 uboot 传递给 Linux 内核的参数,以下面命令为例
setenv bootargs console= ttymxc0, 115200 root= /dev/mmcblk1p2 rootwait rw
bootargs 中常用的参数有:
- console:用来设置 linux终端,即通过什么设备来和 Linux进行交互,是串口还是 LC 屏幕,一般设置串口作为 Linux终端,这样就可以在电脑上通过串口助手来和 linux进行交互了
console= ttymxc0, 115200
//console 为 ttymxc0,因为 linux启动以后I.MX6ULL的串口1
//在linux下的设备文件就是/dev/ttymxc0
//ttymxc0 后面的“115200”,是设置串口的波特率
- root:用来设置根文件系统的位置
root= /dev/mmcblk1p2 rootwait rw
// /dev/mmcblk1p2用于指明根文件系统存放在mmcblk1设备的分区2中
// /dev/mmcblkxpy(x=0~ n,y=1~ n)表示mmc设备x的分区y
// rootwait表示等待mmc设备初始化完成以后再挂载,否则的话会出错
// rw 表示根文件系统是可以读写的,不加rw的话可能只能读而无法进行写操作
- rootfstype:一般与root一起使用, 用于指定根文件系统类型,如果根文件系统为ext 格式的话此选项无所谓。 如果根文件系统是 yaffs、 jffs 或 ubifs 的话就需要设置此选项,指定根文件系统的类型
3.U-Boot启动Linux测试
uboot 已经移植好后,就要测试一下 uboot 能不能完成它的工作:启动 Linux 内核。 这里测试两种启动 Linux 内核的方法,一种是直接从 EMMC 启动,一种是从网络启动
3.1 从EMMC启动Linux
从 EMMC 启动也就是将编译出来的 Linux 镜像文件 zImage 和设备树文件保存在 EMMC中, uboot 从 EMMC 中读取这两个文件并启动,这个是产品最终的启动方式。 此处默认已经将 zImage 文件和设备树文件烧写到了 EMMC 中,可以直接读取来进行测试
使用命令“ls mmc 1:1”检查 EMMC 的分区 1 中是否已有相关文件,下图结果表示已有相关文件
设置 bootargs 和 bootcmd 这两个环境变量
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000
imx6ull-andyxi-emmc.dtb; bootz 80800000 - 83000000;'
saveenv
输入“boot”命令,启动内核即可
3.2 从网络启动Linux
从网络启动 linux系统的唯一目的就是为了调试! 不管是为了调试 linux系统还是 linux下的驱动,每次修改 linux系统文件或者 linux下的某个驱动后都要将其烧写到 EMMC 中去测试,这样太麻烦了。 可以设置从网络启动,将 linux镜像文件和根文件系统都放到 Ubuntu下指定的文件夹中,这样每次重新编译 linux内核或者 linux驱动后只需要将其拷贝到这个指定的文件夹中即可,这样就无需频繁的烧写 EMMC
可以通过 nfs或者 tftp从 Ubuntu中下载 zImage和设备树文件,本文使用 tftp从 Ubuntu中下载 zImage和设备树文件,默认已经将 zImage和设备树文件放到 Ubuntu下的 tftp目录中
设置 bootargs 和 bootcmd 这两个环境变量
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-andyxi-emmc.dtb; bootz
80800000 - 83000000'
saveenv
输入“boot”命令,启动内核,下图结果表示内核启动成功
4.U-Boot移植总结
uboot 移植到此结束,简单总结一下 uboot 移植的过程:
- 不管是购买的还是自己做的开发板,基本都是参考半导体厂商的 dmeo板,半导体厂商会在他们的开发板上移植好 uboot、kernel和 rootfs等,最终制作好 BSP包提供给用户。 我们可在官方提供的 BSP包的基础上添加自已的板子,即俗称的移植
- 购买的或者自己做的开发板一般不会原封不动的照抄半导体厂商的 demo板,都会根据实际情况来做修改,有修改就会涉及到 uboot下驱动的移植
- 一般 uboot中需要解决串口、NAND、EMMC或 SD卡、网络和 LCD动,因为 uboot的主要目的是启动 Linux内核,所以不用考虑太多的外设驱动
- 在 uboot中添加自己的开发板信息,并根据实际情况来修改 uboot中的驱动
-
NXP
+关注
关注
60文章
1267浏览量
183182 -
lcd
+关注
关注
34文章
4411浏览量
167041 -
Linux
+关注
关注
87文章
11219浏览量
208872 -
u-boot
+关注
关注
0文章
120浏览量
38195 -
开发板
+关注
关注
25文章
4933浏览量
97159
发布评论请先 登录
相关推荐
评论