SMDK2440A 5.0BSP之eboot流程(作者:wogoyixikexie@gliet)

这两天为了搞明白bootloader的binfs分区功能,看了大量代码,觉得有必要把整个eboot流程疏理一下。至于binfs分区以及MBR等相关信息,请看http://topic.csdn.net/u/20081203/11/6d0f940c-03e1-487b-a922-e08cc980908d.html这个帖子吧,我贴了好多代码,我想应该可以看出他们的工作原理了。

好,投入正题,bootloader是裸奔的,所以一定会有main函数,所以我们就从这个main函数开始吧。

  1. /*
  2. @func   void | main | Samsung bootloader C routine entry point.
  3. @rdesc  N/A.
  4. @comm
  5. @xref
  6. @裸奔时候的main函数
  7. */
  8. void main(void)
  9. {
  10. // Clear LEDs.
  11. //
  12. OEMWriteDebugLED(0, 0x3);
  13. // Common boot loader (blcommon) main routine.
  14. //C:/WINCE500/PUBLIC/COMMON/OAK/DRIVERS/ETHDBG/BLCOMMON/blcommon.c
  15. //BootloaderMain函数调用eboot中的函数,完成eboot功能
  16. BootloaderMain();
  17. // Should never get here.
  18. //
  19. SpinForever();
  20. }

显然这个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. // relocate globals to RAM为了共享变量
  8. if (!KernelRelocate (pTOC))
  9. {
  10. // spin forever
  11. HALT (BLERR_KERNELRELOCATE);
  12. }
  13. // (1) Init debug support. We can use OEMWriteDebugString afterward.
  14. if (!OEMDebugInit ())
  15. {
  16. // spin forever
  17. HALT (BLERR_DBGINIT);
  18. }
  19. // output banner
  20. EdbgOutputDebugString (NKSignon, CURRENT_VERSION_MAJOR, CURRENT_VERSION_MINOR);
  21. // (3) initialize platform (clock, drivers, transports, etc)
  22. if (!OEMPlatformInit ())
  23. {
  24. // spin forever
  25. HALT (BLERR_PLATINIT);
  26. }
  27. // system ready, preparing for download
  28. EdbgOutputDebugString ("System ready!/r/nPreparing for download.../r/n");
  29. // (4) call OEM specific pre-download function
  30. switch (dwAction = OEMPreDownload ())
  31. {
  32. case BL_DOWNLOAD:
  33. // (5) download image
  34. if (!DownloadImage (&dwImageStart, &dwImageLength, &dwLaunchAddr))
  35. {
  36. // error already reported in DownloadImage
  37. SPIN_FOREVER;
  38. }
  39. bDownloaded = TRUE;
  40. // Check for pTOC signature ("CECE") here, after image in place
  41. if (*(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)
  42. {
  43. dwpToc = *(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG));
  44. // need to map the content again since the pointer is going to be in a fixup address
  45. dwpToc = (DWORD) OEMMapMemAddr (dwImageStart, dwpToc + g_dwROMOffset);
  46. EdbgOutputDebugString ("ROMHDR at Address %Xh/r/n", dwImageStart + ROM_SIGNATURE_OFFSET + sizeof (DWORD)); // right after signature
  47. }
  48. // fall through 注意这里并没有break,这个用的很巧妙。
  49. case BL_JUMP:
  50. // Before jumping to the image, optionally check the image signature.
  51. // NOTE: if we haven't downloaded the image by now, we assume that it'll be loaded from local storage in OEMLaunch (or it
  52. // already resides in RAM from an earlier download), and in this case, the image start address might be 0.  This means
  53. // that the image signature routine will need to find the image in storage or in RAM to validate it.  Since the OEM"s
  54. // OEMLaunch function will need to do this anyways, we trust that it's within their abilities to do it here.
  55. //
  56. if (g_bBINDownload && g_pOEMCheckSignature)
  57. {
  58. if (!g_pOEMCheckSignature(dwImageStart, g_dwROMOffset, dwLaunchAddr, bDownloaded))
  59. HALT(BLERR_CAT_SIGNATURE);
  60. }
  61. // (5) final call to launch the image. never returned
  62. OEMLaunch (dwImageStart, dwImageLength, dwLaunchAddr, (const ROMHDR *)dwpToc);
  63. // should never return
  64. // fall through
  65. default:
  66. // ERROR! spin forever
  67. HALT (BLERR_INVALIDCMD);
  68. }
  69. }

上面很多函数,都是在eboot中实现的。

下面这个函数,俺水平有限,都不知道是如何实现原理

    1. //
    2. // KernelRelocate: move global variables to RAM
    3. //
    4. static BOOL KernelRelocate (ROMHDR *const pTOC)
    5. {
    6. ULONG loop;
    7. COPYentry *cptr;
    8. if (pTOC == (ROMHDR *const) -1)
    9. {
    10. return (FALSE); // spin forever!
    11. }
    12. // This is where the data sections become valid... don't read globals until after this
    13. for (loop = 0; loop < pTOC->ulCopyEntries; loop++)
    14. {
    15. cptr = (COPYentry *)(pTOC->ulCopyOffset + loop*sizeof(COPYentry));
    16. if (cptr->ulCopyLen)
    17. memcpy((LPVOID)cptr->ulDest,(LPVOID)cptr->ulSource,cptr->ulCopyLen);
    18. if (cptr->ulCopyLen != cptr->ulDestLen)
    19. memset((LPVOID)(cptr->ulDest+cptr->ulCopyLen),0,cptr->ulDestLen-cptr->ulCopyLen);
    20. }
    21. return (TRUE);
    22. }

    /*

  1. @func   DWORD | OEMPreDownload | Complete pre-download tasks - get IP address, initialize TFTP, etc.
  2. @rdesc  BL_DOWNLOAD = Platform Builder is asking us to download an image, BL_JUMP = Platform Builder is requesting we jump to an existing image, BL_ERROR = Failure.
  3. @comm
  4. @xref
  5. */
  6. DWORD OEMPreDownload(void)
  7. {
  8. BOOL  bGotJump = FALSE;
  9. DWORD dwDHCPLeaseTime = 0;
  10. PDWORD pdwDHCPLeaseTime = &dwDHCPLeaseTime;
  11. DWORD dwBootFlags = 0;
  12. OALMSG(OAL_FUNC, (TEXT("+OEMPreDownload./r/n")));
  13. // Create device name based on Ethernet address (this is how Platform Builder identifies this device).
  14. //
  15. OALKitlCreateName(BSP_DEVICE_PREFIX, pBSPArgs->kitl.mac, pBSPArgs->deviceId);
  16. OALMSG(OAL_INFO, (L"INFO: *** Device Name '%hs' ***/r/n", pBSPArgs->deviceId));
  17. if ( g_bUSBDownload == FALSE )
  18. {
  19. // If the user wants to use a static IP address, don't request an address
  20. // from a DHCP server.  This is done by passing in a NULL for the DHCP
  21. // lease time variable.  If user specified a static IP address, use it (don't use DHCP).
  22. //
  23. if (!(g_pBootCfg->ConfigFlags & CONFIG_FLAGS_DHCP))
  24. {
  25. // Static IP address.
  26. pBSPArgs->kitl.ipAddress  = g_pBootCfg->EdbgAddr.dwIP;
  27. pBSPArgs->kitl.ipMask     = g_pBootCfg->SubnetMask;
  28. pBSPArgs->kitl.flags     &= ~OAL_KITL_FLAGS_DHCP;
  29. pdwDHCPLeaseTime = NULL;
  30. OALMSG(OAL_INFO, (TEXT("INFO: Using static IP address %s./r/n"), inet_ntoa(pBSPArgs->kitl.ipAddress)));
  31. OALMSG(OAL_INFO, (TEXT("INFO: Using subnet mask %s./r/n"),       inet_ntoa(pBSPArgs->kitl.ipMask)));
  32. }
  33. else
  34. {
  35. pBSPArgs->kitl.ipAddress = 0;
  36. pBSPArgs->kitl.ipMask    = 0;
  37. }
  38. if ( !g_bDownloadImage)
  39. {
  40. return(BL_JUMP);
  41. }
  42. // Initialize the the TFTP transport.
  43. //
  44. g_DeviceAddr.dwIP = pBSPArgs->kitl.ipAddress;
  45. memcpy(g_DeviceAddr.wMAC, pBSPArgs->kitl.mac, (3 * sizeof(UINT16)));
  46. g_DeviceAddr.wPort = 0;
  47. if (!EbootInitEtherTransport(&g_DeviceAddr,
  48. &pBSPArgs->kitl.ipMask,
  49. &bGotJump,
  50. pdwDHCPLeaseTime,
  51. EBOOT_VERSION_MAJOR,
  52. EBOOT_VERSION_MINOR,
  53. BSP_DEVICE_PREFIX,
  54. pBSPArgs->deviceId,
  55. EDBG_CPU_ARM720,
  56. dwBootFlags))
  57. {
  58. OALMSG(OAL_ERROR, (TEXT("ERROR: OEMPreDownload: Failed to initialize Ethernet connection./r/n")));
  59. return(BL_ERROR);
  60. }
  61. // If the user wanted a DHCP address, we presumably have it now - save it for the OS to use.
  62. //
  63. if (g_pBootCfg->ConfigFlags & CONFIG_FLAGS_DHCP)
  64. {
  65. // DHCP address.
  66. pBSPArgs->kitl.ipAddress  = g_DeviceAddr.dwIP;
  67. pBSPArgs->kitl.flags     |= OAL_KITL_FLAGS_DHCP;
  68. }
  69. OALMSG(OAL_FUNC, (TEXT("_OEMPreDownload./r/n")));
  70. }
  71. else
  72. {
  73. OALMSG(TRUE, (TEXT("Please send the Image through USB./r/n")));
  74. }
  75. return(bGotJump ? BL_JUMP : BL_DOWNLOAD);
  76. }

