注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

Eboot调试(三)--blcommon 框架  

2011-06-14 17:50:56|  分类: ARM学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

歇了两天,我们重新找时间开始写BLCOMMON部分,在前面的两节分析里,我们知道,在startup.s文件过后,会调用main.c,然后在main函数里会调用BootLoaderMain(),大家不要着急,我们一步步的来解析,凡事都怕认真两

个字,只要我们认真的去做,就没有不能成功的。毕竟这个东西又不是什么高精尖的东西。
微软为了编写BOOTLOADER的统一和方便,开发了这个blcommon 框架,一些主要的东西由微软写代码来完成,诸如下载镜像文件等,然后把一些必要的函数接口暴露出来,让客户进行实际的定制,从而达到在本框架下进行二次

开发的目的,这个看起来是不是很象WDM啥滴。包括后来的WDF,不都这是这样么。
说得简单一点儿,blcommon 就是把Boot Loader搬到RAM里以获得更快的访问速度;解析以及接报.BIN文件的格式;检验校验以及跟踪加载进度;调用OEM代码处理硬件初始化等操作。可直接链接Blcommon.lib来使用。
说正事,我们在startup.s里调用了main.c ,在main函数里,
void main(void)
{

 EBOOT_LowLevelInit();
 EBOOT_WatchdogRefresh();

    // Common boot loader (blcommon) main routine.
    BootloaderMain();

    // Should never get here.
    EBOOT_SpinForever();
}
我们会发现我们这次调用的BootloaderMain这个函数,而这个函数就是blcommon 框架里一个最主要的函数。
1.BootloaderMain函数首先调用KernelRelocate函数将Bootloader中用到的全局变量拷贝到RAM中。
2.然后调用OEMDebugInit函数来初始化Debug调试功能,一般都是初始化串口,这样从这里以后就可以使用串口打印调试信息了。
3.之后调用OEMPlatformInit函数,来对板子进行初始化,很多和平台相关的初始化工作都可以在这个函数中完成。
4.调用OEMPreDownload函数,从流程上来说应该是为下载内核做一些准备工作,该函数执行后,根据返回值得不同可以选择下载内核,或者跳转执行。实际上,该函数中首先会读取Boot配置信息,然后初始化下载设备,一般

是网卡设备。
5.如果OEMPreDownload函数返回BL_DOWNLOAD时,将会从主机下载WinCE image。
6.如果OEMPreDownload函数返回BL_JUMP时,直接跳转到WinCE image所在的位置开始执行。
其中涉及的OEM函数都是需要用户自己实现的,然后被BLCOMMON模块来调用。这些函数我们会在编写时详细说明。

下面我们对主要的几个函数进行说明,重新定位全局变量函数- KernelRelocate
在BLCommon.c文件中。将全局变量转移到RAM中。
static BOOL KernelRelocate (ROMHDR *const pTOC)
{
    ULONG loop;
    COPYentry *cptr;
    if (pTOC == (ROMHDR *const) -1)
    {
        return (FALSE); // spin forever!
    }
    // This is where the data sections become valid... don't read globals until after this
    for (loop = 0; loop < pTOC->ulCopyEntries; loop++)
    {
        cptr = (COPYentry *)(pTOC->ulCopyOffset + loop*sizeof(COPYentry));
        if (cptr->ulCopyLen)
            memcpy((LPVOID)cptr->ulDest,(LPVOID)cptr->ulSource,cptr->ulCopyLen);
        if (cptr->ulCopyLen != cptr->ulDestLen)
            memset((LPVOID)(cptr->ulDest+cptr->ulCopyLen),0,cptr->ulDestLen-cptr->ulCopyLen);
    }
    return (TRUE);
}
 
1. 问什么要把全局变量重定位到RAM中?    Boot Loader大多数代码用C编写,在被编译成二进制代码后,这些全局变量被放在可执行文件的一个数据段中,然后被烧写到目标设备上。很多情况下,Boot Loader是在只读媒体

上运行的(如NOR Flash ROM),这样要对全局变量进行写操作时就会失败。因此需要把全局变量所在的数据段转移到RAM,以确保全局变量可写。
2. 如何转移数据段?    由pTOC决定。
 其定义:ROMHDR * volatile const pTOC = (ROMHDR *const) -1;
此指针描述了整个ROM几乎所有的信息。定义的时候,赋予非法值-1。编写代码时,代码不可能知道自己将会被烧写到什么样的ROM里,因此全局变量pTOC是在工具RomImage.exe在把EBOOT打包为ROM文件时初始化的。
 
经重定位后,EBOOT的全局变量就可以在RAM中正确的读写了,从而保证Eboot代码的正确运行。接下来可以进行端口初始化等其他任务了。
 
初始化调试端口- OEMDebugInit
代码由OEM实现。通常初始化一个UART端口,用来输出调试信息,这样就尅方便的在开发机上使用超级终端等接收调试信息。
 
初始化平台- OEMPlatformInit
代码由OEM实现,主要初始化目标板上的设备:
?         实时钟  EBoot在后面的网络下载及用户输入等判断超时都需要通过实时钟进行。
?         显示屏  可选。如果要在操作系统启动时,在显示屏上显示logo等信息,在此时初始化显示屏。
?         Flash  如果下载后的映像必须烧写到Flash中或其他方式要用的Flash,则可在这里初始化Flash。另外,FMD驱动程序也可在这里初始化。
?         网卡  EBoot必须用到网卡下载映像,在这里初始化网卡,包括MAC地址、I/O方式等。
?         BSP的共享参数  OAL和EBoot通常会共享一些参数,需要在这里初始化。
如果要在EBoot上与超级终端中的用户交互,也可在这个步骤进行。
OEMPlatformInit()结束后,就可以开始下载工作了。
 
下载映像之前函数- OEMPreDownload
代码有OEM实现。主要任务是完成以太网下载前的一些准备工作,包括:通过DHCP获得IP地址,初始化TFTP服务等。
 
下载映像函数-DownloadImage
是BLCommon库提供的一个库函数,作用是从远程开发机上下载操作系统映像。与传输介质无关,DownloadImage()调用OEMReadData()函数来读取下载的数据。
支持一次下载多个BIN文件(Muti-Bin)构成的映像。
除了下载外,DownloadImage还负责把映像的长度、大小和运行起始地址返回给调用者。
如果用户配置的映像下载地址是一段Flash的地址,那么DownloadImage函数还负责调用OEM函数,把下载的系统映像烧写到Flash中去。
源代码:%WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\ETHDBG
\BLCOMMON\mian.c
 
启动映像函数-OEMLaunch
由OEM实现。
这样,我们blcommon框架就基本讲解清楚了,大家有什么细节还要知道,可以在网上查,没什么太深的东西了。

  评论这张
 
阅读(947)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017