随笔 - 7, 文章 - 3, 评论 - 22, 引用 - 0

导航

<2007年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

留言簿(0)

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜

2007年5月22日

关于mult-xip bin 的一些资料整理

关于mult-xip  bin 的一些资料整理
参考  http://www.cnblogs.com/yakin/archive/2005/07/20/196572.aspx
      http://msdn2.microsoft.com/en-us/library/aa451015.aspx
   http://embed.e800.com.cn/articles/2007/510/1178760966833421250_1.html


一.实现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提供信息的


感觉这块总是理不顺,如果那位能理得更清晰点,贴出来大家学习下,我也起到抛砖引玉的作用了

发表于 2007-05-22 15:11 liu090 阅读(2150) | 评论 (1)编辑 收藏