S3C2450 Bootloader调试总结

本文详细解析了S3C2450的Bootloader组成及其功能,包括Eboot、NBL1.IROM_SD、NBL1.LSB及NBL2等部分。重点介绍了Eboot.Whimory的实现细节,以及BootloaderMain函数中的关键流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.nb0Eboot.bin 两个文件已经生成。

三:Eboot.Whimory

整个Bootloader 最关键的部分就是这一块了。该部分用于产生Eboot.binEboot.nb0 文件。

主函数中由三个函数组成:

1 ):powerlock_init();

用于软置锁,开机后通过IO 口给电源的使能脚供电,保证系统正常供电。

2 ):BootloaderMain();

整个bootloader 的最关键的函数。下面将重点介绍。

3 ):SpinForever();

这个函数是不会执行的,在执行第二个函数后,就会跳到NK 的地址启动系统了。如果执行到这个函数,那系统肯定就挂在Eboot 这里了。

下面主要看BootloaderMain() 这个函数。

整个函数代码如下:

void BootloaderMain (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 use OEMWriteDebugString afterward.

    // 初始化串口

    if (!OEMDebugInit () )

    {

        // spin forever

        HALT (BLERR_DBGINIT);

    }

 

    // output banner

    // 打印第一条信息 :

    // Microsoft Windows CE Ethernet Bootloader Common 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 ("System ready!/r/nPreparing for download.../r/n");

 

// (4) call OEM specific pre-download function

    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 again since the pointer is going to be in a fixup address

            dwpToc = (DWORD) OEMMapMemAddr (dwImageStart, dwpToc + g_dwROMOffset);

 

            EdbgOutputDebugString ("ROMHDR at 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 the image by now, we assume that it'll be loaded from local storage in OEMLaunch (or it

        // already resides in RAM from an earlier download), and in this case, the image start address might be 0.  This means

        // that the image signature routine will 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's within 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 也就完成任务了。

 

原文地址:http://blog.sina.com.cn/s/blog_455851af0100ecbn.html~type=v5_one&label=rela_nextarticle

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值