| #define LOAD_DEBUG 0 |
| |
| static int get_x_header(unsigned char *data, unsigned long now); |
| static void jump_2ep(); |
| static unsigned char ce_signature[] = {'B', '0', '0', '0', 'F', 'F', '\n',}; |
| static char ** ep; |
| |
| #define BOOT_ARG_PTR_LOCATION 0x001FFFFC |
| |
| typedef struct _BOOT_ARGS{ |
| unsigned char ucVideoMode; |
| unsigned char ucComPort; |
| unsigned char ucBaudDivisor; |
| unsigned char ucPCIConfigType; |
| |
| unsigned long dwSig; |
| #define BOOTARG_SIG 0x544F4F42 |
| unsigned long dwLen; |
| |
| unsigned char ucLoaderFlags; |
| unsigned char ucEshellFlags; |
| unsigned char ucEdbgAdapterType; |
| unsigned char ucEdbgIRQ; |
| |
| unsigned long dwEdbgBaseAddr; |
| unsigned long dwEdbgDebugZone; |
| unsigned long dwDHCPLeaseTime; |
| unsigned long dwEdbgFlags; |
| |
| unsigned long dwEBootFlag; |
| unsigned long dwEBootAddr; |
| unsigned long dwLaunchAddr; |
| |
| unsigned long pvFlatFrameBuffer; |
| unsigned short vesaMode; |
| unsigned short cxDisplayScreen; |
| unsigned short cyDisplayScreen; |
| unsigned short cxPhysicalScreen; |
| unsigned short cyPhysicalScreen; |
| unsigned short cbScanLineLength; |
| unsigned short bppScreen; |
| |
| unsigned char RedMaskSize; |
| unsigned char REdMaskPosition; |
| unsigned char GreenMaskSize; |
| unsigned char GreenMaskPosition; |
| unsigned char BlueMaskSize; |
| unsigned char BlueMaskPosition; |
| } BOOT_ARGS; |
| |
| BOOT_ARGS BootArgs; |
| |
| static struct segment_info{ |
| unsigned long addr; // Section Address |
| unsigned long size; // Section Size |
| unsigned long checksum; // Section CheckSum |
| } X; |
| |
| #define PSIZE (1500) //Max Packet Size |
| #define DSIZE (PSIZE+12) |
| static unsigned long dbuffer_available =0; |
| static unsigned long not_loadin =0; |
| static unsigned long d_now =0; |
| |
| unsigned long entry; |
| static unsigned long ce_curaddr; |
| |
| |
| static sector_t ce_loader(unsigned char *data, unsigned int len, int eof); |
| static os_download_t wince_probe(unsigned char *data, unsigned int len) |
| { |
| if (strncmp(ce_signature, data, sizeof(ce_signature)) != 0) { |
| return 0; |
| } |
| printf("(WINCE)"); |
| return ce_loader; |
| } |
| |
| static sector_t ce_loader(unsigned char *data, unsigned int len, int eof) |
| { |
| static unsigned char dbuffer[DSIZE]; |
| int this_write = 0; |
| static int firsttime = 1; |
| |
| /* |
| * new packet in, we have to |
| * [1] copy data to dbuffer, |
| * |
| * update... |
| * [2] dbuffer_available |
| */ |
| memcpy( (dbuffer+dbuffer_available), data, len); //[1] |
| dbuffer_available += len; // [2] |
| len = 0; |
| |
| d_now = 0; |
| |
| #if 0 |
| printf("dbuffer_available =%ld \n", dbuffer_available); |
| #endif |
| |
| if (firsttime) |
| { |
| d_now = sizeof(ce_signature); |
| printf("String Physical Address = %lx \n", |
| *(unsigned long *)(dbuffer+d_now)); |
| |
| d_now += sizeof(unsigned long); |
| printf("Image Size = %ld [%lx]\n", |
| *(unsigned long *)(dbuffer+d_now), |
| *(unsigned long *)(dbuffer+d_now)); |
| |
| d_now += sizeof(unsigned long); |
| dbuffer_available -= d_now; |
| |
| d_now = (unsigned long)get_x_header(dbuffer, d_now); |
| firsttime = 0; |
| } |
| |
| if (not_loadin == 0) |
| { |
| d_now = get_x_header(dbuffer, d_now); |
| } |
| |
| while ( not_loadin > 0 ) |
| { |
| /* dbuffer do not have enough data to loading, copy all */ |
| #if LOAD_DEBUG |
| printf("[0] not_loadin = [%ld], dbuffer_available = [%ld] \n", |
| not_loadin, dbuffer_available); |
| printf("[0] d_now = [%ld] \n", d_now); |
| #endif |
| |
| if( dbuffer_available <= not_loadin) |
| { |
| this_write = dbuffer_available ; |
| memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write ); |
| ce_curaddr += this_write; |
| not_loadin -= this_write; |
| |
| /* reset index and available in the dbuffer */ |
| dbuffer_available = 0; |
| d_now = 0; |
| #if LOAD_DEBUG |
| printf("[1] not_loadin = [%ld], dbuffer_available = [%ld] \n", |
| not_loadin, dbuffer_available); |
| printf("[1] d_now = [%ld], this_write = [%d] \n", |
| d_now, this_write); |
| #endif |
| |
| // get the next packet... |
| return (0); |
| } |
| |
| /* dbuffer have more data then loading ... , copy partital.... */ |
| else |
| { |
| this_write = not_loadin; |
| memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write); |
| ce_curaddr += this_write; |
| not_loadin = 0; |
| |
| /* reset index and available in the dbuffer */ |
| dbuffer_available -= this_write; |
| d_now += this_write; |
| #if LOAD_DEBUG |
| printf("[2] not_loadin = [%ld], dbuffer_available = [%ld] \n", |
| not_loadin, dbuffer_available); |
| printf("[2] d_now = [%ld], this_write = [%d] \n\n", |
| d_now, this_write); |
| #endif |
| |
| /* dbuffer not empty, proceed processing... */ |
| |
| // don't have enough data to get_x_header.. |
| if ( dbuffer_available < (sizeof(unsigned long) * 3) ) |
| { |
| // printf("we don't have enough data remaining to call get_x. \n"); |
| memcpy( (dbuffer+0), (dbuffer+d_now), dbuffer_available); |
| return (0); |
| } |
| else |
| { |
| #if LOAD_DEBUG |
| printf("with remaining data to call get_x \n"); |
| printf("dbuffer available = %ld , d_now = %ld\n", |
| dbuffer_available, d_now); |
| #endif |
| d_now = get_x_header(dbuffer, d_now); |
| } |
| } |
| } |
| return (0); |
| } |
| |
| static int get_x_header(unsigned char *dbuffer, unsigned long now) |
| { |
| X.addr = *(unsigned long *)(dbuffer + now); |
| X.size = *(unsigned long *)(dbuffer + now + sizeof(unsigned long)); |
| X.checksum = *(unsigned long *)(dbuffer + now + sizeof(unsigned long)*2); |
| |
| if (X.addr == 0) |
| { |
| entry = X.size; |
| done(1); |
| printf("Entry Point Address = [%lx] \n", entry); |
| jump_2ep(); |
| } |
| |
| if (!prep_segment(X.addr, X.addr + X.size, X.addr + X.size, 0, 0)) { |
| longjmp(restart_etherboot, -2); |
| } |
| |
| ce_curaddr = X.addr; |
| now += sizeof(unsigned long)*3; |
| |
| /* re-calculate dbuffer available... */ |
| dbuffer_available -= sizeof(unsigned long)*3; |
| |
| /* reset index of this section */ |
| not_loadin = X.size; |
| |
| #if 1 |
| printf("\n"); |
| printf("\t Section Address = [%lx] \n", X.addr); |
| printf("\t Size = %d [%lx]\n", X.size, X.size); |
| printf("\t Checksum = %ld [%lx]\n", X.checksum, X.checksum); |
| #endif |
| #if LOAD_DEBUG |
| printf("____________________________________________\n"); |
| printf("\t dbuffer_now = %ld \n", now); |
| printf("\t dbuffer available = %ld \n", dbuffer_available); |
| printf("\t not_loadin = %ld \n", not_loadin); |
| #endif |
| |
| return now; |
| } |
| |
| static void jump_2ep() |
| { |
| BootArgs.ucVideoMode = 1; |
| BootArgs.ucComPort = 1; |
| BootArgs.ucBaudDivisor = 1; |
| BootArgs.ucPCIConfigType = 1; // do not fill with 0 |
| |
| BootArgs.dwSig = BOOTARG_SIG; |
| BootArgs.dwLen = sizeof(BootArgs); |
| |
| if(BootArgs.ucVideoMode == 0) |
| { |
| BootArgs.cxDisplayScreen = 640; |
| BootArgs.cyDisplayScreen = 480; |
| BootArgs.cxPhysicalScreen = 640; |
| BootArgs.cyPhysicalScreen = 480; |
| BootArgs.bppScreen = 16; |
| BootArgs.cbScanLineLength = 1024; |
| BootArgs.pvFlatFrameBuffer = 0x800a0000; // ollie say 0x98000000 |
| } |
| else if(BootArgs.ucVideoMode != 0xFF) |
| { |
| BootArgs.cxDisplayScreen = 0; |
| BootArgs.cyDisplayScreen = 0; |
| BootArgs.cxPhysicalScreen = 0; |
| BootArgs.cyPhysicalScreen = 0; |
| BootArgs.bppScreen = 0; |
| BootArgs.cbScanLineLength = 0; |
| BootArgs.pvFlatFrameBuffer = 0; |
| } |
| |
| ep = phys_to_virt(BOOT_ARG_PTR_LOCATION); |
| *ep= virt_to_phys(&BootArgs); |
| xstart32(entry); |
| } |