这些函数都有详细的注释,非常明了,我就不注释了。

  1. /*
  2. @func   BOOL | OEMPlatformInit | Initialize the Samsung SMD2440 platform hardware.
  3. @rdesc  TRUE = Success, FALSE = Failure.
  4. @comm
  5. @xref
  6. */
  7. BOOL OEMPlatformInit(void)
  8. {
  9. ULONG BootDelay;
  10. UINT8 KeySelect;
  11. UINT32 dwStartTime, dwPrevTime, dwCurrTime;
  12. BOOLEAN bResult = FALSE;
  13. FlashInfo flashInfo;
  14. OALMSG(OAL_FUNC, (TEXT("+OEMPlatformInit./r/n")));
  15. EdbgOutputDebugString("Microsoft Windows CE Bootloader for the Samsung SMDK2440 Version %d.%d Built %s/r/n/r/n",
  16. EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, __DATE__);
  17. // Initialize the display.
  18. //
  19. InitDisplay();
  20. // Initialize the BSP args structure.
  21. //
  22. memset(pBSPArgs, 0, sizeof(BSP_ARGS));
  23. pBSPArgs->header.signature       = OAL_ARGS_SIGNATURE;
  24. pBSPArgs->header.oalVersion      = OAL_ARGS_VERSION;
  25. pBSPArgs->header.bspVersion      = BSP_ARGS_VERSION;
  26. pBSPArgs->kitl.flags             = OAL_KITL_FLAGS_ENABLED | OAL_KITL_FLAGS_VMINI;
  27. pBSPArgs->kitl.devLoc.IfcType    = Internal;
  28. pBSPArgs->kitl.devLoc.BusNumber  = 0;
  29. pBSPArgs->kitl.devLoc.LogicalLoc = BSP_BASE_REG_PA_CS8900A_IOBASE;
  30. // For USB Download functon
  31. //
  32. if (!InitUSB())
  33. {
  34. DEBUGMSG(1, (TEXT("OEMPlatformInit: Failed to initialize USB./r/n")));
  35. return(FALSE);
  36. }
  37. Isr_Init();
  38. // This should not change unless reserved blocks are added/removed;
  39. // made global to do the calc only once.
  40. g_dwImageStartBlock = IMAGE_START_BLOCK;
  41. // Try to initialize the boot media block driver and BinFS partition.
  42. //
  43. OALMSG(TRUE, (TEXT("BP_Init/r/n")));
  44. if ( !BP_Init((LPBYTE)BINFS_RAM_START, BINFS_RAM_LENGTH, NULL, NULL, NULL) )
  45. {
  46. OALMSG(OAL_WARN, (TEXT("WARNING: OEMPlatformInit failed to initialize Boot Media./r/n")));
  47. g_bBootMediaExist = FALSE;
  48. }
  49. else
  50. g_bBootMediaExist = TRUE;
  51. // Get flash info
  52. if (!FMD_GetInfo(&flashInfo)) {
  53. OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
  54. L"FMD_GetInfo call failed/r/n"
  55. ));
  56. }
  57. wNUM_BLOCKS = flashInfo.dwNumBlocks;
  58. RETAILMSG(1, (TEXT("wNUM_BLOCKS : %d(0x%x) /r/n"), wNUM_BLOCKS, wNUM_BLOCKS));
  59. // Try to retrieve TOC (and Boot config) from boot media
  60. //
  61. if ( !TOC_Read( ) )
  62. {
  63. // use default settings
  64. TOC_Init(DEFAULT_IMAGE_DESCRIPTOR, (IMAGE_TYPE_RAMIMAGE), 0, 0, 0);
  65. }
  66. // Display boot message - user can halt the autoboot by pressing any key on the serial terminal emulator.
  67. //
  68. BootDelay = g_pBootCfg->BootDelay;
  69. if (g_pBootCfg->ConfigFlags & BOOT_TYPE_DIRECT)
  70. {
  71. OALMSG(TRUE, (TEXT("Press [ENTER] to launch image stored on boot media, or [SPACE] to enter boot monitor./r/n")));
  72. OALMSG(TRUE, (TEXT("/r/nInitiating image launch in %d seconds. "),BootDelay--));
  73. }
  74. else
  75. {
  76. OALMSG(TRUE, (TEXT("Press [ENTER] to download image stored on boot media, or [SPACE] to enter boot monitor./r/n")));
  77. OALMSG(TRUE, (TEXT("/r/nInitiating image download in %d seconds. "),BootDelay--));
  78. }
  79. dwStartTime = OEMEthGetSecs();
  80. dwPrevTime  = dwStartTime;
  81. dwCurrTime  = dwStartTime;
  82. KeySelect   = 0;
  83. // Allow the user to break into the bootloader menu.
  84. //
  85. while((dwCurrTime - dwStartTime) < g_pBootCfg->BootDelay)
  86. {
  87. KeySelect = OEMReadDebugByte();
  88. if ((KeySelect == 0x20) || (KeySelect == 0x0d))
  89. break;
  90. dwCurrTime = OEMEthGetSecs();
  91. if (dwCurrTime > dwPrevTime)
  92. {
  93. int i, j;
  94. // 1 Second has elapsed - update the countdown timer.
  95. dwPrevTime = dwCurrTime;
  96. if (BootDelay < 9)
  97. i = 11;
  98. else if (BootDelay < 99)
  99. i = 12;
  100. else if (BootDelay < 999)
  101. i = 13;
  102. for(j = 0; j < i; j++)
  103. OEMWriteDebugByte((BYTE)0x08); // print back space
  104. EdbgOutputDebugString ( "%d seconds. ", BootDelay--);
  105. }
  106. }
  107. OALMSG(OAL_INFO, (TEXT("/r/n")));
  108. // Boot or enter bootloader menu.
  109. //
  110. switch(KeySelect)
  111. {
  112. case 0x20: // Boot menu.
  113. g_bDownloadImage = MainMenu(g_pBootCfg);
  114. break;
  115. case 0x00: // Fall through if no keys were pressed -or-
  116. case 0x0d: // the user cancelled the countdown.
  117. default:
  118. if (g_pBootCfg->ConfigFlags & BOOT_TYPE_DIRECT)
  119. {
  120. OALMSG(TRUE, (TEXT("/r/nLaunching image from boot media ... /r/n")));
  121. g_bDownloadImage = FALSE;
  122. }
  123. else
  124. {
  125. OALMSG(TRUE, (TEXT("/r/nStarting auto-download ... /r/n")));
  126. g_bDownloadImage = TRUE;
  127. }
  128. break;
  129. }
  130. if ( !g_bDownloadImage )
  131. {
  132. // User doesn't want to download image - load it from the boot media.
  133. // We could read an entire nk.bin or nk.nb0 into ram and jump.
  134. if ( !VALID_TOC(g_pTOC) ) {
  135. OALMSG(OAL_ERROR, (TEXT("OEMPlatformInit: ERROR_INVALID_TOC, can not autoboot./r/n")));
  136. return FALSE;
  137. }
  138. switch (g_ImageType) {
  139. case IMAGE_TYPE_STEPLDR:
  140. OALMSG(TRUE, (TEXT("Don't support launch STEPLDR.bin/r/n")));
  141. break;
  142. case IMAGE_TYPE_LOADER:
  143. OALMSG(TRUE, (TEXT("Don't support launch EBOOT.bin/r/n")));
  144. break;
  145. case IMAGE_TYPE_RAMIMAGE:
  146. OALMSG(TRUE, (TEXT("OEMPlatformInit: IMAGE_TYPE_RAMIMAGE/r/n")));
  147. if ( !ReadOSImageFromBootMedia( ) )
  148. {
  149. OALMSG(OAL_ERROR, (TEXT("OEMPlatformInit ERROR: Failed to load kernel region into RAM./r/n")));
  150. return FALSE;
  151. }
  152. break;
  153. default:
  154. OALMSG(OAL_ERROR, (TEXT("OEMPlatformInit ERROR: unknown image type: 0x%x /r/n"), g_ImageType));
  155. return FALSE;
  156. }
  157. }
  158. // Configure Ethernet controller.
  159. //
  160. if ( g_bDownloadImage && (g_bUSBDownload == FALSE) )
  161. {
  162. if (!InitEthDevice(g_pBootCfg))
  163. {
  164. OALMSG(OAL_ERROR, (TEXT("ERROR: OEMPlatformInit: Failed to initialize Ethernet controller./r/n")));
  165. goto CleanUp;
  166. }
  167. }
  168. bResult = TRUE;
  169. CleanUp:
  170. OALMSG(OAL_FUNC, (TEXT("_OEMPlatformInit./r/n")));
  171. return(bResult);
  172. }

