实验证明在一片Norflash上划分两个TrueFFS分区的误区
实验证明在一片Norflash上划分两个TrueFFS分区的误区 DanielLee_USTB?2013-8-1 QQ:382899443 ? ? ? ? ?这几天研究flash TrueFFS驱动,以及挂载dosfs文件系统,发现格式化C盘后再重启系统出现挂载失败的情况,于是决定做flash重新分区以及在同一个Norflash上划分两个磁盘分区的实验。网上有一些文章讲了修改步骤以及在划分2的非n次幂大小空间出现了分歧,令人感到困惑。如果已经找到这些文章可以与本文做一下对比。下面就通过一些了的实验说明问题。 ???????? 实验条件:vxworks5.5, s3c2410开发板,flash sst39vf160大小为8M,起始地址为0x00000000,结束地址为0x00800000。 ???????? 系统镜像存储区为0-2M,C盘dosfs文件系统地址为2M-8M,为6M大小。 一、查看信息 查看C盘: -> dosFsShow "/C:" …… - total number of sectors:??????? 11,747 ?-bytes per sector:????????? 512 …… - free space on volume:?? 1,990,656 bytes value = 0 = 0x0 发现确实为6M大小 查看C盘有很多文件: -> ls "/C" /C/butterfly240.bin …… /C/blackbeauty480.bin /C/my.txt value = 0 = 0x0 下面将C盘格式化掉: -> dosFsVolFormat("/C",0) …… ?? value = 0 = 0x0 再查看C盘大小: dosFsShow("/C:") - free space on volume:?? 5,988,352 bytes value = 0 = 0x0 确实已经格式化成功,整个格式化过程仅1S多点,可见vxworks格式化真的很快。 二、改变C盘大小 将C盘大小从6M改为4M (1)修改sst39MTDIdentify if (vol.socket->serialNo == 0){ ?????????????????? flSetWindowSize(vol.socket,FIRST_FLASH_SIZE>>12); ?????????????????? vol.chipSize= 0x400000;//FIRST_FLASH_SIZE; ?????????????????? vol.map?? = sst39MTDMap0; ?????????????????? vol.mtdVars= &mtdVars[flSocketNoOf(vol.socket)]; ???????? ??????? baseFlashPtr = (FlashWPTR)vol.map(&vol,(CardAddress)0,vol.interleaving); ???????? } (2)网上说窗口大小到大于等于chipsize,即实际分区的大小,先这样试试,稍后验证,修改#define ?FIRST_FLASH_SIZE? ?????????????????? 0x800000//0x600000窗口大小为整片flash大小。 (3)添加格式化函数,挂载任何文件系统之前都需要先格式化 ? ? ? ? ??添加擦除函数: ??tffsDevFormatParams params = {{0,99,1,0x10000,NULL,{0,0},2,NULL},FTL_FORMAT}; 其中共用两个参数: ? ? ? ? ?tffsFormatParams ?=? {0,NULL} ???????? 这个参数的详细介绍在installDirtargethtffstffsDrv.h?有详细的介绍,除了第一项以外都不用修改。其中第一个参数是擦除的偏移地址,一般为系统镜像留出,如果系统镜像不放在文件系统中的话,而是放在rawdata中,这一项就设置为0,其实是不需要改动的。 ???????? MyFormatC(); ???????? if(usrTffsConfig(0,"/C")==0) ???????? { ?????????????????? ioDefPathSet("/C"); ???????? }; 结果: sst39VF160 serialNo=0 sst39VF160 serialNo=0 sst39VF160 serialNo=0 -> initisizing....... CMD0 Chk_CMDend:1. In idle. In SD ready. End id. In stand-by sd/mmc_card_init OK. RK2410 USB DEVICE Download FileTest-UsbRxAddr=0x318395c4 Wait for usb line...... devs drv name??????????????? ? 0/null?????????????? ? 1/tyCo/0???????????? ? 1/tyCo/1???????????? ? 3 /ram??????????????? ? 5host:?????????????? ? 8/vio??????????????? ? 3/C????????????????? ? 3/E????????????????? value = 25 = 0x19 = PLL_ON_START + 0x18 -> dosFsShow "/C:" - allocation group size:??? 1 clusters ?-free space on volume: 3,973,120 bytes value = 0 = 0x0 ? ? ? ? ?结果是成功的,但这里面存在两个问题: ? ? ? ?(1)为什么在所有改动之前(没有加入格式化函数),使用Jlink把整片flash全部擦除,直接挂载后6M不成功?????? ? ? ? ?(2)为什么窗口大小是整片flash大小而不是FIRST_FLASH_SIZE呢? 对于(1)看看格式化的问题。基于以上结果在usrAppinit()中注释掉//MyFormatC()直接挂载C盘,注之前已运行过一次,即对C盘已经格式化。使用Jlink下载: - Erasing affected sectors ... ??? - Erasing sector 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,256,272,288,304 ??? - Erase operation completed successfully ?- Target programmed successfully - Completedafter 92.032 sec注意:Jlink擦除了304个sector 结果: sst39VF160 serialNo=0 ->initisizing....... CMD0Chk_CMDend:1. In idle. In SD ready. End id. In stand-by sd/mmc_card_initOK. RK2410 USBDEVICE Download File Test-UsbRxAddr=0x31839fe4 Wait for usbline...... devs drv name??????????????? ? 0 /null?????????????? ? 1 /tyCo/0???????????? ? 1 /tyCo/1???????????? ? 3 /ram??????????????? ? 5 host:?????????????? ? 8 /vio??????????????? ? 3 /C????????????????? ? 3 /E????????????????? value = 25 =0x19 = PLL_ON_START + 0x18 挂载成功 如果使用Jlink先erase chip 呢? Erasing 2048 sectors,0x0 - 0x7FFFFF ?- RAM tested O.K. ?- Erasing sector 0,304,……,1488,1504,1520 ?- Erase operation completed successfully -Completed after 47.205 sec ???????? 可以看出一共擦除了2048个sectors,显然把之前从2M-6M格式化的空间也擦除掉了,所以再写入系统镜像挂载C盘是失败的。同时也说明Jlink自己擦除已用flash空间的时候并没有擦除已经格式化的空间,不知道使用的是什么方法。 ???????? 原来如果是新做的开发板,或是把flash完全擦除,flash内完全没有内容,需要在程序中先使用MyFormatC()将flash进行格式化,之后在进行挂载,然后在程序中删掉MyFormatC(),再编译下载镜像,防止每次运行都格式化一次。买的开发板的话厂家已经做了这一步了。 ???????? 再看(2),恢复到之前的运行结果,即不注释MyFormatC(),将#define FIRST_FLASH_SIZE定义的窗口大小,改为文件系统实际大小0x400000 运行结果: sst39VF160 serialNo=0 sst39VF160 serialNo=0 sst39VF160 serialNo=0 -> initisizing....... CMD0 Chk_CMDend:1. In idle. In SD ready. End id. In stand-by sd/mmc_card_init OK. RK2410 USB DEVICE Download FileTest-UsbRxAddr=0x318385bc Wait for usb line...... devs drv name??????????????? ? 0/null?????????????? ? 1/tyCo/0???????????? ? 1/tyCo/1???????????? ? 3/ram??????????????? ? 5host:?????????????? ? 8/vio??????????????? ? 3/C????????????????? ? 3/E????? ???????? 居然成功了!这就很明了了,窗口大小可以和文件系统大小一样,而不是网上说的必须大于等于芯片大小,在vxworks BSP中显然也没有将文件系统大小与窗口大小做宏定义上的区分,人家这么做说明两者相同完全是可以的。所以,遇到问题要自己分析实验,对网上的说法要批判性的吸收,不能盲从。 三、重新划分为两个磁盘为偶数大小 ???????? 为了更好对dosfs文件系统有跟好的了解,下面将原来的6M空间划分为4M的C盘以及2M的D盘。 ???????? ConfigTffs.h基地址以及大小: ???????? C盘基地址为 ???????? #defineFIRST_FLASH_START???????????????????? 0x200000? //2M 开始 ???????? #defineFIRST_FLASH_SIZE???????????????????????? 0x400000? //0x600000 改为4M大小 ???????? D盘基地址以及大小: ???????? #defineSECOND_FLASH_START ? ? ? ? ? ? ?0x600000 ?//6M位置开始 ???????? #defineSECOND_FLASH_SIZE?????????????????? 0x200000 // 8M大小 ???????? 另外,看SECOND_FLASH_BASE到底是0x600000,还是0x000000.因为这两个分区时在同一个flash中进行的,由于对flash的写和擦除都需要写入解锁命令,这个命令对于两个分区来说是没有区别的,都应该写在flash中同一地址上,因此断定SECOND_FLASH_BASE为0x000000。 ? ? ? ? 1.修改:sst39vf160.c sst39MTDIdentify() static void FAR0 *??? sst39MTDMap0(FLFlash *vol,CardAddress addr,int length) { ???????? UINT32ret; ???????? ret= FIRST_FLASH_START +addr; ???????? return(void FAR0 *)ret; } static void FAR0 *??? sst39MTDMap1(FLFlash *vol,int length) { ???????? UINT32ret; ???????? ret= SECOND_FLASH_START +addr; ???????? return(void FAR0 *)ret; } ???????? if(vol.socket->serialNo == 0){ ?????????????????? flSetWindowSize(vol.socket,FIRST_FLASH_SIZE>>12); ?????????????????? vol.chipSize= FIRST_FLASH_SIZE;? //0x400000 ?????????????????? vol.map?? = sst39MTDMap0; ?????????????????? vol.mtdVars= &mtdVars[flSocketNoOf(vol.socket)]; ???????? ??????? baseFlashPtr = (FlashWPTR)vol.map(&vol,(CardAddress)0,vol.interleaving); ???????? } ???????? elseif(vol.socket->serialNo == 1) ???????? { ?????????????????? flSetWindowSize(vol.socket,SECOND_FLASH_SIZE>>12); ?????????????????? vol.chipSize= SECOND_FLASH_SIZE;? //0x200000 ?????????????????? vol.map?? = sst39MTDMap1; ?????????????????? vol.mtdVars= &mtdVars[flSocketNoOf(vol.socket)]; ???????? ??????? baseFlashPtr = (FlashWPTR)vol.map(&vol,vol.interleaving); ???????? } flSetWindowSize 这个函数设置指出了窗口的大小,是4KB页的倍数,也是右移12位的原因。其实这个WindowSize设置的可以比实际申请的空间大的,但是绝对不能小。 ? ? ? ? 2.在sysTffs.c文件中修改Socket接口 ???????? if? (noOfDrives == 0) ??? ???????? vol.window.baseAddress =FIRST_FLASH_START >> 12; ???else if(noOfDrives == 1) ?????????????????? vol.window.baseAddress= SECOND_FLASH_START >> 12; ???????? noOfDrives++; LOCAL void rfaSetWindow ??? ( ??? ???????? FLSocket vol?????????????? /* pointer identifying drive */ ??? ) ??? { ???/* Physical base as a 4K page */ ???if???? (vol.serialNo == 0){ ??? ???????? vol.window.baseAddress =FIRST_FLASH_START >> 12; ??? ???????? flSetWindowSize (&vol,FIRST_FLASH_SIZE >> 12); ??? } ???else if(vol.serialNo == 1){ ??? ???????? vol.window.baseAddress =SECOND_FLASH_START >> 12; ??? ???????? flSetWindowSize (&vol,SECOND_FLASH_SIZE >> 12); ???????? } } ? ? ?3.挂载dosfs修改usrAppInit.c ???MyFormatC(); ???????? if(usrTffsConfig(0,"/C")==0) ???????? { ?????????????????? ioDefPathSet("/C"); ???????? }; ???????? MyFormatD(); ???????? if(usrTffsConfig(1,"/D")==0) ???????? { ?????????????????? ioDefPathSet("/D"); ???????? }; ???结果: sst39VF160serialNo=0 sst39VF160serialNo=0 sst39VF160serialNo=0 sst39VF160serialNo=1 sst39VF160serialNo=1 sst39VF160serialNo=1 ->initisizing....... CMD0Chk_CMDend:1. In idle. In SDready. End id. Instand-by sd/mmc_card_initOK. RK2410USB DEVICE Download File Test-UsbRxAddr=0x31817488 Wait forusb line...... devs drvname??????????????? ? 0 /null?????????????? ? 1 /tyCo/0???????????? ? 1 /tyCo/1???????????? ? 3 /ram??????????????? ? 5 host:?????????????? ? 8 /vio??????????????? ? 3 /C????????????????? ? 3 /D????????????????? ? 3 /E????????????????? value =25 = 0x19 = PLL_ON_START + 0x18 查看空间: ->dosFsShow "/C:" - totalnumber of sectors:??????? 7,791 -allocation group size:??? 1 clusters ?- free space on volume: 3,120bytes ->dosFsShow "/D:" - totalnumber of sectors:??????? 3,831 -allocation group size:??? 1 clusters ?- free space on volume: 1,949,696bytes value = 0= 0x0?????????? ? ? ? ? C盘和D盘都挂载成功了,而且容量都是正确的。现在先总结一下以前实验不成功的原因:(1)挂载之前没有格式化,所以挂载失败(2)挂载盘卷号写错误导致挂载出现异常。而且通过验证,窗口设置的大小flSetWindowSize (&vol,FIRST_FLASH_SIZE >> 12);与分区大小一致就可以了,用不着设置成整个芯片的大小。 四、重新划分为两个磁盘为非2的N次幂大小 ? ? ? ? 现在把C盘划分为3M,D盘划分为3M试一下 ? ? ? ? 做如下定义: #define FIRST_FLASH_BASE?????????????????????? 0x000000 #define FIRST_FLASH_START???????????????????? 0x200000 #define FIRST_FLASH_SIZE???????????????????????? 0x300000//0x400000 #define FIRST_FLASH_TYPE????????? 0x01 #define SECOND_FLASH_BASE????????????????? 0x000000 #define SECOND_FLASH_START????? ??? 0x500000//0x600000 #define SECOND_FLASH_SIZE?????????????????? 0x300000//0x200000 #define SECOND_FLASH_TYPE????????????????? 0x02 编译下载,结果: sst39VF160serialNo=0 sst39VF160serialNo=0 sst39VF160serialNo=0 sst39VF160serialNo=1 sst39VF160serialNo=1 sst39VF160serialNo=1 devs drvname??????????????? ? 0 /null?????????????? ? 1 /tyCo/0???????????? ? 1 /tyCo/1???????????? ? 3 /ram??????????????? ? 5 host:?????????????? ? 8 /vio??????????????? ? 3 /C????????????????? ? 3 /D????????????????? ? 3 /E????????????????? ->dosFsShow "/C:" - free space on volume:?? 2,961,408 bytes value = 0= 0x0 ->dosFsShow "/D:" - free space on volume:?? 2,408 bytes value = 0= 0x0 ? ? ? ? 为了保险起见,又尝试重新划分为1M和5M大小,结果为: ->dosFsShow "/C:" - free space on volume:?? 940,032 bytes value = 0= 0x0 ->dosFsShow "/D:" - free space on volume:?? 4,984,832 bytes value = 0= 0x0 ? ? ? ? ?同样是成功的。 ???????? 之所以做这个实验,是因为看到网上 “只能建立2的n次幂M大小的文件系统的疑问”的说法,说如果遇到非2的n次幂情况格式化flash不成功,解决的方法是修改窗口为整个芯片大小,其实这样的说法是不合理的。因为本实验发现即使将C盘和D盘均分为3M以及分为1M和5M都是可以成功的,是不是2的n次幂的磁盘空间修改的方法都一样,都是修改configTffs.h里的宏定义。 ? ? ? ? 由于vxworks系统版本以及硬件环境上存在差异,不排斥其他博文说明的情况,只是在找原因的时候要多动手做实验自己找原因,不能盲从。欢迎讨论。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |