WinCE Bootloader学习笔记之KernelRelocate()函数

来源:互联网 发布:求导软件手机版 编辑:程序博客网 时间:2024/04/27 23:50

内核的初始化数据都保存在镜像文件中(data段的数据)。对数据的读写,必须要把镜像的真实数据内容,复制到RAM中,才允许使用。Kernelrelocate()函数就是完成该功能的,把镜像中的全局变量Copy到Ram中,该过程完成之后,其他模块才能正常访问保存的全局数据。

 

1.需要用到的两个概念:

ROMIMAGE.exe:  生成系统镜像文件的程序。

TOC: Table Of Contents, 保存了系统的指针和数据。在镜像文件开头附近,有一个标志,内容是CECE(0x44424442)。这个标志后面就存放着TOC的偏移值,那么bootloader和其他程序可以通过TOC找到镜像相关的信息。

 

2.需要用到的的两个结构体:

ROMHDR结构体:

typedef struct ROMHDR {

    ULONG   dllfirst;               // first DLL address

    ULONG   dlllast;                // last DLL address

    ULONG   physfirst;              // first physical address

    ULONG   physlast;               // highest physical address

    ULONG   nummods;                // number of TOCentry's

    ULONG   ulRAMStart;             // start of RAM

    ULONG   ulRAMFree;              // start of RAM free space

    ULONG   ulRAMEnd;               // end of RAM

    ULONG   ulCopyEntries;          // number of copy section entries

    ULONG   ulCopyOffset;           // offset to copy section

    ULONG   ulProfileLen;           // length of PROFentries RAM

    ULONG   ulProfileOffset;        // offset to PROFentries

    ULONG   numfiles;               // number of FILES

    ULONG   ulKernelFlags;      // optional kernel flags from ROMFLAGS .bib config option

    ULONG   ulFSRamPercent;         // Percentage of RAM used for filesystem

    ULONG   ulDrivglobStart;        // device driver global starting address

    ULONG   ulDrivglobLen;          // device driver global length

    USHORT  usCPUType;              // CPU (machine) Type

    USHORT  usMiscFlags;            // Miscellaneous flags

    PVOID   pExtensions;            // pointer to ROM Header extensions

    ULONG   ulTrackingStart;        // tracking memory starting address

    ULONG   ulTrackingLen;          // tracking memory ending address

} ROMHDR;

ulCopyOffset:全局变量存放的起始地址。

 

全局变量描述结构体:

typedef struct COPYentry {

    ULONG   ulSource;                 // copy source address

    ULONG   ulDest;                     // copy destination address

    ULONG   ulCopyLen;              // copy length

    ULONG   ulDestLen;               // copy destination length

                                                    // (zero fill to end if > ulCopyLen)

} COPYentry; 

ulDest:全局变量被存放的RAM起始地址

ulSource:全局变量被存放的ROM中的起始地址

ulCopyLen:全局变量真实个数长度
ulDestLen:为期望全局变量长度

 

3.代码如下:

//这是该文件中TOC的全局指针变量,拷贝到这里方便分析

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

//

// KernelRelocate: move global variables to RAM

static BOOL KernelRelocate (ROMHDR *const pTOC)

{

    ULONG loop;

    COPYentry *cptr;

 

   //这里仔细阅读一下,看看和上面的全局变量是不是一样?

    if (pTOC == (ROMHDR *const) -1)     

    {

        return (FALSE); // spin forever!

    }

 

    //这里把镜像中的数据拷贝到Ram中。

// 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));

         //全部拷贝到RAM中

        if (cptr->ulCopyLen)

            memcpy((LPVOID)cptr->ulDest,(LPVOID)cptr->ulSource,cptr->ulCopyLen);

 

       //如果大小不相等的话,需要把剩余部分置0

        if (cptr->ulCopyLen != cptr->ulDestLen)

            memset((LPVOID)(cptr->ulDest+cptr->ulCopyLen),

0,cptr->ulDestLen-cptr->ulCopyLen);

    }

    return (TRUE);

}

问题来咯:

如果你仔细去阅读该代码,你就会发现一个问题,pTOC是被赋值为(ROMHDR *)-1,那么在KernelRelocate()函数中:

    if (pTOC == (ROMHDR *const) -1)

    {

        return (FALSE); // spin forever!

    }

这个判断一直为真,直接就退出了。这个问题查了一下资料,其实在Romimage.exe中初始化了C代码定义的非0值全局变量。(我靠,感觉好奇怪!)

pTOC == (ROMHDR *const) -1

在这里完成了对pTOC的初始化。具体的流程需要去看Romimage的代码。我没有仔细去看。有兴趣的可以查看:

C:\WINCE500\PRIVATE\WINCEOS\COREOS\NK\TOOLS\ROMIMAGE\ROM

原创粉丝点击