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这个文件。这部分未做尝试。

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

原文地址:https://www.cnblogs.com/lh03061238/p/11143511.html

时间: 2024-08-29 12:25:46

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

linux-3.2.36内核启动1-启动参数(arm平台 启动参数的获取和处理,分析setup_arch)【转】

转自:http://blog.csdn.net/tommy_wxie/article/details/17093297 最近公司要求调试一个内核,启动时有问题,所以就花了一点时间看看内核启动. 看的过程中总结了一点东西,希望可以帮助大家调试内核. 当我开始看的时候,第一件事是从网上搜集资料,不看不知道,一看吓一跳!牛人太多了,像这种内核启动的上古代码早就被人分析的彻彻底底.这注定我写的只能是烂微博了. 为了此微博有存在的必要,我会显示内核启动打印的代码位置(用绿色表示)及出现错误打印的原因(用红

System.gc()和-XX:+DisableExplicitGC启动参数,以及DirectByteBuffer的内存释放

我之前的一篇博客:java中使用堆外内存,关于内存回收需要注意的事和没有解决的遗留问题(等大神解答)  介绍了java堆外内存的使用,以及堆外内存的释放.那篇博客遗留了一个问题:DirectByteBuffer究竟是如何释放堆外内存的?本文主要是解决下那篇博客的遗留问题. 首先我们修改下JVM的启动参数,重新运行之前博客中的代码.JVM启动参数和测试代码如下: -verbose:gc -XX:+PrintGCDetails -XX:+DisableExplicitGC -XX:MaxDirect

u-boot启动输出信息分析——基于tiny6410

CPU: [email protected] Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode) Board: MINI6410DRAM: 256 MBFlash: 0 kBNAND: 2048 MB In: serialOut: serialErr: serialMAC: 08:90:90:90:90:90下面代码的输出信息就可以在里面查得到1.初始化本阶段要使用到的硬件设备2.检测系统内存映射3.将

u-boot启动第二阶段简要分析

u-boot第一启动阶段的最后跳转到 start_armboot 函数.这个函数在 lib_arm/board.c 中定义.下面就来看看这个函数做了哪些工作.本文的分析过程比较肤浅.只能说是大致流程.更细的流程还需要仔细的钻研. 下面是两个整个u-boot所使用的最重要的两个全局变量结构体.u-boot的第二阶段也是围绕这两个结构体展开的. typedef unsigned long long phys_size_t; typedef struct bd_info { unsigned long

Android --- Zygote和System进程启动过程简要分析

Android --- Zygote和System进程启动过程简要分析 在看过<Android情景源代码>的Zygote启动章节后,作如下简要总结.Zygote进程在init进程启动过程中被以service服务的形式启动: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root syste

u-boot 第一启动阶段简要分析

1. u-boot 整体启动流程  bootloader是板子上电到linux系统加载之间的一段执行代码.分为两个启动阶段BL1,BL2.BL1主要用汇编语言编写,做一些初始化工作,并将自身从存储介质如flash拷贝到内存中,然后跳到BL2的c程序入口.BL2加载各个设备的驱动,并提供一个命令行的界面来提供各种操作,最终目的是为了加载linux内核.bootloader将启动参数传递给linux内核让其自举,它的使命也就完成了.下面是s3c6410的启动流程,非常经典. 板子自上电开始启动流程供

linux内核可以接受的参数 | Linux kernel启动参数 | 通过grub给内核传递参数

在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时,可以参数在kernel被GRUB或LILO等启动程序调用之时传递给kernel. 3.在kernel运行时,修改/proc或/sys目录下的文件. 这里我简单讲的就是第二种方式了,kernel在grub中配置的启动参数. 首先,kernel有哪些参数呢? 在linux的源代码中,有这样的一个文档Documentation/kern

Android之rild进程启动源码分析

Android 电话系统框架介绍 在android系统中rild运行在AP上,AP上的应用通过rild发送AT指令给BP,BP接收到信息后又通过rild传送给AP.AP与BP之间有两种通信方式: 1.Solicited Response:Ap向Bp发送请求,Bp给Ap发送回复,该类型的AT指令及其回调函数以数组的形式存放在Ril_commands.h文件中: {数组中的索引号,请求回调函数,响应回调函数} [plain] view plaincopy {0, NULL, NULL},      

Android系统默认Home应用程序(Launcher)的启动过程源代码分析

在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个 Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应用程序就是Launcher了,本文将详细分析 Launcher应用程序的启动过程. Android系统的Home应用程序Launcher是由ActivityManagerService启动的,而 ActivityManagerService和PackageManagerService一样,都是在开