wince binfs详解-程序员宅基地

技术标签: wince  system  file  存储  compression  三星  

 
理解BinFS, Multi-XIP, Multi-bin:http://chenyq2008.spaces.live.com/blog/cns!F73164AC8D0D8D50!218.entry

 

转自http://www.armce.com/bbs/thread-1043-1-1.html

网上不少介绍三星24x0系列的BINFS启动方式实现,有些内容上描述的不是非常全面下面就WinCE6上的BINFS实现,从基本原理到修改BSP,再到如何烧录启动做一个较全面的讲解

 

一 BINFS到底是什么?

其实BINFS就是MS给CE做的一种存放系统镜像的一个文件系统。一说文件系统,大家可能比较头大。那么这么说,其实就是一个结构体(说是文件系统确实比较勉强,结构体可能更合适),里面有记录各模块的起始地址,大小等的信息,你要找模块可以根据这个信息到后面找。

 

二 为什么要用BINFS?有什么好处?

其实我觉得最大的好处是“按需加载系统模块到内存”,这里衍生出两个优点:

1 开机需要加载的核心部分很少,大大减少开机读取系统的时间

2 不需要为操作系统预留全尺寸的内存大小,只需预留最小开机核心的大小,剩下的作为通用内存空间,所以使系统内存使用有了很大灵活性,可用系统内存大大增加

 

三 BINFS的实现基础

这里不得不说WinCE的烧写和引导方式,在默认情况下,大家都知道WinCE会生成nk.bin和nk.nb0,bin其实就是nb0的压缩形式

nb0怎么可以压缩?因为nb0中有很多空白区域

bin是如何压缩的?很简单的描述下,就是用一个结构体记录一下,起始地址,大小,校验和,然后后面就是实际的内容

这样的一个一个结构体顺序排在一起就组成了bin这个简单的压缩格式,实际上只是压缩了nb0里面不必要的0,而不是对数据做了算法压缩,所以很好理解,所以你用winrar等去压缩bin,发现可以更小,呵呵

 

最简单的烧写和启动WinCE的方法是:

直接把nk.bin烧到存储设备上,比如NAND上假设nk.bin是30MB,那么就在NAND上顺序留下30MB给NK.bin

启动的时候把nk.bin按照那个结构体,解压到内存中,跳转到起始地址,就可以运行了

但是我发现有趣的是,很多开发板厂家并不是这么做的他们实际上是用了BINFS来存放解压出来的系统镜像

这里大家可能比较疑惑一个问题,明明很多开发板都没有用“BINFS”,你怎么说他们用了BINFS?

实际上这里有一个重要的误会

BINFS是一个文件系统,但是大家关注BINFS是因为想实现上面说的加快开机和节省内存的好处,实际上需要完成这种好处,BINFS是一个文件系统基础,真正做到将系统镜像分为两个部分还需要用到multi-bin技术 所以这个就是误会所在。

很多开发板确实用了BINFS文件系统,但是他们只是把系统镜像全部写入到BINFS分区,启动时再全部读出来,这样就没有达到前面说的“好处”

怎么确定我的系统现在有没有用BINFS?

看看自己的烧写代码,如果用了bootpart的库进行分区,写入,比如

  1. BP_OpenPartition(NEXT_FREE_LOC, dwNumSectors, PART_BINFS, TRUE, PART_OPEN_ALWAYS);

这里就是典型的建立了一个BINFS分区,然后使用BP_WriteData将镜像内容写入到这个分区

如果你的程序没有使用这么一套机制,那么说明你的系统没有使用BINFS

前面说到除了BINFS作为文件系统的支持,还需要multi-bin技术,那么这个multi-bin技术是做什么的呢
实际上,我们想到,系统可以分为多块,我们只需要把核心启动的内容放到内存中,然后其它用到的从固态存储器中(使用了BINFS文件系统)读出来就可以了,这个就是我们前面说到的“好处”的实现原理

那么如何将系统镜像分开来,这个就是需要一些BSP里面的修改了,后面在实现方法中介绍

那么最简单的分配就是将系统镜像分为两块:
一块用来存放系统启动时候需要在内存中运行的“最小内核
一块用来存放系统后续需要“按需加载”的模块文件

我们一般也都是这么做的

编译的时候我们会通过配置文件告诉系统什么地址范围是在内存中运行的内核,什么地址范围是在存储器(使用BINFS存放镜像)上的系统其它模块,然后启动时候只需要加载最小内核,然后由最小内核使用BINFS文件系统驱动来读取存储器BINFS分区上的其它所需模块

系统怎么知道那些文件在什么地址?怎么知道哪些文件是在最小内核里还是存储器BINFS分区上的?


系统有记录各文件地址的结构体,有了文件地址就自然知道是放在什么地方的了,别忘了前面说的配置文件,里面已经告诉了各块的起止地址,很容易就可以判断到。关于结构体是如何记录模块地址等内容,不是本文讨论范围,这里就先放下,大家知道系统有方法知道文件的地址和大小就可以了。

所以为什么一些开发板系统用了BINFS,却没有那些“好处”,就是因为虽然用了BINFS文件系统,但是把全部内容都放进了最小内核,所以没有达到任何的优势效果。
就是说我们在实现了BINFS文件系统之后需要做的就是将“最小内核”和“系统其它文件”分离开来

四 BINFS的实现
前面已经较详细的说明了原理,其实说到这里文章题目已经需要有些改变了,我们实际上讨论的是“使用BINFS实现multi-bin来节省系统内存”,而不只是实现BINFS文件系统。因为我怕标题太长,大家有些费解,而且很多人把这个就称为BINFS,所以才取了这个题目。实际上将这种技术单单叫做BINFS是不准确的。

1 首先说说如何实现BINFS文件系统


前面说了,BINFS文件系统是基础,为什么?因为分离系统镜像之后,系统“最小内核”会使用BINFS去读系统其它模块,所以我们必须将系统镜像使用BINFS文件系统写入固态存取器(后面无特别说明,所有"存储器"均指“固态存储器”,内存指"SDRAM"或"DDR"等程序运行介质)


那么我们可不可以不用BINFS,用FAT?理论上应该是可以的,不过需要修改MS的系统加载模块的程序,我不知道是不是所有涉及到的模块都有开源,所以这个我们不讨论

其实MS对WinCE设备的存储器分区启动管理有点像PC的
在WinCE中首先在存储器一开始,存放的是MBR(master boot record,我没记错的话...),熟悉文件系统的朋友一看就明白了MBR是干什么的。MBR在CE中主要是记录后面的存储器空间是如何分区的,这个记录应该和PC上是一样的,起始sector号码,总共有几个Sectors,分区使用什么文件系统。但是不同的是,MBR不需要承担引导代码的功能

在MBR之后,按照分区记录中的起始地址,就是各个分区,大家不妨想象为PC上的分区,只不过我们现在C盘不用FAT或者NTFS,而是使用一种叫做BINFS的文件系统。

我们需要创建,修改MBR,增加删除,查询,读取分区信息和内容。这些功能都是bootpart库里面的,大家可以查询相关内容,这里不详细说明bootpart库是如何使用的。

只要了解过磁盘分区概念的朋友,应该很快就可以操作bootpart函数,而且一般的EBoot在烧写这里都是有例子的。大家可以参考,这里只是列出基本步骤
a) BP_LowLevelFormat 用来格式化所有存储空间
b) BP_OpenPartition 打开某个分区,如果不存在可以创建该分区,比如BINFS
c) BP_WriteData 往分区里写数据
d) BP_ReadData 读取分区里的数据
这些是一些基本的操作函数,具体实现细节大家需要多参考EBoot里面的代码,实际需要考虑的问题还可能包括整个存储器的布局

2 往BINFS分区中写入镜像


如果创建好了BINFS分区,那么下面要做的就是把镜像写入BINFS分区
如果大家下载的是BIN文件,首先需要把BIN文件解压缩出来,解压缩代码可以参考EBoot里面的代码然后调用BP_WriteData可以写入BINFS分区
详细步骤大家还是多看示例代码,过程并不复杂

3 如何将系统镜像分成多个部分
这里就是说的multi-bin的,把镜像分为“最小内核”与“系统其它文件”
MS帮助文件里面有How to Implement BinFS ,这里将大致流程介绍了一下

首先就是需要修改config.bib文件,对CE比较了解的朋友知道,CE的地址等配置都是在config.bib里面修改的,所以

我们要去改config.bib文件

这里可以看到现在系统对于镜像的划分,例如

  1. Name        Address     Size        Type
  2. NK          88200000    03000000    RAMIMAGE
  3. RAM         8B200000    04E00000    RAM

这个很容易理解,NK是唯一的一个bin文件,存放RAMIMAGE
这里面RAMIMAGE是关键字,告诉系统这个是需要启动的“最小内核”,现在是48MB...
RAM是告诉系统可用的内存起始地址和大小

首先我们需要把NK给分开成为两部分,即“最小内核”与“系统其它文件”
修改如下

  1. Name        Address     Size        Type
  2. XIPKERNEL  88200000    00400000    RAMIMAGE
  3. CHAIN     88600000    00001000    RESERVED
  4. NK        88601000    02BFF000     NANDIMAGE
  5. RAM        88601000    079FF000    RAM

我们好好看下这个配置,这里完成的是将系统镜像内容分为两部分


XIPKERNEL,就是我们的“最小内核”,就是RAMIMAGE
NK,就是“系统其它文件”,就是NANDIMAGE(关键字,不可改)

CHAIN是什么?

CHAIN是实现multi-bin的必须部分,是告诉系统各bin文件位置的信息。一定需要了解CHAIN的内容?
其实CHAIN也是结构体...,大家如果把chain.bin解压出来,会发现是这个结构体

  1. {
  2. bin个数
  3. bin信息描述结构体[bin个数]
  4. }

这里说的bin就是把系统镜像拆分开的子区块,我们这里就是2个,分别是XIPKERNEL和NK
信息描述会记录各个bin的起始位置,实际大小和最大大小,分区名称等
实际大小就是编译出来的实际大小,最大大小就是我们在config.bib里面指定的大小

还有一些其它的配置也需要修改

  1. AUTOSIZE=ON
  2. COMPRESSION=ON
  3. DLLADDR_AUTOSIZE=ON
  4. KERNELFIXUPS=ON
  5. PROFILE=OFF
  6. RAM_AUTOSIZE=OFF
  7. ROMFLAGS=0
  8. ROM_AUTOSIZE=OFF
  9. ROMSIZE=03000000
  10. ROMSTART=88000000
  11. ROMWIDTH=32
  12. XIPSCHAIN=88600000

这里你能订制的就是后面4项,我这里ROMSTART=88000000,因为前面还有一些地址配置因为与系统镜像生成无关,所

以我就没有贴上来,不过为了防止大家搞不清这个88000000是怎么来的,还是贴一下

  1. Name        Address     Size        Type
  2. ARGS        88000000    00001000    RESERVED
  3. VPU         88001000    000FF000    RESERVED
  4. FRAMEBUFFER 88100000    00100000    RESERVED

88000000就是我内存映射到的起始地址
这里需要注意XIPSCHAIN,这个一定要设置为CHAIN的起始地址,带了XIPSCHAIN,才会生成后面需要的xip.bin

MS的帮助文件里面的例子是用的NK作为RAMIMAGE的名字,EXT作为NANDIMAGE的名字
当然名字不是最重要的,但是实际使用中,大家会发现使用NK作为RAMIMAGE的名字亏大了
为什么呢?
这就是我们下面需要做的
把各分区都配置好之后,下面需要决定把哪些内容放到什么分区下了
如前面所述,我们需要把启动需要的“最小内核”放到RAMIMAGE里面
首先定义一下哪些是“最小内核”
其实说白了就是系统可以使用BINFS读取在存储器上文件所需要的最小系统文件


这里其实需要了解WinCE的启动过程,但是我们并不深入到函数,只是模块级的
系统启动后需要初始化,所以关于初始化的OAL层都需要放进来,然后我们需要使用device.exe来加载我们的存储器驱动,这样才能访问存储器,所以关于设备驱动加载,总线枚举的模块都要加上,还有我们需要的BINFS驱动模块,还有mspart分区模块,不然无法找到BINFS分区的位置。这些都是较通用的模块,还有一些模块你一定要注意,就是你的存储器驱动所依赖的驱动模块,比如ceddk?你的bsp里的gpio驱动?dma驱动?等等。

