wince_loader.c

Go to the documentation of this file.
00001 #define LOAD_DEBUG      0
00002 
00003 static int get_x_header(unsigned char *data, unsigned long now);
00004 static void jump_2ep();
00005 static unsigned char ce_signature[] = {'B', '0', '0', '0', 'F', 'F', '\n',};
00006 static char ** ep;
00007 
00008 #define BOOT_ARG_PTR_LOCATION 0x001FFFFC
00009 
00010 typedef struct _BOOT_ARGS{
00011         unsigned char ucVideoMode;
00012         unsigned char ucComPort;
00013         unsigned char ucBaudDivisor;
00014         unsigned char ucPCIConfigType;
00015         
00016         unsigned long dwSig;
00017         #define BOOTARG_SIG 0x544F4F42
00018         unsigned long dwLen;
00019         
00020         unsigned char ucLoaderFlags;
00021         unsigned char ucEshellFlags;
00022         unsigned char ucEdbgAdapterType;
00023         unsigned char ucEdbgIRQ;
00024         
00025         unsigned long dwEdbgBaseAddr;
00026         unsigned long dwEdbgDebugZone;  
00027         unsigned long dwDHCPLeaseTime;
00028         unsigned long dwEdbgFlags;
00029         
00030         unsigned long dwEBootFlag;
00031         unsigned long dwEBootAddr;
00032         unsigned long dwLaunchAddr;
00033         
00034         unsigned long pvFlatFrameBuffer;
00035         unsigned short vesaMode;
00036         unsigned short cxDisplayScreen;
00037         unsigned short cyDisplayScreen;
00038         unsigned short cxPhysicalScreen;
00039         unsigned short cyPhysicalScreen;
00040         unsigned short cbScanLineLength;
00041         unsigned short bppScreen;
00042         
00043         unsigned char RedMaskSize;
00044         unsigned char REdMaskPosition;
00045         unsigned char GreenMaskSize;
00046         unsigned char GreenMaskPosition;
00047         unsigned char BlueMaskSize;
00048         unsigned char BlueMaskPosition;
00049 } BOOT_ARGS;
00050 
00051 BOOT_ARGS BootArgs;
00052 
00053 static struct segment_info{
00054         unsigned long addr;             // Section Address
00055         unsigned long size;             // Section Size
00056         unsigned long checksum;         // Section CheckSum
00057 } X;
00058 
00059 #define PSIZE   (1500)                  //Max Packet Size
00060 #define DSIZE  (PSIZE+12)
00061 static unsigned long dbuffer_available =0;
00062 static unsigned long not_loadin =0;
00063 static unsigned long d_now =0;
00064 
00065 unsigned long entry;
00066 static unsigned long ce_curaddr;
00067 
00068 
00069 static sector_t ce_loader(unsigned char *data, unsigned int len, int eof);
00070 static os_download_t wince_probe(unsigned char *data, unsigned int len)
00071 {
00072         if (strncmp(ce_signature, data, sizeof(ce_signature)) != 0) {
00073                 return 0;
00074         }
00075         printf("(WINCE)");
00076         return ce_loader;
00077 }
00078 
00079 static sector_t ce_loader(unsigned char *data, unsigned int len, int eof)
00080 {
00081         static unsigned char dbuffer[DSIZE];
00082         int this_write = 0;
00083         static int firsttime = 1;
00084 
00085         /*
00086          *      new packet in, we have to 
00087          *      [1] copy data to dbuffer,
00088          *
00089          *      update...
00090          *      [2]  dbuffer_available
00091          */
00092         memcpy( (dbuffer+dbuffer_available), data, len);        //[1]
00093         dbuffer_available += len;       // [2]
00094         len = 0;
00095 
00096         d_now = 0;
00097         
00098 #if 0
00099         printf("dbuffer_available =%ld \n", dbuffer_available);
00100 #endif 
00101         
00102         if (firsttime) 
00103         {
00104                 d_now = sizeof(ce_signature);
00105                 printf("String Physical Address = %lx \n", 
00106                         *(unsigned long *)(dbuffer+d_now));
00107                 
00108                 d_now += sizeof(unsigned long);
00109                 printf("Image Size = %ld [%lx]\n", 
00110                         *(unsigned long *)(dbuffer+d_now), 
00111                         *(unsigned long *)(dbuffer+d_now));
00112                 
00113                 d_now += sizeof(unsigned long);
00114                 dbuffer_available -= d_now;                     
00115                 
00116                 d_now = (unsigned long)get_x_header(dbuffer, d_now);
00117                 firsttime = 0;
00118         }
00119         
00120         if (not_loadin == 0)
00121         {
00122                 d_now = get_x_header(dbuffer, d_now);
00123         }
00124         
00125         while ( not_loadin > 0 )
00126         {
00127                 /* dbuffer do not have enough data to loading, copy all */
00128 #if LOAD_DEBUG
00129                 printf("[0] not_loadin = [%ld], dbuffer_available = [%ld] \n", 
00130                         not_loadin, dbuffer_available);
00131                 printf("[0] d_now = [%ld] \n", d_now);
00132 #endif
00133                 
00134                 if( dbuffer_available <= not_loadin)
00135                 {
00136                         this_write = dbuffer_available ;
00137                         memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write );
00138                         ce_curaddr += this_write;
00139                         not_loadin -= this_write;
00140                         
00141                         /* reset index and available in the dbuffer */
00142                         dbuffer_available = 0;
00143                         d_now = 0;
00144 #if LOAD_DEBUG
00145                         printf("[1] not_loadin = [%ld], dbuffer_available = [%ld] \n", 
00146                                 not_loadin, dbuffer_available);
00147                         printf("[1] d_now = [%ld], this_write = [%d] \n", 
00148                                 d_now, this_write);
00149 #endif
00150                                 
00151                         // get the next packet...
00152                         return (0);
00153                 }
00154                         
00155                 /* dbuffer have more data then loading ... , copy partital.... */
00156                 else
00157                 {
00158                         this_write = not_loadin;
00159                         memcpy(phys_to_virt(ce_curaddr), (dbuffer+d_now), this_write);
00160                         ce_curaddr += this_write;
00161                         not_loadin = 0;
00162                         
00163                         /* reset index and available in the dbuffer */
00164                         dbuffer_available -= this_write;
00165                         d_now += this_write;
00166 #if LOAD_DEBUG
00167                         printf("[2] not_loadin = [%ld], dbuffer_available = [%ld] \n", 
00168                                 not_loadin, dbuffer_available);
00169                         printf("[2] d_now = [%ld], this_write = [%d] \n\n", 
00170                                 d_now, this_write);
00171 #endif
00172                         
00173                         /* dbuffer not empty, proceed processing... */
00174                         
00175                         // don't have enough data to get_x_header..
00176                         if ( dbuffer_available < (sizeof(unsigned long) * 3) )
00177                         {
00178 //                              printf("we don't have enough data remaining to call get_x. \n");
00179                                 memcpy( (dbuffer+0), (dbuffer+d_now), dbuffer_available);
00180                                 return (0);
00181                         }
00182                         else
00183                         {
00184 #if LOAD_DEBUG                          
00185                                 printf("with remaining data to call get_x \n");
00186                                 printf("dbuffer available = %ld , d_now = %ld\n", 
00187                                         dbuffer_available, d_now);
00188 #endif                                  
00189                                 d_now = get_x_header(dbuffer, d_now);
00190                         }
00191                 }
00192         }
00193         return (0);
00194 }
00195 
00196 static int get_x_header(unsigned char *dbuffer, unsigned long now)
00197 {
00198         X.addr = *(unsigned long *)(dbuffer + now);
00199         X.size = *(unsigned long *)(dbuffer + now + sizeof(unsigned long));
00200         X.checksum = *(unsigned long *)(dbuffer + now + sizeof(unsigned long)*2);
00201 
00202         if (X.addr == 0)
00203         {
00204                 entry = X.size;
00205                 done(1);
00206                 printf("Entry Point Address = [%lx] \n", entry);
00207                 jump_2ep();             
00208         }
00209 
00210         if (!prep_segment(X.addr, X.addr + X.size, X.addr + X.size, 0, 0)) {
00211                 longjmp(restart_etherboot, -2);
00212         }
00213 
00214         ce_curaddr = X.addr;
00215         now += sizeof(unsigned long)*3;
00216 
00217         /* re-calculate dbuffer available... */
00218         dbuffer_available -= sizeof(unsigned long)*3;
00219 
00220         /* reset index of this section */
00221         not_loadin = X.size;
00222         
00223 #if 1
00224         printf("\n");
00225         printf("\t Section Address = [%lx] \n", X.addr);
00226         printf("\t Size = %d [%lx]\n", X.size, X.size);
00227         printf("\t Checksum = %ld [%lx]\n", X.checksum, X.checksum);
00228 #endif
00229 #if LOAD_DEBUG
00230         printf("____________________________________________\n");
00231         printf("\t dbuffer_now = %ld \n", now);
00232         printf("\t dbuffer available = %ld \n", dbuffer_available);
00233         printf("\t not_loadin = %ld \n", not_loadin);
00234 #endif
00235 
00236         return now;
00237 }
00238 
00239 static void jump_2ep()
00240 {
00241         BootArgs.ucVideoMode = 1;
00242         BootArgs.ucComPort = 1;
00243         BootArgs.ucBaudDivisor = 1;
00244         BootArgs.ucPCIConfigType = 1;   // do not fill with 0
00245         
00246         BootArgs.dwSig = BOOTARG_SIG;
00247         BootArgs.dwLen = sizeof(BootArgs);
00248         
00249         if(BootArgs.ucVideoMode == 0)
00250         {
00251                 BootArgs.cxDisplayScreen = 640;
00252                 BootArgs.cyDisplayScreen = 480;
00253                 BootArgs.cxPhysicalScreen = 640;
00254                 BootArgs.cyPhysicalScreen = 480;
00255                 BootArgs.bppScreen = 16;
00256                 BootArgs.cbScanLineLength  = 1024;
00257                 BootArgs.pvFlatFrameBuffer = 0x800a0000;        // ollie say 0x98000000
00258         }       
00259         else if(BootArgs.ucVideoMode != 0xFF)
00260         {
00261                 BootArgs.cxDisplayScreen = 0;
00262                 BootArgs.cyDisplayScreen = 0;
00263                 BootArgs.cxPhysicalScreen = 0;
00264                 BootArgs.cyPhysicalScreen = 0;
00265                 BootArgs.bppScreen = 0;
00266                 BootArgs.cbScanLineLength  = 0;
00267                 BootArgs.pvFlatFrameBuffer = 0; 
00268         }
00269 
00270         ep = phys_to_virt(BOOT_ARG_PTR_LOCATION);
00271         *ep= virt_to_phys(&BootArgs);
00272         xstart32(entry);
00273 }

Generated on Tue Apr 6 20:00:49 2010 for gPXE by  doxygen 1.5.7.1