📄 log2physmap.cpp
字号:
address; otherwise NULL if the secondary table doesn't exist.
------------------------------------------------------------------------------*/
PBYTE MappingTable::GetPhysicalSectorAddr(SECTOR_ADDR logicalSectorAddr, PSECTOR_ADDR pPhysicalSectorAddr)
{
static DWORD dwSecondaryTableID = 0;
static DWORD dwOffset = 0;
//----- 0. Check the parameters to insure they are legitimate -----
if(pPhysicalSectorAddr == NULL)
{
ReportError((TEXT("FLASHDRV.DLL:MappingTable::GetPhysicalSectorAddr() - Invalid parameter: pPhysicalSectorAddr == NULL\r\n")));
return NULL;
}
*pPhysicalSectorAddr = UNMAPPED_LOGICAL_SECTOR;
if (logicalSectorAddr < m_dwStartLogSector || logicalSectorAddr >= (m_dwStartLogSector + m_dwNumLogSectors))
{
ReportError((TEXT("FLASHDRV.DLL:MappingTable::GetPhysicalSectorAddr() - Logical sector(0x%x) is out of range\r\n"), logicalSectorAddr));
return NULL;
}
//----- 1. Rebase the logical sector that we are interested in before looking it up in the secondary table -----
logicalSectorAddr -= m_dwStartLogSector;
//----- 2. Determine the secondary table for this logical sector address -----
// NOTE: Notice that a shift operation is used to avoid a potentially expensive
// division operation if the # of sectors/secondary table is a power of 2
if(m_bIsNumSectorsPerSecTableLog2)
{
dwSecondaryTableID = logicalSectorAddr >> m_dwNumSectorsPerSecTable;
}else
{
dwSecondaryTableID = logicalSectorAddr / m_dwNumSectorsPerSecTable;
}
if (dwSecondaryTableID >= MASTER_TABLE_SIZE)
goto GET_ERROR;
//----- 3. If this logical sector's secondary table isn't setup, a logical --> physical mapping does NOT exist -----
if(m_pDynamicLUT[dwSecondaryTableID] == NULL)
{
DEBUGMSG(ZONE_INIT, (TEXT("FLASHDRV.DLL:MappingTable::GetPhysicalSectorAddr() - Secondary table doesn't exist for logical sector 0x%x!!!\r\n"), logicalSectorAddr));
*pPhysicalSectorAddr = 0xFFFFFFFF; // Logical sector is NOT mapped to a physical sector...
goto GET_ERROR;
}
//----- 4. Determine the offset within the secondary table for this logical sector address -----
COMPUTE_OFFSET(logicalSectorAddr);
//----- 5. Lookup the physical sector address in the secondary table -----
// NOTE: For performance reasons, all multiplications are avoided. Hence, it is necessary to explicitly
// handle the four different cases for the physical sector address width.
switch(m_cbPhysicalAddr)
{
case ONE_BYTE_PHYSICAL_ADDR: // 0 >= FLASH media <= 2^8 sectors
*pPhysicalSectorAddr = MAX_PHYSICAL_ADDR_FOR_ONE_BYTES & (UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr));
if(*pPhysicalSectorAddr == MAX_PHYSICAL_ADDR_FOR_ONE_BYTES)
{
*pPhysicalSectorAddr = 0xFFFFFFFF; // Logical sector is NOT mapped to a physical sector...
}
break;
case TWO_BYTE_PHYSICAL_ADDR: // 2^8 > FLASH media <= 2^16 sectors
*pPhysicalSectorAddr = MAX_PHYSICAL_ADDR_FOR_TWO_BYTES & ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr))<<8);
*pPhysicalSectorAddr += (UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+1));
if(*pPhysicalSectorAddr == MAX_PHYSICAL_ADDR_FOR_TWO_BYTES)
{
*pPhysicalSectorAddr = 0xFFFFFFFF; // Logical sector is NOT mapped to a physical sector...
}
break;
case THREE_BYTE_PHYSICAL_ADDR: // 2^16 > FLASH media <= 2^24 sectors
*pPhysicalSectorAddr = MAX_PHYSICAL_ADDR_FOR_THREE_BYTES & ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr))<<16);
*pPhysicalSectorAddr += ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+1))<<8);
*pPhysicalSectorAddr += (UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+2));
if(*pPhysicalSectorAddr == MAX_PHYSICAL_ADDR_FOR_THREE_BYTES)
{
*pPhysicalSectorAddr = 0xFFFFFFFF; // Logical sector is NOT mapped to a physical sector...
}
break;
case FOUR_BYTE_PHYSICAL_ADDR: // 2^24 > FLASH media <= 2^32 sectors
*pPhysicalSectorAddr = MAX_PHYSICAL_ADDR_FOR_FOUR_BYTES & ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr))<<24);
*pPhysicalSectorAddr += ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+1))<<16);
*pPhysicalSectorAddr += ((UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+2))<<8);
*pPhysicalSectorAddr += (UCHAR)(*(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr+3));
break;
}
CELOG_GetPhysicalSectorAddr (logicalSectorAddr, *pPhysicalSectorAddr);
return (PBYTE)(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr);
GET_ERROR:
return NULL;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: MappingTable::MapLogicalSector()
Description: Maps the specified logical sector address to the specified
physical sector address.
Notes: If the logical sector is already mapped to a physical sector,
the secondary table is appropriately updated with the new
physical sector address.
Returns: Pointer to the position in secondary table containing physical sector
address; otherwise NULL if the secondary table doesn't exist.
------------------------------------------------------------------------------*/
PBYTE MappingTable::MapLogicalSector(SECTOR_ADDR logicalSectorAddr, SECTOR_ADDR physicalSectorAddr,
PSECTOR_ADDR pExistingPhysicalSectorAddr)
{
static PBYTE pMappedPhysicalSectorAddr = 0;
static DWORD dwSecondaryTableID = 0;
//----- 0. Check the parameters to insure they are legitimate -----
if(pExistingPhysicalSectorAddr == NULL)
{
ReportError((TEXT("FLASHDRV.DLL:MappingTable::MapLogicalSector() - Invalid parameter: pExistingPhysicalSectorAddr == NULL\r\n")));
return NULL;
}
*pExistingPhysicalSectorAddr = UNMAPPED_LOGICAL_SECTOR;
if (logicalSectorAddr < m_dwStartLogSector || logicalSectorAddr >= (m_dwStartLogSector + m_dwNumLogSectors))
{
ReportError((TEXT("FLASHDRV.DLL:MappingTable::MapLogicalSector() - Logical sector(0x%x) is out of range\r\n"), logicalSectorAddr));
return NULL;
}
//----- 1. Get a pointer to the mapped physical sector address in our secondary table -----
pMappedPhysicalSectorAddr = GetPhysicalSectorAddr(logicalSectorAddr, pExistingPhysicalSectorAddr);
//----- 2. Rebase the logical sector that we are interested in before looking it up in the secondary table -----
logicalSectorAddr -= m_dwStartLogSector;
if(pMappedPhysicalSectorAddr == NULL)
{
//----- 3. Secondary table for this logical sector address does NOT exist, let's create it... -----
// NOTE: Notice that a shift operation is used to avoid a potentially expensive
// division operation if the # of sectors/secondary table is a power of 2
if(m_bIsNumSectorsPerSecTableLog2)
{
dwSecondaryTableID = logicalSectorAddr >> m_dwNumSectorsPerSecTable;
}else
{
dwSecondaryTableID = logicalSectorAddr / m_dwNumSectorsPerSecTable;
}
if (dwSecondaryTableID >= MASTER_TABLE_SIZE)
goto MAPPING_ERROR;
if((m_pDynamicLUT[dwSecondaryTableID] = (PBYTE)LocalAlloc(LMEM_FIXED, m_dwSecondaryTableSize)) == NULL)
{
ReportError((TEXT("FLASHDRV.DLL:MapLogicalSector() - Unable to allocate secondary table for logical sector %d\r\n"), logicalSectorAddr));
goto MAPPING_ERROR;
}
//----- 4. Initialize the secondary table so that all logical sector addresses are unmapped (physical sector address is all '1's) -----
memset(m_pDynamicLUT[dwSecondaryTableID], 0xFF, m_dwSecondaryTableSize);
//----- 5. Determine the offset within the secondary table for this logical sector address -----
COMPUTE_OFFSET(logicalSectorAddr);
//----- 6. Get a pointer to the position in the secondary table that stores the physical sector address -----
pMappedPhysicalSectorAddr = (PBYTE)(m_pDynamicLUT[dwSecondaryTableID]+logicalSectorAddr);
}
//----- 7. Map the specified logical sector address to the specified physical sector address -----
// NOTE: For performance reasons, all multiplications are avoided. Hence, it is necessary to explicitly
// handle the four different cases for the physical sector address width.
switch(m_cbPhysicalAddr)
{
case ONE_BYTE_PHYSICAL_ADDR: // 0 >= FLASH media <= 2^8 sectors
*pMappedPhysicalSectorAddr = (UCHAR)physicalSectorAddr;
break;
case TWO_BYTE_PHYSICAL_ADDR: // 2^8 > FLASH media <= 2^16 sectors
*pMappedPhysicalSectorAddr = (UCHAR)(physicalSectorAddr>>8);
*(pMappedPhysicalSectorAddr+1) = (UCHAR)(physicalSectorAddr);
break;
case THREE_BYTE_PHYSICAL_ADDR: // 2^16 > FLASH media <= 2^24 sectors
*pMappedPhysicalSectorAddr = (UCHAR)(physicalSectorAddr>>16);
*(pMappedPhysicalSectorAddr+1) = (UCHAR)(physicalSectorAddr>>8);
*(pMappedPhysicalSectorAddr+2) = (UCHAR)(physicalSectorAddr);
break;
case FOUR_BYTE_PHYSICAL_ADDR: // 2^24 > FLASH media <= 2^32 sectors
*pMappedPhysicalSectorAddr = (UCHAR)(physicalSectorAddr>>24);
*(pMappedPhysicalSectorAddr+1) = (UCHAR)(physicalSectorAddr>>16);
*(pMappedPhysicalSectorAddr+2) = (UCHAR)(physicalSectorAddr>>8);
*(pMappedPhysicalSectorAddr+3) = (UCHAR)(physicalSectorAddr);
break;
}
CELOG_MapLogicalSector(logicalSectorAddr, physicalSectorAddr, *pMappedPhysicalSectorAddr);
return pMappedPhysicalSectorAddr;
MAPPING_ERROR:
return NULL;
}
//--------------------------------------- Helper Functions ------------------------------------
BOOL MappingTable::IsValidLogicalSector(SECTOR_ADDR logicalSectorAddr)
{
if (logicalSectorAddr < m_dwStartLogSector || logicalSectorAddr >= (m_dwStartLogSector + m_dwNumLogSectors))
return FALSE;
else
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -