360全景网站制作,网站站点规划实例,组态王如何做网站链接,建设网站需要什么以下内容源于网络资源的学习与整理#xff0c;如有侵权请告知删除。
参考博客 u-boot sdfuse命令烧录分析----从SD卡加载内核_white_bugs的博客-CSDN博客 一、将镜像文件烧写至iNand的步骤 步骤1#xff1a;完成准备工作。 #xff08;1#xff09;准备fastboot相关软件包…以下内容源于网络资源的学习与整理如有侵权请告知删除。
参考博客 u-boot sdfuse命令烧录分析----从SD卡加载内核_white_bugs的博客-CSDN博客 一、将镜像文件烧写至iNand的步骤 步骤1完成准备工作。 1准备fastboot相关软件包。 fastboot在windows端的软件包、fastboot在windows端的驱动包。 2用usb转otg数据线连接电脑和开发板。 3正确安装fastboot的驱动。 在uboot控制台输入fastboot如果尚未安装驱动在windows端的设备管理器相应项目下会显示问号或感叹号此时选中该项目右键选择属性选择更新驱动程序然后选择驱动包所在的路径勾选“包括子文件夹”点击下一项即可。 正确安装fastboot驱动之后显示的内容如下 4准备好待烧录的镜像文件。 假如要烧录linux内核镜像文件、QT4.8文件系统镜像、uboot镜像。相关镜像文件在开发板资料的X210V3S_B\linux\QT4.8目录中账号与密码分别是root、123456。 为了操作方便这里将镜像文件和fastboot软件包的内容放在同一目录。 步骤2在uboot控制台下输入命令fastboot。 步骤3开始烧写uboot、内核以及根文件系统镜像 1在window命令窗口中切换到fastboot软件包所在的路径。 2输入“fastboot devices”查看是否有设备没有不能进行下一步内容。 3利用“fastboot flash inand的分区 镜像文件路径”命令烧写各个镜像文件。 1烧录uboot镜像文件 在windows端输入“fastboot flash bootloader uboot.bin”时windows控制台与uboot控制台显示内容如下。 C:\Users\34316\Desktop\fastbootfastboot flash bootloader uboot.bin
sending bootloader (384 KB)... OKAY
writing bootloader... OKAY Received 17 bytes: download:00060000
Starting download of 393216 bytesdownloading of 393216 bytes finished
Received 16 bytes: flash:bootloader
flashing bootloader
Writing BL1 to sector 1 (16 sectors).. checksum : 0xed75e
writing bootloader.. 49, 1024
MMC write: dev # 0, block # 49, count 1024 ... 1024 blocks written: OK
completed
partition bootloader flashed 2对iNand进行重新分区 在烧写完uboot之后一般要重启此时开发板会运行刚才烧写的uboot然后在uboot控制台输入“fdisk -c 0”对iNand进行分区。 对iNand重新分区的原因是之前的uboot对inand的system分区只有100多MB放不下本次提供的200多MB的根文件系统镜像如果继续用之前的uboot规划的分区烧写根文件系统时会提示文件太大放不能进分区。刚刚烧录的uboot.bin已经重新设置了分区信息烧录并运行它之后执行“fdisk -c 0”就可以对inand重新分区。 之前的uboot对inand的分区情况如下 x210 # fdisk -p 0 //查看编号为0的设备即iNand的分区情况partion # size(MB) block start # block count partition_Id 1 258 22374 529518 0x83 2 120 551892 246114 0x83 3 101 798006 208824 0x83 4 3222 1006830 6600330 0x83
x210 # 新的uboot对inand进行重新分区之后inand中的分区情况如下。 x210 # fdisk -p 0partion # size(MB) block start # block count partition_Id 1 258 22374 529518 0x83 2 258 551892 529518 0x83 3 101 1081410 208824 0x83 4 3084 1290234 6316926 0x83
x210 # 对比可知重新分区后inand的分区2变为了258MB。 3烧录内核镜像文件 重新分区之后在uboot控制台输入fastboot命令。 然后在windows控制台输入“fastboot flash kernel zImage-qt ”。 windows控制台与uboot控制台显示的内容如下 C:\Users\34316\Desktop\fastbootfastboot flash kernel zImage-qt
sending kernel (3566 KB)... OKAY
writing kernel... OKAY Received 17 bytes: download:0037b800
Starting download of 3651584 bytes
...
downloading of 3651584 bytes finished
Received 12 bytes: flash:kernel
flashing kernel
writing kernel.. 1073, 8192
MMC write: dev # 0, block # 1073, count 8192 ... 8192 blocks written: OK
completed
partition kernel flashed 4烧录根文件系统镜像文件 在windows控制台输入“fastboot flash system rootfs_qt4.ext3 ”。 windows控制台与uboot控制台显示的内容如下 C:\Users\34316\Desktop\fastbootfastboot flash system rootfs_qt4.ext3
sending system (262144 KB)... OKAY
writing system... OKAY Received 17 bytes: download:10000000
Starting download of 268435456 bytes
................................................................................
................................................................................
................................................................................
...............
downloading of 268435456 bytes finished
Received 12 bytes: flash:system
flashing systemMMC write: dev # 0, block # 551892, count 529518 ... 529518 blocks written: OK
partition system flashed 二、fastboot命令的源码分析
接下来将分析fastboot命令在uboot端的源码重点在于分析bootloader、kernel、system这三个标签是如何与inand中具体地址关联的。
在uboot分区信息尚未修改的uboot控制台输入fastboot时显示下面信息
x210 # fastboot
[Partition table on MoviNAND]
ptn 0 namebootloader start0x0 lenN/A (use hard-coded info. (cmd: movi))
ptn 1 namekernel startN/A lenN/A (use hard-coded info. (cmd: movi))
ptn 2 nameramdisk startN/A len0x300000(~3072KB) (use hard-coded info. (cmd: movi))
ptn 3 nameconfig start0xAECC00 len0x1028DC00(~264759KB)
ptn 4 namesystem start0x10D7A800 len0x782C400(~123057KB)
ptn 5 namecache start0x185A6C00 len0x65F7000(~104412KB)
ptn 6 nameuserdata start0x1EB9DC00 len0xC96D1400(~3300165KB)
Insert a OTG cable into the connector!
在修改分区信息之后的uboot控制台输入fastboot时显示下面信息
x210 # fastboot
[Partition table on MoviNAND]
ptn 0 namebootloader start0x0 lenN/A (use hard-coded info. (cmd: movi))
ptn 1 namekernel startN/A lenN/A (use hard-coded info. (cmd: movi))
ptn 2 nameramdisk startN/A len0x300000(~3072KB) (use hard-coded info. (cmd: movi))
ptn 3 nameconfig start0xAECC00 len0x1028DC00(~264759KB)
ptn 4 namesystem start0x10D7A800 len0x1028DC00(~264759KB)
ptn 5 namecache start0x21008400 len0x65F7000(~104412KB)
ptn 6 nameuserdata start0x275FF400 len0xC0C6FC00(~3158463KB)
可见这里有bootloader、kernel、…、userdata等标签似乎是分区标志但它们不是真正意义上的分区因为没有写进主引导扇区中它们只是用来表征iNand中某段存储空间的字符串或者说用来表征iNand中某个以扇区为单位的偏移地址的字符串这两种说法意思一样前者指整段空间后者指整段空间的开头。
比如在uboot下使用movi命令例如movi read kernel xxxxx或者“fastboot flash kernel 内核镜像文件”时参数kernel只是一个表征着某个扇区地址的字符串。
那么这些标签和与之对应的地址是在哪里定义的呢
1、set_partition_table函数
我们知道uboot执行fastboot命令时会调用do_fastboot函数。通览do_fastboot函数其中与分区有关的是set_partition_table函数。该函数定义在/common/cmd_fastboot.c文件中。
删除条件编译等内容该函数内容如下
static int set_partition_table()
//删除一些条件编译的代码#elif defined(CFG_FASTBOOT_SDMMCBSP)
{int start, count;unsigned char pid;pcount 0;#if defined(CONFIG_FUSED) //没有定义这个宏/* FW BL1 for fused chip */strcpy(ptable[pcount].name, fwbl1);ptable[pcount].start 0;ptable[pcount].length 0;ptable[pcount].flags FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;pcount;
#endif/* 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 */strcpy(ptable[pcount].name, ramdisk);ptable[pcount].start 0;ptable[pcount].length 0x300000;ptable[pcount].flags FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD;pcount;/* Config */get_mmc_part_info(0, 1, start, count, pid);if (pid ! 0x83)goto part_type_error;strcpy(ptable[pcount].name, config);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;/* System */get_mmc_part_info(0, 2, start, count, pid);if (pid ! 0x83)goto part_type_error;strcpy(ptable[pcount].name, system);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 */get_mmc_part_info(0, 3, 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;/* Data */get_mmc_part_info(0, 4, 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;#if 1 // Debugfastboot_flash_dump_ptn();
#endif//省略部分代码
}
由此可知这个函数只设置了config、system、cache、userdata这些标签所对应的空间起始扇区、扇区数目、标志没有对bootloader、kernel、ramdisk这些标签进行设置。
如何设置的呢以config标签为例说明设置过程。
首先代码“get_mmc_part_info(0, 1, start, count, pid);”。第一个参数0表示存储设备的编号为0也就是iNand第二个参数1表示这个存储设备的分区1下面2,3,4是分区2,3,4第三第四第五个参数前面的表示它们是输出型参数其中start表示分区1的以扇区为单位的起始地址count表示分区1有多少个扇区。这个函数返回时start22374count529518。
然后将分区1的以扇区为单位的起始地址转换成以字节为单位的起始地址将分区1的扇区总数转换成以字节为单位的空间大小。这里的CFG_FASTBOOT_SDMMC_BLOCKSIZE值为512因为一个扇区大小是512字节。
因为22374*5121145548810 AECC0016529518*5121028DC0016因此config标签对应的空间信息为startAECC00length1028DC00。
这与执行fastboot命令时显示的数据是一样的执行fastboot命令时之所以会显示信息是因为函数do_fastboot中间接调用了fastboot_flash_dump_ptn函数该函数用来打印这些信息。
同理可以得到其他标签对应的空间的信息这里不赘述。
注意config标签所对应的空间与分区1是一致的因为本来就是先调用get_mmc_part_info函数来获取分区1的数据然后用这些数据来填充congfig标签所对应的空间的数据结构ptable[0]。
同理system标签所对应的空间与分区2的空间是一致的。我们知道system标签所对应的空间是用来烧录根文件系统的也就是说根文件系统将来存储在system标签所对应的空间由于这个空间与分区2的空间一致所以可以说根文件系系统位于分区2因此uboot给kernel传参时bootargs里面有一个项目“rootmmcblk0p2 rw”表示的就是根文件系统在设备0的第2分区。
同理cache、userdata标签所对应的空间与分区3、分区4一致。
因此fastboot命令体系下的“分区表”如下。
分区号分区名称ptable[0]bootloader暂无对应ptable[1]kernel暂无对应ptable[2]ramdisk暂无对应ptable[3]config对应着分区1ptable[4]system对应着分区2ptable[5]cache对应着分区3ptable[6]userdata对应着分区4上面写到set_partition_table函数只是设置了config、system、cache、userdata这些标签对应的空间没有对bootloader、kernel、ramdisk这些标签进行设置只是简单地设置为0。
我们利用fastboot flash来烧录镜像时常用bootloaderkernelsystem这三个标签。其中system标签对应的空间是分区2那bootLoader、kernel标签对应什么空间呢
注意到执行fastboot时关于bootloader、kernel、ramdisk标签显示的内容中有“(use hard-coded info. (cmd: movi))”这说明这三个标签可能以硬编码方式写在了movi命令对应的函数中。
对do_movi函数进行分析见博文do_movi函数的源码分析可知该命令体系下也有一个“分区表”没有写入主引导区叫做raw分区表分区表里有u-boot、kerne、rfs等分区这些分区都有实实在在的范围而不像fastboot命令体系下bootLoader、kernel、ramdisk分区那样没有实实在在的范围简单地设置为0而已。
fastboot命令体系下的kernel分区兴许对应着movi命令体系下的kernel分区因为两者都是用字符串“kernel”表示。fastboot命令体系下的bootloader分区与movi命令体系下的u-boot分区两者的名字不同但意义一样会不会也是对应关系呢如果是执行“fastboot flash bootloader uboo.bin”时bootloader这个标签是如何转为u-boot的。
另外经过思考既然使用“movi write u-boot xxxxxx”时表示将内存地址xxxxx处的内容写进也就是烧录到inand的ub-boot分区使用“fastboot flash bootloader uboo.bin”时表示将uboot的镜像文件写进bootloader分区两者操作本质一样那fastboot flash在uboot端应该也采用movi命令。
选择几个执行“fastboot flash bootloader uboo.bin”时在uboot中显示的内容的关键词定位到位于/common/cmd_fastboot.c文件中的rx_handler函数。
该函数的部分内容如下
static int rx_handler (const unsigned char *buffer, unsigned int buffer_size)
{//省略部分代码/* flashFlash what was downloaded */if (memcmp(cmdbuf, flash:, 6) 0){//省略部分代码struct fastboot_ptentry *ptn;ptn fastboot_flash_find_ptn(cmdbuf 6);//省略部分代码/* 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);}}
}
其中的write_to_ptn函数内容与分析如下
/*
该函数功能是将镜像写进fastboot命令体系下的分区。
以执行“fastboot flash bootloader uboot.bin”为例进行说明。
以执行“fastboot flash system rootfs_qt4.ext3”为例进行说明。
*///fastboot命令体系下的某个分区名储存着待烧录数据的某个内存地址待烧写的数据长度
static int write_to_ptn(struct fastboot_ptentry *ptn, unsigned int addr, unsigned int size)
{ int ret 1;char device[32], part[32];char start[32], length[32], buffer[32];char *argv[6] { NULL, write, NULL, NULL, NULL, NULL, };/* 此时argv[1]write。根据下面的分析write_to_ptn函数调用do_movi函数或者do_mmcops来完成烧写。填充这个字符指针数组其实是在构造“movi write u-boot xxxxx”或者“mmc write system …”字符串。*/int argc 0;if ((ptn-length ! 0) (size ptn-length))//因为bootloader的ptn-length0所以不会执行。{ //假定要烧写的根文件系统镜像小于system分区因此不会执行。//可见这里烧录的镜像如果大于该分区则会报错返回。printf(Error: Image size is larger than partition size!\n);return 1;}printf(flashing %s\n, ptn-name);// 打印信息“ flashing bootloader”或者“ flashing system ”。if (ptn-flags FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD)//表示在烧写system分区{argv[2] device;//argv[0]NULL,argv[1]writeargv[3] buffer;argv[4] start;argv[5] length;sprintf(device, mmc %d, 1); //argv[2]mmc 1sprintf(buffer, 0x%x, addr);//argv[3]0x内存地址表示储存着待烧录数据的某个内存地址sprintf(start, 0x%x, (ptn-start / CFG_FASTBOOT_SDMMC_BLOCKSIZE)); //argv[4]0x分区起始扇区system分区起始扇区号sprintf(length, 0x%x, (ptn-length / CFG_FASTBOOT_SDMMC_BLOCKSIZE));//argv[5]0x分区扇区总数system分区扇区的总数ret do_mmcops(NULL, 0, 6, argv);//注意内部是怎么写的/*argv[0]NULLargv[1]writeargv[2]mmc 1argv[3]0x内存地址argv[4]0x分区起始扇区argv[5]0x分区扇区总数*/}else if (ptn-flags FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD)//表示是在烧写bootloader、kernel{argv[2] part;//argv[0]NULLargv[1]writeargv[3] buffer; argc 4;//argc 4/* use the partition name that can be understood by a command, movi */if (!strcmp(ptn-name, bootloader))//简单理解为给bootloader换个别名{strncpy(part, u-boot, 7);//将fastboot的分区“bootloader”转换成movi中的分区“u-boot”这里argv[2]u-boot}else if (!strcmp(ptn-name, ramdisk))//没涉及到这个略过{strncpy(part, rootfs, 7);argv[4] length;sprintf(length, 0x%x, ((size CFG_FASTBOOT_SDMMC_BLOCKSIZE - 1)/CFG_FASTBOOT_SDMMC_BLOCKSIZE ) * CFG_FASTBOOT_SDMMC_BLOCKSIZE);argc;//argc 5}/* kernel, fwbl1 */ //这里表示在烧写kernelelse{argv[2] ptn-name;//因为kernel在fastboot中的分区名和在movi中的分区名一致所以直接赋值}sprintf(buffer, 0x%x, addr);//argv[3]0x内存地址表示储存着待烧录数据的某个内存地址ret do_movi(NULL, 0, argc, argv);/* argc4argv[0]NULLargv[1]writeargv[2]u-boot argv[3]0x内存地址argv[4]0x数据长度argv[5]NULL*//* the return value of do_movi is different from usual commands. Hence the followings. */ret 1 - ret;}return ret;
}
由此可知
1bootloader转换成u-boot是在write_to_ptn函数中完成的。
2write_to_ptn函数通过调用do_mmcops(NULL, 0, 6, argv)来完成system区的烧写。
3write_to_ptn函数通过调用do_movi(NULL,0,argc,argv)来完成bootloader或kernel区的烧写。在do_movi函数中调用movi_write_bl1(addr)函数来完成bl1在扇区1~16的烧写调用run_command(run_cmd, 0)函数来完成bl2在49~xxx扇区的烧写。
而run_command(run_cmd, 0)通过运行命令解析函数得知要执行mmc命令而mmc命令又对应着函数do_mmcops而system分区的烧写也是由这个函数完成的因此有必要分析do_mmcops函数。
该函数主要实现从MMC中读数据或者写数据到MMC中。 三、fdisk\fastboot\movi三者的分区表关系