Eboot开始一段是用汇编写的,暂不考虑,跳到C函数后:
1 void main(void)
2 {
3 BootloaderMain(); //Eboot的框架函数,在BLCOMMON模块中
4 SpinForever();
5 }
BLCOMMON路径 :%_WINCEROOT%\Public\Common\Oak\Drivers\Ethdbg\Blcommon
框架函数BootloaderMain:
1 void BootloaderMain (void)
2 {
3 DWORD dwAction;
4 DWORD dwpToc = 0;
5 DWORD dwImageStart = 0, dwImageLength = 0, dwLaunchAddr = 0;
6 BOOL bDownloaded = FALSE;
7
8 // relocate globals to RAM
9 if (!KernelRelocate (pTOC))
10 {
11 // spin forever
12 HALT (BLERR_KERNELRELOCATE);
13 }
14
15 // (1) Init debug support. We can use OEMWriteDebugString afterward.
16 if (!OEMDebugInit ())
17 {
18 // spin forever
19 HALT (BLERR_DBGINIT);
20 }
21
22 // (2) initialize platform (clock, drivers, transports, etc)
23 if (!OEMPlatformInit ())
24 {
25 // spin forever
26 HALT (BLERR_PLATINIT);
27 }
28
29 // (3) call OEM specific pre-download function
30 switch (dwAction = OEMPreDownload ())
31 {
32 case BL_DOWNLOAD: //在OEMLaunch中下载nk
33 // (4) download image
34 if (!DownloadImage (&dwImageStart, &dwImageLength, &dwLaunchAddr))//此处就是NK信息的获取函数,通过解析镜像文件获取
35 {
36 // error already reported in DownloadImage
37 SPIN_FOREVER;
38 }
39 bDownloaded = TRUE;
40
41 // Check for pTOC signature ("CECE") here, after image in place
42 if (*(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)
43 {
44 dwpToc = *(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG));
45 // need to map the content again since the pointer is going to be in a fixup address
46 dwpToc = (DWORD) OEMMapMemAddr (dwImageStart, dwpToc + g_dwROMOffset);
47
48 EdbgOutputDebugString ("ROMHDR at Address %Xh\r\n", dwImageStart + ROM_SIGNATURE_OFFSET + sizeof (DWORD)); // right after signature
49 }
50 // fall through
51
53 case BL_JUMP:
54
55 if (g_bBINDownload && g_pOEMCheckSignature)
56 {
57 if (!g_pOEMCheckSignature(dwImageStart, g_dwROMOffset, dwLaunchAddr, bDownloaded))
58 HALT(BLERR_CAT_SIGNATURE);
59 }
60 // (4) final call to launch the image. never returned
61 OEMLaunch (dwImageStart, dwImageLength, dwLaunchAddr, (const ROMHDR *)dwpToc);
62 // should never return
63 // fall through
64 default:
65 // ERROR! spin forever
66 HALT (BLERR_INVALIDCMD);
67 }
68 }
69
启动函数OEMLaunch:
1 void OEMLaunch( DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr )
2 {
3 DWORD dwPhysLaunchAddr;
4
5 OALMSG(OAL_FUNC, (TEXT("+OEMLaunch. dwImageStart =0x%x,dwImageLength=0x%x,dwLaunchAddr=0x%x\r\n"),dwImageStart,dwImageLength,dwLaunchAddr));
6
7 if( g_bUSBDownload)
8 {
9 g_pTOC->id[g_dwTocEntry].dwLoadAddress = dwImageStart;
10 g_pTOC->id[g_dwTocEntry].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);
11 g_pTOC->id[g_dwTocEntry].dwJumpAddress = dwLaunchAddr;
12 if (!WriteOSImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))//将OSImage写入Flash中
13 {
14 OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media.\r\n")));
15 goto CleanUp;
16 }
17
18
19 if ( !TOC_Write() ) //将TOC保存到Flash中
20 {
21 EdbgOutputDebugString("*** OEMLaunch ERROR: TOC_Write failed! Next boot may not load from disk *** \r\n");
22 }
23 TOC_Print();
24 }
25 else
26 {
27 EdbgOutputDebugString("To start Launch OS! List TOC table :\r\n");
28 TOC_Print();
29 dwLaunchAddr = g_pTOC->id[g_dwTocEntry].dwJumpAddress;
30 }
31 dwPhysLaunchAddr = (DWORD)OALVAtoPA((void *)dwLaunchAddr);
32 OALMSG(TRUE, (TEXT("INFO: OEMLaunch: Jumping to Physical Address 0x%Xh (Virtual Address 0x%Xh)...\r\n\r\n\r\n"), dwPhysLaunchAddr, dwLaunchAddr));
33
34 Launch(dwPhysLaunchAddr); //跳到OS起始地址
35 CleanUp:
36
37 OALMSG(TRUE, (TEXT("ERROR: OEMLaunch: Halting...\r\n")));
38 SpinForever();
39 }
OEMLaunch传入了内核镜像的起始地址dwImageStart、大小dwImageLength(用来将NK写入Flash中)和启动地址dwLaunchAddr(最终启动内核)。
通过USB下载NK时,则将其保存到Flash的TOC块中(TOC_Write()),下次启动时就可以找到并加载NK了。
现只是大体理一下,还有好多细节问题需要整理。
参考:http://blog.csdn.net/nanjianhui/archive/2008/10/21/3111422.aspx