uboot源码里的movi命令分析

举报
DS小龙哥 发表于 2022/06/22 22:09:43 2022/06/22
【摘要】 这篇文章分析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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。