http://blog.csdn.net/yunfly163/article/details/7496869
- 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++;
- -------------->
- <PRE class=cpp name="code">---------------------------->
- //获取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;
- }
- ---------------------------->
- </PRE><BR>
- <PRE></PRE>
- <P> </P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">=================================================================</SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue">设置完分区地址空间后,继续</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">=================================================================</SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue">主要初始化</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">usb</SPAN></SPAN><SPAN style="COLOR: blue">接口,来等待数据传输。</SPAN></SPAN></P>
- <SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"></SPAN></SPAN>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">fastboot_init(&interface)</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">fastboot_interface = interface;</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>fastboot_interface->product_name = device_strings[DEVICE_STRING_PRODUCT_INDEX];</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>fastboot_interface->serial_no = device_strings[DEVICE_STRING_SERIAL_NUMBER_INDEX];</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>fastboot_interface->nand_block_size = CFG_FASTBOOT_PAGESIZE * 64; //2046*64</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>fastboot_interface->transfer_buffer = (unsigned char *) CFG_FASTBOOT_TRANSFER_BUFFER;//0x40000000</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>fastboot_interface->transfer_buffer_size = CFG_FASTBOOT_TRANSFER_BUFFER_SIZE; //272MB</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>/* Fastboot variables */</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#define CFG_FASTBOOT_TRANSFER_BUFFER </SPAN></SPAN> (0x40000000) //</P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE </SPAN></SPAN>(0x11000000) /* 272MB
- </SPAN><SPAN style="COLOR: blue">,大于烧录文件就行</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">*/</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#define CFG_FASTBOOT_ADDR_KERNEL </SPAN></SPAN> (0xC0008000)</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#define CFG_FASTBOOT_ADDR_RAMDISK </SPAN></SPAN> (0x30A00000)</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#define CFG_FASTBOOT_PAGESIZE </SPAN></SPAN> (2048) // Page size of booting device</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#define CFG_FASTBOOT_SDMMC_BLOCKSIZE </SPAN></SPAN> (512) // Block size of sdmmc</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">==================================</SPAN></SPAN></P>
- <P></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">static struct cmd_fastboot_interface interface =</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">{</SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN>.rx_handler = rx_handler, //</SPAN><SPAN style="COLOR: blue">通过此接口烧写</SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>.reset_handler = reset_handler,</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>.product_name = NULL,</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>.serial_no = NULL,</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>.nand_block_size = 0,</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>.transfer_buffer = (unsigned char *)0xffffffff,</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>.transfer_buffer_size = 0,</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">};</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">================================================================</SPAN></SPAN></P>
- <PRE class=cpp name="code">---------------------------------------------
- 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);
- }
- =======================================================
- </PRE>
- <P><BR>
- </P>
- <PRE class=cpp name="code">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");
- }
- }
- -------------------------------------------
- </PRE>
- <P><BR>
- </P>
- <P><SPAN style="COLOR: red"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">/* Kernel */</SPAN></SPAN></P>
- <P><SPAN style="COLOR: red"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>strcpy(ptable[pcount].name, "kernel");</P>
- <P><SPAN style="COLOR: red"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>ptable[pcount].start = 0;</P>
- <P><SPAN style="COLOR: red"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>ptable[pcount].length = 0;</P>
- <P><SPAN style="COLOR: red"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;</P>
- <P><SPAN style="COLOR: red"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>pcount++;</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>
- </P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#######################################################################</SPAN></SPAN></P>
- <PRE class=cpp name="code">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;
- }</PRE><PRE class=cpp name="code"> //add by <A href="mailto:xiao@2012-04-16">xiao@2012-04-16</A> : 只获取实际文件大小,因下面烧写文件时,是根据分区大小来烧写文件。对于几百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 <A href="mailto:xiao@2012-04-16">xiao@2012-04-16</A> :
- #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;
- }
- </PRE>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">===========================</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">cmd_mmc.c</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">====================</SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue">注意:此命令</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> movi</SPAN></SPAN><SPAN style="COLOR: blue">也会调用,</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">mmc</SPAN></SPAN><SPAN style="COLOR: blue">也调用。所以</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">u-boot</SPAN></SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">kernel ramdisk system</SPAN></SPAN><SPAN style="COLOR: blue">等多是调用此接口</SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue">也就是</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">do_movi</SPAN></SPAN><SPAN style="COLOR: blue">调用</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">
- do_mmcops</SPAN></SPAN><SPAN style="COLOR: blue">命令来读写</SPAN></SPAN></P>
- <PRE class=cpp name="code">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;
- }
- }
- ---------------------------------------------
- </PRE>
- <P><BR>
- </P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">---------------------------------------------</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue">分析</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> ret = do_movi(NULL, 0, argc, argv);</SPAN></SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue">分析</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> u-boot </SPAN></SPAN>kernel ramdisk
- </SPAN><SPAN style="COLOR: blue">烧写!!!</SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">---------------------------------------</SPAN></SPAN></P>
- <PRE class=cpp name="code">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;
- }
- </PRE>
- <P><BR>
- </P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#########################################################</SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue">分析:</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">cmd_movi.c</SPAN></SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#ifdef CONFIG_CMD_MOVINAND</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>init_raw_area_table(&host->block_dev);</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#endif</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">#########################################################</SPAN></SPAN></P>
- <P> </P>
- <PRE class=cpp name="code">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;
- }
- ------------------------------
- </PRE>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue">总结一下</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">:</SPAN></SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN>raw
- </SPAN><SPAN style="COLOR: blue">分区:</SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN>16M -- 16M + 1K
- </SPAN><SPAN style="COLOR: blue">:</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> efuse</SPAN></SPAN><SPAN style="COLOR: blue">区域</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN><SPAN style="COLOR: blue">标示:</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">initial
- raw table</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>image[1] , 0x1</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN>16M + 1K -- 16M + 1K + 8K
- </SPAN><SPAN style="COLOR: blue">:</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">bl2</SPAN></SPAN><SPAN style="COLOR: blue">前半部分区域</SPAN><SPAN style="COLOR: blue">标示:</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">
- u-boot parted</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>image[2] , 0x10</P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN>16M + 9K -- 16M + 9K +16K :
- </SPAN><SPAN style="COLOR: blue">环境参数保存区域</SPAN><SPAN style="COLOR: blue">:</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">environment</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>image[3], 0x2
- </P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN>16M + 9K +16K -- 16M + 25K +512K :bl2
- </SPAN><SPAN style="COLOR: blue">后半部分区域:</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> u-boot</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>image[4[, 0x4</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN>16M + 25K +512K -- 16M + 25K +512K + 4MB : kernel
- </SPAN><SPAN style="COLOR: blue">区域:</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> kernel</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>image[5],0x8
- </P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN>16M + 25K +512K + 4MB - 16M + 25K +512K + 4MB +26MB</P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN> rootfs</SPAN><SPAN style="COLOR: blue">区域,</SPAN><SPAN style="COLOR: blue">表示:</SPAN><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman">
- rfs</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px">image[5].attribute = 0x8;</SPAN></SPAN></P>
- <P><SPAN style="FONT-SIZE: 16px"><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman"> </SPAN></SPAN><SPAN style="COLOR: blue">方便烧写对应:</SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN></P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN> case 'r':</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN> if (argc != 5)</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN> goto usage;</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN> attribute = 0x8;</P>
- <P><SPAN style="COLOR: blue"><SPAN style="FONT-FAMILY: Times New Roman; FONT-SIZE: 16px"> </SPAN></SPAN> ###############################################################</P>
- <P><BR>
- <BR>
- </P>
- <P> </P>
- <PRE></PRE>