一,移植步骤
1.添加开发板默认配置文件:***_defconfig
在configs目录下,复制并修改mx6ull_14x14_evk_defconfig。需要修改CONFIG_SYS_EXTRA_OPTIONS,这个变量指向了板子的配置文件,定义一个宏:CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC,特别注意这个CONFIG_后面的内容要和板子配置文件MAINTAINERS第一行要一致,也要与arch/arm/cpu/armv7/mx6/Kconfig中uBoot图形界面声明的一致。第一行MX6ULL_EVK_EMMC_REWORK在板子文件夹的配置文件*.c中演变为#define CONFIG_MX6ULL_EVK_EMMC_REWORK,相当于给.C文件传递了一个宏定义,文件中其它的CONFIG_*并未发现。
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_alientek_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK" CONFIG_ARM=y CONFIG_ARCH_MX6=y CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC2=y CONFIG_CMD_GPIO=y
2.添加开发板对应的头文件:mx6ull_*.h
在include/configs/下,复制并修改mx6ullevk.h。 需要修#ifndef __MX6ULLEVK_CONFIG_H #define __MX6ULLEVK_CONFIG_H 头文件宏,这个文件便是以后给uBoot增加,删除功能的核心文件,这个文件名字要和MAINTAINERS对应,
3.添加开发板对应的板级文件夹:mx6ull*
在board/freescale下,复制并修改mx6ullevk。需要修改imximage.cfg,Kconfig,MAINTAINERS,Makefile,*.c文件。相关修改见注释.imximage.cfg包含裸机/uboot开发,寄存器初始值设置,imxdownload 命令就是把相关信息添加到bin头部
2.8K 2月 22 15:24 imximage.cfg #名字不需要修改,但是要修改PLUGIN,让它指向板子的文件夹,**_defconfg的指向文件 3.2K 2月 22 17:23 imximage.cfg.cfgtmp 2.8K 2月 22 15:14 imximage_lpddr2.cfg 186 2月 22 17:11 Kconfig #重要见下面解析 158 2月 22 17:23 MAINTAINERS #名字不需要修改,好像不影响,见下面解析 247 2月 22 17:09 Makefile #名字不需要修改,但是要配置lib-y:=*.c。这个C文件时板子下的唯一.C文件 30K 2月 22 15:14 mx6ull_alientek_emmc.c #名字要修改注意和Makefile名字要一致 5.0K 2月 22 15:14 plugin.S 716 2月 22 15:14 README #Kconfig 配置文件与 arch/arm/cpu/armv7/mx6/Kconfig 的source 目标一致 if TARGET_MX6ULL_ALIENTEK_EMMC2 #和**_defconfg后半部分要一致 config SYS_BOARD default "mx6ull_alientek_emmc" #与板子文件夹名字(board/freescale/mx6ull_alientek_emmc)要一致 config SYS_VENDOR default "freescale" #与板子文件夹父文件夹(board/freescale)名字一致 config SYS_CONFIG_NAME default "mx6ull_alientek_emmc" #与板子配置文件(include/configs/*.h)名字一致 endif #Kconfig 配置文件,但是胡乱修改没有出问题 MX6ULL_ALIENTEK_EMMC BOARD #和**_defconfg后半部分要一致 M: Peng Fan <peng.fan@nxp.com> S: Maintained F: board/freescale/mx6ull_alientek_emmc3/ #与板子文件夹父文件夹(board/freescale)名字一致 F: include/configs/mx6ull_alientek_emmc9.h#与板子配置文件(include/configs/*.h)名字一致
4.修改 U-Boot 图形界面配置文件
文件位于:arch/arm/cpu/armv7/mx6/Kconfig,需要增加几行:
195 config TARGET_MX6ULL_14X14_EVK 196 bool "Support mx6ull_14x14_evk" 197 select MX6ULL 198 select DM 199 select DM_THERMAL 200 201 config TARGET_MX6ULL_ALIENTEK_EMMC #和**_defconfg后半部分要一致 202 bool "Support mx6ull_alientek_emmc" 203 select MX6ULL 204 select DM 205 select DM_THERMAL 269 source "board/freescale/mx6ull_alientek_emmc/Kconfig" #注意要和板子文件位置一致
二.uBoot启动流程
汇编文件arch/arm/cpu/u-boot.lds 引导了uBoot的整个过程
#include <config.h> OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) //定义了程序入口:ENTRY(_start) arch/arm/lib/vectors.S SECTIONS { #if defined(CONFIG_ARMV7_SECURE_BASE) && defined(CONFIG_ARMV7_NONSEC) /DISCARD/ : { *(.rel._secure*) } #endif . = 0x00000000; . = ALIGN(4); .text : { *(.__image_copy_start) //从u-boot.map 可以获知链接地址是0X87800000 也是.text起始地址 *(.vectors) CPUDIR/start.o (.text*) *(.text*) } #ifdef CONFIG_ARMV7_NONSEC #ifndef CONFIG_ARMV7_SECURE_BASE #define CONFIG_ARMV7_SECURE_BASE #endif .__secure_start : { . = ALIGN(0x1000); *(.__secure_start) } .secure_text CONFIG_ARMV7_SECURE_BASE : AT(ADDR(.__secure_start) + SIZEOF(.__secure_start)) { *(._secure.text) } . = LOADADDR(.__secure_start) + SIZEOF(.__secure_start) + SIZEOF(.secure_text); __secure_end_lma = .; .__secure_end : AT(__secure_end_lma) { *(.__secure_end) LONG(0x1d1071c); /* Must output something to reset LMA */ } #endif . = ALIGN(4); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } . = ALIGN(4); .data : { *(.data*) } . = ALIGN(4); . = .; . = ALIGN(4); .u_boot_list : { KEEP(*(SORT(.u_boot_list*))); } . = ALIGN(4); .image_copy_end : { *(.__image_copy_end) } .rel_dyn_start : { *(.__rel_dyn_start) } .rel.dyn : { *(.rel*) } .rel_dyn_end : { *(.__rel_dyn_end) } .end : { *(.__end) } _image_binary_end = .; . = ALIGN(4096); .mmutable : { *(.mmutable) } /* * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c * __bss_base and __bss_limit are for linker only (overlay ordering) */ .bss_start __rel_dyn_start (OVERLAY) : { KEEP(*(.__bss_start)); __bss_base = .; } .bss __bss_base (OVERLAY) : { *(.bss*) . = ALIGN(4); __bss_limit = .; } .bss_end __bss_limit (OVERLAY) : { KEEP(*(.__bss_end)); } .dynsym _image_binary_end : { *(.dynsym) } .dynbss : { *(.dynbss) } .dynstr : { *(.dynstr*) } .dynamic : { *(.dynamic*) } .plt : { *(.plt*) } .interp : { *(.interp*) } .gnu.hash : { *(.gnu.hash) } .gnu : { *(.gnu*) } .ARM.exidx : { *(.ARM.exidx*) } .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) } }
1.arch/arm/cpu/u-boot.lds //定义了程序入口:ENTRY(_start)
由上可知程序入口点是arch/arm/lib/vectors.S 中的_start
……………………
过程太复杂了详见32章,最终调用了arch/arm/lib/crt0.S 中的_main:
_main会调用board_init_f、relocate_code、relocate_vectors 和 board_init_r 四个重要函数
board_init_f 此函数定义在文件 common/board_f.c 中定义 关键代码:if (initcall_run_list(init_sequence_f)) 这个会初始化一系列外设,比如串口、定时器,或者打印一些消息等。 详见32.2.5,
三.移植后修改驱动
因为上面的的移植实际上是复制了NXP EVK开发板子NXP 官方 I.MX6ULL EVK 开发板配置,EVK的开发板和自己的开发板可能某些外设驱动不一样,需要修改。 uboot 在正点原子 EMMC 版本 I.MX6ULL开发板上的运行情况:
①、uboot 启动正常,DRAM 识别正确,SD 卡和 EMMC 驱动正常。
②、uboot 里面的 LCD 驱动默认是给 4.3 寸 480×272 分辨率的,如果使用的其他分辨率的屏幕需要修改驱动。
③、网络不能工作,识别不出来网络信息,需要修改驱动。
接下来我们要做的工作如下:
①、前面我们一直使用着 NXP 官方开发板的 uboot 配置,接下来需要在 uboot 中添加我们自己的开发板,也就是正点原子的 I.MX6ULL 开发板。
②、解决 LCD 驱动和网络驱动的问题。
1.LCD驱动问题
一般 uboot 中修改驱动基本都是在 xxx.h 和 xxx.c 这两个文件中进行的,xxx 为板子名称,比如 mx6ull_alientek_emmc.h 和 mx6ull_alientek_emmc.c 这两个文件。一般修改 LCD 驱动重点注意以下几点:
①、LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。
②、LCD 背光引脚 GPIO 的配置。
③、LCD 配置参数是否正确。
正点原子的 I.MX6U-ALPHA 开发板 LCD 原理图和 NXP 官方 I.MX6ULL 开发板一致,也就是 LCD 的 IO 和背光 IO 都一样的,所以 IO 部分就不用修改了。需要修改的之后 LCD 参数,打开文件 mx6ull_alientek_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 = "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 } } };
2.DDR配置
uboot启动的时候用到了ddr,但是arm必须根据ddr的实际情况 在启动的时候初始化某些寄存器的值才能够使用ddr,imxdownload 就是在bin文件前增加IVT bootdata DCD 等头部信息,需要用链接工具完成DDR参数的测定,否则ddr用不了需要ddr_stress_tester_v3.00_setup.exe 还需要一个excel表格用于计算DDR初始寄存器值,根据ddr芯片手册配置好Excel如下图:
配置完毕后,打开第三个选项卡会发现寄存器配置信息,这个文件信息与板级文件下的imximage.cfg 完全一致!!!!也与imxdownload的添加的头一致!!!注意第三个选项卡下面有4个选项是红色的,那就是需要用ddr工具测试出来的几个寄存器参数!!这个与BOM相关,DDR走线变了就要重新测试
3.变量参数定义
开发版板级文件中的*.h,定义了大量的宏,这些宏一部分用来定义一些变量,一部分定义CONDIG_*。所有的环境变量都存在include/env_default.h的一个const uchar default_environment数组中,其存储格式是:var1=value,para\0var2=var21=value\0,变量都是以\0作为结束符,在板级*.c文件可以调用setenv来设置变量,研究头文件include/env_default.h 引用了板级文件*.h然后定义了最终的环境变量。include/env_default.h含有大量的如下的宏:
#ifdef CONFIG_EXTRA_ENV_SETTINGS CONFIG_EXTRA_ENV_SETTINGS #endif
而这些宏恰好是在板级*.h文件中定义的。还可以在板级的*.c文件中调用setenv函数定义环境变量