资料来源正点原子嵌入式LINUX
目录
驱动修改步骤
添加开发板默认配置文件
添加开发板对应头文件
添加开发板对应的板级文件夹
修改U-boot图形配置文件
添加脚本编译U-boot
LCD 驱动修改
网络驱动修改
bootcmd 和 bootargs 环境变量
bootcmd
bootargs
实际使用中,移植的都是参考NXP官方开发板的U-boot进行移植。
直接编译官方的U-Boot,可以在正点原子开发板上运行,MMC1 SD卡与MMC2 EMMC运行正常,但是其他一些驱动,比如LCD,网络等配置不正常,所以需要修改U-boot。
复制修改configs下的默认配置文件mx6ull_14x14_evk_emmc_defconfig,将所有evk信息都修改为emmc
复制修改include/configs/mx6ullevk.h(官方evk开发板定义的头文件),将evk信息修改为mx6ull_alientek_emmc.h,并且修改头文件里面相关evk信息
在board/freescale中修改复制开发板mx6ullevk为mx6ull_alientek_emmc。
修改mx6ull_alientek_emmc中makefile中的obj-y
修改mx6ull_alientek_emmc中的imximage.cfg
修改mx6ull_alientek_emmc中的Kconfig
修改mx6ull_alientek_emmc中的MAINTAINERS
修改arch/arm/cpu/armv7/mx6/Kconfig添加正点原子开发板信息
在在 uboot 根目录下新建一个名为 mx6ull_alientek_emmc.sh 的 shell 脚本,用来编译
1 #!/bin/bash
2 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
3 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihfmx6ull_alientek__emmc_defconfig
4 make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
到此,U-boot已经可以正常启动,但是还需要修改LCD与网络等驱动
U-boot驱动都是在mx6ull_alientek_emmc.h 和 mx6ull_alientek_emmc.c中进行,正点原子开发板的LCD与NXP官方EVK开发板的LCD的IO口都是一致的,仅需要修改LCD的参数
在struct display_info_t const displays[]中修改LCD参数
正点原子的 I.MX6U-ALPHA 开发板提供了这两个网络接口,其中 ENET1 和 ENET2 都使用 LAN8720A 作为 PHY 芯片。
在mx6ull_alientek_emmc.h中修改相关参数与引脚配置
Uboot中有两个重要的环境变量bootcmd 和 bootargs ,bootcmd主要用于启动linux,bootargs主要用于uboot向Liunx传递一些参数信息。
在mx6ull_alientek_emmc.h中有以下定义:
#define CONFIG_BOOTCOMMAND \//加载镜像,加载设备树,启动linux
"run findfdt;" \//设置fdt_file环境变量为imx6ull-14x14-evk.dtb
"mmc dev ${mmcdev};" \//切换mmc1,mmc1就是emmc设备
"mmc dev ${mmcdev}; if mmc rescan; then " \//如果mmc扫描结果不为空,则
"if run loadbootscript; then " \//从emmc1的分区1加载boot.scr到80800000中,但是前提是文件存在,由于文件不存在,分支不成立
"run bootscript; " \
"else " \
"if run loadimage; then " \//进入该分支,从分区中读取zImage,
"run mmcboot; " \//读取设备树,启动linux内核
"else run netboot; " \
"fi; " \
"fi; " \
"else run netboot; fi"
#endif
1.run findfdt
"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" \
fdt_file默认定义值undefined,所以第一句成立,board_name默认值EVK,board_rev默认值14×14,所以最后执行"setenv fdt_file imx6ull-14x14-evk.dtb; fi; " 也就是设置fdt_file环境变量为imx6ull-14x14-evk.dtb。
2. "mmc dev ${mmcdev};"
"mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" ,CONFIG_SYS_MMC_ENV_DEV定义为1,也就是切换到mmc1中
3.mmc dev ${mmcdev}; if mmc rescan; then
重复切换一次,如果mmc扫描结果不为空,则继续往下走
4."if run loadbootscript; then "
运行loadbootscript
"loadbootscript=" \
"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \//展开后:fotload mmc 1:1 80800000 boot.scr ,从emmc1的分区1加载boot.scr到80800000中
loadaddr定义为80800000 script定义为boot.scr,也就是从emmc1的分区1加载boot.scr到80800000中。
但是boot.scr不存在,所以直接进入else后面的语句。
5. "if run loadimage; then "
loadimage
"loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \//展开后:fatload mmc 1:1 80800000 zImage,从分区中读取zImage
从分区中读取zImage,文件是存在的,所以继续往下走
6."run mmcboot; "
mmcboot
"mmcboot=echo Booting from mmc ...; " \
"run mmcargs; " \//设置bootargs环境变量
"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \//条件成立
"if run loadfdt; then " \//从emmc分区读取设备树文件
"bootz ${loadaddr} - ${fdt_addr}; " \//bootz 80800000 - 83000000,启动linux内核
"else " \
"if test ${boot_fdt} = try; then " \
"bootz; " \
"else " \
"echo WARN: Cannot load the DT; " \
"fi; " \
"fi; " \
"else " \
"bootz; " \
"fi;\0" \
首先运行mmcargs,这里就是设置bootargs的环境变量值,后面讨论
接着测试两个值的数据,条件成立,跳转到loadfdt
"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \//展开后:fatload mmc 1:1 0x83000000 imx6ull-14x14-evk.dtb,从emmc分区读取设备树文件
也就是从分区中读取imx6ull-14x14-evk.dtb设备树文件到83000000.
最后使用bootz加载启动linux
所以bootcmd环境变量的运行可以总结为:
mmc dev 1 //切换到emmc
fatload mmc 1:1 80800000 zImage
fatload mmc 1:1 83000000 imx6ull-14x14-evk.dtb
booz 80800000 - 83000000
bootargs是在bootcmd中设置的,
"mmcargs=setenv bootargs console=${console},${baudrate} " \//bootargs保存一些参数会传递给linux内核//展开:setenv bootargs console=ttymxc0,115200,设置控制台,波特率
CONFIG_BOOTARGS_CMA_SIZE \//空值
"root=${mmcroot}\0" \//"root=/dev/mmcblk1p2",根文件系统保存到emmc1分区2
console 用来设置 linux 终端(或者叫控制台),也就是通过什么设备来和 Linux 进行交互,是串口还是 LCD 屏幕?如果是串口的话应该是串口几等等。一般设置串口作为 Linux 终端,这样我们就可以在电脑上通过 SecureCRT 来和 linux 交互了。这里设置 console 为 ttymxc0,因为 linux启动以后 I.MX6ULL 的串口 1 在 linux 下的设备文件就是/dev/ttymxc0。ttymxc0 后面有“,115200”,这是设置串口的波特率, console=ttymxc0,115200 综合起来就是设置 ttymxc0(也就是串口 1)作为 Linux 的终端,并且串口波特率设置为 115200。
第二行的宏为空,第三行就是设置根文件系统的位置。这些信息都会随着linux 的启动传递给linux
Bootargs环境变量也叫做命令行参数。