九鼎创展论坛中文版English
登录 | 立即注册 设为首页收藏本站 切换到宽版
查看: 4925|回复: 1
打印 上一主题 下一主题

S3C2450 Bootloader总结

[复制链接]
跳转到指定楼层
楼主
发表于 2012-7-19 11:46:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
S3C2450 Bootloader调试总结
S3C2450的整个Bootloader包括四个部分:
1):Eboot.Whimory
2):NBL1.IROM_SD
3):NBL1.LSB
4):NBL2
实现功能:生成三个有用的文件:block0img.nb0,Eboot.nb0/Eboot.bin,以及IROM_SD_EBOOT.nb0。其中前两个文件用于烧到NAND的前几个block,用于初始化整个系统的环境,以及引导NK。最后面的IROM_SD_EBOOT.nb0文件,是将第二个Eboot.nb0/Eboot.bin文件打包得到的文件,用于烧写到SD卡中,从SD卡启动。下面针对前面的四个文件逐一说明。
一:NBL2
该文件用于生成block0img.nb0。用于完成如下功能:
1):初始化硬件配置,如堆栈,中断向量表,MMU等。
2):将后面生成的Eboot.bin文件拷备到DRAM中。
3):打印部分串口信息,表示系统已经启动。
4):初始化显示设备,输出开机LOGO。但此时背光没点亮,故肉眼是看不清有开机LOGO显示的。
5):初始化NAND FLASH。
6):跳转到拷备Eboot.bin的地址,执行Eboot程序。
注:执行此段代码的前提是,开机必须是从NAND启动的。之所以从SD卡启动时会白屏一下,就是因为从SD卡启动并没有执行这一段代码,即先点亮了背光,再初始化显示设备。如果从T卡启动,这段代码没有任何作用。
二:NBL1.LSB
此段代码个人觉得没有任何用处,应该可以直接删除。将该段屏蔽掉后,仍然能从SD卡启动,但是由于从NAND启动需要跳线,没做相关实验。但是block0img.nb0和Eboot.bin两个文件已经生成。
三:Eboot.Whimory
整个Bootloader最关键的部分就是这一块了。该部分用于产生Eboot.bin和Eboot.nb0文件。
主函数中由三个函数组成:
1):powerlock_init();
用于软置锁,开机后通过IO口给电源的使能脚供电,保证系统正常供电。
2):BootloaderMain();
整个bootloader的最关键的函数。下面将重点介绍。
3):SpinForever();
这个函数是不会执行的,在执行第二个函数后,就会跳到NK的地址启动系统了。如果执行到这个函数,那系统肯定就挂在Eboot这里了。
下面主要看BootloaderMain()这个函数。
整个函数代码如下:
voidBootloaderMain (void)
{
    DWORD dwAction;   
    DWORD dwpToc = 0;
    DWORD dwImageStart = 0, dwImageLength = 0,dwLaunchAddr = 0;
    BOOL bDownloaded = FALSE;
    // relocate globals to RAM
    // 将全局变量在RAM中声明
    if (!KernelRelocate(pTOC))
    {
        // spin forever
        HALT (BLERR_KERNELRELOCATE);
    }
    // (1) Init debug support. We can useOEMWriteDebugString afterward.
    // 初始化串口
    if (!OEMDebugInit())
    {
        // spin forever
        HALT (BLERR_DBGINIT);
    }
    // output banner
    // 打印第一条信息:
    // Microsoft Windows CE Ethernet BootloaderCommon Library Version 1.1 Built Jul 13 2009 00:17:59
    EdbgOutputDebugString (NKSignon,CURRENT_VERSION_MAJOR, CURRENT_VERSION_MINOR);
    // (3) initialize platform (clock, drivers,transports, etc)
    if (!OEMPlatformInit())
    {
        // spin forever
        HALT (BLERR_PLATINIT);
    }
    // system ready, preparing for download
    EdbgOutputDebugString ("Systemready!\r\nPreparing for download...\r\n");
    // (4) call OEM specific pre-downloadfunction
    switch (dwAction =OEMPreDownload ())
    {
    case BL_DOWNLOAD:
        // (5) download image
        if (!DownloadImage(&dwImageStart, &dwImageLength, &dwLaunchAddr))
        {
            // error already reported in DownloadImage
            SPIN_FOREVER;
        }
        bDownloaded = TRUE;
        // Check for pTOC signature("CECE") here, after image in place
        if (*(LPDWORD)OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET) ==ROM_SIGNATURE)
        {
            dwpToc = *(LPDWORD) OEMMapMemAddr(dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG));
            // need to map the content againsince the pointer is going to be in a fixup address
            dwpToc = (DWORD) OEMMapMemAddr(dwImageStart, dwpToc + g_dwROMOffset);
            EdbgOutputDebugString ("ROMHDRat Address %Xh\r\n", dwImageStart + ROM_SIGNATURE_OFFSET + sizeof(DWORD)); // right after signature
        }
        // fall through
    case BL_JUMP:
        // Before jumping to the image,optionally check the image signature.
        // NOTE: if we haven't downloaded theimage by now, we assume that it'll be loaded from local storage in OEMLaunch(or it
        // already resides in RAM from anearlier download), and in this case, the image start address might be 0.  This means
        // that the image signature routinewill need to find the image in storage or in RAM to validate it.  Since the OEM"s
       // OEMLaunch function will need to do this anyways, we trust that it'swithin their abilities to do it here.
        //
        if (g_bBINDownload &&g_pOEMCheckSignature)
        {
            if (!g_pOEMCheckSignature(dwImageStart,g_dwROMOffset, dwLaunchAddr, bDownloaded))
                HALT(BLERR_CAT_SIGNATURE);
        }
        // (5) final call to launch the image.never returned
        OEMLaunch(dwImageStart, dwImageLength, dwLaunchAddr, (const ROMHDR *)dwpToc);
        // should never return
        // fall through
    default:
        // ERROR! spin forever
        HALT (BLERR_INVALIDCMD);
    }
}
从以上程序可以看出,整个BootloaderMain()函数由五大函数组成,分别是:
1):KernelRelocate (pTOC);
用于将全局变量在DRAM中声明。
2):OEMDebugInit ();
用于初始化串口,给后续代码提供串口打印信息,便于调试。
3):OEMPlatformInit ();
用于初始化硬件平台,如时钟,驱动等。
该函数通过如下子函数完成各硬件平台的初始化:
A:memset():
初始化BSP args结构;
B:InitUSB();
初始化USB接口;
C:Isr_Init();
初始化中断;
D:BP_Init();
初始化Nand Flash;
E:InitDisplay();
初始化显示设备;
F:ShowLogo();
显示logo;
G:FMD_GetInfo();
读Flash信息;
H:TOC_Read();
读TOC信息;
I:OEMEthGetSecs();
读取当前时间,进行5秒倒计时;同时在这5秒的时间内检测是否有回车或空格键按下,如果回车,则运行NK。如果空格,则进入USB下载的菜单。
J:backlight_open();
亮背光。
以上是OEMPlatformInit ()函数的作用,具体每一句如何执行,每个函数是如何工作的,限于篇幅,这里就不详细介绍了。
4):OEMPreDownload ();
该函数用于判断程序是下载映像还是引导映像。执行完该函数后,将根据函数的返回值选择。程序通过一个switch语句完成。
5):DownloadImage()或OEMLaunch() 函数;
在步骤4中,如果返回值是BL_DOWNLOAD,则执行DownloadImage()函数,用于下载映像。如果返回值是BL_JUMP,则执行OEMLaunch() 函数,用于引导映像,最终启动系统。程序执行到OEMLaunch()后,整个bootloader也就完成任务了。
电子技术论坛[phosphor---[http://bbs.armeasy.com]---转载请注明出处

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳市九鼎创展科技官方论坛 ( 粤ICP备11028681号-2  

GMT+8, 2024-5-18 23:06 , Processed in 0.018118 second(s), 16 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表