uboot源码里的movi命令分析
【摘要】 这篇文章分析uboot源码里的movi命令源码,分析命令的执行流程,根据命令的实现方式,找到uboot里环境变量存放的位置,并且根据movi命令实现自己的一套命令,完成内核、uboot、文件系统数据一键拷贝到EMMC。
这篇文章分析uboot源码里的movi命令源码,分析命令的执行流程,根据命令的实现方式,找到uboot里环境变量存放的位置,并且根据movi命令实现自己的一套命令,完成内核、uboot、文件系统数据一键拷贝到EMMC。
movi命令分析与实现
(1)查看命令用法,查看帮助
(2)将SD卡里的数据固化到EMMC用法
将 UBOOT 和内核数据固化到 EMMC 精简命令: movi r f 0 40008000;emmc open 1;movi w z f 1 40008000;emmc close 1; movi r b 0 40008000;emmc open 1;movi w z b 1 40008000;emmc close 1; movi r u 0 40008000;emmc open 1;movi w z u 1 40008000;emmc close 1; movi r t 0 40008000;emmc open 1;movi w z t 1 40008000;emmc close 1; movi r k 0 40008000;movi w k 1 40008000; |
(3)编写UBOOT命令实现数据拷贝:
#include <common.h>
#include <command.h>
#include <environment.h>
#include <search.h>
#include <errno.h>
#include <malloc.h>
#include <watchdog.h>
#include <serial.h>
#include <linux/stddef.h>
#include <asm/byteorder.h>
#include <nand.h>
#include <onenand_uboot.h>
#include <mmc.h>
#include <asm/arch/cpu.h>
#include <asm/arch/movi_partition.h>
int do_writedata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
/*1. 查找设备0-SD卡*/
struct mmc *mmc0 = find_mmc_device(0);
if(mmc0==NULL)
{
printf("设备0查找失败!\n");
return 0;
}
/*2. 查找设备1--MMC*/
struct mmc *mmc1 = find_mmc_device(1);
if(mmc1==NULL)
{
printf("设备1查找失败!\n");
return 0;
}
/*3. 初始化SD卡*/
mmc_init(mmc0); /*设备0初始化--SD卡*/
/*4. 初始化EMMC*/
emmc_boot_open(mmc1); /*设备1打开---EMMC*/
mmc_init(mmc1); /*设备1初始化--EMMC卡*/
/*5. 烧写数据*/
/*5.1 BL1*/
int r_cnt=movi_read(0,1,16,(void*)0x40000000); //读出SD卡里存放到所有数据到DDR指定地址
int w_cnt=movi_write(1,0,16,(void*)0x40000000);//将读出的数据写入到EMMC
printf("BL1_r_cnt=%d\n",r_cnt);
printf("BL1_w_cnt=%d\n",w_cnt);
/*5.2 BL2*/
r_cnt=movi_read(0,17,32,(void*)0x40000000); //读出SD卡里存放到所有数据到DDR指定地址
w_cnt=movi_write(1,16,32,(void*)0x40000000);//将读出的数据写入到EMMC
printf("BL2_r_cnt=%d\n",r_cnt);
printf("BL2_w_cnt=%d\n",w_cnt);
/*5.3 UBOOT\这里最好使用malloc申请空间,太大的地址可能会被其他数据覆盖掉*/
r_cnt=movi_read(0,49,656,(void*)0x40000000); //读出SD卡里存放到所有数据到DDR指定地址
w_cnt=movi_write(1,48,656,(void*)0x40000000);//将读出的数据写入到EMMC
printf("UBOOT_r_cnt=%d\n",r_cnt);
printf("UBOOT_w_cnt=%d\n",w_cnt);
/*5.4 TZSW*/
r_cnt=movi_read(0,705,320,(void*)0x40000000); //读出SD卡里存放到所有数据到DDR指定地址
w_cnt=movi_write(1,704,320,(void*)0x40000000);//将读出的数据写入到EMMC
printf("TZSW_r_cnt=%d\n",r_cnt);
printf("TZSW_w_cnt=%d\n",w_cnt);
/*5.5 Linux内核*/
r_cnt=movi_read(0,1057,12288,(void*)0x40000000); //读出SD卡里存放到所有数据到DDR指定地址
w_cnt=movi_write(1,1057,12288,(void*)0x40000000);//将读出的数据写入到EMMC
printf("Linux内核_r_cnt=%d\n",r_cnt);
printf("Linux内核_w_cnt=%d\n",w_cnt);
/*5.5 环境变量*/
r_cnt=movi_read(0,1025,32,(void*)0x40000000); //读出SD卡里存放到所有数据到DDR指定地址
w_cnt=movi_write(1,1025,32,(void*)0x40000000);//将读出的数据写入到EMMC
printf("环境变量_r_cnt=%d\n",r_cnt);
printf("环境变量_w_cnt=%d\n",w_cnt);
emmc_boot_close(mmc1); //关闭EMMC
return 0;
}
U_BOOT_CMD(
writedata, 1, 0,do_writedata,
"write所有数据到EMMC(内核BOOT)",
"write所有数据到EMMC(内核BOOT)"
);
(4)环境变量存放位置分析流程
//环境变量存放在DDR中的地址: 0x43CFBEC8;
由{ulong virt_to_phy_s5pv310(ulong addr)}函数进行得到。该函数在tiny4412.c文件最后一行。
保存环境变量的函数:int saveenv_movinand(void)
该函数在Env_auto.c文件的大约277行。
最终由movi_write_env(virt_to_phys((ulong)env_ptr));函数写到SD卡或者EMMC卡。
最终向EMMC或者SD卡写数据的文件是E:\source_Insight源码分析_工程\源码文件为arch\arm\cpu\armv7\exynos\irom_copy.c
在irom_copy.c文件中调用了movi_write_env函数。
保存环境变量打印的信息:
TINY4412 # save
Saving Environment to SMDK bootable device...
环境变量地址: 43CFBDC8
环境变量地址: 1137688008
环境变量地址: 43CFBD58
环境变量地址: 1137687896
环境变量地址: 43CFBD58
环境变量地址: 1137687896
环境变量地址: 43CFBBE0
环境变量地址: 1137687520
环境变量地址: 43CFC008
环境变量地址: 1137688584
设备编号:0 ,开始块:1025 , 数量:32
done
1025的十进制=401
32的十进制=20
----------------------------------
清除环境变量:
TINY4412 # mmc write 0 40000000 401 20
MMC write: dev # 0, block # 1025, count 32 ... 32 blocks written: OK
存放环境变量的结构体:
/*
* start_blk: start block number for raw area
* total_blk: total block number of card
* next_raw_area: add next raw_area structure
* description: description for raw_area
* image: several image that is controlled by raw_area structure
* by scsuh
*/
typedef struct raw_area {
uint start_blk; /* compare with PT on coherency test */
uint total_blk;
uint next_raw_area; /* should be sector number */
char description[16];
member_t image[15];
} raw_area_t; /* 512 bytes */
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)