您的位置:首页 > 其它

bootload启动流程(二)----Eboot的主要流程

2010-10-09 19:33 369 查看
当跳转到main()函数之后,开始执行下面的c函数。
void main (void)
{
BootloaderMain ();

SPIN_FOREVER;
}
我们不难发现,实际上main()函数里面只有一个函数执行。而这个BootloaderMain ()是由微软提供的,一般放在public下面:
void BootloaderMain (void)
{
ROMHDR *pRomHdr = NULL; // pTOC for NK image. MUST COPY IT OR CLEANBOOT may erase it
DWORD dwAction, dwpToc;
DWORD dwImageStart = 0, dwImageLength = 0, dwLaunchAddr = 0;
BOOL bDownloaded = FALSE;
#ifndef SIMULATOR
// relocate globals to RAM
if (!KernelRelocate (pTOC)) {
// spin forever
HALT (BLERR_KERNELRELOCATE);
}
#endif
//这段是内核重定位
// (1) Init debug support. We can use OEMWriteDebugString afterward.
if (!OEMDebugInit ()) {
//调试端口初始化
// spin forever
HALT (BLERR_DBGINIT);
}

// output banner
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)) {
//下载内核到RAM
// error already reported in DownloadImage
SPIN_FOREVER;
}
bDownloaded = TRUE;

if (dwImageStart) {
// Check for pTOC signature ("CECE") here, after image in place
if (*(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE) {
//检测内核的签名,这个我在另外一篇关于bin文件分析中有详细的介绍,主要是签名在bin的offset = 00x40处
EdbgOutputDebugString("Found pTOC signature./n");
} else {
EdbgOutputDebugString ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/r/n");
EdbgOutputDebugString ("! ERROR: Did not find pTOC signature. ABORTING. !/r/n");
EdbgOutputDebugString ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/r/n");

// If no signature, we're going to fail anyway, so loop forever
HALT (BLERR_SIGNATURE);
}

dwpToc = *(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG));
//找到TOC指针,toc的二级指针在recorf2 第二个字节处,offset = 0x44
// need to map the content again since the pointer is going to be in a fixup address
dwpToc = (DWORD) OEMMapMemAddr (dwImageStart, dwpToc);
// NOTE: MUST COPY or a CLEAN_BOOT flag will erase it
memcpy (pRomHdr = &romhdr, (LPVOID) dwpToc, sizeof(ROMHDR));
//把TOC的内容拷贝到pRomHdr指向的地址里面

EdbgOutputDebugString ("ROMHDR at Address %Xh/r/n", dwImageStart + ROM_SIGNATURE_OFFSET + sizeof (DWORD)); // right after signature
EdbgOutputDebugString ("RomHdr.ulRAMStart=%Xh RomHdr.physfirst=%Xh./r/n", romhdr.ulRAMStart, romhdr.physfirst);
}

// fall through
case BL_JUMP:
// Before jumping to the image, optionally check the image signature.
if (g_pOEMCheckSignature && dwImageStart)
{
if (!g_pOEMCheckSignature(dwImageStart, g_dwROMOffset, dwLaunchAddr, bDownloaded))
HALT(BLERR_WHQL_SIGNATURE);
}
// (5) final call to launch the image. never returned
OEMLaunch (dwImageStart, dwImageLength, dwLaunchAddr, pRomHdr);
跳转到内核地址并且执行,同时把内核拷贝到flash
// should never return
// fall through
default:
// ERROR! spin forever
HALT (BLERR_INVALIDCMD);
}
}
这块实际上也就是eboot的主要启动过程了,流程其实也很简单,主要是初始化一些必要的硬件并且把内核代码拷贝到内存并且开始启动系统。
其中相关的编译配置文件在boot.bib里面,如下面所示:
; Ethernet Boot Loader Source Module
;******************************************************************************

MEMORY
; Name Start Size Type
; ------- -------- -------- ----
DRV_GLB 8c020000 00001000 RESERVED
BIN_FS 8c021000 00005000 RESERVED
RAM 8c026000 00006000 RAM
STACK 8c02c000 00004000 RESERVED
EBOOT 8c038000 00020000 RAMIMAGE
; EBOOT 8c038000 00040000 RAMIMAGE

; 16 MB area used to cache nk.bin while programming boot media.
; TBD: we may need to adjust to 01400000 (20 MB) to cache PPC 2003.
FLSCACHE 8D000000 01000000 RESERVED

CONFIG
COMPRESSION=OFF
PROFILE=OFF
KERNELFIXUPS=ON
SRE=ON
ROMSTART=8c038000
ROMWIDTH=32

; N.B: boot media block size aligned
ROMSIZE=16000

MODULES
; Name Path Memory Type
; -------------- ---------------------------------------------- -----------
nk.exe $(_TARGETPLATROOT)/target/$(_TGTCPU)/$(WINCEDEBUG)/EBOOT.exe EBOOT
上面对其它的东西比较简单,也就是eboot的生成内存分配,下面主要对MODULES中的东西进行详细的解释。这里涉及一些环境变量的运行,前面nk.exe是运行中需要连接的名字,中间是生成这个文件的路径。最后一个是文件连接的区域,这里是EBOOT(EBOOT 8c038000 00020000 RAMIMAGE)。中间那个路径中有许多环境变量,其中可在PB中打开build os->open release directory,然后输入set后将显示所用到的所有环境变量,其中可以看到_TARGETPLATROOT = D:/WINCE500/PLATFORM/SMDK2440,_TGTCPU = ARMV4I,WINCEDEBUG = retail。所以以上的路径$(_TARGETPLATROOT)/target/$(_TGTCPU)/$(WINCEDEBUG)/EBOOT.exe 就可以翻译为D:/WINCE500/PLATFORM/SMDK2440/target/ARMV4I/retail/eboot.exe。其中$()的意思查询环境变量的意思。其实设置环境变量的好处很多,主要就是代码的通用和移植的方便,这里就不再多说。 (待续。。。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: