⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootpart.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
extern "C"	// hmseo-061028
{
#include <WMRConfig.h>
#include <WMRTypes.h>
}

#include <bootpart.h>
#include "bppriv.h"

LPBYTE g_pbMBRSector = NULL;
LPBYTE g_pbBlock = NULL;
DWORD g_dwMBRSectorNum = INVALID_ADDR;
FlashInfo g_FlashInfo;
PARTSTATE g_partStateTable[NUM_PARTS];
PSectorInfo g_pSectorInfoBuf;
DWORD g_dwLastLogSector;          // Stores the last valid logical sector
DWORD g_dwDataBytesPerBlock;
DWORD g_dwLastWrittenLoc;  // Stores the byte address of the last physical flash address written to

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static Addr LBAtoCHS(FlashInfo *pFlashInfo, Addr lba)
{
    if(lba.type == CHS)
        return lba;

    Addr chs;
    DWORD tmp = pFlashInfo->dwNumBlocks * pFlashInfo->wSectorsPerBlock;

    chs.type = CHS;
    chs.chs.cylinder = (WORD)(lba.lba / tmp);
    tmp = lba.lba % tmp;
    chs.chs.head = (WORD)(tmp / pFlashInfo->wSectorsPerBlock);
    chs.chs.sector = (WORD)((tmp % pFlashInfo->wSectorsPerBlock) + 1);

    return chs;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static Addr CHStoLBA(FlashInfo *pFlashInfo, Addr chs)
{
    Addr lba;

    if(chs.type == LBA)
        return chs;

    lba.type = LBA;
    lba.lba = ((chs.chs.cylinder * pFlashInfo->dwNumBlocks + chs.chs.head)
        * pFlashInfo->wSectorsPerBlock)+ chs.chs.sector - 1;

    return lba;
}

#define Log2Phys(sector)	(sector)

#define SECTOR_TO_BLOCK(sector)     ((sector) / (SECTORS_PER_SUPAGE*PAGES_PER_SUBLK) )
#define BLOCK_TO_SECTOR(block)      ((block)  * (SECTORS_PER_SUPAGE*PAGES_PER_SUBLK) )

extern BOOL WriteBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable);
extern BOOL ReadBlock(DWORD dwBlock, LPBYTE pbBlock, PSectorInfo pSectorInfoTable);


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static BOOL WriteMBR()
{
	DWORD dwMBRBlockNum = g_dwMBRSectorNum / g_FlashInfo.wSectorsPerBlock;

	RETAILMSG(1, (TEXT("WriteMBR: MBR block = 0x%x.\r\n"), dwMBRBlockNum));

	memset (g_pbBlock, 0xff, g_dwDataBytesPerBlock);
	memset (g_pSectorInfoBuf, 0xff, sizeof(SectorInfo) * g_FlashInfo.wSectorsPerBlock);

	// No need to check return, since a failed read means data hasn't been written yet.
	ReadBlock (dwMBRBlockNum, g_pbBlock, g_pSectorInfoBuf);

	if (!FMD_EraseBlock (dwMBRBlockNum)) {
		RETAILMSG (1, (TEXT("CreatePartition: error erasing block 0x%x\r\n"), dwMBRBlockNum));
		return FALSE;
	}

	memcpy (g_pbBlock + (g_dwMBRSectorNum % g_FlashInfo.wSectorsPerBlock) * g_FlashInfo.wDataBytesPerSector, g_pbMBRSector, g_FlashInfo.wDataBytesPerSector);
	g_pSectorInfoBuf->bOEMReserved &= ~OEM_BLOCK_READONLY;
	g_pSectorInfoBuf->wReserved2 &= ~SECTOR_WRITE_COMPLETED;
	g_pSectorInfoBuf->dwReserved1 = 0;

	RETAILMSG(1, (TEXT("WriteBlock: dwMBRBlockNum = 0x%x.\r\n"), dwMBRBlockNum));
#if 0
	for (DWORD i = 0; i < 512; i++) {
		if (i % 16 == 0)
			RETAILMSG(1, (L"0x%x: ", g_pbBlock+i));
		RETAILMSG(1, (L"%x%x ", (g_pbBlock[i] >> 4) & 0x0f, g_pbBlock[i] & 0x0f));
		if ((i + 1) % 16 == 0)
			RETAILMSG(1, (L"\r\n"));
	}
#endif
	if (!WriteBlock (dwMBRBlockNum, g_pbBlock, g_pSectorInfoBuf)) {
		RETAILMSG (1, (TEXT("CreatePartition: could not write to block 0x%x\r\n"), dwMBRBlockNum));
		return FALSE;
	}

	return TRUE;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL CreateMBR() 
{
    // This, plus a valid partition table, is all the CE partition manager needs to recognize 
    // the MBR as valid. It does not contain boot code.

    memset (g_pbMBRSector, 0xff, g_FlashInfo.wDataBytesPerSector);
    g_pbMBRSector[0] = 0xE9;
    g_pbMBRSector[1] = 0xfd;
    g_pbMBRSector[2] = 0xff;
    g_pbMBRSector[SECTOR_SIZE-2] = 0x55;
    g_pbMBRSector[SECTOR_SIZE-1] = 0xAA;

    // Zero out partition table so that mspart treats entries as empty.
    memset (g_pbMBRSector+PARTTABLE_OFFSET, 0, sizeof(PARTENTRY) * NUM_PARTS);

    return WriteMBR();

}  

BOOL IsValidMBR() 
{
    // Check to see if the MBR is valid

    // MBR block is always located at logical sector 0
#if 0	// hmseo-061029
    g_dwMBRSectorNum = 0;	//GetMBRSectorNum();        
#else	// hmseo-061029
//    g_dwMBRSectorNum = BLOCK_TO_SECTOR(FTL_AREA_START);	// hmseo-061029 set the MBR sector to FTL area start sector.
#endif	// hmseo-061029
		
    RETAILMSG (1, (TEXT("IsValidMBR: MBR sector = 0x%x\r\n"), g_dwMBRSectorNum));
   
    if ((g_dwMBRSectorNum == INVALID_ADDR) || !FMD_ReadSector (g_dwMBRSectorNum, g_pbMBRSector, NULL, 1)) {
        return FALSE;  
    }
    
#if 0
    LPBYTE pbBuf = g_pbMBRSector + 512 - 0x42;
    RETAILMSG(1, (L"g_pbMBRSector = 0x%x\r\n", g_pbMBRSector));
    for (DWORD i = 0; i < 0x40; i++) {
    	if (i % 16 == 0)
    		RETAILMSG(1, (L"0x%x: ", pbBuf+i));
    	RETAILMSG(1, (L"%x%x ", (pbBuf[i] >> 4) & 0x0f, pbBuf[i] & 0x0f));
    	if ((i + 1) % 16 == 0)
    		RETAILMSG(1, (L"\r\n"));
    }
#endif
    return ((g_pbMBRSector[0] == 0xE9) &&
         (g_pbMBRSector[1] == 0xfd) &&
         (g_pbMBRSector[2] == 0xff) &&
         (g_pbMBRSector[SECTOR_SIZE-2] == 0x55) &&
         (g_pbMBRSector[SECTOR_SIZE-1] == 0xAA));
}  

BOOL IsValidMBRSector(DWORD dwBlock)
{
	g_dwMBRSectorNum = BLOCK_TO_SECTOR(dwBlock);

	return IsValidMBR();
}

static BOOL IsValidPart (PPARTENTRY pPartEntry)
{
    return (pPartEntry->Part_FileSystem != 0xff) && (pPartEntry->Part_FileSystem != 0);
}

/*  AddPartitionTableEntry
 *
 *  Generates the partition entry for the partition table and copies the entry 
 *  into the MBR that is stored in memory.
 *  
 *
 *  ENTRY
 *      entry - index into partition table
 *      startSector - starting logical sector
 *      totalSectors - total logical sectors
 *      fileSystem - type of partition
 *      bootInd - byte in partition entry that stores various flags such as
 *          active and read-only status.
 *
 *  EXIT
 */
 
static void AddPartitionTableEntry(DWORD entry, DWORD startSector, DWORD totalSectors, BYTE fileSystem, BYTE bootInd)
{
    PARTENTRY partentry = {0};
    Addr startAddr;
    Addr endAddr;

    ASSERT(entry < 4);

    // no checking with disk info and start/total sectors because we allow
    // bogus partitions for testing purposes

    // initially known partition table entry
    partentry.Part_BootInd = bootInd;
    partentry.Part_FileSystem = fileSystem;
    partentry.Part_StartSector = startSector;
    partentry.Part_TotalSectors = totalSectors;

    // logical block addresses for the first and final sector (start on the second head)
    startAddr.type = LBA;
    startAddr.lba = partentry.Part_StartSector;
    endAddr.type = LBA;
    endAddr.lba = partentry.Part_StartSector + partentry.Part_TotalSectors-1;

    // translate the LBA addresses to CHS addresses
    startAddr = LBAtoCHS(&g_FlashInfo, startAddr);
    endAddr = LBAtoCHS(&g_FlashInfo, endAddr);

    // starting address
    partentry.Part_FirstTrack = (BYTE)(startAddr.chs.cylinder & 0xFF);
    partentry.Part_FirstHead = (BYTE)(startAddr.chs.head & 0xFF);
    // lower 6-bits == sector, upper 2-bits = cylinder upper 2-bits of 10-bit cylinder #
    partentry.Part_FirstSector = (BYTE)((startAddr.chs.sector & 0x3F) | ((startAddr.chs.cylinder & 0x0300) >> 2));

    // ending address:
    partentry.Part_LastTrack = (BYTE)(endAddr.chs.cylinder & 0xFF);
    partentry.Part_LastHead = (BYTE)(endAddr.chs.head & 0xFF);
    // lower 6-bits == sector, upper 2-bits = cylinder upper 2-bits of 10-bit cylinder #
    partentry.Part_LastSector = (BYTE)((endAddr.chs.sector & 0x3F) | ((endAddr.chs.cylinder & 0x0300) >> 2));

    memcpy(g_pbMBRSector+PARTTABLE_OFFSET+(sizeof(PARTENTRY)*entry), &partentry, sizeof(PARTENTRY));
}



/*  GetPartitionTableIndex
 *
 *  Get the partition index for a particular partition type and active status. 
 *  If partition is not found, then the index of the next free partition in the
 *  partition table of the MBR is returned.
 *  
 *
 *  ENTRY
 *      dwPartType - type of partition 
 *      fActive - TRUE indicates the active partition.  FALSE indicates inactive.
 *
 *  EXIT
 *      pdwIndex - Contains the index of the partition if found.  If not found,
 *          contains the index of the next free partition
 *      returns TRUE if partition found. FALSE if not found.
 */

static BOOL GetPartitionTableIndex (DWORD dwPartType, BOOL fActive, PDWORD pdwIndex)
{
    PPARTENTRY pPartEntry = (PPARTENTRY)(g_pbMBRSector + PARTTABLE_OFFSET);
    DWORD iEntry = 0;
    
    for (iEntry = 0; iEntry < NUM_PARTS; iEntry++, pPartEntry++) {
        if ((pPartEntry->Part_FileSystem == dwPartType) && (((pPartEntry->Part_BootInd & PART_IND_ACTIVE) != 0) == fActive)) {
            *pdwIndex = iEntry;
            return TRUE;
        }
        if (!IsValidPart (pPartEntry)) {
            *pdwIndex = iEntry;
            return FALSE;
        }
    }

    return FALSE;
}

/* WriteLogicalNumbers
 *
 *  Writes a range of logical sector numbers
 *
 *  ENTRY
 *      dwStartSector - starting logical sector
 *      dwNumSectors - number of logical sectors to mark
 *      fReadOnly - TRUE indicates to mark read-only.  FALSE to mark not read-only
 *
 *  EXIT
 *      TRUE on success
 */


static BOOL WriteLogicalNumbers (DWORD dwStartSector, DWORD dwNumSectors, BOOL fReadOnly)
{
    DWORD dwNumSectorsWritten = 0;

    DWORD dwPhysSector = Log2Phys (dwStartSector);
    DWORD dwBlockNum = dwPhysSector / g_FlashInfo.wSectorsPerBlock;
    DWORD dwOffset = dwPhysSector % g_FlashInfo.wSectorsPerBlock;
    
    while (dwNumSectorsWritten < dwNumSectors) {

        // If bad block, move to the next block 
#if 0        
        if (IS_BLOCK_UNUSABLE (dwBlockNum)) {
            dwBlockNum++;
            continue;
        }
#endif

        memset (g_pbBlock, 0xff, g_dwDataBytesPerBlock);
        memset (g_pSectorInfoBuf, 0xff, sizeof(SectorInfo) * g_FlashInfo.wSectorsPerBlock);
        // No need to check return, since a failed read means data hasn't been written yet.
        ReadBlock (dwBlockNum, g_pbBlock, g_pSectorInfoBuf);
        if (!FMD_EraseBlock (dwBlockNum)) {
            return FALSE;
        }

        DWORD dwSectorsToWrite = g_FlashInfo.wSectorsPerBlock - dwOffset;
        PSectorInfo pSectorInfo = g_pSectorInfoBuf + dwOffset;

        // If this is the last block, then calculate sectors to write if there isn't a full block to update
        if ((dwSectorsToWrite + dwNumSectorsWritten) > dwNumSectors)
            dwSectorsToWrite = dwNumSectors - dwNumSectorsWritten;
        
        for (DWORD iSector = 0; iSector < dwSectorsToWrite; iSector++, pSectorInfo++, dwNumSectorsWritten++) {
            // Assert read only by setting bit to 0 to prevent wear-leveling by FAL
            if (fReadOnly)
                pSectorInfo->bOEMReserved &= ~OEM_BLOCK_READONLY;
            // Set to write completed so FAL can map the sector  
            pSectorInfo->wReserved2 &= ~SECTOR_WRITE_COMPLETED;        
            // Write the logical sector number
            pSectorInfo->dwReserved1 = dwStartSector + dwNumSectorsWritten;            
        }

        if (!WriteBlock (dwBlockNum, g_pbBlock, g_pSectorInfoBuf))
            return FALSE; 
        
        dwOffset = 0;
        dwBlockNum++;
    }
    return TRUE;
}



/*  CreatePartition 
 *
 *  Creates a new partition.  If it is a boot section partition, then it formats
 *  flash.
 *
 *  ENTRY
 *      dwStartSector - Logical sector to start the partition.  NEXT_FREE_LOC if  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -