eboot.bin和eboot.nb0的差别就是
eboot.bin中没有填充pTOC结构体,必须使用parser解释器[类似于romimage.exe luther.gliethttp]将全局变量数据段解压释放到运行时使用的地址才行,
eboot.nb0中经过romimage.exe填充了pTOC结构体,所以eboot.nb0可以自己将自己用到的全局量通过KernelRelocate()函数进行解压释放,这就是为什么
eboot.nb0比eboot.bin的size大的原因[luther.gliethttp].

eboot.nb0是一个包含全局变量初始化pTOC结构体的文件,所以当eboot.nb0启动时就可以通过BootloaderMain()==>KernelRelocate(pTOC)来
实现eboot.nb0自己初始化自己定义的全局变量的工作,其实KernelRelocate就相当于ADS启动汇编中对如下四个section的操作:[luther.gliethttp]
Image$$RO$$Limit
Image$$RW$$Base
Image$$ZI$$Base
Image$$ZI$$Limit
但是我们在源程序中只能找到pTOC的定义ROMHDR * volatile const pTOC = (ROMHDR *)-1;根本找不到对它进行赋值的任何操作,无论是.s汇编还是任何宏中,
那pTOC又是从哪里得到了有效的数值的呢?这就是我们下面继续讨论的问题,一切疑惑都可以从romimage.exe中获得答案.[luther.gliethttp]

romimage.exe源码位于WINCE500/PRIVATE/WINCEOS/COREOS/NK/TOOLS/ROMIMAGE/ROMIMAGE目录下,
C:/WINCE500/PRIVATE/WINCEOS/COREOS/NK/TOOLS/ROMIMAGE/ROMIMAGE/module.cpp|118| if(token == "pTOC"){
void Module::check_special_symbol(string token, DWORD o32_section, DWORD offset, MemoryList &memory_list){
    ...
    if(is_kernel()){
        if(token == "pTOC"){
//我们在eboot源码PLATFORM/SMDK2440A/Src/Bootloader/Eboot_usb/blcommon.c中定义了该符号,如下:

//ROMHDR * volatile const pTOC = (ROMHDR *)-1; // Gets replaced by RomLoader with real address

//记录pTOC指针所在位置[luther.gliethttp]

m_TOC_offset = offset + m_load_offset; // doesn't get load offset added, because only compared with rva later

LAST_PASS_PRINT printf("Found pTOC at %08x/n", m_TOC_offset);
        }
        if(needs_signing()){
          if(token == "OEMIoControl")
            s_oem_io_control = offset + m_初始化c代码定义的非0值全局变量[luther.gliethttp]load_offset - page_size();
        }
        ...
    }
    ...
}

bin.cpp|87| kernel->write_TOC_ptr(romhdr_offset);
bool write_bin(AddressList &hole_list, CopyList &copy_list,
                ModuleList &module_list, FileList &file_list,
                MemoryList &memory_list, MemoryList &reserve_list,
                ModuleList::iterator &kernel, Config &config, MemoryList::iterator xip_mem){
    ...
    // write toc into kernel

if(xip_mem->is_kernel() && kernel->is_kernel())
        kernel->write_TOC_ptr(romhdr_offset);//将romimage.exe计算后的toc起始地址存入pTOC 指针所在处,这样eboot.nb0中的pTOC指针就指向了romhdr_offset这个有效空间[luther.gliethttp].

...
}
初始化c代码定义的非0值全局变量[luther.gliethttp]
void Module::write_TOC_ptr(DWORD addr){
  assert(is_kernel());

if(!m_TOC_offset){
    fprintf(stderr, "Error: Found NULL or missing TOC pointer for %s/n", m_name.c_str());
    exit(1);
  }
 
// *(DWORD *)(m_o32_list[0].data.ptr() + m_TOC_offset - page_size()) = addr;

*(DWORD *)rva2ptr(m_TOC_offset) = addr;//等效于eboot.nb0中执行pTOC = (void*)addr;[luther.gliethttp]

}

来看看eboot.nb0是怎么使用pTOC来初始化eboot.bin定义的全局变量的:
main
==>BootloaderMain()
==>KernelRelocate(pTOC)
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;
//

// 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!

}
    // This is where the data sections become valid... don't read globals until after this

// 就像这句话描述的一样,只有执行完该函数之后,全局变量所在地址处才有了真实的全局变量数值,

// 所以只有执行完该函数之后,我们才能够访问全局变量[luther.gliethttp]

for (loop = 0; loop < pTOC->ulCopyEntries; loop++)
    {
//ulCopyOffset为若干个COPYentry结构体的内存偏移地址

//COPYentry为全局变量描述结构体

//其中ulDest为全局变量被使用时的目的地址

//其中ulSource为全局变量被压缩存储在ROM中的起始地址

//其中ulCopyLen为全局变量真实个数长度

//其中ulDestLen为期望全局变量长度

//ulDestLen一定>=ulCopyLen

//如果ulDestLen大于ulCopyLen,那么说明,该region的全局变量除了有非0数据之外

//还存在ulDestLen减去ulCopyLen字节的清0数据空间[lutehr.gliethttp]

//其实KernelRelocate就相当于ADS中如下汇编代码:

/* add r2, pc,#-(8+.-CInitData) ; @ where to read values (relative)
    ldmia r2, {r0, r1, r3, r4}
  
    cmp r0, r1 ; Check that they are different
    beq EndRW
LoopRW 初始化c代码定义的非0值全局变量[luther.gliethttp]
    cmp r1, r3 ; Copy init data
    ldrcc r2, [r0], #4
    strcc r2, [r1], #4
    bcc LoopRW
EndRW

mov r2, #0
LoopZI 初始化c代码未定义的全局变量或者强行指定为0值的全局变量[luther.gliethttp]
    cmp r3, r4 ; Zero init
    strcc r2, [r3], #4
    bcc LoopZI
 
    b EndInitC
              
CInitData
     IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
    IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
    IMPORT |Image$$ZI$$Base| ; Base and limit of area
    IMPORT |Image$$ZI$$Limit| ; Top of zero init segment
  
    DCD |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
     DCD |Image$$RW$$Base| ; Base of RAM to initialise
     DCD |Image$$ZI$$Base| ; Base and limit of area
     DCD |Image$$ZI$$Limit| ; Top of zero init segment
*/
        cptr = (COPYentry *)(pTOC->ulCopyOffset + loop*sizeof(COPYentry));
        if (cptr->ulCopyLen)
            memcpy((LPVOID)cptr->ulDest,(LPVOID)cptr->ulSource,cptr->ulCopyLen);
        if (cptr->ulCopyLen != cptr->ulDestLen)
            memset((LPVOID)(cptr->ulDest+cptr->ulCopyLen),0,cptr->ulDestLen-cptr->ulCopyLen);
    }
    return (TRUE);
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chinesedragon2010/archive/2010/10/09/5929007.aspx

CE5.0 - romimage.exe如何填充eboot.bin中的pTOC特殊指针生成.nb0相关推荐

  1. CE5.0 - eboot汇编Startup.s中MMU设置流程详细分析

    CE5.0 - eboot汇编Startup.s中MMU设置流程详细分析   以下为SMDK开发板startup.s部分启动代码.   ;------------------------------- ...

  2. TCPMP超级播放器Windows CE5.0(ARMV4)编译方法

    本文主要讲解TCPMP播放器到WINDOWS CE平台的移植编译过程,硬件平台以ARMV4为主,结束部分会讲解到ARMV4I编译中需要注意的问题 这几天为公司一个项目做准备,准备编译移植来自linux ...

  3. PE文件和COFF文件格式分析--MS-DOS 2.0兼容Exe文件段

    MS 2.0节是PE文件格式中第一个"节".其大致结构如下:(转载请指明来源于breaksoftware的csdn博客) 在VC\PlatformSDK\Include\WinNT ...

  4. aidl远程服务调用Android,报错:Process 'command 'F:\Android\SDK\build-tools\29.0.0\aidl.exe''

    aidl远程服务调用Android demo1: Alipay 支付App服务: 1.新建: Alipay\app\src\main\aidl\com\glsite\alipay\IAlipaySer ...

  5. 「vlc-3.0.16-win64.exe」 下载

    「vlc-3.0.16-win64.exe」,点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放. 链接:https://www.aliyundrive. ...

  6. .NET CORE 实践(3)--Visual Studio 2015 Update 3更新之后DotNetCore.1.0.1-VS2015Tools.Preview2.0.2.exe无法正确安装

    打开 https://www.microsoft.com/net/core#windows,点击 https://go.microsoft.com/fwlink/?LinkId=691129下载vs2 ...

  7. c语言编译后找不到exe,在VS 2015命令提示符中找不到c – rc.exe

    我刚刚安装了Windows 10 Creators Update(版本10.0.15063). 我安装了多个版本的Visual Studio(2012年,2013年,2015年和2017年).我几周前 ...

  8. WinCE中命令行工具Viewbin简介(查看nk.bin中包含的文件)

    Viewbin是微软提供的一个命令行工具,在WinCE5.0和WinCE6.0中,可以在"/WINCE600/PUBLIC/COMMON/OAK/BIN/I386"找到他.View ...

  9. 如何导出NK.bin中的内容

    如何导出NK.bin中的内容 收藏 需要的工具:1.viewbin和cvrtbin:这两个是PB自带的工具,在\PUBLIC\COMMON\OAK\BIN\I386目录下. 2.dumprom:网上下 ...

最新文章

  1. **52.常用的存储保护方法有哪些?
  2. 【编程大系】Java资源汇总
  3. vue js xlsx 读取 本地 excel
  4. 如何打印出lua里table的内容
  5. 什么是sql注入_什么是Python SQL注入?又如何使用Python防止SQL注入攻击呢?
  6. 过水滑环的结构和工作原理
  7. mysql建表与oracle_oracle建表与MySQL建表区别
  8. 数据分析:某地PM2.5数据分析
  9. 条形码在android上的代码,使条码生成器在android
  10. spring boot火车票售卖系统毕业设计代码211004
  11. 控制台、操作台、调度台如何区分?
  12. 一个可以下载手机网站模板的工作室
  13. Magento相关产品(Related Product)推荐销售(Up-sells)和交叉销售(Cross-sells)
  14. 中兴网卡连不上网,解决方案如下
  15. 第一期:利用旧手机搭建网盘(家庭nas)
  16. phpcms调用一个指定的栏目的url和栏目名称?
  17. 区块链的下一个机会不是ICO2.0,而是ERC-721
  18. NI HIL测试平台环境部署(血与泪的经验)
  19. segy地震数据的读取python_Python-segy格式地震资料segyio读写包说明(二),pythonsegy,数据,学习,笔记...
  20. ubuntu下解决zip解压缩后乱码

热门文章

  1. 032-element模块
  2. 007_CSS ID选择器
  3. 015_html注释
  4. WebDriverAgent安装到iphone真机
  5. 矩形变弧度角_在上海做下颌角整形这些医生错过后悔都来不及,案例分享
  6. 火力发电厂与变电站设计防火标准_火力发电厂与变电站设计防火规范
  7. ANDROID STUDIO 2.2 来啦
  8. vue + element ui 的后台管理系统框架_从零开始搭建 VUE + Element UI后台管理系统框架...
  9. android 英文帮助文档地址,使用android SDk帮助文档(英文) 下载中文SDK帮助文档(中文)...
  10. kaggle账号_机器学习竞赛入门--kaggle篇