作者:wogoyixikexie@gliet 2008-12-10
============================================================
一直在用优龙的ADS bootloader,对eboot的认识还停留在在刚来公司时候的水平,貌似我只看过eboot的startup.s,现在
使用优龙的bootloader遇到很多障碍,最大缺陷就是不支持binfs以及FAT分区,这个导致了不能实现multibin,FAT的问题还可以配置注册表实现自动化分区功能,但是这样还是不理想,但是优龙的bootloader太好用了,不想放弃这块肥肉,所以决定参考eboot增加优龙bootloader的binfs以及FAT分区功能。我的一贯做法是查找关键字眼,然后从关键点入手看程序。现在就看实现eboot功能的菜单程序吧。
============================================================
平台描述:2440+64M flash/SDRAM + 5.0BSP
- 0) IP address: 192.168.0.12
- 1) Subnet mask: 255.255.255.0
- 2) DHCP: Disabled
- 3) Boot delay: 5 seconds
- 4) Reset to factory default configuration
- 5) Startup image: DOWNLOAD NEW
- 6) Program disk image into SmartMedia card: Disabled
- 7) Program CS8900 MAC address (11:12:22:33:44:55)
- 8) Kernel Debugger: DISABLED
- 9) Format Boot Media for BinFS//------------
- E) Erase Reserved Block
- B) Mark Bad Block at Reserved Block
- F) Low-level format the Smart Media card//---------------
- D) Download image now
- L) LAUNCH existing Boot Media image
- R) Read Configuration
- U) DOWNLOAD image now(USB)
- W) Write Configuration Right Now
- A) Erase All Blocks
- Enter your selection:
- /*
- @func BOOL | MainMenu | Manages the Samsung bootloader main menu.
- @rdesc TRUE == Success and FALSE == Failure.
- @comm
- @xref
- */
- static BOOL MainMenu(PBOOT_CFG pBootCfg)
- {
- BYTE KeySelect = 0;
- BOOL bConfigChanged = FALSE;
- BOOLEAN bDownload = TRUE;
- DWORD i;
- while(TRUE)
- {
- KeySelect = 0;
- EdbgOutputDebugString ( "/r/nEthernet Boot Loader Configuration:/r/n/r/n");
- EdbgOutputDebugString ( "0) IP address: %s/r/n",inet_ntoa(pBootCfg->EdbgAddr.dwIP));
- EdbgOutputDebugString ( "1) Subnet mask: %s/r/n", inet_ntoa(pBootCfg->SubnetMask));
- EdbgOutputDebugString ( "2) DHCP: %s/r/n", (pBootCfg->ConfigFlags & CONFIG_FLAGS_DHCP)?"Enabled":"Disabled");
- EdbgOutputDebugString ( "3) Boot delay: %d seconds/r/n", pBootCfg->BootDelay);
- EdbgOutputDebugString ( "4) Reset to factory default configuration/r/n");
- EdbgOutputDebugString ( "5) Startup image: %s/r/n", (g_pBootCfg->ConfigFlags & BOOT_TYPE_DIRECT) ? "LAUNCH EXISTING" : "DOWNLOAD NEW");
- EdbgOutputDebugString ( "6) Program disk image into SmartMedia card: %s/r/n", (pBootCfg->ConfigFlags & TARGET_TYPE_NAND)?"Enabled":"Disabled");
- EdbgOutputDebugString ( "7) Program CS8900 MAC address (%B:%B:%B:%B:%B:%B)/r/n",
- g_pBootCfg->EdbgAddr.wMAC[0] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[0] >> 8,
- g_pBootCfg->EdbgAddr.wMAC[1] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[1] >> 8,
- g_pBootCfg->EdbgAddr.wMAC[2] & 0x00FF, g_pBootCfg->EdbgAddr.wMAC[2] >> 8);
- EdbgOutputDebugString ( "8) Kernel Debugger: %s/r/n", (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_DEBUGGER) ? "ENABLED" : "DISABLED");
- EdbgOutputDebugString ( "9) Format Boot Media for BinFS/r/n");
- // N.B: we need this option here since BinFS is really a RAM image, where you "format" the media
- // with an MBR. There is no way to parse the image to say it's ment to be BinFS enabled.
- EdbgOutputDebugString ( "E) Erase Reserved Block /r/n");
- EdbgOutputDebugString ( "B) Mark Bad Block at Reserved Block /r/n");
- EdbgOutputDebugString ( "F) Low-level format the Smart Media card/r/n");
- EdbgOutputDebugString ( "D) Download image now/r/n");
- EdbgOutputDebugString ( "L) LAUNCH existing Boot Media image/r/n");
- EdbgOutputDebugString ( "R) Read Configuration /r/n");
- EdbgOutputDebugString ( "U) DOWNLOAD image now(USB)/r/n");
- EdbgOutputDebugString ( "W) Write Configuration Right Now/r/n");
- EdbgOutputDebugString ( "A) Erase All Blocks/r/n");
- EdbgOutputDebugString ( "/r/nEnter your selection: ");
- while (! ( ( (KeySelect >= '0') && (KeySelect <= '9') ) ||
- ( (KeySelect == 'A') || (KeySelect == 'a') ) ||
- ( (KeySelect == 'D') || (KeySelect == 'd') ) ||
- ( (KeySelect == 'B') || (KeySelect == 'b') ) ||
- ( (KeySelect == 'E') || (KeySelect == 'e') ) ||
- ( (KeySelect == 'F') || (KeySelect == 'f') ) ||
- ( (KeySelect == 'L') || (KeySelect == 'l') ) ||
- ( (KeySelect == 'R') || (KeySelect == 'r') ) ||
- ( (KeySelect == 'U') || (KeySelect == 'u') ) ||
- ( (KeySelect == 'W') || (KeySelect == 'w') ) ||
- ( (KeySelect == 'X') || (KeySelect == 'x') ) ))
- {
- KeySelect = OEMReadDebugByte();
- }
- EdbgOutputDebugString ( "%c/r/n", KeySelect);
- switch(KeySelect)
- {
- case '0': // Change IP address.
- SetIP(pBootCfg);
- pBootCfg->ConfigFlags &= ~CONFIG_FLAGS_DHCP; // clear DHCP flag
- bConfigChanged = TRUE;
- break;
- case '1': // Change subnet mask.
- SetMask(pBootCfg);
- bConfigChanged = TRUE;
- break;
- case '2': // Toggle static/DHCP mode.
- pBootCfg->ConfigFlags = (pBootCfg->ConfigFlags ^ CONFIG_FLAGS_DHCP);
- bConfigChanged = TRUE;
- break;
- case '3': // Change autoboot delay.
- SetDelay(pBootCfg);
- bConfigChanged = TRUE;
- break;
- case '4': // Reset the bootloader configuration to defaults.
- OALMSG(TRUE, (TEXT("Resetting default TOC.../r/n")));
- TOC_Init(DEFAULT_IMAGE_DESCRIPTOR, (IMAGE_TYPE_RAMIMAGE|IMAGE_TYPE_BINFS), 0, 0, 0);
- if ( !TOC_Write() ) {
- OALMSG(OAL_WARN, (TEXT("TOC_Write Failed!/r/n")));
- }
- OALMSG(TRUE, (TEXT("...TOC complete/r/n")));
- break;
- case '5': // Toggle download/launch status.
- pBootCfg->ConfigFlags = (pBootCfg->ConfigFlags ^ BOOT_TYPE_DIRECT);
- bConfigChanged = TRUE;
- break;
- case '6': // Toggle image storage to Smart Media.
- pBootCfg->ConfigFlags = (pBootCfg->ConfigFlags ^ TARGET_TYPE_NAND);
- bConfigChanged = TRUE;
- break;
- case '7': // Configure Crystal CS8900 MAC address.
- SetCS8900MACAddress(pBootCfg);
- bConfigChanged = TRUE;
- break;
- case '8': // Toggle KD
- g_pBootCfg->ConfigFlags = (g_pBootCfg->ConfigFlags ^ CONFIG_FLAGS_DEBUGGER);
- g_bWaitForConnect = (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_DEBUGGER) ? TRUE : FALSE;
- bConfigChanged = TRUE;
- continue;
- break;
- case '9':
- // format the boot media for BinFS
- // N.B: this does not destroy our OEM reserved sections (TOC, bootloaders, etc)
- if ( !g_bBootMediaExist ) {
- OALMSG(OAL_ERROR, (TEXT("ERROR: BootMonitor: boot media does not exist./r/n")));
- continue;
- }
- // N.B: format offset by # of reserved blocks,
- // decrease the ttl # blocks available by that amount.
- if ( !BP_LowLevelFormat( g_dwImageStartBlock,
- wNUM_BLOCKS - g_dwImageStartBlock,
- 0) )
- {
- OALMSG(OAL_ERROR, (TEXT("ERROR: BootMonitor: Low-level boot media format failed./r/n")));
- continue;
- }
- break;
- case 'F':
- case 'f':
- // low-level format
- // N.B: this erases images, BinFs, FATFS, user data, etc.
- // However, we don't format Bootloaders & TOC bolcks; use JTAG for this.
- if ( !g_bBootMediaExist ) {
- OALMSG(OAL_ERROR, (TEXT("ERROR: BootMonitor: boot media does not exist./r/n")));
- continue;
- } else {
- SectorInfo si;
- // to keep bootpart off of our reserved blocks we must mark it as bad, reserved & read-only
- si.bOEMReserved = OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY;
- si.bBadBlock = BADBLOCKMARK;
- si.dwReserved1 = 0xffffffff;
- si.wReserved2 = 0xffff;
- OALMSG(TRUE, (TEXT("Reserving Blocks [0x%x - 0x%x] .../r/n"), 0, IMAGE_START_BLOCK-1));
- for (i = 0; i < IMAGE_START_SECTOR; i++) {
- FMD_WriteSector(i, NULL, &si, 1);
- }
- OALMSG(TRUE, (TEXT("...reserve complete./r/n")));
- OALMSG(TRUE, (TEXT("Low-level format Blocks [0x%x - 0x%x] .../r/n"), IMAGE_START_BLOCK, wNUM_BLOCKS-1));
- for (i = IMAGE_START_BLOCK; i < wNUM_BLOCKS; i++) {
- FMD_EraseBlock(i);
- }
- OALMSG(TRUE, (TEXT("...erase complete./r/n")));
- } break;
- case 'A':
- case 'a':
- OALMSG(TRUE, (TEXT("All block Erase.../r/n")));
- for (i = 0; i < wNUM_BLOCKS; i++) {
- FMD_EraseBlock(i);
- }
- break;
- case 'B':
- case 'b':
- // low-level format
- // N.B: this erases images, BinFs, FATFS, user data, etc.
- // However, we don't format Bootloaders & TOC bolcks; use JTAG for this.
- if ( !g_bBootMediaExist ) {
- OALMSG(OAL_ERROR, (TEXT("ERROR: BootMonitor: boot media does not exist./r/n")));
- continue;
- } else {
- DWORD i;
- SectorInfo si;
- // to keep bootpart off of our reserved blocks we must mark it as bad, reserved & read-only
- si.bOEMReserved = OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY;
- si.bBadBlock = BADBLOCKMARK;
- // si.bBadBlock = 0xff;
- si.dwReserved1 = 0xffffffff;
- si.wReserved2 = 0xffff;
- OALMSG(TRUE, (TEXT("Reserving Blocks [0x%x - 0x%x] .../r/n"), 0, IMAGE_START_BLOCK-1));
- for (i = 0; i < IMAGE_START_SECTOR; i++) {
- FMD_WriteSector(i, NULL, &si, 1);
- }
- OALMSG(TRUE, (TEXT("...reserve complete./r/n")));
- } break;
- case 'E':
- case 'e':
- // low-level format
- // N.B: this erases images, BinFs, FATFS, user data, etc.
- // However, we don't format Bootloaders & TOC bolcks; use JTAG for this.
- if ( !g_bBootMediaExist ) {
- OALMSG(OAL_ERROR, (TEXT("ERROR: BootMonitor: boot media does not exist./r/n")));
- continue;
- } else {
- int i;
- OALMSG(TRUE, (TEXT("Low-level format Blocks [0x%x - 0x%x] .../r/n"), 0, IMAGE_START_BLOCK-1));
- for (i = NBOOT_BLOCK; i < (NBOOT_BLOCK+NBOOT_BLOCK_SIZE); i++) {
- FMD_EraseBlock(i);
- }
- for (i = EBOOT_BLOCK; i < (EBOOT_BLOCK+EBOOT_BLOCK_SIZE); i++) {
- FMD_EraseBlock(i);
- }
- OALMSG(TRUE, (TEXT("...erase complete./r/n")));
- } break;
- case 'D': // Download? Yes.
- case 'd':
- bDownload = TRUE;
- goto MENU_DONE;
- case 'L': // Download? No.
- case 'l':
- bDownload = FALSE;
- goto MENU_DONE;
- case 'R':
- case 'r':
- TOC_Read();
- TOC_Print();
- // TODO
- break;
- case 'U': // Download? No.
- case 'u':
- bConfigChanged = TRUE;
- g_bUSBDownload = TRUE;
- bDownload = TRUE;
- goto MENU_DONE;
- case 'W': // Configuration Write
- case 'w':
- if (!TOC_Write())
- {
- OALMSG(OAL_WARN, (TEXT("WARNING: MainMenu: Failed to store updated eboot configuration in flash./r/n")));
- }
- else
- {
- OALMSG(OAL_INFO, (TEXT("Successfully Written/r/n")));
- bConfigChanged = FALSE;
- }
- break;
- default:
- break;
- }
- }
- MENU_DONE:
- // If eboot settings were changed by user, save them to flash.
- //
- if (bConfigChanged && !TOC_Write())
- {
- OALMSG(OAL_WARN, (TEXT("WARNING: MainMenu: Failed to store updated bootloader configuration to flash./r/n")));
- }
- return(bDownload);
- }
我现在要关注的是9和f选项
F) Low-level format the Smart Media card
从上面的代码可以看到,这个是给那些nboot和TOC以及eboot所占用的flash block做个标记
- //
- //在eboot中的loader.h中有如下定义
- //
- #define RESERVED_BOOT_BLOCKS (NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE + EBOOT_BLOCK_SIZE)
- // Images start after OEM Reserved Blocks
- #define IMAGE_START_BLOCK RESERVED_BOOT_BLOCKS
- #define IMAGE_START_SECTOR BLOCK_TO_SECTOR(IMAGE_START_BLOCK)
- //
- // OEM Reserved (Nand) Blocks for TOC and various bootloaders
- //
- // NAND Boot (loads into SteppingStone) @ Block 0
- #define NBOOT_BLOCK 0
- #define NBOOT_BLOCK_SIZE 1
- #define NBOOT_SECTOR BLOCK_TO_SECTOR(NBOOT_BLOCK)
- // TOC @ Block 1
- #define TOC_BLOCK 1
- #define TOC_BLOCK_SIZE 1
- #define TOC_SECTOR BLOCK_TO_SECTOR(TOC_BLOCK)
- // Eboot @ Block 2
- #define EBOOT_BLOCK 2
- #define EBOOT_SECTOR_SIZE FILE_TO_SECTOR_SIZE(EBOOT_RAM_IMAGE_SIZE)
- #define EBOOT_BLOCK_SIZE SECTOR_TO_BLOCK(EBOOT_SECTOR_SIZE)
- #define EBOOT_SECTOR BLOCK_TO_SECTOR(EBOOT_BLOCK)
- #define RESERVED_BOOT_BLOCKS (NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE + EBOOT_BLOCK_SIZE)
- // Images start after OEM Reserved Blocks
- #define IMAGE_START_BLOCK RESERVED_BOOT_BLOCKS
- #define IMAGE_START_SECTOR BLOCK_TO_SECTOR(IMAGE_START_BLOCK)
对于64M nand flash 扇区(page)和block关系转换如下。
//#ifndef SECTOR_TO_BLOCK
#define SECTOR_TO_BLOCK(sector) ((sector) >> 8 )
//#endif
//#ifndef BLOCK_TO_SECTOR
#define BLOCK_TO_SECTOR(block) ((block) << 8 )
//#endif
================================================
#define EBOOT_RAM_IMAGE_SIZE 0x00040000 //256K
#define EBOOT_SECTOR_SIZE FILE_TO_SECTOR_SIZE(EBOOT_RAM_IMAGE_SIZE)
#define EBOOT_BLOCK_SIZE SECTOR_TO_BLOCK(EBOOT_SECTOR_SIZE)//求出block数目,eboot.nb0占据2个block
// fs: file size in bytes
// returns sector aligned value 求出EBOOT_RAM_IMAGE_SIZE 占用的flash页数
__inline DWORD FILE_TO_SECTOR_SIZE(DWORD fs) {
return ( (fs / SECTOR_SIZE) + ( (fs % SECTOR_SIZE) ? 1 : 0) );//#define SECTOR_SIZE 512
}
从上面可以看出IMAGE_START_SECTOR=(NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE + EBOOT_BLOCK_SIZE)
=1+1+2=4(block)
===================================================
根据上面的准备,我现在把这个F菜单程序摘抄下来详细分析
SectorInfo si;
// to keep bootpart off of our reserved blocks we must mark it as bad, reserved & read-only
si.bOEMReserved = OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY;
si.bBadBlock = BADBLOCKMARK;
si.dwReserved1 = 0xffffffff;
si.wReserved2 = 0xffff;
OALMSG(TRUE, (TEXT("Reserving Blocks [0x%x - 0x%x] .../r/n"), 0, IMAGE_START_BLOCK-1));
//
//给非FAT区域写入标志
for (i = 0; i < IMAGE_START_SECTOR; i++) {
FMD_WriteSector(i, NULL, &si, 1);
}
OALMSG(TRUE, (TEXT("...reserve complete./r/n")));
OALMSG(TRUE, (TEXT("Low-level format Blocks [0x%x - 0x%x] .../r/n"), IMAGE_START_BLOCK, wNUM_BLOCKS-1));
for (i = IMAGE_START_BLOCK; i < wNUM_BLOCKS; i++) {
FMD_EraseBlock(i);
}
OALMSG(TRUE, (TEXT("...erase complete./r/n")));
我看了eboot的sources文件,发现 FMD_WriteSector函数居然是来自$(_TARGETPLATROOT)/Src/Common/Smartmedia/Fmd
也就是说这个FMD驱动是Src/Common/Smartmedia/Fmd的代码(充分利用了代码)
——FMD_WriteSector(i, NULL, &si, 1)这个函数到底做了什么呢?现在就要详细看看这个函数的各个参数的作用
3. BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors): 这个函数用于写nandflash的一个扇区。对于nandflash来说,分大page和小page,大page是2048个bytes一页,小page是512个bytes一页。所以大page每个扇区有2048 bytes,小page每个扇区有512 bytes。
startSectorAddr: nandflash物理扇区的起始地址,对于nandflash来说,就是nandflash中从哪个page开始。
pSectorBuff:扇区数据buffer,从nandflash中写入的每一个扇区的数据都存放在这个buffer中。
pSectorInfoBuff:扇区信息buffer,一般每个扇区的信息会被保存在nandflash的带外数据中,针对小page,带外数据有16 bytes,大page有64 bytes。从nandflash的带外数据将该扇区的相关信息读出来,存放在这个buffer中。
dwNumSectors:读取多少个扇区,对于nandflash来说相当于读取多少个page。
——再来摘抄一下慕水大哥的文章
对NANDFLASH的结构认识,其中忽略了非常重要的一块,就是NAND用来保存其它信息的一块区域,这些信息包括块好坏的标记,块的逻辑地址,还有页内数据的ECC校验和等。。。。
这部分数据通过结构SectorInfo保存
typedef struct _SectorInfo
{
DWORD dwReserved1; // Reserved - used by FAL
BYTE bOEMReserved; // For use by OEM
BYTE bBadBlock; // Indicates if block is BAD
WORD wReserved2; // Reserved - used by FAL
}SectorInfo, *PSectorInfo;
在读写NAND时通过
BOOL FMD_ReadSector (SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors);
BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors);
pSectorInfoBuff参数读取相应sector状态,如果pSectorInfoBuff参数为NULL则读写sector数据。pSectorBuff为非NULL则读写sector状态。
——从以上两点对FMD_WriteSector分析可以知道FMD_WriteSector(i, NULL, &si, 1)是把flash的状态写入数据带外区。但是还是不能完满解释怎么样把flash的一些block标记为坏块或者只读,保留的呢,我推测是微软自己定义了一些数据。现在来看看。
程序好长,在fmd.cpp里面,关键是NAND_LB_WriteSectorInfo(SECTOR_ADDR sectorAddr, PSectorInfo pInfo, int mode)这个函数,在这里就不贴出来了。
=============================现在看看他是怎么格式化的。MBR到底在哪里写了呢?
OALMSG(TRUE, (TEXT("Low-level format Blocks [0x%x - 0x%x] .../r/n"), IMAGE_START_BLOCK, wNUM_BLOCKS-1));
for (i = IMAGE_START_BLOCK; i < wNUM_BLOCKS; i++) {
FMD_EraseBlock(i);
}
OALMSG(TRUE, (TEXT("...erase complete./r/n")));
从上面的代码看,他只是察除而已?看看FMD_EraseBlock这个函数——这个是FMD部分的,复用的不错,这里所谓的高低格式化就是标记保留区以及察除FAT部分。那MBR跑哪里去了呢?看另外一个菜单吧。
====================9) Format Boot Media for BinFS菜单实现分析=====================
case '9':
// format the boot media for BinFS
// N.B: this does not destroy our OEM reserved sections (TOC, bootloaders, etc)
if ( !g_bBootMediaExist ) //检查flash是否初始化成功
{
OALMSG(OAL_ERROR, (TEXT("ERROR: BootMonitor: boot media does not exist./r/n")));
continue;
}
// N.B: format offset by # of reserved blocks,
// decrease the ttl # blocks available by that amount.
//这个是微软的库函数,我觉得这个是支持binfs的难点和关键点
if ( !BP_LowLevelFormat( g_dwImageStartBlock,
wNUM_BLOCKS - g_dwImageStartBlock,
0) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: BootMonitor: Low-level boot media format failed./r/n")));
continue;
}
break;
C:/WINCE500/PUBLIC/COMMON/OAK/DRIVERS/ETHDBG/BOOTPART/bootpart.cpp(1135)BP_LowLevelFormat
- /* BP_LowLevelFormat
- *
- * Called when preparing flash for a multiple-BIN download.
- * Erases, verifies, and writes logical sector numbers in the range to be written.
- *
- * ENTRY
- * dwStartBlock - starting physical block for format
- * dwNumBlocks - number of physical blocks to format
- * dwFlags - Flags used in formatting.
- *
- * EXIT
- * TRUE returned on success and FALSE on failure.
- */
- BOOL BP_LowLevelFormat(DWORD dwStartBlock, DWORD dwNumBlocks, DWORD dwFlags)
- {
- dwNumBlocks = min (dwNumBlocks, g_FlashInfo.dwNumBlocks);
- RETAILMSG(1,(TEXT("Enter LowLevelFormat [0x%x, 0x%x]./r/n"), dwStartBlock, dwStartBlock + dwNumBlocks - 1));
- // Erase all the flash blocks.
- if (!EraseBlocks(dwStartBlock, dwNumBlocks, dwFlags))
- return(FALSE);
- // Determine first good starting block
- while (IS_BLOCK_UNUSABLE (dwStartBlock) && dwStartBlock < g_FlashInfo.dwNumBlocks) {
- dwStartBlock++;
- }
- if (dwStartBlock >= g_FlashInfo.dwNumBlocks) {
- RETAILMSG(1,(TEXT("BP_LowLevelFormat: no good blocks/r/n")));
- return FALSE;
- }
- // MBR goes in the first sector of the starting block. This will be logical sector 0.
- g_dwMBRSectorNum = dwStartBlock * g_FlashInfo.wSectorsPerBlock;
- // Create an MBR. 哦原来创建了MBR...................哈哈,找到关键点了
- CreateMBR();
- RETAILMSG (1, (TEXT("Done./r/n/r/n")));
- return(TRUE);
- }
——转微软MVP对这个函数的解释
2. BOOL BP_LowLevelFormat(DWORD dwStartBlock, DWORD dwNumBlocks, DWORD dwFlags)
该函数用于低级格式化,它会格式化Flash设备中的Block,重新创建MBR并将MBR存到第一个Blockd的第一个扇区中。dwStartBlock为起始Block,dwNumBlocks为多少个Block,dwFlags为格式化标记位,表示采用何种格式化方式。该函数会根据需要来由EBOOT中的函数调用。
// This should not change unless reserved blocks are added/removed;
// made global to do the calc only once.
g_dwImageStartBlock = IMAGE_START_BLOCK;
再从前面看可知
#define RESERVED_BOOT_BLOCKS (NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE + EBOOT_BLOCK_SIZE)
// Images start after OEM Reserved Blocks
#define IMAGE_START_BLOCK RESERVED_BOOT_BLOCKS
#define IMAGE_START_SECTOR BLOCK_TO_SECTOR MAGE_START_BLOCK
综上所述,MBR不是是放在FAT区域的第一个block里面;而是放在NK占用部分的第一个block里面,为什么会这样呢?那系统是怎么读取MBR的,他怎么知道这个MBR所在的位置?
——本文到此结束,关于MBR以及分区等的事情,准备到下一篇文章讨论。
转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协。如有错误,希望能够留言指出。