这个OEMPlatformInit 函数不简单,把菜单啊,分区等的事情都做的相当完美。eboot一系列配置都在这里完成的。

  1. /*
  2. @func   void | OEMLaunch | Executes the stored/downloaded image.
  3. @rdesc  N/A.
  4. @comm
  5. @xref
  6. C:/WINCE500/PUBLIC/COMMON/OAK/DRIVERS/ETHDBG/BLCOMMON/blcommon.c(149):
  7. */
  8. void OEMLaunch( DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr )
  9. {
  10. DWORD dwPhysLaunchAddr;
  11. EDBG_ADDR EshellHostAddr;
  12. EDBG_OS_CONFIG_DATA *pCfgData;
  13. OALMSG(OAL_FUNC, (TEXT("+OEMLaunch./r/n")));
  14. // If the user requested that a disk image (stored in RAM now) be written to the SmartMedia card, so it now.
  15. //
  16. if (g_bDownloadImage && (g_pBootCfg->ConfigFlags & TARGET_TYPE_NAND))
  17. {
  18. // Since this platform only supports RAM images, the image cache address is the same as the image RAM address.
  19. //
  20. switch (g_ImageType)
  21. {
  22. case IMAGE_TYPE_STEPLDR:
  23. if (!WriteRawImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))
  24. {
  25. OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));
  26. goto CleanUp;
  27. }
  28. OALMSG(TRUE, (TEXT("INFO: Step loader image stored to Smart Media.  Please Reboot.  Halting.../r/n")));
  29. while(1)
  30. {
  31. // Wait...
  32. }
  33. break;
  34. case IMAGE_TYPE_LOADER:
  35. g_pTOC->id[0].dwLoadAddress = dwImageStart;
  36. g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);
  37. if (!WriteRawImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))
  38. {
  39. OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));
  40. goto CleanUp;
  41. }
  42. if (dwLaunchAddr && (g_pTOC->id[0].dwJumpAddress != dwLaunchAddr))
  43. {
  44. g_pTOC->id[0].dwJumpAddress = dwLaunchAddr;
  45. if ( !TOC_Write() ) {
  46. EdbgOutputDebugString("*** OEMLaunch ERROR: TOC_Write failed! Next boot may not load from disk *** /r/n");
  47. }
  48. TOC_Print();
  49. }
  50. OALMSG(TRUE, (TEXT("INFO: Eboot image stored to Smart Media.  Please Reboot.  Halting.../r/n")));
  51. while(1)
  52. {
  53. // Wait...
  54. }
  55. break;
  56. case IMAGE_TYPE_RAMIMAGE:
  57. g_pTOC->id[g_dwTocEntry].dwLoadAddress = dwImageStart;
  58. g_pTOC->id[g_dwTocEntry].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);
  59. if (!WriteOSImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))
  60. {
  61. OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));
  62. goto CleanUp;
  63. }
  64. //---如果设定地址和实际启动地址不符合
  65. if (dwLaunchAddr && (g_pTOC->id[g_dwTocEntry].dwJumpAddress != dwLaunchAddr))
  66. {
  67. g_pTOC->id[g_dwTocEntry].dwJumpAddress = dwLaunchAddr;
  68. if ( !TOC_Write() ) {
  69. EdbgOutputDebugString("*** OEMLaunch ERROR: TOC_Write failed! Next boot may not load from disk *** /r/n");
  70. }
  71. TOC_Print();
  72. }
  73. else
  74. {
  75. dwLaunchAddr= g_pTOC->id[g_dwTocEntry].dwJumpAddress;
  76. EdbgOutputDebugString("INFO: using TOC[%d] dwJumpAddress: 0x%x/r/n", g_dwTocEntry, dwLaunchAddr);
  77. }
  78. break;
  79. }
  80. }
  81. else if(g_bDownloadImage)
  82. {
  83. switch (g_ImageType)
  84. {
  85. case IMAGE_TYPE_STEPLDR:
  86. OALMSG(TRUE, (TEXT("Stepldr image can't launch from ram./r/n")));
  87. OALMSG(TRUE, (TEXT("You should program it into flash./r/n")));
  88. SpinForever();
  89. break;
  90. case IMAGE_TYPE_LOADER:
  91. OALMSG(TRUE, (TEXT("Eboot image can't launch from ram./r/n")));
  92. OALMSG(TRUE, (TEXT("You should program it into flash./r/n")));
  93. SpinForever();
  94. break;
  95. default:
  96. break;
  97. }
  98. }
  99. OALMSG(1, (TEXT("waitforconnect/r/n")));
  100. // Wait for Platform Builder to connect after the download and send us IP and port settings for service
  101. // connections - also sends us KITL flags.  This information is used later by the OS (KITL).
  102. //
  103. if (~g_bUSBDownload & g_bDownloadImage & g_bWaitForConnect)
  104. {
  105. memset(&EshellHostAddr, 0, sizeof(EDBG_ADDR));
  106. g_DeviceAddr.dwIP  = pBSPArgs->kitl.ipAddress;
  107. memcpy(g_DeviceAddr.wMAC, pBSPArgs->kitl.mac, (3 * sizeof(UINT16)));
  108. g_DeviceAddr.wPort = 0;
  109. if (!(pCfgData = EbootWaitForHostConnect(&g_DeviceAddr, &EshellHostAddr)))
  110. {
  111. OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: EbootWaitForHostConnect failed./r/n")));
  112. goto CleanUp;
  113. }
  114. // If the user selected "passive" KITL (i.e., don't connect to the target at boot time), set the
  115. // flag in the args structure so the OS image can honor it when it boots.
  116. //
  117. if (pCfgData->KitlTransport & KTS_PASSIVE_MODE)
  118. {
  119. pBSPArgs->kitl.flags |= OAL_KITL_FLAGS_PASSIVE;
  120. }
  121. }
  122. // If a launch address was provided, we must have downloaded the image, save the address in case we
  123. // want to jump to this image next time.  If no launch address was provided, retrieve the last one.
  124. //
  125. if (dwLaunchAddr && (g_pTOC->id[g_dwTocEntry].dwJumpAddress != dwLaunchAddr))
  126. {
  127. g_pTOC->id[g_dwTocEntry].dwJumpAddress = dwLaunchAddr;
  128. }
  129. else
  130. {
  131. dwLaunchAddr= g_pTOC->id[g_dwTocEntry].dwJumpAddress;
  132. OALMSG(OAL_INFO, (TEXT("INFO: using TOC[%d] dwJumpAddress: 0x%x/r/n"), g_dwTocEntry, dwLaunchAddr));
  133. }
  134. // Jump to downloaded image (use the physical address since we'll be turning the MMU off)...
  135. //
  136. dwPhysLaunchAddr = (DWORD)OALVAtoPA((void *)dwLaunchAddr);
  137. OALMSG(TRUE, (TEXT("INFO: OEMLaunch: Jumping to Physical Address 0x%Xh (Virtual Address 0x%Xh).../r/n/r/n/r/n"), dwPhysLaunchAddr, dwLaunchAddr));
  138. // Jump...
  139. //开始运行wince
  140. Launch(dwPhysLaunchAddr);
  141. CleanUp:
  142. OALMSG(TRUE, (TEXT("ERROR: OEMLaunch: Halting.../r/n")));
  143. SpinForever();
  144. }

OEMLaunch这个函数可以根据eboot菜单的控制决定是何种方式启动都行,包括KITL功能。

================================================================================

DownloadImage这个函数是在C:/WINCE500/PLATFORM/COMMON/SRC/COMMON/BOOT/BLCOMMON/blcommon.c实现的。

有空再分析一下吧。

现在看看这个真正使内核运行的Launch函数是怎么实现的

C:/WINCE500/PLATFORM/SMDK2440A/Src/Bootloader/Eboot/util.s(32): LEAF_ENTRY Launch

----------------------------------------------------------------------------------------------------------------------------

==================Launch(dwPhysLaunchAddr);这个dwPhysLaunchAddr是怎么传递进来的?

INCLUDE kxarm.h

PHY_RAM_START EQU 0x30000000
VIR_RAM_START EQU 0x80000000

TEXTAREA

LEAF_ENTRY  Launch

ldr r2, = PhysicalStart
 ldr     r3, = (VIR_RAM_START - PHY_RAM_START)虚拟地址和物理地址想减,为什么要这么做呢?

sub     r2, r2, r3

mov     r1, #0x0070             ; Disable MMU
 mcr     p15, 0, r1, c1, c0, 0
 nop
 mov     pc, r2                  ; Jump to PStart
 nop

; MMU & caches now disabled.

