Chinaunix首页 | 论坛 | 博客
  • 博客访问: 921015
  • 博文数量: 96
  • 博客积分: 10071
  • 博客等级: 上将
  • 技术积分: 1118
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-20 17:54
文章分类

全部博文(96)

文章存档

2011年(3)

2010年(3)

2009年(29)

2008年(54)

2007年(7)

分类: WINDOWS

2009-03-04 16:18:23

wince FAL+FMD的简单分析
creator
sz111@126.com

1.首先弄清楚FAL中的设备驱动,物理设备数据类型如下:
typedef struct _DEVICE
{
    DWORD   dwID;
    PVOID   hFMD;
    PVOID   hFMDHook;

} DEVICE , *PDEVICE;
有一个公共变量g_pDevice来保存这个。pDevice指向g_pDevice

2.在DSK_Init初始化化中,会通过GetFMDInterface(pDevice)获得FMD。

VOID GetFMDInterface(PDEVICE pDevice)
{
    FMD.cbSize = sizeof(FMDInterface);

    // query FMD intrface from the FMD    
    FMD.pOEMIoControl = FMD_OEMIoControl;
    if (!FMD_OEMIoControl (IOCTL_FMD_GET_INTERFACE, NULL, 0, (PBYTE)&FMD, sizeof(FMDInterface), NULL))
    {
        // FMD does not support IOCTL_FMD_GET_INTERFACE, so build the FMDInterface 
        // structure using the legacy FMD functions
        FMD.pInit = FMD_Init;
        FMD.pDeInit = FMD_Deinit;
        FMD.pGetInfo = FMD_GetInfo;        
        FMD.pGetBlockStatus = FMD_GetBlockStatus;     
        FMD.pSetBlockStatus = FMD_SetBlockStatus;
        FMD.pReadSector = FMD_ReadSector;
        FMD.pWriteSector = FMD_WriteSector;
        FMD.pEraseBlock = FMD_EraseBlock;
        FMD.pPowerUp = FMD_PowerUp;
        FMD.pPowerDown = FMD_PowerDown;
    }

    // query hook library in case any FMD functions need to be shimmed
    pDevice->hFMDHook = FMDHOOK_HookInterface(&FMD);
}
其中FMD_OEMIoControl是在Fmd.cpp中定义的。通过这个函数把msflash.dll和nandflash.dll联系起来。
通过它获得FMD,是一个函数指针接口,以后就通过FMD来执行FMD中的实际函数了。

BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
switch(dwIoControlCode)
{
case IOCTL_FMD_GET_INTERFACE:
{
RETAILMSG(1, (TEXT("[FMD] FMD_OEMIoControl() : IOCTL_FMD_GET_INTERFACE\r\n")));

if (!pOutBuf || nOutBufSize < sizeof(FMDInterface))
{
DEBUGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE bad parameter(s).\r\n")));
return(FALSE);
}

PFMDInterface pInterface = (PFMDInterface)pOutBuf;

pInterface->cbSize = sizeof(FMDInterface);
pInterface->pInit = FMD_Init;
pInterface->pDeInit = FMD_Deinit;
pInterface->pGetInfo = FMD_GetInfo;
pInterface->pGetInfoEx = NULL; //FMD_GetInfoEx;
pInterface->pGetBlockStatus = FMD_GetBlockStatus;
pInterface->pSetBlockStatus = FMD_SetBlockStatus;
pInterface->pReadSector = FMD_ReadSector;
pInterface->pWriteSector = FMD_WriteSector;
pInterface->pEraseBlock = FMD_EraseBlock;
pInterface->pPowerUp = FMD_PowerUp;
pInterface->pPowerDown = FMD_PowerDown;
pInterface->pGetPhysSectorAddr = NULL;

break;
}
.....
}

3.获得FMD之后,首先调用FMD.pInit, 对FMD设备进行初始化。主要是控制器的配置,读ID得到nandflash的容量,
等信息。

4.调用FMD.pGetInfo(&oldFlashInfo)获得nandflash的信息。最终也是调用BOOL FMD_GetInfo(PFlashInfo pFlashInfo)
pFlashInfo->dwNumBlocks         = NUM_OF_BLOCKS;
pFlashInfo->wSectorsPerBlock    = PAGES_PER_BLOCK;
pFlashInfo->wDataBytesPerSector = NAND_SECTOR_SIZE;
pFlashInfo->dwBytesPerBlock     = (PAGES_PER_BLOCK * NAND_SECTOR_SIZE);
把相关信息读到oldFlashInfo中。然后把相关数据写入公共变量g_pFlashMediaInfo
5.然后通过调用CalculateLogicalRange来统计nandflash的区域大小和可以用的block
BOOL CalculateLogicalRange(PFlashRegion pRegion)
{
    DWORD dwBlockID;
    DWORD dwNumLogicalBlocks = 0;
    
    for (dwBlockID = pRegion->dwStartPhysBlock; dwBlockID < pRegion->dwStartPhysBlock + pRegion->dwNumPhysBlocks; dwBlockID++)
    {
        DWORD dwStatus = FMD.pGetBlockStatus (dwBlockID);

        if (!(dwStatus & (BLOCK_STATUS_RESERVED | BLOCK_STATUS_BAD)))
        {
            dwNumLogicalBlocks++;
        }
    }
    //pRegion->dwCompactBlocks=MINIMUM_FLASH_BLOCKS_TO_RESERVE最少的block为2,如果wince发现少于2个block的可用块,就会返回error。
    if (dwNumLogicalBlocks <= pRegion->dwCompactBlocks)
    {
        ReportError((TEXT("FLASHDRV.DLL:CalculateLogicalRange() - Invalid number of logical blocks %d\r\n"), dwNumLogicalBlocks));
        return FALSE;
    }

    // Account for compaction blocks
    dwNumLogicalBlocks -= pRegion->dwCompactBlocks;
    pRegion->dwNumLogicalBlocks = dwNumLogicalBlocks;
    return TRUE;
}
最终也是调用FMD_GetBlockStatus函数。

阅读(3275) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-10-24 17:46:10

上面说的代码在哪里能看到,FAL的代码?