以下内容是本人经验总结,如需转贴请注明出处!
http://blog.youkuaiyun.com/nick_TS16949/archive/2009/07/14/4346647.aspx
关于nandflash分区问题,由于在文件系统/MBR方面的欠缺让我走了许多弯路,虽然在网上搜了很多关于nandflash分区的文章,但我都没有成功。 在经过1个星期的修改/测试终于搞定了,所以现在把经验和步骤贴出来跟大家分享下。
一、实现分区的地方
因为我的boot是ADS写的,不能直接使用microsoft的bootpart源代码来分区,所以分区是在flash驱动中通过调用bootpart.lib来实现的。
另外!
不过根据其他人的经验,ADS下实现FLASH分区可以使用uc/fs的文件系统,而且更方便的做法:实现usb host,直接通过PC拷贝nk和应用程序到flash盘下,不需要烧录!
uc/fs分区的示意代码:
FS_Init();
FS_IoCtl("nf:0:", FS_CMD_FORMAT_AUTO, 0, 0);
FS_IoCtl("nf:1:", FS_CMD_FORMAT_AUTO, 0, 0);
还有种方法就是把boopart.cpp的代码移植到ADS下,不过在移植BOOL BP_Init (LPBYTE pMemory, DWORD dwSize, LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)函数时遇到问题,这个PPCI_REG_INFO定义涉及到需要头文件,相当麻烦!所以放弃了,改用在os中实现分区。
二、注册表部分
之所以先贴出注册表,是因为当初我以为flash分区应该跟注册表有关,需要修改它,后来才发现这部分不需要修改。
贴出我的注册表:
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/NandFlash]
"Dll"="smflash.dll"
"Order"=dword:0
"Prefix"="DSK"
"Profile"="FlashDisk"
"IClass"=multi_sz:"{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"
"FriendlyName"="MICHAEL NAND FLASH"
"Index"=dword:1
"BmlVolumedld"=dword:0
"BmlPartitionld"=dword:8
;"Flags"=dword:1000 ;have changed. add
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDisk]
"Name"="MICHAEL NAND FLASH"
"Folder"="NandDisk"
"DefaultFileSystem"="FATFS"
"AutoMount"=dword:1
"AutoPart"=dword:1
"AutoFormat"=dword:1
"PartitionDriver"="mspart.dll"
"BootPhase"=dword:0
"MountFlags"=dword:6
"Ioctl"=dword:4
[HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDisk/FATFS]
"EnableCacheWarm"=dword:0
"Paging"=dword:1
"Flags"=dword:00000024
;"MountAsBootable"=dword:1
; END HIVE BOOT SECTION
三、代码部分怎样实现分区,调用哪些API
总共就需要两个bootpart中的API,BP_Init(...)和BP_OpenPartition(...).
贴出我的代码:
HANDLE hPart, hPartEx;
// Try to initialize the boot media block driver and BinFS partition.
//
if ( !BP_Init((LPBYTE)(0x803b0000 | 0x20000000), 0x21000, NULL, NULL, NULL) )
{
RETAILMSG(1,(L"WARNING: OEMPlatformInit failed to initialize Boot Media./r/n/r/n"));
return;
}
RETAILMSG(1,(TEXT("PartNandFlash start......./r/n")));
hPart = BP_OpenPartition( (RESEVER_BOLCK_NUM+1)*PAGES_PER_BLOCK, // next block of MBR
//SECTOR_TO_BLOCK_SIZE(FILE_TO_SECTOR_SIZE(dwBINFSPartLength))*PAGES_PER_BLOCK, // align to block
(40)*PAGES_PER_BLOCK,
PART_DOS3_FAT,/*PART_DOS32*/
TRUE,
PART_OPEN_ALWAYS);
if (hPart == INVALID_HANDLE_VALUE )
{
//part failed!
return;
}
hPartEx = BP_OpenPartition( NEXT_FREE_LOC,
USE_REMAINING_SPACE,
PART_DOS32,
TRUE,
PART_OPEN_ALWAYS);
if (hPartEx == INVALID_HANDLE_VALUE )
{
//part failed
}
其中代码部分需要特别注意的地方,我已经用红色字体标示出来了。
首先需要在config.bib中定义一块RESERVED区域给BP_Init来初始化分区信息。
比如我在config.bib中作如下定义:
PART 803b0000 00021000 RESERVED
然后将这个地址和大小传递给BP_Init函数,因为地址是uncached的,所以传递的时候需要与上0x20000000.
至于保留区域的大小如何确定,有个公式:size最小需要 每扇区字节+ 每块字节+(每块扇区数*10).我的nandflash是k9f1g08,大小就是2048+64*2048+64*10 = 0x20A80, 所以分配0x21000就可以了。
(问题:在控制面板中通过存储管理器来分区又是如何操作的? 难度是动态申请一块static空间?)
做完以上动作,那么恭喜你,你的分区基本实现了。
///
但最最需要注意的地方是在BP_OpenPartition的第一次调用的时候是用PART_DOS3_FAT, 而不是PART_DOS32 !!!!
否则你的第二个分区将看不到。
///
就是这个小小的参数搞了我快1个星期,查了N多资料和网站。。。但是至于为什么这样做到现在为止我还没有弄明白,如果哪位知道,请在后来留个言,本人非常感激!!