如果没有加入全的话就会出现加载不了存储器驱动,也就没法找到分区,没法访问BINFS...
有人说如果需要用HIVE的话,还要加载FAT驱动,实际上并不需要,因为我们的目的是要完成“可以访问BINFS”,

boot.hv一定是要放到RAMIMAGE里的,所以基础注册表都是有的,可以让你完成对存储器驱动的加载,而这之后都可以用BINFS访问“系统其它文件”了,所以FAT驱动是不需要放到RAMIMAGE里面的,在用到FAT时,BINFS已经好用了,同时default.hv,user.hv也都是不需要放到RAMIMAGE里面的

如果你使用非英文的系统,还有一个文件不要忘记:wince.nls,少了这个你也会启动不了

下面给出例子,我相信可以涵盖大部分平台应用了

  1. MODULES
  2.     nk.exe          $(_FLATRELEASEDIR)/oal.exe                  XIPKERNEL  SHZ
  3.     kernel.dll      $(_FLATRELEASEDIR)/kern.dll                 XIPKERNEL  SHZ
  4.     coredll.dll     $(_FLATRELEASEDIR)/coredll.dll              XIPKERNEL  SH
  5.      k.coredll.dll   $(_FLATRELEASEDIR)/k.coredll.dll            XIPKERNEL  SHMK
  6.      oalioctl.dll    $(_FLATRELEASEDIR)/oalioctl.dll             XIPKERNEL  SHK
  7.      filesys.dll     $(_FLATRELEASEDIR)/filesys.dll              XIPKERNEL  SHK
  8.      fsdmgr.dll     $(_FLATRELEASEDIR)/fsdmgr.dll                XIPKERNEL  SHMK
  9.      mspart.dll     $(_FLATRELEASEDIR)/mspart.dll                XIPKERNEL  SHK
  10.      romfsd.dll     $(_FLATRELEASEDIR)/romfsd.dll              XIPKERNEL  SHK
  11.      binfs.dll     $(_FLATRELEASEDIR)/binfs.dll                      XIPKERNEL  SHK
  12.      fpcrt.dll       $(_FLATRELEASEDIR)/fpcrt.dll                XIPKERNEL  SH
  13.      k.fpcrt.dll     $(_FLATRELEASEDIR)/fpcrt.dll                XIPKERNEL  SHMK
  14.      ceddk.dll       $(_FLATRELEASEDIR)/ceddk.dll                XIPKERNEL  SHQ
  15.      device.dll      $(_FLATRELEASEDIR)/device.dll               XIPKERNEL  SHMK
  16.    udevice.exe     $(_FLATRELEASEDIR)/udevice.exe              XIPKERNEL  SHM
  17.    devmgr.dll      $(_FLATRELEASEDIR)/devmgr.dll               XIPKERNEL  SHMK
  18.    regenum.dll     $(_FLATRELEASEDIR)/regenum.dll              XIPKERNEL  SHK
  19.    busenum.dll     $(_FLATRELEASEDIR)/busenum.dll              XIPKERNEL  SHK
  20.     pm.dll       $(_FLATRELEASEDIR)/pm.dll                      XIPKERNEL  SHMK
  21.     nandfmd.dll         $(_FLATRELEASEDIR)/nandfmd.dll              XIPKERNEL  SHK
  22. FILES
  23.     boot.hv         $(_FLATRELEASEDIR)/boot.hv                  XIPKERNEL  SH
  24.    wince.nls      $(_FLATRELEASEDIR)/wince.nls                XIPKERNEL  SHU

这里的nandfmd.dll是我的NAND驱动,可以改成你自己的
可能有一些还是可以优化掉的,但是我还没有尝试,大家可以给出意见

上面这段代码放到哪里?
放到config.bib最后!没错,是config.bib,不是platform.bib

这里再回头来说说使用NK当作RAMIMAGE名称的缺点
大家看到,我们只要把需要的模块改成XIPKERNEL就好了,但是系统默认的都是用的NK这个名字,如果我们使用NK当作RAMIMAGE的名字的话,我们要把其他所有不要加进来的改名字...这个工作量太大了,所以我们把NK当作了NANDIMAGE的名字

