android系统移植emmc记录(5)-- fastboot命令分析

======================================================================
fastboot分析:
---------------------------------
 
int do_fastboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

{//设置u-boot,kernel,ramdisk ,system,userdata,cache空间地址

       if (set_partition_table())

       

---------------------------------------->  // set_partition_table      
   //主要设置bootloader ramdisk kernel 和fdisk所分的区的起始地址和大小,保存在ptable里面。

       /* Bootloader */

       strcpy(ptable[pcount].name, "bootloader");

       ptable[pcount].start = 0;

       ptable[pcount].length = 0;

       ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;

       pcount++;

       

       /* Kernel */

       strcpy(ptable[pcount].name, "kernel");

       ptable[pcount].start = 0;

       ptable[pcount].length = 0;

       ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;

       pcount++;

 

       /* Ramdisk  3M */

       strcpy(ptable[pcount].name, "ramdisk");

       ptable[pcount].start = 0;

       ptable[pcount].length = 0x300000; //3MB,初始值,如果文件大于3M,则会使用文件大小

       //写ramdisk的命令类型标志,这里用movi命令来写

       ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;

       pcount++;

       -----------------------

       /* System */

       get_mmc_part_info("0", 2, &start, &count, &pid);

       -------------------------

       if (pid != 0x83)

              goto part_type_error;

       strcpy(ptable[pcount].name, "system");

/*

                     decode_partitionInfo(&mbr[0x1CE], &partInfo);

                     *block_start    = partInfo.block_start;   

                     *block_count  = partInfo.block_count; 

                     *part_Id        = partInfo.partitionId;

*/    //system 开始的地址

       ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE;

       //大小,256M

       ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE;

       //写system数据类型的标志,这里用MMC命令来写

       ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD;

       pcount++;

       

       /* Data  350M*/

       get_mmc_part_info("0", 3, &start, &count, &pid);

       if (pid != 0x83)

              goto part_type_error;

       strcpy(ptable[pcount].name, "userdata");

       ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE;

       ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE;

       ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD;

       pcount++;

       

       /* Cache  100 M */

       get_mmc_part_info("0", 4, &start, &count, &pid);

       if (pid != 0x83)

              goto part_type_error;

       strcpy(ptable[pcount].name, "cache");

       ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE;

       ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE;

       ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD;

       pcount++;

       

       /* fat 剩余空间分区,剩余空间分区格式fat?标志为 0c*/

       get_mmc_part_info("0", 1, &start, &count, &pid);

       if (pid != 0xc)

              goto part_type_error;

       strcpy(ptable[pcount].name, "fat");

       ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE;

       ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE;

       ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD;

       pcount++;

       

-------------->
---------------------------->
//获取fdisk 对system userdata  cache分区的大小
int get_mmc_part_info(char *device_name, int part_num, int *block_start, int *block_count, unsigned char *part_Id)
{
	int		rv;
	PartitionInfo	partInfo;
	unsigned char	mbr[512];
	//从设备0中读取MBR主分区目录,里面定义了各个分区的信息,和起始,结束扇区
	rv = get_mmc_mbr(device_name, mbr);
	
	if(rv !=0)
		return -1;
				
	switch(part_num)
	{
		//剩余容量空间
		case 1:
			decode_partitionInfo(&mbr[0x1BE], &partInfo);
			*block_start	= partInfo.block_start;	
			*block_count	= partInfo.block_count;	
			*part_Id 	= partInfo.partitionId;	
			break;
		//system 分区表2。fdisk给system分了256M大小	
		case 2:
			decode_partitionInfo(&mbr[0x1CE], &partInfo);
			*block_start	= partInfo.block_start;	
			*block_count	= partInfo.block_count;	
			*part_Id 	= partInfo.partitionId;	//83
			break;
		//userdata 分区
		case 3:
			decode_partitionInfo(&mbr[0x1DE], &partInfo);
			*block_start	= partInfo.block_start;	
			*block_count	= partInfo.block_count;	
			*part_Id 	= partInfo.partitionId;	
			break;
		//cache分区
		case 4:
			decode_partitionInfo(&mbr[0x1EE], &partInfo);
			*block_start	= partInfo.block_start;	
			*block_count	= partInfo.block_count;	
			*part_Id 	= partInfo.partitionId;	
			break;
		default:
			return -1;
	}	

	return 0;
}
---------------------------->


 

=================================================================

设置完分区地址空间后,继续

=================================================================

主要初始化usb接口,来等待数据传输。

fastboot_init(&interface)

 

fastboot_interface = interface;

      fastboot_interface->product_name                  = device_strings[DEVICE_STRING_PRODUCT_INDEX];

      fastboot_interface->serial_no                     = device_strings[DEVICE_STRING_SERIAL_NUMBER_INDEX];

      fastboot_interface->nand_block_size               = CFG_FASTBOOT_PAGESIZE * 64; //2046*64

      fastboot_interface->transfer_buffer               = (unsigned char *) CFG_FASTBOOT_TRANSFER_BUFFER;//0x40000000

      fastboot_interface->transfer_buffer_size          = CFG_FASTBOOT_TRANSFER_BUFFER_SIZE; //272MB

      

 /* Fastboot variables */

#define CFG_FASTBOOT_TRANSFER_BUFFER           (0x40000000) //

#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE  (0x11000000)   /* 272MB ,大于烧录文件就行*/

#define CFG_FASTBOOT_ADDR_KERNEL            (0xC0008000)

#define CFG_FASTBOOT_ADDR_RAMDISK         (0x30A00000)

#define CFG_FASTBOOT_PAGESIZE                    (2048)     // Page size of booting device

#define CFG_FASTBOOT_SDMMC_BLOCKSIZE          (512)      // Block size of sdmmc

==================================

static struct cmd_fastboot_interface interface =

{

      .rx_handler            = rx_handler,   //通过此接口烧写

      .reset_handler         = reset_handler,

      .product_name          = NULL,

      .serial_no             = NULL,

      .nand_block_size       = 0,

      .transfer_buffer       = (unsigned char *)0xffffffff,

      .transfer_buffer_size  = 0,

};

================================================================

---------------------------------------------
cmd_fastboot.c
-----------------------------


//擦除接口 fastboot erase 
if (memcmp(cmdbuf, "erase:", 6) == 0)
		{
			struct fastboot_ptentry *ptn;

			ptn = fastboot_flash_find_ptn(cmdbuf + 6);
			if (ptn == 0)

------------------------------------------------------------
//获取fat system userdata cache 分区名字
fastboot_ptentry *fastboot_flash_find_ptn(const char *name)
{
	unsigned int n;
    
	for (n = 0; n < pcount; n++)
	{
		/* Make sure a substring is not accepted */
		if (strlen(name) == strlen(ptable[n].name))
		{
			if (0 == strcmp(ptable[n].name, name))
				return ptable + n;
		}
	}
	return 0;
}
-------------------------------------------------------

//只有擦除userdata  cache fat 这几个功能,kernel u-boot  ramdisk 不能擦除
//其实就是调用ext3format fatmot等格式命令 ,需要添加system 擦除命令
			char run_cmd[80];
			status = 1;

			if (!strcmp(ptn->name, "sytem"))
			{
				sprintf(run_cmd, "ext3format mmc 0:2");
				status = run_command(run_cmd, 0);
			}
			Else if (!strcmp(ptn->name, "userdata"))
			{
				sprintf(run_cmd, "ext3format mmc 0:3");
				status = run_command(run_cmd, 0);
			}
			else if (!strcmp(ptn->name, "cache"))
			{
				sprintf(run_cmd, "ext3format mmc 0:4");
				status = run_command(run_cmd, 0);
			}
			else if (!strcmp(ptn->name, "fat"))
			{
				sprintf(run_cmd, "fatformat mmc 0:1");
				status = run_command(run_cmd, 0);
			}
=======================================================


 

Flash what was downloaded */
		if (memcmp(cmdbuf, "flash:", 6) == 0)
		{
			if (download_bytes == 0)
			{
				sprintf(response, "FAILno image downloaded");
				ret = 0;
				goto send_tx_status;
			}
			//从此句开始判断 kernel。 ramdisk system,获取ptable
			ptn = fastboot_flash_find_ptn(cmdbuf + 6);
			----------------------
			if ((download_bytes > ptn->length) && (ptn->length != 0) &&	
				   !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV))
			{ //注意。system写,会出现这个信息。注意检查
			 //分析,只有当system文件大小小于分区大小时,是不会进入的
				sprintf(response, "FAILimage too large for partition");
				/* TODO : Improve check for yaffs write */
			}
			else
			{
					/* Normal case */
					if (write_to_ptn(ptn, (unsigned int)interface.transfer_buffer, download_bytes))
					{
						printf("flashing '%s' failed\n", ptn->name);
						sprintf(response, "FAILfailed to flash partition");
					}
					else
					{
						printf("partition '%s' flashed\n", ptn->name);
						sprintf(response, "OKAY");
					}
			}
			-------------------------------------------


 

/* Kernel */

      strcpy(ptable[pcount].name, "kernel");

      ptable[pcount].start = 0;

      ptable[pcount].length = 0;

      ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;

      pcount++;

                   

#######################################################################

static int write_to_ptn(struct fastboot_ptentry *ptn, unsigned int addr, unsigned int size)
{
				
#elif defined(CFG_FASTBOOT_SDMMCBSP)
{
	int ret = 1;
	char device[32], part[32];
	char start[32], length[32], buffer[32];

	char *argv[6]  = { NULL, "write", NULL, NULL, NULL, NULL, };
	int argc = 0;
	//区别出kernel u-boot ,当ramdisk,system等文件大于分区大小时。
	if ((ptn->length != 0) && (size > ptn->length))
	{
		printf("Error: Image size is larger than partition size!\n");
		return 1;
	}
    	//add by xiao@2012-04-16 :  只获取实际文件大小,因下面烧写文件时,是根据分区大小来烧写文件。对于几百MB的空间来说实在是太大和耗时间。
    	real_len = (size /CFG_FASTBOOT_SDMMC_BLOCKSIZE + 1);

//写system userdata cache  fat 接口
	if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD)
	{
		argv[2] = device;
		argv[3] = buffer;
		argv[4] = start;
		argv[5] = length;
		sprintf(device, "mmc %d", 1);
		sprintf(buffer, "0x%x", addr);
		sprintf(start, "0x%x", (ptn->start / CFG_FASTBOOT_SDMMC_BLOCKSIZE));
		//sprintf(length, "0x%x", (ptn->length / CFG_FASTBOOT_SDMMC_BLOCKSIZE));
        //add by xiao@2012-04-16 :
        #ifndef CONFIG_EMMC_INAND
            sprintf(length, "0x%x", (ptn->length / CFG_FASTBOOT_SDMMC_BLOCKSIZE));
        #else
            sprintf(length, "0x%x", real_len);
        #endif
//mmc 命令
		ret = do_mmcops(NULL, 0, 6, argv);
	}//写u-boot kernel ramdisk接口
	else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD)
	{
		argv[2] = part;  //指向part
		argv[3] = buffer; //指向buffer

		argc = 4;

		/* use the partition name that can be understood by a command, movi */
		if (!strcmp(ptn->name, "bootloader"))
		{	
			// part 改为 u-boot 名称 ,为movi 读写作区别
			strncpy(part, "u-boot", 7);
		}
		else if (!strcmp(ptn->name, "ramdisk"))
		{	
			//改为rootfs 名称,为movi 读写作区别
			strncpy(part, "rootfs", 7);
			//指向length,
			argv[4] = length;
			//此时,ramdisk 大小为下载的文件实际大小。 download_bytes
			sprintf(length, "0x%x",
				((size + CFG_FASTBOOT_SDMMC_BLOCKSIZE - 1)
				/ CFG_FASTBOOT_SDMMC_BLOCKSIZE ) * CFG_FASTBOOT_SDMMC_BLOCKSIZE);
			argc++;
		}
		else	/* kernel, fwbl1 */
		{	//kernel 名称
			argv[2] = ptn->name;
		}
		//把DRAM1 = 0x40000000 地址给buffer
		sprintf(buffer, "0x%x", addr);
		//用movi命令写kernel ,ramdisk u-boot数据
		ret = do_movi(NULL, 0, argc, argv);

		/* the return value of do_movi is different from usual commands. Hence the followings. */
		ret = 1 - ret;
	}

	return ret;
}

===========================

cmd_mmc.c

====================

注意:此命令 movi也会调用,mmc也调用。所以u-boot

kernel ramdisk system等多是调用此接口

也就是do_movi调用 do_mmcops命令来读写

int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int rc = 0;

	switch (argc) {
	

	default: /* at least 5 args */

		 if (strcmp(argv[1], "write") == 0) {
			int dev = simple_strtoul(argv[2], NULL, 10);
			void *addr = (void *)simple_strtoul(argv[3], NULL, 16);
			u32 cnt = simple_strtoul(argv[5], NULL, 10);
			int blk = simple_strtoul(argv[4], NULL, 10);
			u32 n;
			u32 written_cnt;
			u32 cnt_to_write;
			void *addr_to_write = addr;
			struct mmc *mmc = find_mmc_device(dev);


			if (!mmc)
				return 1;

			//重新初始化设备。
			rc = mmc_init(mmc);
			if(rc)
				return rc;

			n = 0;
			addr_to_write = addr;
			do {
				if (cnt - n > MAXIMUM_BLOCK_COUNT)
					cnt_to_write = MAXIMUM_BLOCK_COUNT;
				else
					cnt_to_write = cnt - n;

				written_cnt = mmc->block_dev.block_write(dev, blk, cnt_to_write, addr_to_write);
				n += written_cnt;
				blk += written_cnt;
				addr_to_write += written_cnt * 512;
				if(cnt_to_write != written_cnt) {
					printf("%d blocks written: %s\n",
						n, "ERROR");
					return -1;
				}
			} while(cnt > n);

			printf("%d blocks written: %s\n",
				n, "OK");
			return 0;
		} else {
			printf("Usage:\n%s\n", cmdtp->usage);
			rc = 1;
		}

		return rc;
	}
}

---------------------------------------------


 

---------------------------------------------

 

分析 ret = do_movi(NULL, 0, argc, argv);

 

分析 u-boot kernel  ramdisk 烧写!!!

---------------------------------------

int do_movi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	char *cmd;
	ulong addr, start_blk, blkcnt;
	uint rfs_size;
	char run_cmd[100];
	uint rw = 0, attribute = 0;
	int i;
	member_t *image;
	struct mmc *mmc;
	//此处节点为 0
	int dev_num = 0;

	cmd = argv[1];
	switch (cmd[0]) {
	
	case 'r':
		rw = 0;	/* read case */
		break;
	case 'w':
		rw = 1; /* write case */
		break;
	default:
		goto usage;
	}
	//获取,文件名称
	cmd = argv[2];


switch (cmd[0]) {
	//u-boot
	case 'u':
		if (argc != 4)
			goto usage;
		attribute = 0x2;
		//地址为DRAM1 = 0x40000000 此处的地址
		addr = simple_strtoul(argv[3], NULL, 16);
		break;
	//kernel
	case 'k':
		if (argc != 4)
			goto usage;
		attribute = 0x4;
		//地址为DRAM1 = 0x40000000 此处的地址
		addr = simple_strtoul(argv[3], NULL, 16);
		break;
	//rootfs
	case 'r':
		if (argc != 5)
			goto usage;
		attribute = 0x8;
		//地址为DRAM1 = 0x40000000 此处的地址
		addr = simple_strtoul(argv[3], NULL, 16);
		break;
	default:
		goto usage;
	}
//此处查找节点 0 
	mmc = find_mmc_device(dev_num);
	//重新注册
	mmc_init(mmc);
	/* u-boot r/w */
	//bl2 后半部分区域: u-boot 大小 512K
if (attribute == 0x2) {	
		//rw =1 表示写。0:表示读
		if (rw) {
			//先去写BL1部分
			start_blk = raw_area_control.image[1].start_blk;
			blkcnt = raw_area_control.image[1].used_blk;
			printf("Writing BL1 to sector %ld (%ld sectors).. ",
					start_blk, blkcnt);
			//16M + 1K -- 16M + 1K + 8K
			//从dram1 上吧数据写入BL1 区域
			movi_write_bl1(addr);
		}
		//找到BL2后半部分位置。
		for (i=0, image = raw_area_control.image; i<15; i++) {
			if (image[i].attribute == attribute)
				break;
		}
		//image[3] 大小512k
		start_blk = image[i].start_blk;
		blkcnt = image[i].used_blk;
		printf("%s bootloader.. %ld, %ld ", rw ? "writing":"reading",
				start_blk, blkcnt);
				
		//使用mmc 命令来烧写 bl2 后半部分
		sprintf(run_cmd,"mmc %s 0 0x%lx 0x%lx 0x%lx",
				rw ? "write":"read",
				addr, start_blk, blkcnt);
		//mmc write  0  0x40000000 star len
		//do_mmcops 写的时候,会根据argv[2]来获取设备号。
		//这里  mmc write  0 指定了设备号了。
		//16M + 9K +16K -- 16M + 25K +512K 
		run_command(run_cmd, 0);
		printf("completed\n");
		return 1;
	}
	//烧写内核 16M + 25K +512K -- 16M + 25K +512K + 4MB
	/* kernel r/w */
	if (attribute == 0x4) {
		//找到内核区域 image[4] 
		for (i=0, image = raw_area_control.image; i<15; i++) {
			if (image[i].attribute == attribute)
				break;
		}
		//
		start_blk = image[i].start_blk;
		//大小为4MB
		blkcnt = image[i].used_blk;
		
		printf("%s kernel.. %ld, %ld ", rw ? "writing" : "reading",
		       start_blk, blkcnt);
		//命令 mmc write 0 0x40000000 star len
		sprintf(run_cmd, "mmc %s 0 0x%lx 0x%lx 0x%lx",
			rw ? "write" : "read", addr, start_blk, blkcnt);
		//写入到设备 0中
		run_command(run_cmd, 0);

		printf("completed\n");
		return 1;
	}
	//根文件系统烧写  16M + 25K +512K + 4MB - 16M + 25K +512K + 4MB +26MB
	/* root file system r/w */
	if (attribute == 0x8) {
		//获取rootfs的实际文件大小 download_bytes
		rfs_size = simple_strtoul(argv[4], NULL, 16);
		//获取rootfs 区域 image[5] 
		for (i=0, image = raw_area_control.image; i<15; i++) {
			if (image[i].attribute == attribute)
				break;
		}
		
		start_blk = image[i].start_blk;
		//一个块512的大小对齐
		blkcnt = rfs_size/MOVI_BLKSIZE +
			((rfs_size&(MOVI_BLKSIZE-1)) ? 1 : 0);
		image[i].used_blk = blkcnt;
		printf("%s RFS.. %ld, %ld ", rw ? "writing":"reading",
				start_blk, blkcnt);
		//写rootfs 16M + 25K +512K + 4MB - 16M + 25K +512K + 4MB +26MB
		sprintf(run_cmd,"mmc %s 0 0x%lx 0x%lx 0x%lx",
				rw ? "write":"read",
				addr, start_blk, blkcnt);
		run_command(run_cmd, 0);
		printf("completed\n");
		return 1;
	}

	return 1;