PhysicalStart

mov     r2, #0
 mcr     p15, 0, r2, c8, c7, 0   ; Flush the TLB
 mov     pc, r0   ; Jump to program we are launching.

还有OALVAtoPA函数我也觉得比较有意思。虚拟地址转换为物理地址。

C:/WINCE500/PLATFORM/COMMON/SRC/ARM/COMMON/MEMORY/memory.c(65):UINT32 OALVAtoPA(VOID *pVA)
有些虚拟内存和物理内存转换的函数实现。C:/WINCE500/PLATFORM/SMDK2440A/Src/Inc/oal_memory.h(84):#define OALVAtoPA(va)       (((UINT32)(va))&~0xE0000000)也有。具体还不知道用了哪里,不过方法几乎一样的。

  1. typedef struct {
  2. UINT32  CA;                         // cached virtual address
  3. UINT32  PA;                         // physical address
  4. UINT32  size;                       // size, in MB bytes
  5. } OAL_ADDRESS_TABLE, *POAL_ADDRESS_TABLE;
  6. //------------------------------------------------------------------------------
  7. //
  8. //  Define:  OAL_MEMORY_CACHE_BIT
  9. //
  10. //  Defines the address bit that determines if an address is cached
  11. //  or uncached, according to the ranges below:
  12. //
  13. //      0x80000000 - 0x9FFFFFFF ==> CACHED   address
  14. //      0xA0000000 - 0xBFFFFFFF ==> UNCACHED address
  15. //
  16. #define OAL_MEMORY_CACHE_BIT            0x20000000
  17. //------------------------------------------------------------------------------
  18. //
  19. //  Extern:  g_oalAddressTable
  20. //
  21. //  This table is used by kernel to establish the virtual to physical address
  22. //  mapping. It is alos used in OALPAtoVA and OALVAtoPA functions to allow
  23. //  get virtual address for physical and vice versa.
  24. //
  25. extern OAL_ADDRESS_TABLE g_oalAddressTable[];
  26. //------------------------------------------------------------------------------
  27. #define OALCAtoUA(va)       (VOID*)(((UINT32)(va))|OAL_MEMORY_CACHE_BIT)
  28. #define OALUAtoCA(va)       (VOID*)(((UINT32)(va))&~OAL_MEMORY_CACHE_BIT)
  29. #define OALPAtoCA(pa)       OALPAtoVA(pa, TRUE)
  30. #define OALPAtoUA(pa)       OALPAtoVA(pa, FALSE)
  31. VOID* OALPAtoVA(UINT32 pa, BOOL cached);
  32. UINT32 OALVAtoPA(VOID *va);
  33. //从这些可以看出物理内存和虚拟内存有什么关系了。

