分享

Nboot 与Eboot .

 lhzstudio 2012-05-16

引自:http://blog.csdn.net/lyx_wq/archive/2009/06/04/4241703.aspx

S3C2410处理器支持将启动代码存储在NAND Flash中。为了实现这一功能,2410配备了一个名为“Steppingstone”的内部SRAM。在启动时,NAND Flash中第一个4K字节的内容将被加载到Steppingstone中并执行。这个工作由MCU主动完成,而我们只需将NAND Flash配置为Auto Boot模式即可。

一般来说,启动代码会拷贝存储在NAND Flash中的内容至SDRAM中。在使用ECC校验时,NAND Flash中数据的有效性将被确认。在完成拷贝的工作后,启动代码将跳转到已加载到SDRAM中的主程序中,这时启动代码的使命完成,MCU由主程序来控制。

WinCE操作系统从文件的组成来看一般分为两部分:BOOTLOADER和NK.bin。在WinCE中,BOOTLOADER一般为EBOOT。它的主要功能是初始化硬件设备,主要包括CPU内部的相关控制器、内存、网络、串口甚至USB口和LCD。在初始化完成后,它将通过网络或USB从外部下载NK.bin,或从本地Flash中加载NK.bin并执行,从而启动WinCE操作系统。可以看到Eboot虽然是启动代码,但它得完成相当多的工作,最终的映像文件也将超过4K。所以,我们不能直接将Eboot存放在NAND Flash的第一个4K字节中。我们需要一个更小的启动代码,这就是通常所说的NBOOT(NAND BOOT)。

通过上面的介绍,我们知道了NBOOT在整个系统中扮演的角色,它负责将EBOOT加载到内存并运行。在EBOOT开始执行后,NBOOT就退出了历史的舞台,事实上也不再有上场的机会。

在NBOOT的代码实现中,我们必须完成以下几个部分。

1. 初始化CPU内部相关控制器,如设置GPIO,关闭Watch Dog,关闭中断,设置系统时钟。

2. 初始化内存。

3. 初始化串口,主要用来输出调试信息。

4. 初始化NAND Flash,因为在MCU启动时默认是Auto Boot模式,为了从NAND Flash中读取EBOOT,需要将其配置成 NAND Flash Mode。

5. 读取NAND Flash中的EBOOT映像文件,并放在内存指定的位置,这个地址是跟EBOOT有关,介绍EBOOT时再详细说明。

6. 完成读取之后,跳转到EBOOT的起始位置,执行EBOOT代码。

一般来说,前面两个功能在startup.s中实现,WinCE6.0下可以参考文件C:"WINCE600"PLATFORM"DEVICEEMULATOR"SRC"BOOTLOADER"EBOOT"startup.s的相关代码。后面四个功能可在main.c中实现。总之,在实现必备功能的情况下,尽可能减少代码量,以将最后的NBOOT映像文件控制在4K以内。

NBOOT的编译环境一般有两种,ADS1.2(或RVDS)、Platform Builder。用ADS1.2编译NBOOT是比较方便的,需要注意的就是RO Base和RW Base的设置,RO Base必须设置为0x0。否则,系统启动时NBOOT将不被运行。在Post-Linker中选择ARM from ELF,在Linker——ARM fromELF——Output Format中选择Plain Binary,这样,编译完成后最终生成NBoot.bin。该文件就可以固化在NAND Flash的第0个BLOCK中。Platform Builder 6.0是作为VS2005的插件来用的,所以,我们现在也可以用VS2005来编译NBOOT,这样就免得再安装ADS或RVDS等软件。用VS2005来编译NBOOT也有两种方法,第一种跟编译EBOOT映像文件类似,第二种是自己写makefile文件,然后用命令行的方式调用ARM编译器来编译。两种方法各有优点,第一种方法在编译OS时,会自动编译生成映像,而第二种方法可由ADS下的程序直接移植过来,不过,要写好makefile文件是相当困难的事情。一般还是少用为好。

