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这个文件。这部分未做尝试。
可以看出:启动命令,启动参数。环境变量文件等都是可以灵活变通的。
AM335X有关MMC的启动参数问题分析的更多相关文章
- external-attacher源码分析(1)-main方法与启动参数分析
更多 ceph-csi 其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 摘要 ceph-csi分析-external-attacher源码分析.external- ...
- external-provisioner源码分析(3)-组件启动参数分析
更多ceph-csi其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 external-provisioner源码分析(3)-组件启动参数分析 本文将对extern ...
- ceph-csi源码分析(2)-组件启动参数分析
更多ceph-csi其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 ceph-csi源码分析(2)-组件启动参数分析 ceph-csi组件的源码分析分为五部分: ...
- uboot启动阶段修改启动参数方法及分析
作者:围补 本来启动方式这节不是什么复杂的事儿,不过想简单的说清楚明白,还真是不知道怎么组织.毕竟文字跟有声语言表达有别.但愿简单的东西别让我讲的太复杂! Arm板系统文件一般有三个——bootloa ...
- 【ARM-Linux开发】 uboot启动阶段修改启动参数方法及分析
作者:围补 本来启动方式这节不是什么复杂的事儿,不过想简单的说清楚明白,还真是不知道怎么组织.毕竟文字跟有声语言表达有别.但愿简单的东西别让我讲的太复杂! Arm板系统文件一般有三个--bootloa ...
- [置顶] linux内核启动1-启动参数(启动参数的获取和处理,分析setup_arch)
最近公司要求调试一个内核,启动时有问题,所以就花了一点时间看看内核启动. 看的过程中总结了一点东西,希望可以帮助大家调试内核. 当我开始看的时候,第一件事是从网上搜集资料,不看不知道,一看吓一跳!牛人 ...
- linux-3.2.36内核启动1-启动参数(arm平台 启动参数的获取和处理,分析setup_arch)【转】
转自:http://blog.csdn.net/tommy_wxie/article/details/17093297 最近公司要求调试一个内核,启动时有问题,所以就花了一点时间看看内核启动. 看的过 ...
- u-boot向linux内核传递启动参数(详细)
U-BOOT 在启动内核时,会向内核传递一些参数.BootLoader 可以通过两种方法传递参数给内核,一种是旧的参数结构方式(parameter_struct),主要是 2.6 之前的内核使用的方式 ...
- U-Boot启动过程完全分析
U-Boot启动过程完全分析 1.1 U-Boot工作过程 U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶段的功能 硬件设备初始化 加载U-Boot第二阶段 ...
随机推荐
- 【GMT43智能液晶模块】例程十五:LAN_TCPC实验——以太网数据传输
源代码下载链接: 链接:https://pan.baidu.com/s/1bFX8_UpUlML29oqoDGaw5g提取码:mrf5 复制这段内容后打开百度网盘手机App,操作更方便哦 GMT43购 ...
- cent os 部署blade
一:安装docker 二:安装docker-compose 三:安装Harbor 四:配置Harbor使用https和2376端口 在/etc/docker 目录下面创建文件:create_tls_c ...
- netty-websocket-spring-boot-starter不同url端口复用
netty-websocket-spring-boot-starter是一个基于netty的websocket服务端,目前笔者使用的版本依托于Springboot.官方网址https://github ...
- java学习摘抄笔记mybaits2
mybatis第二天 高级映射 查询缓存 和spring整合 课程复习: mybatis是什么? mybatis是一人持久层框架,mybatis是一个不完全的ORM框架.sql语句需要程序员自己去编 ...
- 恋恋山城 Jean de Florette (1986) 男人的野心 / 弗洛莱特的若望 / 让·德·弗罗莱特 / 水源 下一部 甘泉,玛侬
<让·德·弗洛莱特>电影剧本 文/[法]马赛尔·巴涅尔译/苏原 编者按:<让·德·弗洛莱特>和<甘泉,玛侬>是根据法国著名作家马赛尔·巴涅尔的同名小说改编的电影.马 ...
- MTCNN代码解读
代码基于bm1682芯片 #include "mtcnn.hpp" #include "utils.hpp" using namespace std; usin ...
- Linux 就该这么学 CH02新手必须掌握的Linux命令
0 概述 本章内容如下 强大的shell. 帮助文档命令(1) 系统工作命令(10) 系统状态监测命令(8) 工作目录切换命令(3) 文本文件编辑命令(9) 文件目录管理命令(7) 打包压缩或搜索命令 ...
- (转)mysql使用Navicat 导出和导入数据库
mysql使用Navicat 导出和导入数据库 ps:在导入本地数据库的时候,要先建立相同的数据库,然后再运行sql文件,即可导入相应的数据库
- 小甲鱼汇编语言学习笔记——day01
1.计算机CPU由如下三部分组成(如下图):运算器.控制器.寄存器. 2.寄存器:简单说,就是用来存储数据的器件,类似内存,不过这个是CPU专用,跟内存不一样. 8086CPU里,寄存器总共有14个, ...
- 域名解析中的cname解析和显性URL跳转和隐性URL跳转三者有什么区别
通俗的来讲,cname解析还是属于dns解析,只是把某个域名解析到另外一个域名对应的某个IP的空间中,所以还需要在服务器端(比如nginx)做域名解析(比如把baidu.com做一个cname解析到i ...