免费手机网站建设,任丘建设网站,手机网站搭建用什么软件?,重庆百科网站推广文章目录 相关结构体flash_eraseall 函数实现flash_eraseall 实现流程图 文件路径#xff1a;busybox-1.20.2/miscutils/flash_eraseall.c
相关结构体
MTD 相关信息结构体
struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设… 文章目录 相关结构体flash_eraseall 函数实现flash_eraseall 实现流程图 文件路径busybox-1.20.2/miscutils/flash_eraseall.c
相关结构体
MTD 相关信息结构体
struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设备属性标志__u32 size; // mtd设备的大小__u32 erasesize; // MTD设备的擦除单元大小对于 NandFlash来说就是 Block的大小__u32 writesize; // MTD设备的读写单元大小对于 NandFlash来说就是page 的大小__u32 oobsize; // oob区域大小__u64 padding; // 有效的oob区域大小
};flash_eraseall 函数实现
假如内核位于第二个分区即mtd2在擦除该分区时使用的命令是./flash_eraseall /dev/mtd2
int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
{struct jffs2_unknown_node cleanmarker;mtd_info_t meminfo;int fd, clmpos, clmlen;erase_info_t erase;struct stat st;unsigned int flags;char *mtd_name;opt_complementary 1;flags BBTEST | getopt32(argv, jq); // 获取命令行中参数mtd_name argv[optind];fd xopen(mtd_name, O_RDWR); // 打开设备/dev/mtd2fstat(fd, st); if (!S_ISCHR(st.st_mode)) // 判断设备/dev/mtd2 是否为字符设备bb_error_msg_and_die(%s: not a char device, mtd_name);xioctl(fd, MEMGETINFO, meminfo); // 获取内存信息参看结构体1erase.length meminfo.erasesize;if (meminfo.type MTD_NANDFLASH)flags | IS_NAND;clmpos 0;clmlen 8;if (flags OPTION_J) { // jffs2格式化分区uint32_t *crc32_table;crc32_table crc32_filltable(NULL, 0);cleanmarker.magic cpu_to_je16(JFFS2_MAGIC_BITMASK);cleanmarker.nodetype cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);if (!(flags IS_NAND))cleanmarker.totlen cpu_to_je32(sizeof(struct jffs2_unknown_node));else {struct nand_oobinfo oobinfo;xioctl(fd, MEMGETOOBSEL, oobinfo);/* Check for autoplacement */if (oobinfo.useecc MTD_NANDECC_AUTOPLACE) {/* Get the position of the free bytes */clmpos oobinfo.oobfree[0][0];clmlen oobinfo.oobfree[0][1];if (clmlen 8)clmlen 8;if (clmlen 0)bb_error_msg_and_die(autoplacement selected and no empty space in oob);} else {/* Legacy mode */switch (meminfo.oobsize) {case 8:clmpos 6;clmlen 2;break;case 16:clmpos 8;/*clmlen 8;*/break;case 64:clmpos 16;/*clmlen 8;*/break;}}cleanmarker.totlen cpu_to_je32(8);}cleanmarker.hdr_crc cpu_to_je32(crc32_block_endian0(0, cleanmarker, sizeof(struct jffs2_unknown_node) - 4, crc32_table));}/* Dont want to destroy progress indicator by bb_error_msgs */applet_name xasprintf(\n%s: %s, applet_name, mtd_name);for (erase.start 0; erase.start meminfo.size; // 循环擦除flash芯片按块大小擦除 meminfo.erasesizeerase.start meminfo.erasesize) {if (flags BBTEST) {int ret;loff_t offset erase.start;ret ioctl(fd, MEMGETBADBLOCK, offset); //通过offset判定该偏移处是否是坏块if (ret 0) {if (!(flags OPTION_Q)) // 判断是否为静默模式不打印信息bb_info_msg(\nSkipping bad block at 0x%08x, erase.start);continue;}if (ret 0) { // block块表是不可用的某些flash类型如NOR/* Black block table is not available on certain flash* types e.g. NOR*/if (errno EOPNOTSUPP) {flags ~BBTEST;if (flags IS_NAND)bb_error_msg_and_die(bad block check not available);} else {bb_perror_msg_and_die(MEMGETBADBLOCK error);}}}//更新擦除进度条if (!(flags OPTION_Q))show_progress(meminfo, erase);// 块擦除操作xioctl(fd, MEMERASE, erase);/* format for JFFS2 ? */if (!(flags OPTION_J))continue;/* write cleanmarker */if (flags IS_NAND) {struct mtd_oob_buf oob;oob.ptr (unsigned char *) cleanmarker;oob.start erase.start clmpos;oob.length clmlen;xioctl(fd, MEMWRITEOOB, oob);} else {xlseek(fd, erase.start, SEEK_SET);/* if (lseek(fd, erase.start, SEEK_SET) 0) {bb_perror_msg(MTD %s failure, seek);continue;} */xwrite(fd, cleanmarker, sizeof(cleanmarker));/* if (write(fd, cleanmarker, sizeof(cleanmarker)) ! sizeof(cleanmarker)) {bb_perror_msg(MTD %s failure, write);continue;} */}if (!(flags OPTION_Q))printf( Cleanmarker written at %x., erase.start);}if (!(flags OPTION_Q)) {show_progress(meminfo, erase);bb_putchar(\n);}if (ENABLE_FEATURE_CLEAN_UP)close(fd);return EXIT_SUCCESS;
}注 cleanmarker是用于标记一个块是否完整地被擦除的。 在Flash存储器中只有在块完整地擦除后才能进行写入操作。这是因为在某些特殊情况下比如系统在擦除周期末尾重启可能导致Flash中的位不稳定即读出的值可能在不同时间点不一致。为了解决这个问题引入了cleanmarker来标记块是否真正完整地擦除。
在制作jffs2文件系统时由于文件系统会对块进行管理因此不再需要使用cleanmarker标记。 在制作文件系统时可以使用-n或–no-cleanmarker选项来表示不使用cleanmarker。这意味着在第一次挂载文件系统时cleanmarker并不重要。而在使用mtd工具flash_eraseall对Flash进行格式化时应该使用 -j 参数来带上cleanmarker标记。这样在擦除完Flash后会在oobout-of-band区域设置相应的cleanmark位表示该块已经完整擦除。这样在以后对该块进行操作时jffs2文件系统可以发现该块已经被擦除从而避免浪费时间重新擦除已经是0xff的块。 flash_eraseall 实现流程图