usage:
	printf("Usage:\n%s\n", cmdtp->usage);
	return -1;
}


 

#########################################################

分析:cmd_movi.c

 

#ifdef CONFIG_CMD_MOVINAND

 

      init_raw_area_table(&host->block_dev);

#endif

#########################################################

 

int init_raw_area_table (block_dev_desc_t * dev_desc)
{
	//找到设备
	struct mmc *host = find_mmc_device(dev_desc->dev);
	//第一次确实不相等
	if (raw_area_control.magic_number != MAGIC_NUMBER_MOVI) {
		int i = 0;
		member_t *image;
		u32 capacity;
	
		if (host->high_capacity) {
			capacity = host->capacity;
		#ifdef CONFIG_S3C6410
			if(IS_SD(host))
				capacity -= 1024;
		#endif
		} else {
			//注意此处,块大小 > 512时
			capacity = host->capacity * (host->read_bl_len / MOVI_BLKSIZE);
		}	

		//读取是否有raw分区表。
		dev_desc->block_read(dev_desc->dev,
			capacity - (eFUSE_SIZE/MOVI_BLKSIZE) - 1,
			1, &raw_area_control);
		if (raw_area_control.magic_number == MAGIC_NUMBER_MOVI) {
			return 0;
		}
		//没有raw分区表就增加一个
		/* add magic number */
		raw_area_control.magic_number = MAGIC_NUMBER_MOVI;
		//从bl1 开始放
		/* init raw_area will be 16MB */
		//一个块大小512,的倍数表示起始的块地址,也就是偏移16M?
		raw_area_control.start_blk = 16*1024*1024/MOVI_BLKSIZE;
		//0.5k 的efuse 和 0.5k的recvers 总大小块
		raw_area_control.total_blk = capacity;
		
		raw_area_control.next_raw_area = 0;
		strcpy(raw_area_control.description, "initial raw table");
		//指向image
		image = raw_area_control.image;
		/* image 0 should be fwbl1 */
		//image【0】 我们没必要有。
		#######################################
		/* image 1 should be bl2 */
		//第一次写完了efuse后,在它后面写bl2.所以使用efuse作为起始块地址。
		image[1].start_blk = (eFUSE_SIZE/MOVI_BLKSIZE);
		//8K 的块大小个数
		image[1].used_blk = MOVI_BL1_BLKCNT;
		//大小8K
		image[1].size = SS_SIZE;

		image[1].attribute = 0x1;
		//标注此区为u-boot parted
		strcpy(image[1].description, "u-boot parted");
		#######################################################
		//接下来保存环境参数
		/* image 2 should be environment */
		//上一个的结束块地址
		image[2].start_blk = image[1].start_blk + MOVI_BL1_BLKCNT;
		//使用了16k的块大小个数
		image[2].used_blk = MOVI_ENV_BLKCNT;
		//大小16K
		image[2].size = CFG_ENV_SIZE;
		
		image[2].attribute = 0x10;
		//标注此区为 environment
		strcpy(image[2].description, "environment");
		dbg("env: %d\n", image[2].start_blk);
###########################################################
		/* image 3 should be bl2 */
		//开始放BL2
		image[3].start_blk = image[2].start_blk + MOVI_ENV_BLKCNT;
		//512KB的块大小个数
		image[3].used_blk = MOVI_BL2_BLKCNT;
		//512KB
		image[3].size = PART_SIZE_BL;
		image[3].attribute = 0x2;
		//标注此区为u-boot 
		strcpy(image[3].description, "u-boot");
		dbg("bl2: %d\n", image[3].start_blk);
		####################################################
		/* image 4 should be kernel */
		//这里接下来存放内核信息
		image[4].start_blk = image[3].start_blk + MOVI_BL2_BLKCNT;
		//4M的块大小个数
		image[4].used_blk = MOVI_ZIMAGE_BLKCNT;
		//大小4M
		image[4].size = PART_SIZE_KERNEL;
		
		image[4].attribute = 0x4;
		//标注此区为kernel 
		strcpy(image[4].description, "kernel");
		dbg("knl: %d\n", image[4].start_blk);
		######################################################
		/* image 5 should be RFS */
		//接下来放rootfs
		image[5].start_blk = image[4].start_blk + MOVI_ZIMAGE_BLKCNT;
		//26M的块大小
		image[5].used_blk = MOVI_ROOTFS_BLKCNT;
		//26M大小
		image[5].size = PART_SIZE_ROOTFS;
		image[5].attribute = 0x8;
		strcpy(image[5].description, "rfs");
		dbg("rfs: %d\n", image[5].start_blk);
		
		for (i=6; i<15; i++) {
			raw_area_control.image[i].start_blk = 0;
			raw_area_control.image[i].used_blk = 0;
		}
		
------------------------------

总结一下:

      raw 分区:

      16M -- 16M + 1K efuse区域 标示:initial raw table

      

      image[1]  , 0x1

      

      16M + 1K -- 16M + 1K + 8K bl2前半部分区域标示: u-boot parted

      

      

      image[2] , 0x10

      16M + 9K  -- 16M + 9K +16K  : 环境参数保存区域environment

      

      image[3], 0x2

      16M + 9K +16K -- 16M + 25K +512K :bl2 后半部分区域: u-boot

      

      image[4[, 0x4

      

      16M + 25K +512K -- 16M + 25K +512K + 4MB : kernel 区域: kernel

      

      image[5],0x8

      

      16M + 25K +512K + 4MB - 16M + 25K +512K + 4MB +26MB

       rootfs区域,表示: rfs

      

image[5].attribute = 0x8;

      方便烧写对应:

      

             case 'r':

             if (argc != 5)

                    goto usage;

             attribute = 0x8;

             ###############################################################



 

 


   

你可能感兴趣的:(android,image,cmd,null,System,buffer)