4 配置注册表
到了这一步还没有完成,我们需要配置些注册表
其实我默认的注册表还真没有什么需要改的
大家看看MS的帮助文件里面关于注册表的配置,这里列出一些设置

  1. [HKEY_LOCAL_MACHINE/System/StorageManager/PartitionTable]
  2.     "21"="BINFS"
  3. [HKEY_LOCAL_MACHINE/System/StorageManager/Profiles/FlashDisk/BINFS]
  4.     "MountHidden"=dword:1
  5.     "MountAsROM"=dword:1

这里不得不说一下RAM and ROM file system和ROM-Only file system
很多帖子都说用BINFS一定要用RAM and ROM file system,实际上并不是这样
使用ROM-Only file system一样可以,但是大家需要记住,在使用ROM-Only file system时,把FAT mount为根目录

五 BINFS的烧写和启动


上面把BSP那里该修改的都修改了,只要编译就可以了,关于如何编译系统,其实是一个非常非常重要的问题,一定要
重视,参考http://www.armce.com/bbs/thread-804-1-1.html
不正确的编译,会影响你本来应该正确的结果!
下面又是一个问题,现在生成了4个可以用的bin,分别是XIKERNEL.bin,nk.bin,chain.bin,xip.bin
那么到底该怎么烧写呢?
实际上大家从大小就可以看出XIP包含了所有其他bin的内容,所以大家直接把XIP.bin下载解压,然后用bootpart的函数烧写到存储器上就可以了

启动的时候怎么引导?和原来启动系统一样,但是记住,不需要把全部的xip.bin里面指定的大小都读取出来了,最多只要读你在config.bib里面指定的RAMIMAGE大小就可以了

RAMIMAGE大小怎么确定的?这个你可以先放的比较大,比如10MB,然后看编译出来的RAMIMAGE分区有多大,再调整,

一般都是3MB以内吧,我这里保守的用4MB

 

调试技巧
调试BINFS的multi-bin启动,需要反复的烧写,设置有一点不正确经常就是卡在某个地方,对于我们用中文镜像的就更痛苦了,release版都有30-40MB,debug版不改存储布局,烧都烧不进去
我建议大家新建一个项目,然后选择thin client,不妨将显示驱动也加入,其他驱动都不要,然后一定选择debug版本,debug版本的调试信息非常重要
花这点时间去编译一个thin client是非常值得的,调试速度很快

下面给一些调试建议
1 引导之后就死机,什么消息都没有
估计是内存配置有问题,或者烧写的有问题,或者没有把需要的内核模块加进去

2 死在OEMInit之后
后面应该开始加载NAND驱动了,看看你的关于设备管理,驱动加载和总线枚举的模块有没有加全
如果已经有NAND驱动的信息出来了,看看NAND驱动是不是因为什么原因没有加载起来,比如缺少某个dll支持

3 其他
如果NAND正常了,BINFS没问题了,大家需要根据自己的BSP来看看其他的问题

 

 

6410的三星原版bsp支持multi-bin,在smdk6410.bat中设置 ,代码上要做部分修改

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lin415804/article/details/6987076

智能推荐

Docker 快速上手学习入门教程_docker菜鸟教程-程序员宅基地

文章浏览阅读2.5w次,点赞6次,收藏50次。官方解释是,docker 容器是机器上的沙盒进程,它与主机上的所有其他进程隔离。所以容器只是操作系统中被隔离开来的一个进程,所谓的容器化,其实也只是对操作系统进行欺骗的一种语法糖。_docker菜鸟教程

电脑技巧:Windows系统原版纯净软件必备的两个网站_msdn我告诉你-程序员宅基地

文章浏览阅读5.7k次,点赞3次,收藏14次。该如何避免的,今天小编给大家推荐两个下载Windows系统官方软件的资源网站,可以杜绝软件捆绑等行为。该站提供了丰富的Windows官方技术资源,比较重要的有MSDN技术资源文档库、官方工具和资源、应用程序、开发人员工具(Visual Studio 、SQLServer等等)、系统镜像、设计人员工具等。总的来说,这两个都是非常优秀的Windows系统镜像资源站,提供了丰富的Windows系统镜像资源,并且保证了资源的纯净和安全性,有需要的朋友可以去了解一下。这个非常实用的资源网站的创建者是国内的一个网友。_msdn我告诉你

