以下内容来自:正点原子Linux驱动文档
一、简介
uboot移植主要是根据原厂的uboot移植:芯片厂商通常会做一块自己的评估板并发布BSP,当我们需要定制自己的开发板时可以根据自己的需求(硬件上的不同),对原厂的uboot裁剪等等。
注:BSP 通常包含uboot、Linux内核、设备树。
nxp官方imx6ull uboot 试编译
编译一个uboot工程主要有以下3条命令:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean #清理工程
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig #根据配置文件配置uboot
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 #编译uboot,j16 表示用16核编译
ARCH: 架构。
CROSS_COMPILE: 交叉编译器。
编译后会生成uboot.bin 等等文件。
使用imx6ull 官方uboot启动我们的板子会有些驱动存在问题,这是应为硬件的不同。例如LCD、网络等。
在uboot中添加自定义开发板
添加开发板默认配置文件
uboot 除了引导 Linux 以外还可以引导其它的系统,而且 uboot 还支持其它的架构和外设,比如 USB、 网络、 SD 卡等。
所以在编译前我们要根据自己的需求配置uboot。
在configs 目录下有很多配置文件,可想而知,每一个配置文件就对应一块开发板。
我们找到 mx6ull_14x14_evk_emmc_defconfig, 这是nxp官方的配置文件,我们就是参考它做修改。
拷贝并修改:
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_zjh_emmc_defconfig
添加自己开发板的头文件
在include/configs 下拷贝mx6ullevk.h 并修改。
在这个头文件中有许多宏定义,这些宏基本用于配置uboot,也有一些I.MX6ULL 的配置项目。
如果我们想要禁用uboot的某些功能,在这个头文件中修改即可。
mx6ullevk.h 文件中基本都是“CONFIG_”开头的宏定义,这也说明 mx6ull_alientek_emmc.h 文件的主要功能就是配置或者裁剪 uboot。如果需要某个功能的话就在里面添加这个功能对应的 CONFIG_XXX 宏即可,如果不需要某个功能的话就删除掉对应的宏即可。
mx6ullevk.h 中包含了 mx6_common.h,如果没有在mx6ullevk.h中发现某个功能或命令,但uboot中又确实存在,可以去mx6_common.h 中寻找。
- 设置DRAM大小: 宏PHYS_SDRAM_SIZE 是用来设置DRAM 大小。正点原子的 I.MX6U-ALPHA 开发板用的是 512MB DDR3。
- 输出cpu信息: 定义宏 CONFIG_DISPLAY_CPUINFO, uboot 启动的时候可以输出 CPU 信息。
- 输出板子信息: 定义宏 CONFIG_DISPLAY_BOARDINFO, uboot 启动的时候可以输出板子信息。
- 设置内存池大小: CONFIG_SYS_MALLOC_LEN 为 malloc 内存池大小,这里设置为 16MB。
- 定义宏 CONFIG_BOARD_EARLY_INIT_F,这样 board_init_f 函数就会调用board_early_init_f 函数。
- 定义宏 CONFIG_BOARD_LATE_INIT,这样 board_init_r 函数就会调用board_late_init 函数。
- 使能 I.MX6ULL 的串口功能: 宏 CONFIG_MXC_UART_BASE 表示串口寄存器基地址,这里使用的串口 1,基地址为 UART1_BASE, UART1_BASE 定义在文件arch/arm/include/asm/arch-mx6/imx-regs.h 中, imx-regs.h 是 I.MX6ULL 寄存器描述文件。
- 。。。。(太多了,放弃,看原子驱动文档)
- 控制I2C: 用于控制使能哪个 I2C, I2C 的速度为多少。
- NAND 的分区设置: CONFIG_SYS_BOOT_NAND
- 宏 CONFIG_MFG_ENV_SETTINGS 定义了一些环境变量,使用 MfgTool 烧写系统时候会用到这里面的环境变量。
- 通 过 条 件 编 译 来 设 置 宏 CONFIG_EXTRA_ENV_SETTINGS , 宏CONFIG_EXTRA_ENV_SETTINGS 也是设置一些环境变量,此宏会设置 bootargs 这个环境变量。
- 设置宏 CONFIG_BOOTCOMMAND ,此宏就是设置环境变量 bootcmd 的值。
- CONFIG_SYS_LOAD_ADDR: 表示 linux kernel 在 DRAM 中的加载地址,也就是 linux kernel 在 DRAM 中的存储首地址, CONFIG_LOADADDR=0X80800000。
- 时钟频率: 宏 CONFIG_SYS_HZ 为系统时钟频率,这里为 1000Hz。
- 栈大小 宏 CONFIG_STACKSIZE 为栈大小,这里为 128KB。
- DRAM首地址: CONFIG_SYS_SDRAM_BASE 为 DRAM 的起始地址。
- 宏 CONFIG_SYS_INIT_SP_OFFSET 和 CONFIG_SYS_INIT_SP_ADDR 与初始 SP 有关,第一个为初始 SP 偏移,第二个为初始 SP 地址。
- 宏 CONFIG_MMCROOT 设置进入 linux 系统的根文件系统所在的分区 ,这里设置为"/dev/mmcblk1p2",也就是 EMMC 设备的第 2 个分区。第 0 个分区保存 uboot,第 1 个分区保存 linux 镜像和设备树,第 2 个分区为 Linux 系统的根文件系统。
- 网络相关: CONFIG_CMD_NET,比如使能ping、dhcp等功能。
- 指定网口: CONFIG_FEC_ENET_DEV ,指定 uboot 所使用的网口, I.MX6ULL 有两个网口,为 0 的时候使用 ENET1,为 1 的时候使用 ENET2。
- 第 344~END,剩下的都是一些配置宏,比如 CONFIG_VIDEO 宏用于开启 LCD,CONFIG_VIDEO_LOGO 使能 LOGO 显示, CONFIG_CMD_BMP 使能 BMP 图片显示指令。这样就可以在 uboot 中显示图片了,一般用于显示 logo。
- CONFIG_CMD 开头的宏都是用于使能相应命令的,其他的以 CONFIG 开头的宏都是完成一些配置功能的。
添加开发板对应的板级文件夹
uboot中每一块板子都拥有一个板级文件夹,用来存放板级文件。比如开发板上的外设驱动文件等。
NXP 的 I.MX 系列芯片的所有板级文件夹都存放在 board/freescale 目录下,imx6ull 对应的板级文件夹是mx6ullevk。同样备份重命名。
进 入 mx6ull_alientek_emmc 目 录 中 , 将 其 中 的 mx6ullevk.c 文 件 重 命 名 为mx6ull_alientek_emmc.c
1、修改板级文件夹目录下的 Makefile 文件
将文件名修改为刚刚改的文件,这样才会编译mx6ull_zjh_emmc.c这个文件。
2、修改 imximage.cfg 文件
PLUGIN 这一项路径改成我们自己文件夹的路径。
3、修改 Kconfig 文件
4、修改 MAINTAINERS 文件
修改 U-Boot 图形界面配置文件
uboot 是支持图形界面配置,关于 uboot 的图形界面配置下一章会详细的讲解。修改文件arch/arm/cpu/armv7/mx6/Kconfig,在207行加入如下内容:
config TARGET_MX6ULL_ZJH_EMMC
bool "Support mx6ull_zjh_emmc"
select MX6ULL
select DM
select DM_THERMAL
在最后一行的 endif 的前一行添加如下内容:
source "board/freescale/mx6ull_zjh_emmc/Kconfig"
开发板添加完成,接下来就是编译这个uboot。
LCD 驱动修改
一般 uboot 中修改驱动基本都是在 xxx.h 和 xxx.c 这两个文件中进行的, xxx 为板子名称,比如 mx6ull_alientek_emmc.h 和 mx6ull_alientek_emmc.c 这两个文件。
一般修改 LCD 驱动重点注意以下几点:
①、 LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。
②、 LCD 背光引脚 GPIO 的配置。
③、 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
} } };
如上所示,在板级文件夹mx6ull_zjh_emmc/mx6ull_zjh_emmc.c中定义了变量 displays,类型为 display_info_t,这个结构体是 LCD信息结构体,其中包括了 LCD 的分辨率,像素格式, LCD 的各个参数等。display_info_t 定义在文件 arch/arm/include/asm/imx-common/video.h 中,定义如下:
struct display_info_t {
int bus;
int addr;
int pixfmt; //像素格式的位数,如RGB888 就是24位
int (*detect)(struct display_info_t const *dev);
void (*enable)(struct display_info_t const *dev);
struct fb_videomode mode;
};
结构体 display_info_t 中还有个 mode 成员变量,此成员变量也是个结构体,为 fb_videomode,定义在文件 include/linux/fb.h 中,定义如下:
struct fb_videomode {
const char *name; /* LCD 名字,要和环境变量中的 panel 相等。 */
u32 refresh;
u32 xres; /* LCD X 轴和 Y 轴像素数量。 */
u32 yres;
u32 pixclock; /* 像素时钟,每个像素时钟周期的长度,单位为皮秒。 */
u32 left_margin;
u32 right_margin;
u32 upper_margin;
u32 lower_margin;
u32 hsync_len;
u32 vsync_len;
u32 sync;
u32 vmode;
u32 flag;
};
总结
①、不管是购买的开发板还是自己做的开发板,基本都是参考半导体厂商的 dmeo 板,而半导体厂商会在他们自己的开发板上移植好 uboot、linux kernel 和 rootfs 等,最终制作好 BSP包提供给用户。
我们可以在官方提供的 BSP 包的基础上添加我们的板子,也就是俗称的移植。
②、我们购买的开发板或者自己做的板子一般都不会原封不动的照抄半导体厂商的 demo板,都会根据实际的情况来做修改,既然有修改就必然涉及到 uboot 下驱动的移植。
③、一般 uboot 中需要解决串口、NAND、EMMC 或 SD 卡、网络和 LCD 驱动,因为 uboot的主要目的就是启动 Linux 内核,所以不需要考虑太多的外设驱动。
④、在 uboot 中添加自己的板子信息,根据自己板子的实际情况来修改 uboot 中的驱动。