Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

wince_loader.c 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #define LOAD_DEBUG 0
  2. static int get_x_header(unsigned char *data, unsigned long now);
  3. static void jump_2ep();
  4. static unsigned char ce_signature[] = {'B', '0', '0', '0', 'F', 'F', '\n',};
  5. static char ** ep;
  6. #define BOOT_ARG_PTR_LOCATION 0x001FFFFC
  7. typedef struct _BOOT_ARGS{
  8. unsigned char ucVideoMode;
  9. unsigned char ucComPort;
  10. unsigned char ucBaudDivisor;
  11. unsigned char ucPCIConfigType;
  12. unsigned long dwSig;
  13. #define BOOTARG_SIG 0x544F4F42
  14. unsigned long dwLen;
  15. unsigned char ucLoaderFlags;
  16. unsigned char ucEshellFlags;
  17. unsigned char ucEdbgAdapterType;
  18. unsigned char ucEdbgIRQ;
  19. unsigned long dwEdbgBaseAddr;
  20. unsigned long dwEdbgDebugZone;
  21. unsigned long dwDHCPLeaseTime;
  22. unsigned long dwEdbgFlags;
  23. unsigned long dwEBootFlag;
  24. unsigned long dwEBootAddr;
  25. unsigned long dwLaunchAddr;
  26. unsigned long pvFlatFrameBuffer;
  27. unsigned short vesaMode;
  28. unsigned short cxDisplayScreen;
  29. unsigned short cyDisplayScreen;
  30. unsigned short cxPhysicalScreen;
  31. unsigned short cyPhysicalScreen;
  32. unsigned short cbScanLineLength;
  33. unsigned short bppScreen;
  34. unsigned char RedMaskSize;
  35. unsigned char REdMaskPosition;
  36. unsigned char GreenMaskSize;
  37. unsigned char GreenMaskPosition;
  38. unsigned char BlueMaskSize;
  39. unsigned char BlueMaskPosition;
  40. } BOOT_ARGS;
  41. BOOT_ARGS BootArgs;
  42. static struct segment_info{
  43. unsigned long addr; // Section Address
  44. unsigned long size; // Section Size
  45. unsigned long checksum; // Section CheckSum
  46. } X;
  47. #define PSIZE (1500) //Max Packet Size
  48. #define DSIZE (PSIZE+12)
  49. static unsigned long dbuffer_available =0;
  50. static unsigned long not_loadin =0;
  51. static unsigned long d_now =0;
  52. unsigned long entry;
  53. static unsigned long ce_curaddr;
  54. static sector_t ce_loader(unsigned char *data, unsigned int len, int eof);
  55. static os_download_t wince_probe(unsigned char *data, unsigned int len)
  56. {
  57. if (strncmp(ce_signature, data, sizeof(ce_signature)) != 0) {
  58. return 0;
  59. }
  60. printf("(WINCE)");
  61. return ce_loader;
  62. }
  63. static sector_t ce_loader(unsigned char *data, unsigned int len, int eof)
  64. {
  65. static unsigned char dbuffer[DSIZE];
  66. int this_write = 0;
  67. static int firsttime = 1;
  68. /*
  69. * new packet in, we have to
  70. * [1] copy data to dbuffer,
  71. *
  72. * update...
  73. * [2] dbuffer_available
  74. */
  75. memcpy( (dbuffer+dbuffer_available), data, len); //[1]
  76. dbuffer_available += len; // [2]
  77. len = 0;
  78. d_now = 0;
  79. #if 0
  80. printf("dbuffer_available =%ld \n", dbuffer_available);
  81. #endif
  82. if (firsttime)
  83. {
  84. d_now = sizeof(ce_signature);
  85. printf("String Physical Address = %lx \n",
  86. *(unsigned long *)(dbuffer+d_now));
  87. d_now += sizeof(unsigned long);
  88. printf("Image Size = %ld [%lx]\n",
  89. *(unsigned long *)(dbuffer+d_now),
  90. *(unsigned long *)(dbuffer+d_now));
  91. d_now += sizeof(unsigned long);
  92. dbuffer_available -= d_now;
  93. d_now = (unsigned long)get_x_header(dbuffer, d_now);
  94. firsttime = 0;
  95. }
  96. if (not_loadin == 0)
  97. {
  98. d_now = get_x_header(dbuffer, d_now);
  99. }
  100. while ( not_loadin > 0 )
  101. {
  102. /* dbuffer do not have enough data to loading, copy all */
  103. #if LOAD_DEBUG
  104. printf("[0] not_loadin = [%ld], dbuffer_available = [%ld] \n",
  105. not_loadin, dbuffer_available);
  106. printf("[0] d_now = [%ld] \n", d_now);
  107. #endif
  108. if( dbuffer_available <= not_loadin)
  109. {
  110. this_write = dbuffer_available ;
  111. memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write );
  112. ce_curaddr += this_write;
  113. not_loadin -= this_write;
  114. /* reset index and available in the dbuffer */
  115. dbuffer_available = 0;
  116. d_now = 0;
  117. #if LOAD_DEBUG
  118. printf("[1] not_loadin = [%ld], dbuffer_available = [%ld] \n",
  119. not_loadin, dbuffer_available);
  120. printf("[1] d_now = [%ld], this_write = [%d] \n",
  121. d_now, this_write);
  122. #endif
  123. // get the next packet...
  124. return (0);
  125. }
  126. /* dbuffer have more data then loading ... , copy partital.... */
  127. else
  128. {
  129. this_write = not_loadin;
  130. memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write);
  131. ce_curaddr += this_write;
  132. not_loadin = 0;
  133. /* reset index and available in the dbuffer */
  134. dbuffer_available -= this_write;
  135. d_now += this_write;
  136. #if LOAD_DEBUG
  137. printf("[2] not_loadin = [%ld], dbuffer_available = [%ld] \n",
  138. not_loadin, dbuffer_available);
  139. printf("[2] d_now = [%ld], this_write = [%d] \n\n",
  140. d_now, this_write);
  141. #endif
  142. /* dbuffer not empty, proceed processing... */
  143. // don't have enough data to get_x_header..
  144. if ( dbuffer_available < (sizeof(unsigned long) * 3) )
  145. {
  146. // printf("we don't have enough data remaining to call get_x. \n");
  147. memcpy( (dbuffer+0), (dbuffer+d_now), dbuffer_available);
  148. return (0);
  149. }
  150. else
  151. {
  152. #if LOAD_DEBUG
  153. printf("with remaining data to call get_x \n");
  154. printf("dbuffer available = %ld , d_now = %ld\n",
  155. dbuffer_available, d_now);
  156. #endif
  157. d_now = get_x_header(dbuffer, d_now);
  158. }
  159. }
  160. }
  161. return (0);
  162. }
  163. static int get_x_header(unsigned char *dbuffer, unsigned long now)
  164. {
  165. X.addr = *(unsigned long *)(dbuffer + now);
  166. X.size = *(unsigned long *)(dbuffer + now + sizeof(unsigned long));
  167. X.checksum = *(unsigned long *)(dbuffer + now + sizeof(unsigned long)*2);
  168. if (X.addr == 0)
  169. {
  170. entry = X.size;
  171. done(1);
  172. printf("Entry Point Address = [%lx] \n", entry);
  173. jump_2ep();
  174. }
  175. if (!prep_segment(X.addr, X.addr + X.size, X.addr + X.size, 0, 0)) {
  176. longjmp(restart_etherboot, -2);
  177. }
  178. ce_curaddr = X.addr;
  179. now += sizeof(unsigned long)*3;
  180. /* re-calculate dbuffer available... */
  181. dbuffer_available -= sizeof(unsigned long)*3;
  182. /* reset index of this section */
  183. not_loadin = X.size;
  184. #if 1
  185. printf("\n");
  186. printf("\t Section Address = [%lx] \n", X.addr);
  187. printf("\t Size = %d [%lx]\n", X.size, X.size);
  188. printf("\t Checksum = %ld [%lx]\n", X.checksum, X.checksum);
  189. #endif
  190. #if LOAD_DEBUG
  191. printf("____________________________________________\n");
  192. printf("\t dbuffer_now = %ld \n", now);
  193. printf("\t dbuffer available = %ld \n", dbuffer_available);
  194. printf("\t not_loadin = %ld \n", not_loadin);
  195. #endif
  196. return now;
  197. }
  198. static void jump_2ep()
  199. {
  200. BootArgs.ucVideoMode = 1;
  201. BootArgs.ucComPort = 1;
  202. BootArgs.ucBaudDivisor = 1;
  203. BootArgs.ucPCIConfigType = 1; // do not fill with 0
  204. BootArgs.dwSig = BOOTARG_SIG;
  205. BootArgs.dwLen = sizeof(BootArgs);
  206. if(BootArgs.ucVideoMode == 0)
  207. {
  208. BootArgs.cxDisplayScreen = 640;
  209. BootArgs.cyDisplayScreen = 480;
  210. BootArgs.cxPhysicalScreen = 640;
  211. BootArgs.cyPhysicalScreen = 480;
  212. BootArgs.bppScreen = 16;
  213. BootArgs.cbScanLineLength = 1024;
  214. BootArgs.pvFlatFrameBuffer = 0x800a0000; // ollie say 0x98000000
  215. }
  216. else if(BootArgs.ucVideoMode != 0xFF)
  217. {
  218. BootArgs.cxDisplayScreen = 0;
  219. BootArgs.cyDisplayScreen = 0;
  220. BootArgs.cxPhysicalScreen = 0;
  221. BootArgs.cyPhysicalScreen = 0;
  222. BootArgs.bppScreen = 0;
  223. BootArgs.cbScanLineLength = 0;
  224. BootArgs.pvFlatFrameBuffer = 0;
  225. }
  226. ep = phys_to_virt(BOOT_ARG_PTR_LOCATION);
  227. *ep= virt_to_phys(&BootArgs);
  228. xstart32(entry);
  229. }