这几天,使用立宇泰2440 开发板光盘的BSP放到手持机上,运行是没有问题了,但是却发现不了盘符。后来看串口打印信息,原来是页大小根本没有识别出来,本来是2048byte的,但是打印出来确实512byte。
- FMD::FMD_Init
- FMD::FMD_Init - pBSPArgs->nfsblk = 0xffffffff
- FMD::FMD_Init - READ_REGISTER_BYTE(pNFSBLK) = 0x0
- FMD::FMD_Init Softreset .....
- FMD::FMD_Init Done
- MID = 0xec, DID = 0xdc 4th Cycle : 0x10
- NUMBLOCKS : 4096(0x1000), SECTORSPERBLOCK = 256(0x100), BYTESPERSECTOR = 512(0x200)
- //每扇区字节数并不正确。是不是这个原因导致flash盘符发现不了呢?我猜我的flash驱动
BYTESPERSECTOR 不正确就从它入手
C:/WINCE500/PLATFORM/SMDK2440A/Src/Common/Smartmedia/fmd/fmd.cpp
- // OK, instead of reading it from the chip, we use the hardcoded
- // numbers here.
- pFlashInfo->dwNumBlocks = wNUM_BLOCKS;
- pFlashInfo->wSectorsPerBlock = PAGES_PER_BLOCK;
- pFlashInfo->wDataBytesPerSector = SECTOR_SIZE;
- pFlashInfo->dwBytesPerBlock = (pFlashInfo->wSectorsPerBlock * pFlashInfo->wDataBytesPerSector);
- RETAILMSG(1, (TEXT("NUMBLOCKS : %d(0x%x), SECTORSPERBLOCK = %d(0x%x), BYTESPERSECTOR = %d(0x%x) /r/n"), pFlashInfo->dwNumBlocks, pFlashInfo->dwNumBlocks, pFlashInfo->wSectorsPerBlock, pFlashInfo->wSectorsPerBlock, pFlashInfo->wDataBytesPerSector, pFlashInfo->wDataBytesPerSector));
很明显,SECTOR_SIZE是关键所在。看看SECTOR_SIZE调用以及定义的地方
// TODO: Make sector size generic
static BYTE g_pFLSBuffer[SECTOR_SIZE];——从这里看来,他像个宏定义,是常数。
- #ifndef __NAND_H__
- #define __NAND_H__
- #define LARGE_BLOCK_NAND 0
- #define SMALL_BLOCK_NAND 1
- #define USE_NFCE 0
- #define USE_GPIO 1
- #define LB_BLOCK_LOOP 1
- #define SB_BLOCK_LOOP 8
- //为什么会这么定义呢?这样怎么样识别大小页?
- #define SECTOR_SIZE 512
- #define SPARE_SIZE 16
- #define PAGES_PER_BLOCK 256 // Phisical 64 * logical 4
- #define NAND_PAGE_CNT PAGES_PER_BLOCK /* Each Block has 32 Pages */
- #define NAND_PAGE_SIZE SECTOR_SIZE /* Each Page has 512 Bytes */
- #define NAND_BLOCK_SIZE (NAND_PAGE_CNT * NAND_PAGE_SIZE)
- #endif // __NAND_H_.
- ======================nand.h======================
我查找SECTOR_SIZE 出现的地方,全部是512的,三星介绍说已经支持大页flash,真是不太负责。
继续多看几个地方
现在我加了一些串口打印信息
- OEMIoControl: Unsupported Code 0x10100b4 - device 0x0101 func 45
- OEMIoControl: Unsupported Code 0x101008c - device 0x0101 func 35
- FMD::FMD_Init
- FMD::FMD_Init - pBSPArgs->nfsblk = 0xffffffff
- FMD::FMD_Init - READ_REGISTER_BYTE(pNFSBLK) = 0x0
- FMD::FMD_Init Softreset .....
- FMD::FMD_Init Done
- [S2440: IN] ++_ReadXID()
- MID = 0xec, DID = 0xdc 4th Cycle : 0x10
- NUMBLOCKS : 4096(0x1000), SECTORSPERBLOCK = 64(0x40), BYTESPERSECTOR = 2048(0x800)
- FMD_LB_GetBlockStatus (0x0)0x0
- FMD::FMD_LB_ReadSector 0x0
- FMD::NAND_LB_ReadSectorInfo 0x0
- FMD::FMD_LB_ReadSector 0x0
- FMD::NAND_LB_ReadSectorInfo 0x0
- FMD_LB_GetBlockStatus (0x1)0x40
- FMD::FMD_LB_ReadSector 0x100
- FMD::NAND_LB_ReadSectorInfo 0x100
- FMD::FMD_LB_ReadSector 0x40
- FMD::NAND_LB_ReadSectorInfo 0x40
- //------------到了4096就出现错误
- [ERROR:nLength>4096]
- [ERROR:nLength>4096]
- FMD::FMD_LB_ReadSector 0x2b540
- FMD::NAND_LB_ReadSectorInfo 0x2b540
- FMD_LB_GetBlockStatus (0xad6)0x2b580
- FMD::FMD_LB_ReadSector 0xad600
- FMD::NAND_LB_ReadSectorInfo 0xad600
- FMD::FMD_LB_ReadSector 0x2b580
- FMD::NAND_LB_ReadSectorInfo 0x2b580
- .............................
- .............................
- .............................
- //一直检测到这里
- FMD_LB_GetBlockStatus (0xfff)0x3ffc0
- FMD::FMD_LB_ReadSector 0xfff00
- FMD::NAND_LB_ReadSectorInfo 0xfff00
- FMD::FMD_LB_ReadSector 0x3ffc0
- FMD::NAND_LB_ReadSectorInfo 0x3ffc0
- FMD_OEMIoControl: unrecognized IOCTL (0x71c24).
- OEMIoControl: Unsupported Code 0x10100d0 - device 0x0101 func 52
- OEMIoControl: Unsupported Code 0x10100f8 - device 0x0101 func 62
------根据上面的打印信息启动时候和FMD_LB_GetBlockStatus,FMD::FMD_LB_ReadSector ,NAND_LB_ReadSectorInfo 这几个函数相关。
现在我来看FMD_LB_GetBlockStatus这个函数(被FMD_GetBlockStatus 调用)
- // FMD_GetBlockStatus
- //
- // Returns the status of a block. The status information is stored in the spare area of the first sector for
- // the respective block.
- //
- // A block is BAD if the bBadBlock byte on the first page is not equal to 0xff.
- // 根据一些参数确定是大页还是小页,但是这里没有支持我512Mflash的block大小
- DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
- {
- DWORD dwResult = 0;
- int i;
- if ( blockID < wPRIMARY_NAND_BLOCKS )
- {
- if ( astNandSpec[dwPrimaryNandDevice].nSctsPerPg == 4 )
- {//小心LB_BLOCK_LOOP这个宏定义:#define LB_BLOCK_LOOP 1
- for ( i = 0; i < LB_BLOCK_LOOP; i++ )
- {
- dwResult |= FMD_LB_GetBlockStatus(blockID*(LB_BLOCK_LOOP) + i, USE_NFCE);
- }
- }
- else
- {
- for ( i = 0; i < SB_BLOCK_LOOP; i++ )
- {
- dwResult |= FMD_SB_GetBlockStatus(blockID*(SB_BLOCK_LOOP) + i, USE_NFCE);
- }
- }
- }
- else
- {
- if ( astNandSpec[dwSecondaryNandDevice].nSctsPerPg == 4 )
- {
- for ( i = 0; i < LB_BLOCK_LOOP; i++ )
- {
- dwResult |= FMD_LB_GetBlockStatus((blockID-wPRIMARY_NAND_BLOCKS)*(LB_BLOCK_LOOP) + i, USE_GPIO);
- }
- }
- else
- {
- for ( i = 0; i < SB_BLOCK_LOOP; i++ )
- {
- dwResult |= FMD_SB_GetBlockStatus((blockID-wPRIMARY_NAND_BLOCKS)*(SB_BLOCK_LOOP) + i, USE_GPIO);
- }
- }
- }
- return dwResult;
- }
根据上面的情况,再来看看FMD_LB_GetBlockStatus这个函数原型
- // FMD_LB_GetBlockStatus
- //
- // Returns the status of a block. The status information is stored in the spare area of the first sector for
- // the respective block.
- //
- // A block is BAD if the bBadBlock byte on the first page is not equal to 0xff.
- //
- DWORD FMD_LB_GetBlockStatus(BLOCK_ID blockID, int mode)
- {
- SECTOR_ADDR sectorAddr = blockID << LB_NAND_LOG_2_PAGES_PER_BLOCK;
- SectorInfo SI;
- DWORD dwResult = 0;
- //这个函数启动的时候会被调用很多次,串口信息打开影响速度
- //RETAILMSG(1, (TEXT("FMD_LB_GetBlockStatus (0x%x)0x%x /r/n"), blockID, sectorAddr));
- BOOL bLastMode = SetKMode(TRUE);
- if(!FMD_LB_ReadSector(sectorAddr<<2, NULL, &SI, 1, mode))
- {
- return BLOCK_STATUS_UNKNOWN;
- }
- if(!(SI.bOEMReserved & OEM_BLOCK_READONLY))
- {
- dwResult |= BLOCK_STATUS_READONLY;
- }
- if( blockID < pBSPArgs->nfsblk )
- {
- dwResult |= BLOCK_STATUS_READONLY;
- }
- if(SI.bBadBlock != 0xFF)
- {
- dwResult |= BLOCK_STATUS_BAD;
- }
- SetKMode(bLastMode);
- return dwResult;
- }
很明显上面这个函数是根据BLOCKID读这个BLOCK的Spare区的一些信息,从上面的串口信息可以看出,这个函数要把所有的block读完,但是控制这所有block的循环在哪里呢?我现在找不到,真是太奇怪了。因为:#define LB_BLOCK_LOOP 1 所以FMD_GetBlockStatus这个函数在哪里调用了是关键。请看下面他被调用的地方
- static BOOL DefineLayout()
- {
- PFlashRegion pRegion = NULL;
- DWORD dwBlock = 0;
- if (!FMD_GetInfo (&g_flashInfo)) {
- return FALSE;
- }
- // Find the MBR to determine if there is a flash layout sector
- g_dwNumRegions = 0;
- // Find the first usuable block要找的地方就是这里了。哈哈!
- while (dwBlock < g_flashInfo.dwNumBlocks) {
- if (!(FMD_GetBlockStatus(dwBlock) & (BLOCK_STATUS_BAD | BLOCK_STATUS_RESERVED))) {
- break;
- }
- dwBlock++;
- }
- RETAILMSG(1, (TEXT("DefineLayout: dwBlock = 0x%x /r/n"), dwBlock));
- DWORD dwSector = dwBlock * g_flashInfo.wSectorsPerBlock;
- if (!FMD_ReadSector (dwSector, g_pFLSBuffer, NULL, 1)) {
- return FALSE;
- }
- // compare the signatures
- if (IS_VALID_BOOTSEC(g_pFLSBuffer))
- {
- if (!FMD_ReadSector (dwSector+1, g_pFLSBuffer, NULL, 1)) {
- return FALSE;
- }
- if (IS_VALID_FLS(g_pFLSBuffer))
- {
- PFlashLayoutSector pFLS = (PFlashLayoutSector)(g_pFLSBuffer);
- // Cache the flash layout sector information
- g_dwNumRegions = pFLS->cbRegionEntries / sizeof(FlashRegion);
- // RETAILMSG(1, (TEXT("DefineLayout: g_dwNumRegions = 0x%x /r/n"), g_dwNumRegions));
- // FlashRegion table starts after the ReservedEntry table.
- if (g_dwNumRegions)
- {
- pRegion = (PFlashRegion)((LPBYTE)pFLS + sizeof(FlashLayoutSector) + pFLS->cbReservedEntries);
- }
- }
- }
- if (!g_dwNumRegions)
- {
- g_dwNumRegions = 1;
- }
- if (g_dwNumRegions > MAX_REGIONS)
- return FALSE;
- if (pRegion)
- {
- memcpy (g_pRegionTable, pRegion, g_dwNumRegions * sizeof(FlashRegion));
- }
- else
- {
- g_pRegionTable[0].dwStartPhysBlock = 0;
- g_pRegionTable[0].dwNumPhysBlocks = g_flashInfo.dwNumBlocks;
- g_pRegionTable[0].dwNumLogicalBlocks = FIELD_NOT_IN_USE;
- g_pRegionTable[0].dwBytesPerBlock = g_flashInfo.dwBytesPerBlock;
- g_pRegionTable[0].regionType = FILESYS;
- g_pRegionTable[0].dwSectorsPerBlock = g_flashInfo.wSectorsPerBlock;
- g_pRegionTable[0].dwCompactBlocks = DEFAULT_COMPACTION_BLOCKS;
- }
- //——这个地方非常关键,一些MBR和文件系统相关的东西都在这里了
- RETAILMSG(1, (TEXT("DefineLayout: g_pRegionTable[0].dwNumPhysBlocks = 0x%x /r/n"), g_pRegionTable[0].dwNumPhysBlocks));
- return TRUE;
- }
不过并没有这么顺利
#if defined (MAGNETO)
static BOOL DefineLayout();
#endif
--------------#if defined (MAGNETO) 这个并没有定义,所以上面的函数并没有被编译。从串口打印信息也可以看的出来。不过FMD_GetBlockStatus在哪里被调用多次呢?真是很晕了。难道是文件系统做的事情?
wogoyixikexie@gliet 说:
我对比了启动正常和不正常的加载饿文件系统DLL,发现有两个DLL没有被加载
wogoyixikexie@gliet 说:
diskcache.dll和fatfsd.dll没有被加载
=======================无计可施,幸好有朋友帮忙===================