如何实现从SD卡更新NK?——(已经实现)
2008-12-04 09:47
260 查看
作者:gooogleman@foxmail.com 2008-12-04
在前段时间,songtitan牛人在论坛说了一下使用SD卡更新NK的方法。如下:
http://topic.csdn.net/u/20081009/17/4E0F5E66-C7A0-43D2-B33F-14E132280F70.html
在CE下和在bootloader下都可以实现更新NK.
1 在CE下
可以直接用文件系统API读出NK.bin,放到内存buffer中,在通过DEVICEIOCTL的方式来调用nand驱动的接一些接口来直接对nand flash进行写操作。
好处:跳过boot section,FAT/FAT32文件系统的解析;对内存大小无要求
缺点:NAND驱动需要暴露读写的IOCTL,必须进入OS才能更新OS,如果OS挂了的话,无法更新。
2 bootloader下
直接对SD CONTROLLER操作来对SD卡进行读写,解析FAT/FAT32格式,找到NK.BIN,并能将其读取到内存中,再假设NK.BIN如下载一般到内存中,将其烧写到nand flash中。
好处:只要bootloader不挂,就可以对OS进行更新;
缺点:需要自己解析BOOT SECION,FAT/FAT32文件系统;需要至少和NK.BIN大小相同的剩余RAM
如果BSP本身没有支持bootloader下的SD更新nk,自己研究还是需要不少工作量的,最好的捷径就是能“弄到”别的平台的SD更新代码,改动就只是SD HOST controller部分。
=======================现在我的工作就是详细弄出怎么实现这个东西==========================
公司要求在bootloader阶段实现SD更新NK,并且说要实现用触摸屏操作,我觉得这个在裸奔阶段实现触摸屏菜单太难了,简直是不可能的事情。如果非要实现的话就一定要加上GUI,那bootloader搞的这么大,就没有什么意义了。我现在觉得有一种方法可行:就是放弃使用SD卡更新NK的办法,而是在flash里面备份一个NK,更新的时候就把备份NK放到启动的NK上。这样实现起来bootloader修改简单,在wince起来之后实现也不困难。现在的flash都已经1G以上了,那点容量牺牲不成问题,并且SD卡也腾出了空间——哈哈,好,就模仿ghost做一个嵌入式还原精灵吧。
====================================================================================
——经过几天的思索,我觉得在flash上做备份有点不妥当,因为flash有时候不稳定,很容易出问题。现在还是决定采用系统起来后更新NK的方法。很荣幸在这里找了个很好的老帖子——--------------------------------------wince下将flash中的内容全部读出来
http://topic.csdn.net/u/20080530/10/8A86B2C8-1623-4AB9-ACA7-D5DE24994CF6.html内容经典,摘抄下来。
--------------------------------------------------------------------------
硬件:2410 ,64M nandflash,64M RAM
我现在在想在wince下将难道中的内容从地址0,到nandflash结束,全部读出来,
该怎么做!
就好像是给台式电脑做GHOST备份一样,不同的是NANDFLASH为空的地方我们也要读取!
紧急,谢谢
--------------------------------------
要看你的文件系统是否支持.因为文件系统只能识别被分区的地方,那没有分区的空白区域是无法通过WINCE API访问到的.一般flash都有专用的读写器直接复制芯片内容的,也就是生产时用来做母片的工具。
--------------------------------------
恐怕只能自己写一个简单的flash driver,从头到尾读一遍了。wince的fat文件系统肯定是不能保证按flash的物理地址顺序读的。
--------------------------------------
NAND上一层是DISK接口了,不会有相应的API供你读取所有内容的。
如果能修改驱动,那么就让驱动开放一个特殊的IOContrl Code给你,输入地址范围,输出是将地址范围内的数据全部放到指定的buf指针地址去。Nand flash的驱动,修改FMD_OEMIoControl函数
-----------------------------------------------------------------
是标准的流接口,其实还是用DSK驱动就行,只是你自己设计一个原来没有的IOCONTROL_CODE,通过Device的IOControl()函数传下去时,在NAND FLASH的驱动中的IOControl直接判断,如果满足,就将指定范围的数据都读到指定的地址空间。
9楼的有个小错误,NAND驱动的读函数里已经做了ECC校验了,通过FMD_NAND_READ这样的函数读出来的数据是不需要再ECC校验的。
------------------------------------------------------------------------
引用 13 楼 so927 的回复:
引用 12 楼 jlctt 的回复:
修改FMD中FMD_OEMIoControl代码,开放FMD_ReadSector/FMD_WriteSector接口访问,然后用DeviceIoControl去访问整个NAND Flash.
明白您的意思了,我觉得也可以这样实现,谢谢提醒,
不过还有一个问题,我会不会把坏块也一起读出来了,每读一个块我是不是都需要检测一下是不是坏块呢
是的,需要的
=========================================抄贴结束======================================
——这几天,我首先在学习EVC读写SD卡程序,刚开始以为可以像PC一样malloc几十M的内存,结果试验发现当读400K写字板的时候已经那个非常慢,看来一次性读写30M的想法是行不通的。今天终于分段读写30M内核文件成功,下面是关键代码。
C/C++ code
http://blog.csdn.net/nanjianhui/archive/2008/03/19/2196466.aspx微软MVP的文章
——应用程序直接控制flash
===========================采用wince运行下更新NK的方法成功===========================
——现在公布要点。
一、在FMD中增加下面代码
//------------------------------------------------------------------------------
//---------------------------应用程序和flash直接通信-------希望大家看了有启发---
//------------------------------------------------------------------------------
static DWORD g_dwStartSector=2*64;
BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
switch(dwIoControlCode)
{
case 0x77777777:
for(unsigned int i=2;i<=242;i++)//30M NK 占用240 block
FMD_EraseBlock(i); //察除NK所占区域30M
RETAILMSG(1, (TEXT("FMD_OEMIoControl: recognized IOCTL.FMD_EraseBlock (0x%x)./r/n"), dwIoControlCode));
break;
case 0x12345678:
//写入NK所占区域——这个要看eboot中的函数才知道具体起始block
//RETAILMSG(1, (TEXT("FMD_OEMIoControl: recognized IOCTL.FMD_WriteSector(0x%x)./r/n"), dwIoControlCode));
RETAILMSG(1, (TEXT("FMD_OEMIoControl: recognized IOCTL.FMD_WriteSector(0x%x)./r/n"), nInBufSize));
RETAILMSG(1, (TEXT("FMD_OEMIoControl: nInBufSize=%d./r/n"), nInBufSize));
//for(unsigned int k=0;k<nInBufSize;k++)
// {
// FMD_WriteSector(g_dwStartSector,pInBuf,NULL,1);
// g_dwStartSector=g_dwStartSector+1;
// }
//FMD_WriteSector函数的参数很关键,pInBuf是应用程序传入,并且大小只能是一个page
//FMD_WriteSector的代码推测出,pInBuf只能是一个page
FMD_WriteSector(g_dwStartSector,pInBuf,NULL,1);
if(g_dwStartSector<=242*64)
g_dwStartSector=g_dwStartSector+1;
break;
default:
RETAILMSG(1, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x)./r/n"), dwIoControlCode));
return(FALSE);
}
return TRUE;
}
转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协。如有错误,希望能够留言指出;如果你有更加好的方法,也请在博客后面留言,我会感激你的批评和分享。
在前段时间,songtitan牛人在论坛说了一下使用SD卡更新NK的方法。如下:
http://topic.csdn.net/u/20081009/17/4E0F5E66-C7A0-43D2-B33F-14E132280F70.html
在CE下和在bootloader下都可以实现更新NK.
1 在CE下
可以直接用文件系统API读出NK.bin,放到内存buffer中,在通过DEVICEIOCTL的方式来调用nand驱动的接一些接口来直接对nand flash进行写操作。
好处:跳过boot section,FAT/FAT32文件系统的解析;对内存大小无要求
缺点:NAND驱动需要暴露读写的IOCTL,必须进入OS才能更新OS,如果OS挂了的话,无法更新。
2 bootloader下
直接对SD CONTROLLER操作来对SD卡进行读写,解析FAT/FAT32格式,找到NK.BIN,并能将其读取到内存中,再假设NK.BIN如下载一般到内存中,将其烧写到nand flash中。
好处:只要bootloader不挂,就可以对OS进行更新;
缺点:需要自己解析BOOT SECION,FAT/FAT32文件系统;需要至少和NK.BIN大小相同的剩余RAM
如果BSP本身没有支持bootloader下的SD更新nk,自己研究还是需要不少工作量的,最好的捷径就是能“弄到”别的平台的SD更新代码,改动就只是SD HOST controller部分。
=======================现在我的工作就是详细弄出怎么实现这个东西==========================
公司要求在bootloader阶段实现SD更新NK,并且说要实现用触摸屏操作,我觉得这个在裸奔阶段实现触摸屏菜单太难了,简直是不可能的事情。如果非要实现的话就一定要加上GUI,那bootloader搞的这么大,就没有什么意义了。我现在觉得有一种方法可行:就是放弃使用SD卡更新NK的办法,而是在flash里面备份一个NK,更新的时候就把备份NK放到启动的NK上。这样实现起来bootloader修改简单,在wince起来之后实现也不困难。现在的flash都已经1G以上了,那点容量牺牲不成问题,并且SD卡也腾出了空间——哈哈,好,就模仿ghost做一个嵌入式还原精灵吧。
====================================================================================
——经过几天的思索,我觉得在flash上做备份有点不妥当,因为flash有时候不稳定,很容易出问题。现在还是决定采用系统起来后更新NK的方法。很荣幸在这里找了个很好的老帖子——--------------------------------------wince下将flash中的内容全部读出来
http://topic.csdn.net/u/20080530/10/8A86B2C8-1623-4AB9-ACA7-D5DE24994CF6.html内容经典,摘抄下来。
--------------------------------------------------------------------------
硬件:2410 ,64M nandflash,64M RAM
我现在在想在wince下将难道中的内容从地址0,到nandflash结束,全部读出来,
该怎么做!
就好像是给台式电脑做GHOST备份一样,不同的是NANDFLASH为空的地方我们也要读取!
紧急,谢谢
--------------------------------------
要看你的文件系统是否支持.因为文件系统只能识别被分区的地方,那没有分区的空白区域是无法通过WINCE API访问到的.一般flash都有专用的读写器直接复制芯片内容的,也就是生产时用来做母片的工具。
--------------------------------------
恐怕只能自己写一个简单的flash driver,从头到尾读一遍了。wince的fat文件系统肯定是不能保证按flash的物理地址顺序读的。
--------------------------------------
NAND上一层是DISK接口了,不会有相应的API供你读取所有内容的。
如果能修改驱动,那么就让驱动开放一个特殊的IOContrl Code给你,输入地址范围,输出是将地址范围内的数据全部放到指定的buf指针地址去。Nand flash的驱动,修改FMD_OEMIoControl函数
-----------------------------------------------------------------
是标准的流接口,其实还是用DSK驱动就行,只是你自己设计一个原来没有的IOCONTROL_CODE,通过Device的IOControl()函数传下去时,在NAND FLASH的驱动中的IOControl直接判断,如果满足,就将指定范围的数据都读到指定的地址空间。
9楼的有个小错误,NAND驱动的读函数里已经做了ECC校验了,通过FMD_NAND_READ这样的函数读出来的数据是不需要再ECC校验的。
------------------------------------------------------------------------
引用 13 楼 so927 的回复:
引用 12 楼 jlctt 的回复:
修改FMD中FMD_OEMIoControl代码,开放FMD_ReadSector/FMD_WriteSector接口访问,然后用DeviceIoControl去访问整个NAND Flash.
明白您的意思了,我觉得也可以这样实现,谢谢提醒,
不过还有一个问题,我会不会把坏块也一起读出来了,每读一个块我是不是都需要检测一下是不是坏块呢
是的,需要的
=========================================抄贴结束======================================
——这几天,我首先在学习EVC读写SD卡程序,刚开始以为可以像PC一样malloc几十M的内存,结果试验发现当读400K写字板的时候已经那个非常慢,看来一次性读写30M的想法是行不通的。今天终于分段读写30M内核文件成功,下面是关键代码。
C/C++ code
//我把30M的文件读出来,再存放到一个文件,已经完全可行。该结贴了,是修改flash驱动的时候了。晚上回去结贴。 //==================从文件中分段读出数据,每次30K ,读1024次,共30M==================== for (unsigned int count=0;count<READCOUNT;count++) { SetFilePointer(hFile, m_FilePointer, NULL, FILE_BEGIN); /* 移动文件指针到文件开头 */ if (ret == 0xFFFFFFFF) { MessageBox(_T("将文件指针移至文件指定处失败!")); return; } pcharbuff=(char *)malloc(READSIZE); //每次申请30K的内存 ret = ReadFile(hFile, pcharbuff, READSIZE, &actlen, NULL); /* 从文件中分段读出数据,每次30K */ if (ret == FALSE) MessageBox(_T("读文件失败!")); //--------------------write read file to wogo.nb0----------------------- //--读出30K,就写30K SetFilePointer(hTestFile, m_FilePointer, NULL, FILE_BEGIN); /* 移动文件指针到文件开头 */ if (ret == 0xFFFFFFFF) { MessageBox(_T("将文件指针移至文件指定处失败!")); return; } ret = WriteFile(hTestFile, pcharbuff, READSIZE, &writelen, NULL); /* 将数据写入文件中 */ if (ret == FALSE) MessageBox(_T("写文件失败!")); free((void *)pcharbuff);//释放内存 m_FilePointer=m_FilePointer+READSIZE;//每次文件指针下移30K //if (count==1023) //{ // MessageBox(_T("读文件成功!")); //} } ——做这个除了了解了一下wince 虚拟内存申请以外,还得出:不管是二进制文件还是文本文件,
使用的读写函数都一样,要想把二进制的数据读出来显示,不能使用显示文本文件的方法。
=============================flash驱动修改部分==============================
http://blog.csdn.net/nanjianhui/archive/2008/03/19/2196466.aspx微软MVP的文章
——应用程序直接控制flash
===========================采用wince运行下更新NK的方法成功===========================
——现在公布要点。
一、在FMD中增加下面代码
//------------------------------------------------------------------------------
//---------------------------应用程序和flash直接通信-------希望大家看了有启发---
//------------------------------------------------------------------------------
static DWORD g_dwStartSector=2*64;
BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
switch(dwIoControlCode)
{
case 0x77777777:
for(unsigned int i=2;i<=242;i++)//30M NK 占用240 block
FMD_EraseBlock(i); //察除NK所占区域30M
RETAILMSG(1, (TEXT("FMD_OEMIoControl: recognized IOCTL.FMD_EraseBlock (0x%x)./r/n"), dwIoControlCode));
break;
case 0x12345678:
//写入NK所占区域——这个要看eboot中的函数才知道具体起始block
//RETAILMSG(1, (TEXT("FMD_OEMIoControl: recognized IOCTL.FMD_WriteSector(0x%x)./r/n"), dwIoControlCode));
RETAILMSG(1, (TEXT("FMD_OEMIoControl: recognized IOCTL.FMD_WriteSector(0x%x)./r/n"), nInBufSize));
RETAILMSG(1, (TEXT("FMD_OEMIoControl: nInBufSize=%d./r/n"), nInBufSize));
//for(unsigned int k=0;k<nInBufSize;k++)
// {
// FMD_WriteSector(g_dwStartSector,pInBuf,NULL,1);
// g_dwStartSector=g_dwStartSector+1;
// }
//FMD_WriteSector函数的参数很关键,pInBuf是应用程序传入,并且大小只能是一个page
//FMD_WriteSector的代码推测出,pInBuf只能是一个page
FMD_WriteSector(g_dwStartSector,pInBuf,NULL,1);
if(g_dwStartSector<=242*64)
g_dwStartSector=g_dwStartSector+1;
break;
default:
RETAILMSG(1, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x)./r/n"), dwIoControlCode));
return(FALSE);
}
return TRUE;
}
转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协。如有错误,希望能够留言指出;如果你有更加好的方法,也请在博客后面留言,我会感激你的批评和分享。
相关文章推荐
- 如何实现从SD卡更新NK?——(已经实现)
- 如何实现从SD卡更新NK
- 如何实现从SD卡更新NK?
- wince系统运行中如何实现更新flash中的NK.BIN?持续探讨,欢迎关注
- MINI2440从SD卡更新NK及nboot(二)
- arm Linux 如何自动检测并mount SD卡,以及如何得知已经mount
- 如何实现iOS热更新
- Linux下如何实现U盘、SD卡自动挂载功能?
- 如何实现缓存系统的更新机制
- 如何实现缓存系统的更新机制
- ios项目如何实现版本更新?
- arm Linux 如何自动检测并mount SD卡,以及如何得知已经mount
- 如何在Struts 数据库应用程序中实现记录的删除、更新及链接(续)
- SQL更新多行数据为不同的值如何实现?
- Lua5.1.4代码分析 如何实现Lua代码的热更新
- 如何实现插入并更新数据
- ios项目如何实现版本更新?
- 如何实现winform客户端智能更新
- android上如何实现后台日志记录并写文件到sd卡
- Sql Server2008如何在存储过程中实现根据判断插入更新数据