下面就介绍如何用VS2005来编译NBOOT。

首先修改BSP的目录2410"SRC"Bootloader"的dir文件,添加NBOOT,dir文件的内容:


Code
 Nboot /
 eboot /
 bootpart
 
在bootloader下创建NBOOT目录,并创建makefile、makefile.inc、sources、nboot.bib文件,也可从EBOOT的目录下拷贝对应文件过来进行修改。

Makefile.inc文件的内容:


Code

!IF "$(NOLINK)" == ""

 romimage $(ROMIMAGE_FLAGS) nboot.bib

!IF "$(WINCEREL)"=="1"
 copy $(_PLATFORMROOT)"$(_TGTPLAT)"target"$(_TGTCPU)"$(WINCEDEBUG)"nboot.* $(_FLATRELEASEDIR)
!ENDIF

!ENDIF

 
Nboot.bib文件的内容:

Code
; Name Start Size Type

; ------- -------- -------- ----
 NBOOT 00000000 00003000 RAMIMAGE
 STACK 31400000 00001000 RESERVED
 RAM 31500000 00010000 RAM

CONFIG
 COMPRESSION=ON
 PROFILE=OFF
 KERNELFIXUPS=ON

 ROMSTART=00000000
 ROMWIDTH=32
 ROMSIZE=00001000

MODULES

; Name Path Memory Type

; ---------- -------------------------------------------------------------- -----------

 nk.exe $(_TARGETPLATROOT)"target"$(_TGTCPU)"$(WINCEDEBUG)"nboot.exe NBOOT
 
sources文件的内容:


Code
TARGETTYPE=PROGRAM
RELEASETYPE=PLATFORM
EXEENTRY=StartUp
NOMIPS16CODE=1

LDEFINES=-subsystem:native /DEBUG /DEBUGTYPE:CV /FIXED:NO

TARGETLIBS=$(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/fulllibc.lib

SOURCES= /
 startup.s /
 main.c /
 nand.s

WINCETARGETFILES=nboot_romimage
 
再将对应的代码文件拷贝到NBOOT的目录下,这里需要提醒一点的是,在main.c中需要添加一个全局变量的定义,这在ADS1.2的工程代码中是没有的,也是不须的。

Code
//
ROMHDR * volatile const pTOC = (ROMHDR *)-1;

否则,最终生成的Nboot.bin就只有一个文件头。做完相关代码的修改之后,就可以编译NBOOT了。

可以看到,最终编译生成了Nboot.bin、NBOOT.nb0、NBOOT.nb1、NBOOT.nb2。上面我们提到用ADS1.2编译最后可用的NBOOT映像为NBOOT.bin,但这里我们却得用NBOOT.nb1。对比一下ADS下生成的Nboot.bin和Nboot.nb1文件。


 

最后,再看一下反汇编nboot.exe的样子,将其跟startup.s对比一下,一样!

至此,我们就完成了用VS2005编译得到NBOOT的映像文件,NBOOT.nb1,应该来说还是比较简单的,但这中间还有些小的问题需要考虑,下次再整理。

    当然,S3C2410%26amp;%26amp;WinCE6.0也可以用Nor Flash存储启动代码,这种情况下,就不必用NBOOT,直接用Eboot.nb0就行

本文来自: ★编程爱好者博文★ http://www. 详细出处参考:http:///html/NETboke/200811/S3C2410--WINCE6-0--NBOOT_4410.html

作者:nasiry    文章来源:www.    点击数: 319    更新时间:2005-5-19
    eboot弄了很多次了,一直都没有整理一下整个代码流程。这次还是事来做一下吧:
首先通常都是汇编代码:启动时由系统复位导致PC为0为触发条件:以2440代码为例直接进入fw.s文件。主要执行的操作为设LL),设置内存参数,须注意的是在该部分代码虽然在形式上实现了诸多中断向量,但是这些代码根本上不会得到执行。(编译器决定中断向量及其实现单一性的原因”)而在后面会有一些其他手段用于实现中断向量的功能。由于和hal复用该部的函数名称会与内核启动函数的相同(如:KernelStart),但是实现内容却是完全不同的。在该部分的最后还将保存一个的地址指针到下一格函数,进行应有的内存影射。下面还是以2440bsp为例说明。根据windowsCE系统的要求,需要把将会操影射到0x8000 0000后的512M空间中,其中低256M为带缓冲的,高256M则是不带缓冲的。不带缓冲的区域通常是驱动访问设以保障对硬件的操作不受到缓冲的干扰。除了按照OEMAddressTable进行内存空间影射外,还可以要根据程序需求进行其他的做法都是将目前所有的设备/内存在原地址空间上再影射一次,以方便使用。            

    另外就是在将0x0位置影射到内存,这样,就分来进行中短向量的安装了,以实现中断服务程序。(以上内存影射并不是必须的,仅仅是为了方便程序的编写而已,使用射表可以使得不必重新另外建一套头文件,同时如果需要的话可以一直在内存中保存eboot,这样内存空间的规划也会相对以上的这些工作做完,就进入windowsCE提供的eboot入口函数了。 也就是BootloaderMain。这个函数位于WINCE420/PUBLIVERS/ETHDBG/BLCOMMON/blcommon.c文件中。该目录的文件就是微软提供的eboot框架,尽管这不是实现的部分,也一并分析内容一开始就很有意思,第一个执行的语句如下if (!KernelRelocate (pTOC)) { HALT (BLERR_KERNELRELOCATE); }而这个传入的参数却这样定义:ROMHDR * volatile const pTOC = (ROMHDR *)-1; 按照程序的内容来说,这个函数到这里了,可是事实上这个死循环不会得到执行,也就是pTOC = (ROMHDR *)-1并没有真正的起到作用。:) 在pTOC第一次使用前检值,结果如下:pTOC=0x8C04D694。也就是说pTOC在没有被改变之前就已经不再是-1了,而且pTOC是被定义成const的,也没看样子就只能是编译器的过程中这个指针就已经被动了手脚。而查看eboot.map中该地址所对应的内容居然是bootpart.obj从下手了,这样子让人太费解了。

    仔细比较eboot.exe和eboot.nb0后发现,eboot.exe通过romimage处理后长度增加了,而多,在原.eboot.exe后增加了一系列原来没有内容,pTOC的内容就是属于这部分内容中的一部分。由于牵涉到windowsCE的构,所以无法继续往下分析,这部分的内容就先跳过。以后再回头来看。随后在 BootloaderMain中对调试界面进行初始化,由OEMDebugInit完成这个函数的实现是由具体的硬件决定的通常来说为次以后就通过该调试界面进行调试信息的发布。然后在OEMPlatformInit()中对eboot所要用到的硬件资源进行初始化设备,通常这些会包含:存储设备(FLASH、硬盘等)、网卡、USB-RNDIS、无线网卡、CF—LAN等等)、系统时钟,为下面将会进行的os镜像传输、os镜像存储、读取等等一系列动做好准备以后就可以调用OEMPreDownload ()来进行传输OS的准备了,在这个函数中通常会实现一系列功能,诸如:设备的格式化、网卡IP的指定、等等。windowsCE所支持的标准操作则只是两个,一个是跳转、一个是下载、分别对应下载OS镜像点,前面提到的那些功能都是自己的扩展实现。
    下面我们分别来看这两个标准操作的分支:首先是下载的分支,在下载的分支中首先通过OEMReadData来获取在最先收到的为魔法数的数据,用以比较确认该传输的内容是否为windowsCE的镜像数据,随后继续进一步获取将接收的数据的效验和,量,镜像起始地址、长度等信息,有了这些个信息,很自然地就是接收镜像了,
随后检查数据的效验和。下一个镜像的信息的接收,如此往复循环直至所有的镜像信息接收完毕

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多