6 DECLARE_GLOBAL_DATA_PTR; /* defines global data structure pointer */
9 /*/////////////////////////////////////////////////////////////////////////////////////////////*/
14 /* #define CE_RAM_BASE 0x80100000 */
15 /* #define CE_WINCE_VRAM_BASE 0x80000000 */
16 /* #define CE_FIX_ADDRESS(a) (((a) - CE_WINCE_VRAM_BASE) + CE_RAM_BASE) */
17 #define CE_FIX_ADDRESS(a) (a)
19 /* Bin image parse states */
21 #define CE_PS_RTI_ADDR 0
22 #define CE_PS_RTI_LEN 1
23 #define CE_PS_E_ADDR 2
25 #define CE_PS_E_CHKSUM 4
26 #define CE_PS_E_DATA 5
30 #define CE_MIN(a, b) (((a) < (b)) ? (a) : (b))
31 #define CE_MAX(a, b) (((a) > (b)) ? (a) : (b))
36 #define STRMAC(s) _STRMAC(s)
44 ///////////////////////////////////////////////////////////////////////////////////////////////
47 static ce_bin __attribute__ ((aligned (32))) g_bin;
48 static ce_net __attribute__ ((aligned (32))) g_net;
51 ///////////////////////////////////////////////////////////////////////////////////////////////
57 ///////////////////////////////////////////////////////////////////////////////////////////////
60 int ce_bin_load(void* image, int imglen)
62 ce_init_bin(&g_bin, image);
64 g_bin.dataLen = imglen;
66 if (ce_parse_bin(&g_bin) == CE_PR_EOF)
68 ce_prepare_run_bin(&g_bin);
75 int ce_is_bin_image(void* image, int imglen)
77 if (imglen < CE_BIN_SIGN_LEN)
82 return (memcmp(image, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0);
85 void ce_bin_init_parser(void)
87 // No buffer address by now, will be specified
88 // latter by the ce_bin_parse_next routine
90 ce_init_bin(&g_bin, NULL);
93 int ce_bin_parse_next(void* parseBuffer, int len)
97 g_bin.data = (unsigned char*)parseBuffer;
99 rc = ce_parse_bin(&g_bin);
103 ce_prepare_run_bin(&g_bin);
109 void ce_init_bin(ce_bin* bin, unsigned char* dataBuffer)
111 memset(bin, 0, sizeof(ce_bin));
113 bin->data = dataBuffer;
114 bin->parseState = CE_PS_RTI_ADDR;
115 bin->parsePtr = (unsigned char*)&bin->rtiPhysAddr;
118 int ce_parse_bin(ce_bin* bin)
120 unsigned char* pbData = bin->data;
121 int pbLen = bin->dataLen;
125 printf("starting ce image parsing:\n\tbin->binLen: 0x%08X\n", bin->binLen);
126 printf("\tpbData: 0x%08X pbLEN: 0x%08X\n", pbData, pbLen);
131 if (bin->binLen == 0)
133 // Check for the .BIN signature first
135 if (!ce_is_bin_image(pbData, pbLen))
137 printf("Error: Invalid or corrupted .BIN image!\n");
142 printf("Loading Windows CE .BIN image ...\n");
146 pbLen -= CE_BIN_SIGN_LEN;
147 pbData += CE_BIN_SIGN_LEN;
152 switch (bin->parseState)
160 copyLen = CE_MIN(sizeof(unsigned int) - bin->parseLen, pbLen);
162 memcpy(&bin->parsePtr[ bin->parseLen ], pbData, copyLen);
164 bin->parseLen += copyLen;
168 if (bin->parseLen == sizeof(unsigned int))
170 if (bin->parseState == CE_PS_RTI_ADDR)
172 bin->rtiPhysAddr = CE_FIX_ADDRESS(bin->rtiPhysAddr);
174 else if (bin->parseState == CE_PS_E_ADDR)
178 bin->ePhysAddr = CE_FIX_ADDRESS(bin->ePhysAddr);
184 bin->parsePtr += sizeof(unsigned int);
186 if (bin->parseState == CE_PS_E_DATA)
190 bin->parsePtr = (unsigned char*)(bin->ePhysAddr);
191 bin->parseChkSum = 0;
209 copyLen = CE_MIN(bin->ePhysLen - bin->parseLen, pbLen);
210 bin->parseLen += copyLen;
214 printf("copy %d bytes from: 0x%08X to: 0x%08X\n", copyLen, pbData, bin->parsePtr);
218 bin->parseChkSum += *pbData;
219 *bin->parsePtr ++ = *pbData ++;
222 if (bin->parseLen == bin->ePhysLen)
224 printf("Section [%02d]: address 0x%08X, size 0x%08X, checksum %s\n",
228 (bin->eChkSum == bin->parseChkSum) ? "ok" : "fail");
230 if (bin->eChkSum != bin->parseChkSum)
234 printf("Error: Checksum error, corrupted .BIN file!\n");
242 bin->parseState = CE_PS_E_ADDR;
244 bin->parsePtr = (unsigned char*)(&bin->ePhysAddr);
263 if (!ce_lookup_ep_bin(bin))
265 printf("Error: entry point not found!\n");
272 printf("Entry point: 0x%08X, address range: 0x%08X-0x%08X\n",
275 bin->rtiPhysAddr + bin->rtiPhysLen);
282 bin->binLen += bin->dataLen;
293 void ce_prepare_run_bin(ce_bin* bin)
295 ce_driver_globals* drv_glb;
301 // Clear os RAM area (if needed)
303 //if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT)
306 printf("cleaning memory from 0x%08X to 0x%08X\n", bin->eRamStart, bin->eRamStart + bin->eRamLen);
308 printf("Preparing clean boot ... ");
309 memset((void*)bin->eRamStart, 0, bin->eRamLen);
313 // Prepare driver globals (if needed)
317 drv_glb = (ce_driver_globals*)bin->eDrvGlb;
319 // Fill out driver globals
321 memset(drv_glb, 0, sizeof(ce_driver_globals));
325 drv_glb->signature = DRV_GLB_SIGNATURE;
331 /* Local ethernet MAC address */
332 i = getenv_r ("ethaddr", tmp, sizeof (tmp));
333 s = (i > 0) ? tmp : 0;
335 for (i = 0; i < 6; ++i) {
336 drv_glb->macAddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
338 s = (*e) ? e + 1 : e;
343 printf("got MAC address %02X:%02X:%02X:%02X:%02X:%02X from environment\n", drv_glb->macAddr[0],drv_glb->macAddr[1],drv_glb->macAddr[2],drv_glb->macAddr[3],drv_glb->macAddr[4],drv_glb->macAddr[5]);
346 /* Local IP address */
347 drv_glb->ipAddr=(unsigned int)getenv_IPaddr("ipaddr");
349 printf("got IP address ");
350 print_IPaddr((IPaddr_t)drv_glb->ipAddr);
351 printf(" from environment\n");
355 drv_glb->ipMask=(unsigned long)getenv_IPaddr("netmask");
357 printf("got IP mask ");
358 print_IPaddr((IPaddr_t)drv_glb->ipMask);
359 printf(" from environment\n");
363 drv_glb->ipGate=(unsigned long)getenv_IPaddr("gatewayip");
365 printf("got gateway address ");
366 print_IPaddr((IPaddr_t)drv_glb->ipGate);
367 printf(" from environment\n");
374 // EDBG services config
376 memcpy(&drv_glb->edbgConfig, &bin->edbgConfig, sizeof(bin->edbgConfig));
386 int ce_lookup_ep_bin(ce_bin* bin)
389 ce_toc_entry* tentry;
393 // Check image Table Of Contents (TOC) signature
395 if (*(unsigned int*)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE)
397 // Error: Did not find image TOC signature!
403 // Lookup entry point
405 header = (ce_rom_hdr*)CE_FIX_ADDRESS(*(unsigned int*)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET + sizeof(unsigned int)));
406 tentry = (ce_toc_entry*)(header + 1);
408 for (i = 0; i < header->nummods; i ++)
410 // Look for 'nk.exe' module
412 if (strcmp((char*)CE_FIX_ADDRESS(tentry[ i ].fileName), "nk.exe") == 0)
414 // Save entry point and RAM addresses
416 e32 = (e32_rom*)CE_FIX_ADDRESS(tentry[ i ].e32Offset);
418 bin->eEntryPoint = CE_FIX_ADDRESS(tentry[ i ].loadOffset) + e32->e32_entryrva;
419 bin->eRamStart = CE_FIX_ADDRESS(header->ramStart);
420 bin->eRamLen = header->ramEnd - header->ramStart;
422 // Save driver_globals address
423 // Must follow RAM section in CE config.bib file
427 // RAM 80900000 03200000 RAM
428 // DRV_GLB 83B00000 00001000 RESERVED
431 bin->eDrvGlb = CE_FIX_ADDRESS(header->ramEnd);
437 // Error: Did not find 'nk.exe' module
445 typedef void (*CeEntryPointPtr)(void);
449 void ce_run_bin(ce_bin* bin)
451 CeEntryPointPtr EnrtryPoint;
453 printf("Launching Windows CE ...\n");
456 EnrtryPoint = (CeEntryPointPtr)bin->eEntryPoint;
462 int ce_boot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
465 unsigned long image_size;
470 printf ("myUsage:\n%s\n", cmdtp->usage);
474 addr = simple_strtoul(argv[1], NULL, 16);
475 image_size = 0x7fffffff; /* actually we do not know the image size */
477 printf ("## Booting Windows CE Image from address 0x%08lX ...\n", addr);
480 /* check if there is a valid windows CE image */
481 if (ce_is_bin_image((void *)addr, image_size))
483 if (!ce_bin_load((void*)addr, image_size))
485 /* Ops! Corrupted .BIN image! */
486 /* Handle error here ... */
487 printf("corrupted .BIN image !!!\n");
491 if ((s = getenv("autostart")) != NULL) {
494 * just use bootce to load the image to SDRAM;
495 * Do not start it automatically.
500 ce_run_bin(&g_bin); /* start the image */
503 printf("Image seems to be no valid Windows CE image !\n");
507 return 1; /* never reached - just to keep compiler happy */
515 bootce, 2, 0, ce_boot,
516 "bootce\t- Boot a Windows CE image from memory \n",
518 "\taddr\t\t-boot image from address addr\n"
524 static void wince_handler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
528 NetState = NETLOOP_SUCCESS; /* got input - quit net loop */
529 if(!memcmp(g_net.data + g_net.align_offset, gd->bd->bi_enetaddr, 6)) {
530 g_net.got_packet_4me=1;
533 g_net.got_packet_4me=0;
538 g_net.srvAddrRecv.sin_port = ntohs(*((unsigned short *)(g_net.data + ETHER_HDR_SIZE + IP_HDR_SIZE_NO_UDP + g_net.align_offset)));
539 NetCopyIP(&g_net.srvAddrRecv.sin_addr, g_net.data + ETHER_HDR_SIZE + g_net.align_offset + 12);
540 memcpy(NetServerEther, g_net.data + g_net.align_offset +6, 6);
543 printf("received packet: buffer 0x%08X Laenge %d \n", (unsigned long) pkt, len);
545 print_IPaddr(g_net.srvAddrRecv.sin_addr);
546 printf(", port: %d\n", g_net.srvAddrRecv.sin_port);
550 ce_dump_block(pkt, len);
552 printf("Headers:\n");
553 ce_dump_block(pkt - ETHER_HDR_SIZE - IP_HDR_SIZE, ETHER_HDR_SIZE + IP_HDR_SIZE);
554 printf("\n\nmy port should be: %d\n", ntohs(*((unsigned short *)(g_net.data + ETHER_HDR_SIZE + IP_HDR_SIZE_NO_UDP + g_net.align_offset +2))));
562 /* returns packet lengt if successfull */
563 int ce_recv_packet(char *buf, int len, struct sockaddr_in *from, struct sockaddr_in *local, struct timeval *timeout){
570 g_net.got_packet_4me=0;
571 time_started = get_timer(0);
574 NetRxPackets[0] = (uchar *)buf;
575 NetSetHandler(wince_handler);
579 if(g_net.got_packet_4me)
580 return g_net.dataLen;
581 /* check for timeout */
582 if (get_timer(time_started) > timeout->tv_sec * CFG_HZ) {
590 int ce_recv_frame(ce_net* net, int timeout)
592 struct timeval timeo;
596 timeo.tv_sec = timeout;
599 /* Receive UDP packet */
601 net->dataLen = ce_recv_packet(net->data+net->align_offset, sizeof(net->data)-net->align_offset, &net->srvAddrRecv, &net->locAddr, &timeo);
603 if (net->dataLen < 0)
605 /* Error! No data available */
613 int ce_process_download(ce_net* net, ce_bin* bin)
615 int ret = CE_PR_MORE;
617 if (net->dataLen >= 2)
619 unsigned short command;
621 command = ntohs(*(unsigned short*)(net->data+CE_DOFFSET));
624 printf("command found: 0x%04X\n", command);
629 case EDBG_CMD_WRITE_REQ:
633 // Check file name for WRITE request
634 // CE EShell uses "boot.bin" file name
636 /*printf(">>>>>>>> First Frame, IP: %s, port: %d\n",
637 inet_ntoa((in_addr_t *)&net->srvAddrRecv),
638 net->srvAddrRecv.sin_port);*/
640 if (strncmp((char*)(net->data +CE_DOFFSET + 2), "boot.bin", 8) == 0)
646 printf("Locked Down download link, IP: ");
647 print_IPaddr(net->srvAddrRecv.sin_addr);
648 printf(", port: %d\n", net->srvAddrRecv.sin_port);
656 printf("Sending BOOTME request [%d] to ", (int)net->secNum);
657 print_IPaddr(net->srvAddrSend.sin_addr);
664 // Lock down EShell download link
666 net->locAddr.sin_port = (EDBG_DOWNLOAD_PORT + 1);
667 net->srvAddrSend.sin_port = net->srvAddrRecv.sin_port;
668 net->srvAddrSend.sin_addr = net->srvAddrRecv.sin_addr;
675 net->srvAddrRecv.sin_port = 0;
682 ce_send_write_ack(net);
691 bin->dataLen = net->dataLen - 4;
693 // Parse next block of .bin file
695 ret = ce_parse_bin(bin);
697 // Request next block
699 if (ret != CE_PR_ERROR)
703 ce_send_write_ack(net);
708 case EDBG_CMD_READ_REQ:
710 // Read requests are not supported
717 // Error condition on the host side
719 printf("Error: unknown error on the host side\n");
726 printf("unknown command 0x%04X ????\n", command);
738 void ce_init_edbg_link(ce_net* net)
740 /* Initialize EDBG link for commands */
742 net->locAddr.sin_port = EDBG_DOWNLOAD_PORT;
743 net->srvAddrSend.sin_port = EDBG_DOWNLOAD_PORT;
744 net->srvAddrRecv.sin_port = 0;
748 void ce_process_edbg(ce_net* net, ce_bin* bin)
754 if (net->dataLen < sizeof(eth_dbg_hdr))
758 net->srvAddrRecv.sin_port = 0;
762 header = (eth_dbg_hdr*)(net->data + net->align_offset + ETHER_HDR_SIZE + IP_HDR_SIZE);
764 if (header->id != EDBG_ID)
768 net->srvAddrRecv.sin_port = 0;
772 if (header->service != EDBG_SVC_ADMIN)
774 /* Unknown service */
781 /* Some diag output */
785 printf("Locked Down EDBG service link, IP: ");
786 print_IPaddr(net->srvAddrRecv.sin_addr);
787 printf(", port: %d\n", net->srvAddrRecv.sin_port);
790 /* Lock down EDBG link */
792 net->srvAddrSend.sin_port = net->srvAddrRecv.sin_port;
798 case EDBG_CMD_JUMPIMG:
800 net->gotJumpingRequest = 1;
804 printf("Received JUMPING command\n");
807 /* Just pass through and copy CONFIG structure */
809 case EDBG_CMD_OS_CONFIG:
811 /* Copy config structure */
813 memcpy(&bin->edbgConfig, header->data, sizeof(edbg_os_config_data));
817 printf("Received CONFIG command\n");
819 if (bin->edbgConfig.flags & EDBG_FL_DBGMSG)
821 printf("--> Enabling DBGMSG service, IP: %d.%d.%d.%d, port: %d\n",
822 (bin->edbgConfig.dbgMsgIPAddr >> 0) & 0xFF,
823 (bin->edbgConfig.dbgMsgIPAddr >> 8) & 0xFF,
824 (bin->edbgConfig.dbgMsgIPAddr >> 16) & 0xFF,
825 (bin->edbgConfig.dbgMsgIPAddr >> 24) & 0xFF,
826 (int)bin->edbgConfig.dbgMsgPort);
829 if (bin->edbgConfig.flags & EDBG_FL_PPSH)
831 printf("--> Enabling PPSH service, IP: %d.%d.%d.%d, port: %d\n",
832 (bin->edbgConfig.ppshIPAddr >> 0) & 0xFF,
833 (bin->edbgConfig.ppshIPAddr >> 8) & 0xFF,
834 (bin->edbgConfig.ppshIPAddr >> 16) & 0xFF,
835 (bin->edbgConfig.ppshIPAddr >> 24) & 0xFF,
836 (int)bin->edbgConfig.ppshPort);
839 if (bin->edbgConfig.flags & EDBG_FL_KDBG)
841 printf("--> Enabling KDBG service, IP: %d.%d.%d.%d, port: %d\n",
842 (bin->edbgConfig.kdbgIPAddr >> 0) & 0xFF,
843 (bin->edbgConfig.kdbgIPAddr >> 8) & 0xFF,
844 (bin->edbgConfig.kdbgIPAddr >> 16) & 0xFF,
845 (bin->edbgConfig.kdbgIPAddr >> 24) & 0xFF,
846 (int)bin->edbgConfig.kdbgPort);
849 if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT)
851 printf("--> Force clean boot\n");
859 printf("Received unknown command: %08X\n", header->cmd);
864 /* Respond with ack */
865 header->flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;
866 net->dataLen = EDBG_DATA_OFFSET;
870 int ce_send_write_ack(ce_net* net)
872 unsigned short* wdata;
873 unsigned long aligned_address;
875 aligned_address=(unsigned long)net->data+ETHER_HDR_SIZE+IP_HDR_SIZE+net->align_offset;
877 wdata = (unsigned short*)aligned_address;
878 wdata[ 0 ] = htons(EDBG_CMD_WRITE_ACK);
879 wdata[ 1 ] = htons(net->blockNum);
883 return ce_send_frame(net);
888 int ce_send_frame(ce_net* net)
890 /* Send UDP packet */
891 NetTxPacket = (uchar *)net->data + net->align_offset;
892 return NetSendUDPPacket(NetServerEther, net->srvAddrSend.sin_addr, (int)net->srvAddrSend.sin_port, (int)net->locAddr.sin_port, net->dataLen);
901 int ce_send_bootme(ce_net* net)
904 edbg_bootme_data* data;
908 unsigned char tmp[64];
916 /* Fill out BOOTME packet */
917 memset(net->data, 0, PKTSIZE);
918 header = (eth_dbg_hdr*)(net->data +CE_DOFFSET);
919 data = (edbg_bootme_data*)header->data;
922 header->service = EDBG_SVC_ADMIN;
923 header->flags = EDBG_FL_FROM_DEV;
924 header->seqNum = net->secNum ++;
925 header->cmd = EDBG_CMD_BOOTME;
927 data->versionMajor = 0;
928 data->versionMinor = 0;
929 data->cpuId = EDBG_CPU_TYPE_ARM;
930 data->bootmeVer = EDBG_CURRENT_BOOTME_VERSION;
932 data->downloadPort = 0;
935 macp=(unsigned char *)data->macAddr;
936 /* MAC address from environment*/
937 i = getenv_r ("ethaddr", tmp, sizeof (tmp));
938 s = (i > 0) ? tmp : 0;
939 for (i = 0; i < 6; ++i) {
940 macp[i] = s ? simple_strtoul (s, &e, 16) : 0;
942 s = (*e) ? e + 1 : e;
945 /* IP address from environment */
946 data->ipAddr = (unsigned int)getenv_IPaddr("ipaddr");
948 // Device name string (NULL terminated). Should include
949 // platform and number based on Ether address (e.g. Odo42, CEPCLS2346, etc)
951 // We will use lower MAC address segment to create device name
952 // eg. MAC '00-0C-C6-69-09-05', device name 'Triton05'
954 strcpy(data->platformId, "Triton");
955 sprintf(data->deviceName, "%s%02X", data->platformId, macp[5]);
960 printf("header->id: %08X\r\n", header->id);
961 printf("header->service: %08X\r\n", header->service);
962 printf("header->flags: %08X\r\n", header->flags);
963 printf("header->seqNum: %08X\r\n", header->seqNum);
964 printf("header->cmd: %08X\r\n\r\n", header->cmd);
966 printf("data->versionMajor: %08X\r\n", data->versionMajor);
967 printf("data->versionMinor: %08X\r\n", data->versionMinor);
968 printf("data->cpuId: %08X\r\n", data->cpuId);
969 printf("data->bootmeVer: %08X\r\n", data->bootmeVer);
970 printf("data->bootFlags: %08X\r\n", data->bootFlags);
971 printf("data->svcPort: %08X\r\n\r\n", data->svcPort);
973 printf("data->macAddr: %02X-%02X-%02X-%02X-%02X-%02X\r\n",
974 (data->macAddr[0] >> 0) & 0xFF,
975 (data->macAddr[0] >> 8) & 0xFF,
976 (data->macAddr[1] >> 0) & 0xFF,
977 (data->macAddr[1] >> 8) & 0xFF,
978 (data->macAddr[2] >> 0) & 0xFF,
979 (data->macAddr[2] >> 8) & 0xFF);
981 printf("data->ipAddr: %d.%d.%d.%d\r\n",
982 (data->ipAddr >> 0) & 0xFF,
983 (data->ipAddr >> 8) & 0xFF,
984 (data->ipAddr >> 16) & 0xFF,
985 (data->ipAddr >> 24) & 0xFF);
987 printf("data->platformId: %s\r\n", data->platformId);
989 printf("data->deviceName: %s\r\n", data->deviceName);
994 // Some diag output ...
998 printf("Sending BOOTME request [%d] to ", (int)net->secNum);
999 print_IPaddr(net->srvAddrSend.sin_addr);
1005 net->dataLen = BOOTME_PKT_SIZE;
1009 printf("\n\n\nStart of buffer: 0x%08X\n", (unsigned long)net->data);
1010 printf("Start of ethernet buffer: 0x%08X\n", (unsigned long)net->data+net->align_offset);
1011 printf("Start of CE header: 0x%08X\n", (unsigned long)header);
1012 printf("Start of CE data: 0x%08X\n", (unsigned long)data);
1014 pkt = (uchar *)net->data+net->align_offset;
1015 printf("\n\npacket to send (ceconnect): \n");
1016 for(i=0; i<(net->dataLen+ETHER_HDR_SIZE+IP_HDR_SIZE); i++) {
1017 printf("0x%02X ", pkt[i]);
1024 memcpy(NetServerEther, NetBcastAddr, 6);
1026 return ce_send_frame(net);
1031 void ce_dump_block(unsigned char *ptr, int length) {
1036 for(i=0; i<length; i++) {
1038 printf("\n0x%08X: ", (unsigned long)ptr + i);
1041 printf("0x%02X ", ptr[i]);
1045 for(j=i-15; j<i; j++){
1046 if((ptr[j]>0x1f) && (ptr[j]<0x7f)) {
1047 printf("%c", ptr[j]);
1068 void ce_init_download_link(ce_net* net, ce_bin* bin, struct sockaddr_in* host_addr, int verbose)
1070 unsigned long aligned_address;
1071 /* Initialize EDBG link for download */
1074 memset(net, 0, sizeof(ce_net));
1076 /* our buffer contains space for ethernet- ip- and udp- headers */
1077 /* calucalate an offset that our ce field is aligned to 4 bytes */
1078 aligned_address=(unsigned long)net->data; /* this is the start of our physical buffer */
1079 aligned_address += (ETHER_HDR_SIZE+IP_HDR_SIZE); /* we need 42 bytes room for headers (14 Ethernet , 20 IPv4, 8 UDP) */
1080 net->align_offset = 4-(aligned_address%4); /* want CE header aligned to 4 Byte boundary */
1081 if(net->align_offset == 4) {
1082 net->align_offset=0;
1085 net->locAddr.sin_family = AF_INET;
1086 net->locAddr.sin_addr = getenv_IPaddr("ipaddr");
1087 net->locAddr.sin_port = EDBG_DOWNLOAD_PORT;
1089 net->srvAddrSend.sin_family = AF_INET;
1090 net->srvAddrSend.sin_port = EDBG_DOWNLOAD_PORT;
1092 net->srvAddrRecv.sin_family = AF_INET;
1093 net->srvAddrRecv.sin_port = 0;
1095 if (host_addr->sin_addr)
1097 /* Use specified host address ... */
1099 net->srvAddrSend.sin_addr = host_addr->sin_addr;
1100 net->srvAddrRecv.sin_addr = host_addr->sin_addr;
1104 /* ... or use default server address */
1106 net->srvAddrSend.sin_addr = getenv_IPaddr("serverip");
1107 net->srvAddrRecv.sin_addr = getenv_IPaddr("serverip");
1110 net->verbose = verbose;
1111 /* Initialize .BIN parser */
1112 ce_init_bin(bin, net->data + CE_DOFFSET + 4);
1118 #ifdef CONFIG_NET_MULTI
1121 if (eth_init(gd->bd) < 0) {
1123 puts("ceconnect: failed to init ethernet !\n");
1129 puts("ceconnect: init ethernet done!\n");
1133 memcpy (NetOurEther, gd->bd->bi_enetaddr, 6);
1134 NetCopyIP(&NetOurIP, &gd->bd->bi_ip_addr);
1135 NetOurGatewayIP = getenv_IPaddr ("gatewayip");
1136 NetOurSubnetMask= getenv_IPaddr ("netmask");
1137 NetServerIP = getenv_IPaddr ("serverip");
1142 int ce_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
1145 int verbose, use_timeout;
1146 int timeout, recv_timeout, ret;
1147 struct sockaddr_in host_ip_addr;
1156 for(i=0;i<argc;i++){
1157 if (strcmp(argv[i+1], "-v") == 0){
1163 for(i=0;i<(argc-1);i++){
1164 if (strcmp(argv[i+1], "-t") == 0){
1166 timeout = simple_strtoul(argv[i+2], NULL, 10);
1171 printf("verbose=%d, use_timeout=%d, timeout=%d\n", verbose, use_timeout, timeout);
1174 // Check host IP address (if specified)
1176 *((unsigned int *)&host_ip_addr) = 0xFFFFFFFF;
1179 // Initialize download link
1181 ce_init_download_link(&g_net, &g_bin, &host_ip_addr, verbose);
1199 printf("CELOAD - Canceled, timeout\n");
1204 /* Try to catch ^C */
1206 puts("try to catch ^C\n");
1210 printf("CELOAD - canceled by user\n");
1216 puts("sending broadcast frame bootme\n");
1219 if (ce_send_bootme(&g_net))
1221 printf("CELOAD - error while sending BOOTME request\n");
1225 printf("net state is: %d\n", NetState);
1230 printf("Waiting for connection, timeout %d sec\n", timeout);
1234 printf("Waiting for connection, enter ^C to abort\n");
1239 // Try to receive frame
1241 if (ce_recv_frame(&g_net, recv_timeout))
1243 // Process received data
1245 ret = ce_process_download(&g_net, &g_bin);
1247 if (ret != CE_PR_MORE)
1252 else if (use_timeout)
1254 timeout -= recv_timeout;
1260 // Try to receive edbg commands from host
1262 ce_init_edbg_link(&g_net);
1266 printf("Waiting for EDBG commands ...\n");
1269 while (ce_recv_frame(&g_net, 3))
1271 ce_process_edbg(&g_net, &g_bin);
1274 // Prepare WinCE image for execution
1276 ce_prepare_run_bin(&g_bin);
1278 // Launch WinCE, if necessary
1280 if (g_net.gotJumpingRequest)
1296 ceconnect, 2, 1, ce_load,
1297 "ceconnect - Set up a connection to the CE host PC over TCP/IP and download the run-time image\n",
1298 "ceconnect [-v] [-t <timeout>]\n"
1299 " -v verbose operation\n"
1300 " -t <timeout> - max wait time (#sec) for the connection\n"