uboot
1、setenv 命令
该命令用于设置环境变量,用法介绍如下
- # setenv
- setenv - set environment variables
- Usage:
- setenv name value ...
- - set environment variable 'name' to 'value ...'
- setenv name
- - delete environment variable 'name'
2、mmc 命令
该命令用于初始化 SD 存储卡,用法介绍如下
- mmc - MMC sub-system
- Usage:
- mmc init [dev] - init MMC sub system
- mmc device [dev] - show or set current device
3、fatload 命令
该命令用于从 FAT 文件系统设备中读取指定文件放入指定内存中,用法介绍如下:
- usage: fatload <interface> <dev[:part]> <addr> <filename> [bytes]
4、fatinfo 命令
该命令用于查看 FAT 格式设备的基本信息,用法介绍如下:
- usage: fatinfo <interface> <dev[:part]>
- Interface: MMC
- Device 0: Vendor: Rev: Prod:
- Type: Hard Disk
- Capacity: 3789.0 MB = 3.7 GB (7759872 x 512)
- Partition 1: Filesystem: FAT32 "NO NAME "
该命令用于查看 FAT 格式设备的目录和文件信息,用法介绍如下:
- usage: fatls <interface> <dev[:part]> [directory]
- ./
- ../
- 4106240 arm_tools.tar
- 1713 readme_cn.txt
- gen_customer/
- file(s), 3 dir(s)
该命令用于从 FAT 格式设备的根目录读取指定文件,用法介绍如下:
- usage: fatname <interface> <dev[:part]> <filename>
在使用该命令的时候同样需要指定设备和编号,如果该文件存在则会返回读回数据的长度,如果文件不存在则返回 -1 并在命令行打印相关消息,用法如:fatname mmc 1 fire。
附:uboot 调试经验
1、烧录问题:以前经常遇到用串口烧录 xloader、uboot、boot 的时候串口传输出错,就会导致烧录失败并且开不了机,而且在双 uboot 的情况下仍然开不了机。只能用硬件的方式进入强制烧录模式才行。在查看相关源码后发现在烧录的时候不管传输的镜像文件是否完整,都会去做烧录的动作,而且只对传输过去的内容做crc校验,这也造成了crc校验失去了应有的意义。
解决方案:在烧录动作之前加入了镜像完整性检测,如果加载的镜像不完整就不会更新emmc中原有的镜像,这样就解决此问题了。
2、环境变量丢失的问题:有的时候会发现系统里面的一些重要参数(如:电池电量表、充电电流等)丢掉了,这些参数是通过 uboot 环境变量的形式保存在 emmc 中的,如果这些重要参数丢掉了会导致严重的问题,但遇到这种情况的概率比较小,就一直认为是 emmc 的随机问题,还做了环境变量备份的机制。后来通过客户那边的反馈信息才发现一种必现的情况,就是开机的时候一起按住Power 键 +音量加键 ,按照这种情况,系统应该进入烧录模式,也就是会从 SD 卡中读取镜像开始烧录了,如果 SD 卡没有系统镜像则会烧录失败,而测试到的情况表明烧录失败后,重启手机那些环境变量就已经丢掉了。
解决方案:分析代码才发现原来只要进入烧录模式的第一个动作就是擦除原有的环境变量,而不管用户是否有插入 SD 卡或者 SD 卡中是否有镜像,于是将擦除环境变量的动作移动到了 uboot 烧录完成之后,这样就能保证用户误操作开机不会导致环境变量异常丢失了。
3、环境变量备份:为了防止 emmc 或者 nand 异常出错导致环境变量错误,需要对环境变量做一个备份。
解决方案:系统的环境变量(env1)保存在 emmc 偏移为 0x400000 的地址处,长度只有 8192,在设计时为环境变量预留的保存空间为 2M,所以有很大的空间可以用来做备份(env2),现在选定偏移地址为 0x480000 为备份起始地址,长度同样为 8192。在开机的时候,会分别对两处环境变量分别做 crc 检验,然后与其保存的 crc 校验值比较,如果相同则表示环境变量没有错误,如果不同则说明当前环境变量出错,如果出错了则将正确的那处环境变量读到内存中使用,并将出错的那处环境变量重写,如果两处都出错,则应该维修了。为了简化处理流程,在写新的环境变量的时候,同时会写到两处,写的过程则是先完成 env1 的擦除和重写再做 env2 的擦除和重写同时更新 crc 校验值。在 uboot 中把不必要的环境变量都去掉了,这样一般只有在烧录系统的时候才会对环境变量有改写,这样也减少了出错的概率。以下是开机时判断环境变量是否出错的代码:
- void env_relocate_spec (void)
- {
- int crc1_ok = 0, crc2_ok = 0, b_save_env = 0;
- env_t *tmp_env1, *tmp_env2;
- /* 申请两块内存用来保存从 emmc 读取出来的环境变量 */
- tmp_env1 = (env_t *) malloc(CONFIG_ENV_SIZE);
- tmp_env2 = (env_t *) malloc(CONFIG_ENV_SIZE);
- /* 读取环境变量 */
- if (readenv(CONFIG_ENV_OFFSET, (u_char *) tmp_env1))
- printf("No Valid First Environment Area Found\n");
- if (readenv(CONFIG_ENV_BK_OFFSET, (u_char *) tmp_env2))
- printf("No Valid Secondary Environment Area Found\n");
- /* 对环境变量做 crc 校验并与保存值比较 */
- crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
- crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
- /* 判断环境变量是否出错 */
- if(!crc1_ok && !crc2_ok) {
- free(tmp_env1);
- free(tmp_env2);
- printf("Env crc1 and crc2 is not OK\n");
- return use_default();
- } else if(crc1_ok && !crc2_ok) {
- gd->env_valid = 1;
- b_save_env = 1;
- } else if (!crc1_ok && crc2_ok) {
- gd->env_valid = 2;
- } else {
- /* both ok - check serial */
- if(tmp_env1->crc == 0 && tmp_env2->crc != 0) {
- gd->env_valid = 2;
- } else if(tmp_env2->crc == 0 && tmp_env1->crc != 0){
- gd->env_valid = 1;
- b_save_env = 1;
- } else if(tmp_env2->crc == 0 && tmp_env1->crc == 0) {
- printf("No Vaild Env, return to default Env.\n");
- return use_default();
- } else { /* crc are equal - almost impossible */
- gd->env_valid = 1;
- }
- printf("The Same Environment.\n");
- }
- /* 包含部分异常处理 */
- free(env_ptr);
- if(gd->env_valid == 1) {
- env_ptr = tmp_env1;
- if(b_save_env) run_command("saveenv", 0);
- printf ("Env1 is OK\n\n");
- free(tmp_env2);
- } else {
- env_ptr = tmp_env2;
- printf ("Save env2 to env1 \n\n");
- run_command("saveenv", 0);
- free(tmp_env1);
- }
- gd->env_addr = env_ptr->data;
- if(getenv("second_env") == NULL)
- return;
- setenv("second_env", 0);
- /* 将代码中的环境变量保存到 emmc 中,仅在烧录系统时作用 */
- add_sencond_env();
- }
版权声明:本文为博主原创文章,未经博主允许不得转载。
1. 2012-01-09 Samsung工程师提供了一系列patch,支持
ext4load- load binary file from a Ext4 file system
ext4ls - list files in a directory (default /)
ext4write- create a file in ext4 formatted partition
2012-05-25在Uboot maillist中,结束公示,然后Shankar发了一封mail:
Hi All,
We have resolved the review comments received for uboot ext4 feature. Ext4 code is based on existing ext2 implementation in uboot, and is capable to ls, load ext2 partitions as well.
Hence we have removed the ext2 folder from fs folder and will maintain one ext4 directory.
Since ext4 is based on ext2, all ext2 developers name has been added to the respective file headers
To make the command line interface clean, we are maintaining cmd_ext2.c and cmd_ext4.c files. They will act as a wrapper and
a new file cmd_ext_common.c is introduced which will act as an interface file with ext4 directory.
Hence, it will avoid lot of code duplicacy and also will maintain a cleaner command interface.
Also, the current ext4 ls and load is optimized and around 10 times faster than the existing ext2 ls and load in uboot.
Thanks to Wolfgang Denk, Kim Phillips, Graeme Russ, Rob and Mike Frysinger for your valuable suggestions and review comments.
2. 上述3个命令的使用说明
(1). To list the files in ext4 formatted partition, execute
ext4ls <interface> <dev[:part]> [directory]
For example:
UBOOT #ext4ls mmc 0:5 /usr/lib
(2). To read and load a file from an ext4 formatted partition to RAM, execute
ext4load <interface> <dev[:part]> [addr] [filename] [bytes]
For example:
UBOOT #ext4load mmc 2:2 0x30007fc0 uImage
(3). To write a file to a ext4 formatted partition.
(3.1) First load a file to RAM at a particular address for example 0x30007fc0.
Now execute ext4write command
ext4write <interface> <dev[:part]> [filename] [Address] [sizebytes]
For example:
UBOOT #ext4write mmc 2:2 /boot/uImage 0x30007fc0 6183120
(here 6183120 is the size of the file to be written)
Note: Absolute path is required for the file to be written