一.实现multbin
1.首先修改config.bib

比如:
#elif defined IMGMULTIBIN
;  NAME          START ADDR    SIZE      TYPE
;  ----------------------------------------------------------------
    NK            80220000      007DE000  RAMIMAGE 
    SHELL        809FE000      00100000  RAMIMAGE 
    APPS          80AFE000      00100000  RAMIMAGE 
    CHAIN        80BFE000      00002000  RESERVED ; XIP chain info
    RAM          80C00000      01000000  RAM       
    pdwXIPLoc    00000000      80BFE000  FIXUPVAR  ; XIP pTOC

    AUTOSIZE=ON          ;自动调整RAM 起始地址到 最近的 XIP region的末尾
    ROM_AUTOSIZE=ON      ;每个分隔的XIP regin 的大小自动调整
    DLLADDR_AUTOSIZE=ON  ;自动调整 dll地址空间大小根据 multiple XIP regions.
    XIPSCHAIN=80bfe000    ; 指定CHAIN region 在内存段的地址.
Note  This address is applicable for the example provided in the previous step of this procedure.
If you use a customized address for the CHAIN region or a different BSP, you will have to
update this variable to match your settings



pdwXIPLoc 必须定义START ADDR =00000000 SIZE=CHAIN的START ADDR
CHAIN 用来保存多个bin的chain info,CHAIN的位置和你bootloader代码有关,(cepc一般放在 NK region 后面)
所有的RAMIMAGE 必须在物理,虚拟地址上都连续
经验上每个bin 加32K (msdn:As a good practice, add the sizes of all files for a given region,
and then add an extra 32K as a buffer. Adding this extra amount provides room for the files to
reduce and expand as they change between each successive build)


2.修改platform.bib,把不同的部分放入到不动的region中 (其他bib也可以修改的)
比如
if IMGMULTIBIN
  shell.exe  $(_FLATRELEASEDIR)\shell.exe  SHELL  SH
  filesys.exe $(_FLATRELEASEDIR)\filesys.exe SHELL  SH
#else
  shell.exe  $(_FLATRELEASEDIR)\shell.exe  NK  SH
  filesys.exe $(_FLATRELEASEDIR)\filesys.exe NK  SH
#endif

表示把文件系统, shell放到 SHELL regin (shell.bin)


3.设置: 环境变量IMGMULTIBIN =1


4.在cfw.c中的OEMInit中的最后加上对InitRomChain的调用,来连接各个bin,最后连接到OEMRomChain 上!!!

void InitRomChain(void)
{
static  ROMChain_t s_pNextRom[MAX_ROM] = {0};
DWORD  dwRomCount = 0;
    DWORD      dwChainCount = 0;
    DWORD  *pdwCurXIP;
    DWORD      dwNumXIPs;
    PXIPCHAIN_ENTRY pChainEntry = NULL;

    if(pdwXIPLoc == NOT_FIXEDUP)
{
        return;  //pdwXIPLoc 必须是 FIXUPVAR ,否则表示没有chain或者设置不对
    }

    // set the top bit to mark it as a virtual address
    pdwCurXIP = (DWORD*)(((DWORD)pdwXIPLoc) | 0x80000000);

    // first DWORD is number of XIPs
    dwNumXIPs = (*pdwCurXIP); 

    if(dwNumXIPs > MAX_ROM)
{
      lpWriteDebugStringFunc(TEXT("ERROR: Number of XIPs exceeds MAX\n"));
      return;
    }

    pChainEntry = (PXIPCHAIN_ENTRY)(pdwCurXIP + 1);  //其实就是指向CHAIN 中chain info的相关信息

    while(dwChainCount < dwNumXIPs)
    {
        if ((pChainEntry->usFlags & ROMXIP_OK_TO_LOAD) &&  // flags indicates valid XIP
            *(LPDWORD)(((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)
        {
            s_pNextRom[dwRomCount].pTOC = *(ROMHDR **)(  ((DWORD)(pChainEntry->pvAddr)) + ROM_SIGNATURE_OFFSET + 4  );
            s_pNextRom[dwRomCount].pNext = NULL;

            if (dwRomCount != 0)
            {
                s_pNextRom[dwRomCount-1].pNext = &s_pNextRom[dwRomCount];
            }
            else
            {
                OEMRomChain = s_pNextRom;
            }
            dwRomCount++;
        }
        else
        {
            lpWriteDebugStringFunc( _T("Invalid XIP found\n") );
        }

        ++pChainEntry;
  dwChainCount++;
}
}
 



//在romldr.h中 定义了上面的相关的
typedef struct _XIPCHAIN_ENTRY {
    LPVOID  pvAddr;                // address of the XIP
    DWORD  dwLength;              // the size of the XIP
    DWORD  dwMaxLength;            // the biggest it can grow to
    USHORT  usOrder;                // where to put into ROMChain_t
    USHORT  usFlags;                // flags/status of XIP
    DWORD  dwVersion;              // version info
    CHAR    szName[XIP_NAMELEN];    // Name of XIP, typically the bin file''s name, w/o .bin
    DWORD  dwAlgoFlags;            // algorithm to use for signature verification
    DWORD  dwKeyLen;              // length of key in byPublicKey
    BYTE    byPublicKey[596];      // public key data
} XIPCHAIN_ENTRY, *PXIPCHAIN_ENTRY;

#define ROMXIP_OK_TO_LOAD      0x0001
#define ROMXIP_IS_SIGNED        0x0002

#define ROM_SIGNATURE_OFFSET 64   //0x40
#define ROM_SIGNATURE 0x43454345    //cece 4byte    =>ROMHDR 在0x44偏移处,
//每个bin 都有个pToc指向ROMHDR开头的地址,看下面的bin 文件结构,在0x44offset处地址里面放的是ROMHDR地址,开始是-1,由romimage.exe来设置的


//有点糊涂了 再分析下bin文件的结构
struct BinFile{
BYTE signature[7]; // = { ''''B'''', ''''0'''', ''''0'''', ''''0'''', ''''F'''', ''''F'''', ''''\a'''' }
DWORD ImageStart
DWORD ImageLength
Record ImageRecords[RecordNum]
};


struct Record{
DWORD address;
DWORD length;
DWORD chksum;
};
在文件的最开端,会放置一个BinFile结构,imageStart和ImageLength分别对应镜像展开后在内存中存放的首地址和长度。
该结构中的RecordNum为不确定的,通常在最后一个记录之后增加一个address和Chksum都为0的纪录表示结束,
而这个表示结束的结构中的Length则标示其实际入口点。
可以用viewbin -r 去看下nk.bin:
Image Start = 0x8C200000, length = 0x00E158C8
  Start address = 0x8C201000
Checking record #22 for potential TOC (ROMOFFSET = 0xFF446658)
Checking record #177 for potential TOC (ROMOFFSET = 0x00000000)
Found pTOC  = 0x8d013950
ROMOFFSET = 0x00000000

ROMHDR ----------------------------------------
    DLL First          : 0x01E401E7 
    DLL Last            : 0x02000000 
    Physical First      : 0x8C200000 
    Physical Last      : 0x8D0158C8 
    RAM Start          : 0x8E600000 
    RAM Free            : 0x8E629000 
    RAM End            : 0x8FF00000 
    Kernel flags        : 0x00000002 
    Prof Symbol Offset  : 0x00000000 
    Num Copy Entries    :          1   
    Copy Entries Offset : 0x8CC7AE8C 
    Num Modules        :        166   
    Num Files          :        95   
    Kernel Debugger    :        No
    CPU                :    0x01c2 (Thumb)
    Extensions          : 0x8C20266C

ROMHDR Extensions -----------------------------
    PID[0] = 0x00000000
    PID[1] = 0x00000000
    PID[2] = 0x00000000
    PID[3] = 0x00000000
    PID[4] = 0x00000000
    PID[5] = 0x00000000
    PID[6] = 0x00000000
    PID[7] = 0x00000000
    PID[8] = 0x00000000
    PID[9] = 0x00000000
    Next: 00000000

COPY Sections ---------------------------------
    Src: 0x8CD18DA8  Dest: 0x8E606000  CLen: 0x228      DLen: 0x22B4C

MODULES ---------------------------------------
    11/20/2006  03:20:28      268800  nk.exe
    11/20/2006  03:25:22      550400  coredll.dll
    11/20/2006  03:25:22      205824  filesys.exe
    11/20/2006  03:25:22      723968  gwes.exe
    11/20/2006  03:09:08      25600  device.exe
    .......................
    .......................
FILES ----------------------------------------
    11/20/2006  03:10:42  C_R_      2897      12461                ceconfig.h (ROM 0x8C55E4AC)
    11/20/2006  03:25:18  _HRS          0    694654                wince.nls (ROM 0x8CE36984)
      5/09/2007  14:06:14  CHRS      3427      20574              initobj.dat (ROM 0x8C730280)
    .......................
    .......................
done.

分布结构:
Image :
Offset -----------
0x00 | ImageStart
|
|
0x40 | Rom Signature { 0x43454345 }
0x44 | Pointer to the ROMHDR for this Region
|
|
0x???? | ROMHDR{                <-pToc所指
| };
|


Chain file
struct _XIPCHAIN_ENTRY {
LPVOID pvAddr; // address of the XIP
DWORD dwLength; // the size of the XIP
DWORD dwMaxLength; // the biggest it can grow to
USHORT usOrder; // where to put into ROMChain_t
USHORT usFlags; // flags/status of XIP
DWORD dwVersion; // version info
CHAR szName[XIP_NAMELEN]; // Name of XIP, typically the bin file''''s name, w/o .bin
DWORD dwAlgoFlags; // algorithm to use for signature verification
DWORD dwKeyLen; // length of key in byPublicKey
BYTE byPublicKey[596]; // public key data
};


Offset --------------------------
0x00 | DWORD Count;
0x04 | XIPCHAIN_ENTRY[1]{
| };
| XIPCHAIN_ENTRY[2]{
| };
| ...


二.关于OEMMultiBINNotify ,他是被blcommon 来调用,来让我们获得一个或多个 BIN regions的信息的
比如
用结构
typedef struct _MultiBINInfo_
{
    DWORD dwNumRegions;
RegionInfo Region[BL_MAX_BIN_REGIONS];
} MultiBINInfo, *PMultiBINInfo;

定义一个MultiBINInfo    g_BINRegionInfo;全局变量在OEMMultiBINNotify中获得每个bin regins的信息

ReginInfo结构:
typedef struct _RegionInfo_
{
DWORD dwRegionStart;
DWORD dwRegionLength;
} RegionInfo, *PRegionInfo;

g_BINRegionInfo 被WriteRegionsToBootMedia 写regions到flash用到,
我用的是nandflash,
WriteRegionsToBootMedia中这段
// Look in the kernel region''s extension area for a multi-BIN extension descriptor.
    // This region, if found, details the number, start, and size of each BIN region.
    //
    //for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions) && !pChainInfo ; nCount++)
    for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions); nCount++)
    {
        // Does this region contain nk.exe and an extension pointer?
        //
        pExt = (EXTENSION *)GetKernelExtPointer(g_BINRegionInfo.Region[nCount].dwRegionStart,
                                                g_BINRegionInfo.Region[nCount].dwRegionLength );
        if ( pExt != NULL)
        {
            // If there is an extension pointer region, walk it until the end.
            //
            while (pExt)
            {
                DWORD dwBaseAddr = g_BINRegionInfo.Region[nCount].dwRegionStart;
                pExt = (EXTENSION *)OEMMapMemAddr(dwBaseAddr, (DWORD)pExt);
                EdbgOutputDebugString("INFO: OEMLaunch: Found chain extenstion: ''%s'' @ 0x%x\r\n", pExt->name, dwBaseAddr);
                if ((pExt->type == 0) && !strcmp(pExt->name, "chain information"))
                {
                    pChainInfo = (PXIPCHAIN_SUMMARY) OEMMapMemAddr(dwBaseAddr, (DWORD)pExt->pdata);
                    dwNumExts = (pExt->length / sizeof(XIPCHAIN_SUMMARY));
                    EdbgOutputDebugString("INFO: OEMLaunch: Found ''chain information'' (pChainInfo=0x%x  Extensions=0x%x).\r\n", (DWORD)pChainInfo, dwNumExts);
                    break;
                }
                pExt = (EXTENSION *)pExt->pNextExt;
            }
        }
        else {
            //  Search for Chain region. Chain region doesn''t have the ROMSIGNATURE set
            DWORD  dwRegionStart = g_BINRegionInfo.Region[nCount].dwRegionStart;
            DWORD  dwSig = *(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET);

            if ( dwSig != ROM_SIGNATURE) {
                //  It is the chain
                dwChainStart = dwRegionStart;
                dwChainLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
                EdbgOutputDebugString("Found the Chain region: StartAddress: 0x%X; Length: 0x%X\n", dwChainStart, dwChainLength);
            }
        }
    }

    // nk.exe and an extension pointer  这个是什么意思,就是说nk.exe 包含一个扩展point是派什么用处的,那位知道告诉我


感觉是一个是bootlaod时的概念,一个是运行是的概念
bootlaoder时 :通过OEMMultiBINNotify 获得的信息来进行下载等应用

运行时,是根据config.bib中CHAIN的关于regions的信息,通过InitRomChain 来把他串起来,



三.toc block ,是和nand boot有关的东西

typedef struct _TOC {
    DWORD              dwSignature;
    // How to boot the images in this TOC.
    // This could be moved into the image descriptor if desired,
    // but I prefer to conserve space.
    BOOT_CFG            BootCfg;

    // Array of Image Descriptors.
    IMAGE_DESCRIPTOR    id[MAX_TOC_DESCRIPTORS];

//    UCHAR Pad[12];      // align on SECTOR_SIZE
    CHAININFO          chainInfo;
} TOC, *PTOC;          // 512 bytes


typedef struct _IMAGE_DESCRIPTOR {

    // File version info
    DWORD dwVersion;                    // e.g: build number
    DWORD dwSignature;                  // e.g: "EBOT", "CFSH", etc
    UCHAR ucString[IMAGE_STRING_LEN];  // e.g: "PocketPC_2002"

    DWORD dwImageType;      // IMAGE_TYPE_ flags
    DWORD dwTtlSectors;    // TTL image size in sectors.
                            // We store size in sectors instead of bytes
                            // to simplify sector reads in Nboot.

    DWORD dwLoadAddress;    // Virtual address to load image (ImageStart)
    DWORD dwJumpAddress;    // Virtual address to jump (StartAddress/LaunchAddr)

    // This array equates to a sector-based MXIP MultiBINInfo in blcommon.
    // Unused entries are zeroed.
    // You could chain image descriptors if needed.
    SG_SECTOR sgList[MAX_SG_SECTORS];

    // BinFS support to load nk region only
//struct
//{
  ULONG dwStoreOffset;    // byte offset - not needed - remove!
  //ULONG RunAddress;    // nk dwRegionStart address
  //ULONG Length;        // nk dwRegionLength in bytes
  //ULONG LaunchAddress;  // nk dwLaunchAddr
//} NKRegion;

} IMAGE_DESCRIPTOR, *PIMAGE_DESCRIPTOR;

这些信息被写入block 1,
为nboot启动 nk,或 eboot提供信息的

posted on 2010-12-25 19:30  GT_Andy  阅读(838)  评论(0编辑  收藏  举报