Eboot 中给nandflash分区实现.doc_第1页
Eboot 中给nandflash分区实现.doc_第2页
Eboot 中给nandflash分区实现.doc_第3页
Eboot 中给nandflash分区实现.doc_第4页
Eboot 中给nandflash分区实现.doc_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Eboot 中给nandflash分区实现 提到分区就不得不提到MBR,不得不提到分区表。什么是MBR硬盘的0柱面、0磁头、1扇区称为主引导扇区,NANDFLASH由BLOCK和Sector组成,所以NANDFLASH的第0 BLOCK,第1 Sector为主引导扇区,FDISK程序写到该扇区的内容称为主引导记录(MBR)。该记录占用512个字节,它用于硬盘启动时将系统控制权交给用户指定的,并在分区表中登记了的某个操作系统区。MBR的组成一个扇区的硬盘主引导记录MBR由如图6-15所示的4个部分组成。主引导程序(偏移地址0000H-0088H),它负责从活动分区中装载,并运行系统引导程序。出错信息数据区,偏移地址0089H-00E1H为出错信息,00E2H-01BDH全为0字节。分区表(DPT,Disk Partition Table)含4个分区项,偏移地址01BEH-01FDH,每个分区表项长16个字节,共64字节为分区项1、分区项2、分区项3、分区项4。结束标志字,偏移地址01FE-01FF的2个字节值为结束标志55AA,如果该标志错误系统就不能启动。图6-15 MBR的组成结构图MBR中的分区信息结构 占用512个字节的MBR中,偏移地址01BEH-01FDH的64个字节,为4个分区项内容(分区信息表)。它是由磁盘介质类型及用户在使用 FDISK定义分区说确定的。在实际应用中,FDISK对一个磁盘划分的主分区可少于4个,但最多不超过4个。每个分区表的项目是16个字节,其内容含义 如表6-19所示。表6-19 分区项表(16字节)内容及含义EBOOT中对NAND分区主要代码,eboot目录下的fmd.cpp文件,与NAND驱动基本相同,所以,要对NAND进行分区,就得对NAND驱动非常熟悉。透彻了解。然后就是E:WINCE500PUBLICCOMMONOAKDRIVERSETHDBGBOOTPARTbootpart.cpp文件了。该文件主要通过调用NANDFLASH的读写操作来写入MBR,也是今天主要的分析对象。主要函数。/* BP_OpenPartition * * Opens/creates a partition depending on the creation flags. If it is opening * and the partition has already been opened, then it returns a handle to the * opened partition. Otherwise, it loads the state information of that partition * into memory and returns a handle. * * ENTRY * dwStartSector - Logical sector to start the partition. NEXT_FREE_LOC if none * specified. Ignored if opening existing partition. * dwNumSectors - Number of logical sectors of the partition. USE_REMAINING_SPACE * to indicate to take up the rest of the space on the flash for that partition (should * only be used when creating extended partitions). This parameter is ignored * if opening existing partition. * dwPartType - Type of partition to create/open. * fActive - TRUE indicates to create/open the active partition. FALSE for * inactive. * dwCreationFlags - PART_CREATE_NEW to create only. Fail if it already * exists. PART_OPEN_EXISTING to open only. Fail if it doesnt exist. * PART_OPEN_ALWAYS creates if it does not exist and opens if it * does exist. * * EXIT * Handle to the partition on success. INVALID_HANDLE_VALUE on error. */HANDLE BP_OpenPartition(DWORD dwStartSector, DWORD dwNumSectors, DWORD dwPartType, BOOL fActive, DWORD dwCreationFlags)注:示例代码为本人EBOOT中分区实现源码(WINCE5.0+S3C2440+128MNAND,MBR写在第4个BLOCK,分一个BINFS格式分区和一个FAT格式分区)。BOOL WriteRegionsToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)在把SDRAM中的NK烧写到NAND中去之前,先创建一个BINFS分区。hPart = BP_OpenPartition( (NK_START_BLOCK+1)*PAGES_PER_BLOCK, / next block of MBR BINFS_BLOCK*PAGES_PER_BLOCK,/SECTOR_TO_BLOCK_SIZE(FILE_TO_SECTOR_SIZE(dwBINFSPartLength)*PAGES_PER_BLOCK, /align to block PART_BINFS, TRUE, PART_OPEN_ALWAYS);第一个参数分区的起始sector 为(NK_START_BLOCK+1)*PAGES_PER_BLOCK,第二个参数分区的结束 sector为BINFS_BLOCK*PAGES_PER_BLOCK,第三个参数分区的格式为PART_BINFS,即BINFS格式,第四个参数指示该分区为活动分区,fActive = TURE,第五个参数PART_OPEN_ALWAYS指示如果分区不存在就创建该分区,存在就OPEN该分区,返回分区句柄。HANDLE BP_OpenPartition(DWORD dwStartSector, DWORD dwNumSectors, DWORD dwPartType, BOOL fActive, DWORD dwCreationFlags) DWORD dwPartIndex; BOOL fExists; ASSERT (g_pbMBRSector); if (!IsValidMBR() DWORD dwFlags = 0; /fly RETAILMSG(1, (TEXT(BP_OpenPartition: dwStartSector=0x%x ,dwNumSectors= 0x%x.,dwPartType = 0x%xrn), dwStartSector, dwNumSectors,dwPartType); if (dwCreationFlags = PART_OPEN_EXISTING) RETAILMSG(1, (TEXT(OpenPartition: Invalid MBR. Cannot open existing partition 0x%x.rn), dwPartType); return INVALID_HANDLE_VALUE; RETAILMSG(1, (TEXT(OpenPartition: Invalid MBR. Formatting flash.rn); if (g_FlashInfo.flashType = NOR) dwFlags |= FORMAT_SKIP_BLOCK_CHECK; /fly RETAILMSG(1, (TEXT(BP_LowLevelFormat: g_pbMBRSector=0x%x, g_dwMBRSectorNum= 0x%x.rn), *g_pbMBRSector, g_dwMBRSectorNum); BP_LowLevelFormat (SECTOR_TO_BLOCK(dwStartSector), SECTOR_TO_BLOCK(dwNumSectors), dwFlags); dwPartIndex = 0; fExists = FALSE; else fExists = GetPartitionTableIndex(dwPartType, fActive, &dwPartIndex); RETAILMSG(1, (TEXT(OpenPartition: Partition Exists=0x%x for part 0x%x.rn), fExists, dwPartType); if (fExists) / Partition was found. if (dwCreationFlags = PART_CREATE_NEW) return INVALID_HANDLE_VALUE; if (g_partStateTabledwPartIndex.pPartEntry = NULL) / Open partition. If this is the boot section partition, then file pointer starts after MBR g_partStateTabledwPartIndex.pPartEntry = (PPARTENTRY)(g_pbMBRSector + PARTTABLE_OFFSET + sizeof(PARTENTRY)*dwPartIndex); g_partStateTabledwPartIndex.dwDataPointer = 0; if ( dwNumSectors g_partStateTabledwPartIndex.pPartEntry-Part_TotalSectors ) return CreatePartition (dwStartSector, dwNumSectors, dwPartType, fActive, dwPartIndex); else return (HANDLE)&g_partStateTabledwPartIndex; else / If there are already 4 partitions, or creation flag specified OPEN_EXISTING, fail. if (dwPartIndex = NUM_PARTS) | (dwCreationFlags = PART_OPEN_EXISTING) return INVALID_HANDLE_VALUE; / Create new partition return CreatePartition (dwStartSector, dwNumSectors, dwPartType, fActive, dwPartIndex); return INVALID_HANDLE_VALUE; 进入函数,首先做的事就是检测MBR的有效性。通过函数IsValidMBR()实现。检测MBR的有效性,首先要知道MBR保存在哪里,前面说过NANDFLASH的第0 BLOCK,第1 Sector为主引导扇区,也就是MBR,但是NAND如果被当作启动芯片,地址一般被BOOTLOADER代码占据,MBR只有放在后面的BLOCK中。所以我把第0 个BLOCK放NBOOT,第1个BLOCK放TOC,第2个BLOCK放EBOOT,第3个BLOCK保留,第4个BLOCK就放MBR。static BOOL IsValidMBR() / Check to see if the MBR is valid / MBR block is always located at logical sector 0 g_dwMBRSectorNum = GetMBRSectorNum(); RETAILMSG (1, (TEXT(IsValidMBR: MBR sector = 0x%xrn), g_dwMBRSectorNum); if (g_dwMBRSectorNum = INVALID_ADDR) | !FMD_ReadSector (g_dwMBRSectorNum, g_pbMBRSector, NULL, 1) RETAILMSG (1, (TEXT(IsValidMBR-return FALSE-rn); return FALSE; return (g_pbMBRSector0 = 0xE9) & (g_pbMBRSector1 = 0xfd) & (g_pbMBRSector2 = 0xff) & (g_pbMBRSectorSECTOR_SIZE_FS-2 = 0x55) & (g_pbMBRSectorSECTOR_SIZE_FS-1 = 0xAA); IsValidMBR()实现的第一行就是给全局变量g_dwMBRSectorNum 赋值,显而易见,g_dwMBRSectorNum就是指示保存MBR的那个Sector了。g_dwMBRSectorNum = GetMBRSectorNum(); /是获得保存MBR的那个Sectorstatic DWORD GetMBRSectorNum () DWORD dwBlockNum = 3, dwSector = 0; SectorInfo si; while (dwBlockNum 0)然后确定BLOCK是否可使用的BLOCK,最后通si.dwReserved1 = 0来判断是不是选择这个Sector来保存MBR。IsValidMBR()中还有一个重要的结构就是g_pbMBRSector数组,它就是MBR了。函数返回时,MBR必须符合下列记录。 return (g_pbMBRSector0 = 0xE9) & (g_pbMBRSector1 = 0xfd) & (g_pbMBRSector2 = 0xff) & (g_pbMBRSectorSECTOR_SIZE_FS-2 = 0x55) & (g_pbMBRSectorSECTOR_SIZE_FS-1 = 0xAA);可以看到只有开始三个字节为0XE9,FD,FF,当然,还有熟悉的结束标志符0X55AA。如果没有检测到MBR,则先对NANDFLASH进行低级格式化。BP_LowLevelFormat (SECTOR_TO_BLOCK(dwStartSector), SECTOR_TO_BLOCK(dwNumSectors), dwFlags);再创建分区,CreatePartition (dwStartSector, dwNumSectors, dwPartType, fActive, dwPartIndex);。BOOL BP_LowLevelFormat(DWORD dwStartBlock, DWORD dwNumBlocks, DWORD dwFlags) dwNumBlocks = min (dwNumBlocks, g_FlashInfo.dwNumBlocks); RETAILMSG(1,(TEXT(fly:Enter LowLevelFormat 0x%x, 0x%x.rn), dwStartBlock,dwNumBlocks);/ 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) RETAILMSG(1,(TEXT(BP_LowLevelFormat: no good blocksrn); return FALSE; / MBR goes in the first sector of the starting block. This will be logical sector 0. g_dwMBRSectorNum = dwStartBlock * g_FlashInfo.wSectorsPerBlock; RETAILMSG(1,(TEXT(fly:g_dwMBRSectorNum=%drn),g_dwMBRSectorNum); / Create an MBR. CreateMBR(); return(TRUE);在对NANDFLASH进行低格时,主要对坏块的处理。if (!EraseBlocks(dwStartBlock, dwNumBlocks, dwFlags)检测每一个Sector,每个BLOCK只要有一个Sector不能读写这个块都会被处理成坏块,这样才能保证系统的稳定性。在函数的最后调用了 CreateMBR();来创建一个MBR。static 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_pbMBRSector0 = 0xE9; g_pbMBRSector1 = 0xfd; g_pbMBRSector2 = 0xff; g_pbMBRSectorSECTOR_SIZE_FS-2 = 0x55; g_pbMBRSectorSECTOR_SIZE_FS-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(); 当然。因为还没有进行分区,这里写入的MBR分区表部分是空的。static BOOL WriteMBR() DWORD dwMBRBlockNum = g_dwMBRSectorNum / g_FlashInfo.wSectorsPerBlock; /dwMBRBlockNum = 1 ; RETAILMSG(1, (TEXT(WriteMBR: MBR block = 0x%x,g_dwMBRSectorNum = 0x%x.rn), dwMBRBlockNum,g_dwMBRSectorNum); 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 hasnt been written yet. ReadBlock (dwMBRBlockNum, g_pbBlock, g_pSectorInfoBuf); if (!FMD_EraseBlock (dwMBRBlockNum) RETAILMSG (1, (TEXT(CreatePartition: error erasing block 0x%xrn), 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(fly:WriteMBR: MBR block = 0x%x.rn), dwMBRBlockNum); if (!WriteBlock (dwMBRBlockNum, g_pbBlock, g_pSectorInfoBuf) RETAILMSG (1, (TEXT(CreatePartition: could not write to block 0x%xrn), dwMBRBlockNum); return FALSE; return TRUE; 在WriteMBR()函数中,就写入了判断MBR 的一些标志到BLOCK, g_pSectorInfoBuf-bOEMReserved &= OEM_BLOCK_READONLY; g_pSectorInfoBuf-wReserved2 &= SECTOR_WRITE_COMPLETED; g_pSectorInfoBuf-dwReserved1 = 0;Wince系统启动时,具体是NANDFLASH驱动加载成功后,MOUNT文件系统到NANDFLASH之前,也会通过读取这些SectorInfo来得到MBR 保存的BLOCK,进而读取MBR,获得分区信息,从而把各分区MOUNT到相应文件系统。格式化完成,MBR也写入成功后就可以开始新建分区了。/* 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 * none specified. * dwNumSectors - Number of logical sectors of the partition. USE_REMAINING_SPACE * to indicate to take up the rest of the space on the flash for that partition. * dwPartType - Type of partition to create. * fActive - TRUE indicates to create the active partition. FALSE for * inactive. * dwPartIndex - Index of the partition entry on the MBR * * EXIT * Handle to the partition on success. INVALID_HANDLE_VALUE on error. */static HANDLE CreatePartition (DWORD dwStartSector, DWORD dwNumSectors, DWORD dwPartType, BOOL fActive, DWORD dwPartIndex) DWORD dwBootInd = 0; RETAILMSG(1, (TEXT(CreatePartition: Enter CreatePartition for 0x%x.rn), dwPartType); if (fActive) dwBootInd |= PART_IND_ACTIVE; if (dwPartType = PART_BOOTSECTION | dwPartType = PART_BINFS | dwPartType = PART_XIP) dwBootInd |= PART_IND_READ_ONLY; / If start sector is invalid, it means find next free sector if (dwStartSector = NEXT_FREE_LOC) dwStartSector = FindFreeSector(); if (dwStartSector = INVALID_ADDR) RETAILMSG(1, (TEXT(CreatePartition: cant find free sector.rn); return INVALID_HANDLE_VALUE; / Start extended partition on a block boundary if (dwPartType = PART_EXTENDED) & (dwStartSector % g_FlashInfo.wSectorsPerBlock) dwStartSector = (dwStartSector / g_FlashInfo.wSectorsPerBlock + 1) * g_FlashInfo.wSectorsPerBlock; / If num sectors is invalid, fill the rest of the space up if (dwNumSectors = USE_REMAINING_SPACE) DWORD dwLastLogSector = LastLogSector(); if (dwLastLogSector = INVALID_ADDR) return INVALID_HANDLE_VALUE; / Determine the number of blocks to reserve for the FAL compaction when creating an extended partition. DWORD dwReservedBlocks = g_FlashInfo.dwNumBlocks / PERCENTAGE_OF_MEDIA_TO_RESERVE; if(dwReservedBlocks = g_FlashInfo.dwNumBlocks / PERCENTAGE_OF_MEDIA_TO_RESERVE) MINIMUM_FLASH_BLOCKS_TO_RESERVE) dwReservedBlocks = MINIMUM_FLASH_BLOCKS_TO_RESERVE; dwNumSectors = dwLastLogSector - dwStartSector + 1 - dwReservedBlocks * g_FlashInfo.wSectorsPerBlock; if (!AreSectorsFree (dwStartSector, dwNumSectors) RETAILMSG (1, (TEXT(fly:CreatePartition: sectors 0x%x, 0x%x requested are out of range or taken by another partitionrn), dwStartSector, dwNumSectors); return INVALID_HANDLE_VALUE; RETAILMSG(1, (TEXT(CreatePartition: Start = 0x%x, Num = 0x%x.rn), dwStartSector, dwNumSectors); AddPartitionTableEntry (dwPartIndex, dwStartSector, dwNumSectors, (BYTE)dwPartType, (BYTE)dwBootInd); if (dwBootInd & PART_IND_READ_ONLY) if (!WriteLogicalNumbers (dwStartSector, dwNumSectors, TRUE) RETAILMSG(1, (TEXT(CreatePartition: cant mark sector info.rn); return INVALID_HANDLE_VALUE; if (!WriteMBR() return INVALID_HANDLE_VALUE; g_partStateTabledwPartIndex.pPartEntry = (PPARTENTRY)(g_pbMBRSector + PARTTABLE_OFFSET + sizeof(PARTENTRY)*dwPartIndex); g_partStateTabledwPartIndex.dwDataPointer = 0; return (HANDLE)&g_partStateTabledwPartIndex; 如果第二个参数为1,则视为将余下的所有空间划为一个分区。LastLogSector();函数获得最后一个逻辑Sector。static DWORD LastLogSector() if (g_dwLastLogSector) return g_dwLastLogSector; DWORD dwMBRBlock = g_dwMBRSectorNum / g_FlashInfo.wSectorsPerBlock; DWORD dwUnusableBlocks = dwMBRBlock; for (DWORD i = dwMBRBlock; i g_FlashInfo.dwNumBlocks; i+) if (IS_BLOCK_UNUSABLE (i) dwUnusableBlocks+; g_dwLastLogSector = (g_FlashInfo.dwNumBlocks - dwUnusableBlocks) * g_FlashInfo.wSectorsPerBlock - 1; RETAILMSG(1, (TEXT(fly:LastLo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论