转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协。如有错误,希望能够留言指出。

SMDK2440A 5.0BSP之eboot流程(作者:wogoyixikexie@gliet)相关推荐

  1. 如何在wince下添加和删除驱动(作者:wogoyixikexie@gliet)

    刚才我在C:/WINCE500/PLATFORM/SMDK2440A/Src/Drivers下直接把Dirs文件中的camera删除掉了,这样就不会编译camera文件夹下的代码了,但是却会出现如下编 ...

  2. 2440 休眠唤醒的实现过程(作者:wogoyixikexie@gliet)

    2440 休眠唤醒的实现过程(作者:wogoyixikexie@gliet) //----------------------------------------------------------- ...

  3. KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet)

    KernelIoControl和OEMIoControl的分析和使用(作者:wogoyixikexie@gliet) 对于KernelIoControl这个函数我们并不陌生,在2440 5.0BSP当 ...

  4. wince驱动异常调试方法(作者:wogoyixikexie@gliet)

    //-------------------------------------------------------------------------------------------------- ...

  5. 从eboot菜单分析eboot功能实现原理

    作者:wogoyixikexie@gliet 2008-12-10 ============================================================ 一直在用优 ...

  6. wince下更新NK软件(wince ghost V1)成功了!

    作者:wogoyixikexie@gliet 哈哈,这次做的还算比较顺利,看了几天flash驱动的原理,花了半天实现应用程序和FMD通信,运气相当好,当看到DNW窗口不断打印出 FMD_OEMIoCo ...

  7. wince下更新NK软件(wince ghost V1)成功了

    首先给大家分享一个巨牛巨牛的人工智能教程,是我无意中发现的.教程不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈-我正在学习中,觉得太牛了,所以分享给大家!点这里可以跳转 ...

  8. ARM协处理器CP15(设置MMU,cache等)学习

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 作者:w ...

  9. K9F1208U0M 64M nand flash 手册阅读以及相关驱动程序分析

    首先给大家分享一个巨牛巨牛的人工智能教程,是我无意中发现的.教程不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈-我正在学习中,觉得太牛了,所以分享给大家!点这里可以跳转 ...