vue2封装对话框el-dialog组件_<el-dialog 封装成组件 vue2-程序员宅基地

文章浏览阅读1.2k次。vue2封装对话框el-dialog组件_

MFC 文本框换行_c++ mfc同一框内输入二行怎么换行-程序员宅基地

文章浏览阅读4.7k次,点赞5次,收藏6次。MFC 文本框换行 标签: it mfc 文本框1.将Multiline属性设置为True2.换行是使用"\r\n" (宽字符串为L"\r\n")3.如果需要编辑并且按Enter键换行,还要将 Want Return 设置为 True4.如果需要垂直滚动条的话将Vertical Scroll属性设置为True,需要水平滚动条的话将Horizontal Scroll属性设_c++ mfc同一框内输入二行怎么换行

redis-desktop-manager无法连接redis-server的解决方法_redis-server doesn't support auth command or ismis-程序员宅基地

文章浏览阅读832次。检查Linux是否是否开启所需端口,默认为6379,若未打开,将其开启:以root用户执行iptables -I INPUT -p tcp --dport 6379 -j ACCEPT如果还是未能解决,修改redis.conf,修改主机地址:bind 192.168.85.**;然后使用该配置文件,重新启动Redis服务./redis-server redis.conf..._redis-server doesn't support auth command or ismisconfigured. try

实验四 数据选择器及其应用-程序员宅基地

文章浏览阅读4.9k次。济大数电实验报告_数据选择器及其应用

随便推点

灰色预测模型matlab_MATLAB实战|基于灰色预测河南省社会消费品零售总额预测-程序员宅基地

文章浏览阅读236次。1研究内容消费在生产中占据十分重要的地位,是生产的最终目的和动力,是保持省内经济稳定快速发展的核心要素。预测河南省社会消费品零售总额,是进行宏观经济调控和消费体制改变创新的基础,是河南省内人民对美好的全面和谐社会的追求的要求,保持河南省经济稳定和可持续发展具有重要意义。本文建立灰色预测模型,利用MATLAB软件,预测出2019年~2023年河南省社会消费品零售总额预测值分别为21881...._灰色预测模型用什么软件

log4qt-程序员宅基地

文章浏览阅读1.2k次。12.4-在Qt中使用Log4Qt输出Log文件,看这一篇就足够了一、为啥要使用第三方Log库,而不用平台自带的Log库二、Log4j系列库的功能介绍与基本概念三、Log4Qt库的基本介绍四、将Log4qt组装成为一个单独模块五、使用配置文件的方式配置Log4Qt六、使用代码的方式配置Log4Qt七、在Qt工程中引入Log4Qt库模块的方法八、获取示例中的源代码一、为啥要使用第三方Log库,而不用平台自带的Log库首先要说明的是,在平时开发和调试中开发平台自带的“打印输出”已经足够了。但_log4qt

100种思维模型之全局观思维模型-67_计算机中对于全局观的-程序员宅基地

文章浏览阅读786次。全局观思维模型,一个教我们由点到线,由线到面,再由面到体,不断的放大格局去思考问题的思维模型。_计算机中对于全局观的

线程间控制之CountDownLatch和CyclicBarrier使用介绍_countdownluach于cyclicbarrier的用法-程序员宅基地

文章浏览阅读330次。一、CountDownLatch介绍CountDownLatch采用减法计算;是一个同步辅助工具类和CyclicBarrier类功能类似,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。二、CountDownLatch俩种应用场景: 场景一:所有线程在等待开始信号(startSignal.await()),主流程发出开始信号通知,既执行startSignal.countDown()方法后;所有线程才开始执行;每个线程执行完发出做完信号,既执行do..._countdownluach于cyclicbarrier的用法

自动化监控系统Prometheus&Grafana_-自动化监控系统prometheus&grafana实战-程序员宅基地

文章浏览阅读508次。Prometheus 算是一个全能型选手,原生支持容器监控,当然监控传统应用也不是吃干饭的,所以就是容器和非容器他都支持,所有的监控系统都具备这个流程,_-自动化监控系统prometheus&grafana实战

React 组件封装之 Search 搜索_react search-程序员宅基地

文章浏览阅读4.7k次。输入关键字,可以通过键盘的搜索按钮完成搜索功能。_react search