AM335X有关MMC的启动参数问题分析
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这个文件。这部分未做尝试。 可以看出:启动命令,启动参数。环境变量文件等都是可以灵活变通的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ip link eth down和ip link dev eth之间的区别
- linux – 为什么运行中的物理地址是相同的?
- linux – 使用ProxyTunnel通过HTTP进行SSH“套接字读取错误
- Linux基本命令详解《二》(Linux中对目录和文件管理所使用的
- (转)Linux下定时切割Mongodb数据库日志并删除指定天数前的日
- linux – 在Mac OS X上使用AWK拆分文件
- linux – 如何跟踪EC2实例或弹性IP上的公共带宽使用情况?
- linux – MINFREE(为root用户保留的磁盘空间百分比)是旧帽子
- 什么是Linux堆栈?
- linux – 如何在不停止的情况下将作业发送到后台?