AM335X有关MMC的启动参数问题分析

一、 问题来源

硬件平台:AM335X芯片

SDK版本:ti-processor-sdk-linux-am335x-evm-03.00.00.04-Linux-x86-Install

使用创龙相关文档进行参考。

发现问题的过程:使用SD(MMC0)卡启动UBOOT,内核,文件系统,正常启动之后,使用固化程序脚本将UBOOT、内核、文件系统固化到EMMC(MMC1)中。再将BOOT引脚设计为从EMMC(MMC1)启动。

关机后拔下SD卡,启动起来之后、文件系统内核的加载都是在EMMC中进行。

若关机后不拔下SD卡,启动后会有如下现象:

1、 uboot从EMMC(MMC1)启动,

2、 由于启动参数设置的原因,内核和文件系统还是使用的SD(MMC0)卡中的内容。

二、 启动参数详解

1、 相关启动命令及环境变量如下:

/*默认的args_mmc */

args_mmc=run finduuid;setenv bootargs console=${console} ${optargs} root=PARTUUID=${uuid} rw rootfstype=${mmcrootfstype}

/*默认的启动命令 */

bootcmd=run findfdt; run init_console; run envboot; run mmcboot; setenv mmcdev 1;setenv finduuid part uuid mmc 1:2 uuid;run mmcboot;run nandboot;run distro_bootcmd

/*默认的envboot */

envboot=mmc dev ${mmcdev}; if mmc rescan; then echo SD/MMC found on device ${mmcdev};if run loadbootscript; then run bootscript;else if run loadbootenv; then echo Loaded env from ${bootenvfile};run importbootenv;fi;if test -n $uenvcmd; then echo Running uenvcmd ...;run uenvcmd;fi;fi;fi;

/*默认的finduuid */

finduuid=part uuid mmc 0:2 uuid

/*默认的mmcdev */

mmcdev=0

/*默认的bootpart */

bootpart=0:2

/*默认的mmcboot */

mmcboot=mmc dev ${mmcdev}; if mmc rescan; then echo SD/MMC found on device ${mmcdev};run envboot; if run loadimage; then run mmcloados;fi;fi;

/*默认的loadimage */

loadimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}

/*默认的nandboot */

nandboot=echo Booting from nand ...; run nandargs; nand read ${fdtaddr} NAND.u-boot-spl-os; nand read ${loadaddr} NAND.kernel; bootz ${loadaddr} - ${fdtaddr}

/*默认的distro_bootcmd 、boot_targets */

distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done

boot_targets=mmc0 legacy_mmc0 mmc1 legacy_mmc1 nand0 pxe dhcp

三、启动过程分析:

1、Uboot起来后查看MMC0(1)有没有uboot.env,若没有,就使用默认的UBOOT启动参数。默认的的启动参数可以在UBOOT中查看。

2、取出bootcmd,见上一节中的参数,mmcdev初始值为0,本例中没有loadbootscript和bootenvfile。直接到mmcboot

3、mmcboot从MMC0中启动。

4、若mmc0启动未成功(MMC0不存在或者内容不对),则setenv finduuid part uuid mmc 1:2 uuid后,再一次运行mmcboot。

5、若没有成功,则运行nandboot(2)

6、若还不成功,则运行distro_bootcmd(3)

四、问题原因分析

启动参数设置不合理,主要由以下几点:

1、 内核启动时是从默认的MMC0、MMC1。。。等等去进行查找并启动,若本来设置的目的是通过MMC1启动,但是这是若MMC0设备存在并有内核文件在其中,则会被启动。这也是本文开头描述的现象。

2、 MMC0若是没有启动,应该切换到MMC1,需要重新设置一些环境变量的值,bootcmd中对mmcdev 、 finduuid 进行了重新设置,但是未对bootpart进行重新赋值,这会导致MMC1的内核启动还是变为了MMC0的内核启动,参见 mmcboot中的loadimage。

五、问题解决办法

对应上一节提出的问题,解决办法如下:

1、 可以使用判断语句,判断出当前位置,就是确定是哪个MMC,并从中启动内核,但是现阶段没有更改,只是保证SD卡中没有内核文件就好。

2、 增加对bootpart的修改,UBOOT中修改后的bootcmd为:

#define CONFIG_BOOTCOMMAND \

"run findfdt; " \

"run init_console; " \

"run envboot; " \

"run mmcboot; " \

"setenv mmcdev 1;setenv bootpart 1:2;setenv finduuid part uuid mmc 1:2 uuid;" \

"run mmcboot;" \

"run nandboot;" \

"run distro_bootcmd"

六、注释处解释

(1)uboot.env可以设置存放位置,默认在MMC0,在Am335x_evm.h中设置

/* Not NAND, SPI, NOR or eMMC env, so put ENV in a file on FAT */

#define CONFIG_ENV_IS_IN_FAT

#define FAT_ENV_INTERFACE           "mmc"

#define FAT_ENV_DEVICE_AND_PART             "0:1"

#define FAT_ENV_FILE               "uboot.env"

(2)nandboot这个环境变量写的不合理,应判断是否存在再进行读取和启动。不判断直接读取,读取失败后还是进行启动,若这时内存中(kernel_addr_r=0x82000000)刚好有之前读入的内核,启动会出问题,问题原因需要进一步明确。

(3)distro_bootcmd为依次从上述启动路径进行查找内核文件并启动。过程涉及较多,不进行一一分析。这个为保底的启动扫描。

注:若不进行bootpart的重新设置,不插SD卡,还是会从MMC1启动,但是这时不是mmcboot从中MMC1启动的(bootpart设置的还是0:2),而是在distro_bootcmd中扫描到MMC1是启动的,在这之前会进行nandboot,但是会失败。若启动好之后 reboot,则重复上述过程,在nandboot时,发现内存中有内核,则会启动,就会发生问题。所以还是必须要将bootcmd更新,保证功能的健壮性。

反思:

1、总是觉得所有的启动都是和 BOOTPIN有关,其实只有MLO和UBOOT是与BOOTPIN有关。内核的启动是与启动参数有关的。基于本文的分析,启动命令、参数,尤其是bootcmd与args_mmc是可以灵活配置的。

2、开发方式:起初完全可以利用SD卡进行启动,uboot.env也存放在SD卡中,内核部分开发完毕后,可以将uboot.env设置到MMC1 中。这时固化uboot及内核到MMC1中。此时从MMC1启动UBOOT,这个时候就可以重新设置环境变量,使得bootcmd更加精简。之后保存,将uboot.env保存在MMC1上,之后Uboot启动后都会去查找uboot.env这个文件。这部分未做尝试。

可以看出:启动命令,启动参数。环境变量文件等都是可以灵活变通的。

最新文章

  1. 简例 一次执行多条mysql insert语句
  2. Python学习(19)正则表达式
  3. Apache虚拟主机(三)
  4. Linux备份入门:3种克隆方法详解_Clonezilla
  5. table完美css样式,table的基本样式,table样式
  6. C语言结构体(struct)常见使用方法
  7. c++野指针 之 实战篇
  8. 转:MVC Html.AntiForgeryToken() 防止CSRF攻击
  9. js中常用的操作字符串的方法大全
  10. php+redis实现消息队列
  11. Windows防火墙开启ping,禁ping的配置
  12. 【C编程基础】多线程编程
  13. Linux及Windows查看占用端口的进程
  14. 【BZOJ3036】绿豆蛙的归宿 概率DP
  15. day5 五、数字类型、字符串,列表类型的基本操作和内置方法
  16. uvalive 4452 The Ministers’ Major Mess
  17. vue中的minix
  18. 20155213 《JAVA程序设计》实验二(JAVA面向对象程序设计)实验报告
  19. Office 365 Powershell 连接命令
  20. JavaScript的深拷贝与浅拷贝

热门文章

  1. BATJ都爱问的多线程面试题
  2. pipeline配置sonar和自动化
  3. netty-websocket-spring-boot-starter不同url端口复用
  4. 图像拼接(image stitching)
  5. Photoshop 7.0 安装及注册方法
  6. django orm 改动数据库中已存在的表(添加、删除、修改表字段)
  7. VM无法正常使用桥接模式获取IP上网
  8. Kafka Connect简介
  9. 自定义注解实现简单的orm映射框架
  10. QQ联合登录(基于Oauth2.0协议)