最新文章

  1. web前端----jQuery属性操作
  2. c语言函数用指针传递参数问题
  3. 在新建android工程的时候出现This template depends on the Android Support library!
  4. Spring的@Transactional注解踩坑
  5. go get 的不再src目录中_GO语言基础进阶教程:包的使用
  6. redis 关系数据库怎么转换 和_redis数据库设计(转)
  7. php标准库string,PHP中的一些标准库
  8. netbios 和smb
  9. Linux内核调试 - 一般人儿我都不告诉他(一)
  10. 《深入浅出统计学》笔记二--第二章:集中趋势的量度,第三章:分散性与变异性的量度
  11. REST服务简介和实践
  12. 什么是游戏引擎,什么是虚幻引擎(Unreal Engin 4)?
  13. 鱼眼镜头的成像原理到畸变矫正(完整版)
  14. 苹果处理器性能排行榜天梯图2022 苹果处理器排行榜2022
  15. Pandas CSV 文件
  16. 如何在Mysql中运行SQL文件
  17. (附源码)springboot教材订购系统的开发毕业设计081419
  18. 学计算机语言需要英语基础吗,数学和英语不好的人能学编程吗?
  19. 最近的一些杂感-20220107
  20. bat文件刷屏,请规范命名

热门文章

  1. 在线报表设计器如何制作多表单填报(报表工具efreport.com)
  2. 应用zigbee实现智能家居项目
  3. LightOJ 1079 Just another Robbery
  4. iPhone12 屏幕适配
  5. 苹果cms微信对接php,苹果cmsV10微信公众号对接插件安装教程
  6. 洛谷 P1195 口袋的天空 (题解+代码)
  7. Powershell 通过POP3接收邮件
  8. Qt工具栏中设置小部件间隔的方法
  9. Radarsat-2全极化SAR数据C3和T3矩阵的提取———PolSARpro
  10. 南方科技大学深港微电子学院夏令营