Author: sparky
Date: Sat Oct  8 02:21:23 2005
New Revision: 6432

Modified:
   ppcrcd/yaboot/cfg.c
   ppcrcd/yaboot/yaboot.c
Log:
- hopefully added support for extracting vmlinux and initrd from zImage elf
  at last it compiles, I have no way to test it right now :'-(


Modified: ppcrcd/yaboot/cfg.c
==============================================================================
--- ppcrcd/yaboot/cfg.c (original)
+++ ppcrcd/yaboot/cfg.c Sat Oct  8 02:21:23 2005
@@ -88,6 +88,7 @@
      {cft_strg, "initrd", NULL},
      {cft_flag, "initrd-prompt", NULL},
      {cft_strg, "initrd-size", NULL},
+     {cft_strg, "kernel-size", NULL},
      {cft_flag, "pause-after", NULL},
      {cft_strg, "pause-message", NULL},
      {cft_flag, "novideo", NULL},

Modified: ppcrcd/yaboot/yaboot.c
==============================================================================
--- ppcrcd/yaboot/yaboot.c      (original)
+++ ppcrcd/yaboot/yaboot.c      Sat Oct  8 02:21:23 2005
@@ -174,7 +174,9 @@
 
 static struct first_info *quik_fip = NULL;
 
-unsigned long initrd_size;
+unsigned long initrd_size = 0;
+int kernel_size = 0;
+unsigned long kernel_position = 0;
 
 int
 yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
@@ -247,7 +249,6 @@
      result = yaboot_main();
 
      /* Get rid of malloc pool */
-//     malloc_dispose();
      prom_release(malloc_base, MALLOCSIZE);
      DEBUG_F("Malloc buffer released. Exiting with code %d\n",
             result);
@@ -318,18 +319,13 @@
          prom_perror(result, msgfile.file);
          goto done;
      }
-     /*gunzip_file = file;
-     gunzip_test_header();*/
      opened = 1;
     
-     if ( ( /*compressed_file ?
-            gunzip_read(msg, (2000 - paging * 1000)) :*/
-            file.fs->read(&file, (2000 - paging * 1000), msg) 
-          ) <= 0)
+     if ( file.fs->read(&file, (2000 - paging * 1000), msg) <= 0)
          goto done;
      
      if ( paging && (*(msg + 999) != 0) ) {
-            // file longer than 1000 and paging is 1
+            /* file longer than 1000 and paging is 1 */
             char *last_nl;
             int len = 0;
 
@@ -341,15 +337,10 @@
                     len += last_nl - msg + 1;
                     
                     memset(msg, 0, 1001);
-/*                  if ( compressed_file ) {
-                            gunzip_seek(len);
-                            gunzip_read(msg, 1000);
-                    } else {*/
-                            file.fs->seek(&file, len);
-                            file.fs->read(&file, 1000, msg);
-//                  }
+                    file.fs->seek(&file, len);
+                    file.fs->read(&file, 1000, msg);
 
-                    // wait until key
+                    /* wait until key */
                     while ( prom_nbgetchar() == -1 );
             }
             prom_printf("\r             \r%s", msg);
@@ -517,6 +508,17 @@
          *paramsp = p;
 }
 
+int
+string_to_int(char *str) {
+       int number = 0;
+       int len, i;
+       len = strlen(str);
+       for (i=0; i<len; i++) 
+               if ( str[i] <= '9' && str[i] >= '0' )
+                       number = number * 10 + str[i] - '0';
+       return number;
+}
+
 char *
 make_params(char *label, char *params)
 {
@@ -562,17 +564,18 @@
      }
      p = cfg_get_strg(label, "initrd-size");
      if (p) {
-         int len, i;
-          initrd_size = 0;
-         len = strlen(p);
-         for (i=0; i<len; i++)
-                 initrd_size = initrd_size * 10 + p[i] - '0';
+         initrd_size = string_to_int(p);
          
          strcpy (q, "ramdisk_size=");
          strcpy (q + 13, p);
          q = strchr (q, 0);
          *q++ = ' ';
      }
+     p = cfg_get_strg(label, "kernel-size");
+     if (p) {
+         kernel_size = string_to_int(p);
+     }
+    
      if (cfg_get_flag(label, "novideo")) {
          strcpy (q, "video=ofonly");
          q = strchr (q, 0);
@@ -762,7 +765,7 @@
                         check_password ("This image is restricted.");
               }
               params->args = make_params(label, params->args);
-         } else {  // no *p
+         } else {  /* no *p */
                  p = cfg_get_strg(imagename, "text");
                  if (p && *p) {
                          if(!defdevice) defdevice = boot.dev;
@@ -884,6 +887,8 @@
          initrd_base = 0;
          sysmap_base = 0;
          sysmap_size = 0;
+         kernel_size = 0;
+         kernel_position = 0;
        
          if (get_params(&params))
               return;
@@ -893,6 +898,13 @@
          prom_printf("Please wait, loading kernel...\n");
 
          memset(&file, 0, sizeof(file));
+         if ( ( loc = strchr(params.kernel.file, '@')) != NULL ) {
+                 *loc = '\0';
+                 kernel_position = string_to_int( ++loc);
+                 prom_printf("kernel at: %d, uncompressed size: %d\n", 
(int)kernel_position, (int)kernel_size);
+         }
+         loc = NULL;
+         
 
          if (strlen(boot.file) && !strcmp(boot.file,"\\\\") && 
params.kernel.file[0] != '/'
              && params.kernel.file[0] != '\\') {
@@ -912,8 +924,10 @@
               prom_perror(result, params.kernel.file);
               goto next;
          }
-         gunzip_file = file;
-         gunzip_test_header();
+         if ( kernel_position == 0 ) {
+                 gunzip_file = file;
+                 gunzip_test_header();
+         }
 
          /* Read the Elf e_ident, e_type and e_machine fields to
           * determine Elf file type
@@ -1021,34 +1035,53 @@
               prom_printf("Loading ramdisk...");
 
               if ( initrd_size ) {
-                      /* probably multi-file initrd */
-                      char *(part[16]), *sep;
-                      int parts=0, i;
+                      char *sep;
+                      if ( (sep = strchr(params.rd.file, '@')) != NULL ) {
+                               /* initrd is an elf part */
+                               unsigned int initrd_position=0;
+                               *sep = '\0';
+                               initrd_position = string_to_int( ++sep);
+                               prom_printf("initrd position: %d, size: %d\n", 
(int)initrd_position, (int)initrd_size);
+                               
+                               initrd_base = 
prom_claim(loadinfo.base+loadinfo.memsize, initrd_size, 0);
+                               result = open_file(&params.rd, &file);
+                               if (result != FILE_ERR_OK) {
+                                       prom_printf("%s:%d,", params.rd.dev, 
params.rd.part);
+                                       prom_perror(result, params.rd.file);
+                               }
+                               file.fs->seek(&file, initrd_position);
+                               initrd_read = file.fs->read(&file, initrd_size, 
initrd_base);
+                               file.fs->close(&file);
+                      } else {
+                              /* probably multi-file initrd */
+                              char *(part[16]);
+                              int parts=0, i;
                       
-                      initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, 
initrd_size, 0);
-                      prom_printf("size: %d\n", (int)initrd_size);
+                              initrd_base = 
prom_claim(loadinfo.base+loadinfo.memsize, initrd_size, 0);
+                              prom_printf("size: %d\n", (int)initrd_size);
                       
-                      // &params.rd - initrd path
-                      part[0] = strdup(params.rd.file);
-                      while (  (sep = strchr(part[parts++], '|' ))  ) {
-                              *sep = '\0';
-                              part[parts] = sep + 1;
+                              /* &params.rd .file- initrd path */
+                              part[0] = strdup(params.rd.file);
+                              while (  (sep = strchr(part[parts++], '|' ))  ) {
+                                      *sep = '\0';
+                                      part[parts] = ++sep;
+                              }
+                              initrd_more = initrd_base;
+                              for ( i=0; i<parts; i++ ) {
+                                      strcpy(params.rd.file, part[i]);
+                                      result = open_file(&params.rd, &file);
+                                      if (result != FILE_ERR_OK) {
+                                           prom_printf("%s:%d,", 
params.rd.dev, params.rd.part);
+                                           prom_perror(result, params.rd.file);
+                                      }
+#define        INITRD_MAX 0xF00000
+                                      initrd_read = file.fs->read(&file, 
INITRD_MAX, initrd_more);
+                                      initrd_more += initrd_read;
+                                      prom_printf("read: %s\n", 
params.rd.file);
+                                      file.fs->close(&file);
+                              }
+                              free(part[0]);
                       }
-                      initrd_more = initrd_base;
-                      for ( i=0; i<parts; i++ ) {
-                              strcpy(params.rd.file, part[i]);
-                              result = open_file(&params.rd, &file);
-                              if (result != FILE_ERR_OK) {
-                                   prom_printf("%s:%d,", params.rd.dev, 
params.rd.part);
-                                   prom_perror(result, params.rd.file);
-                              }
-#define INITRD_MAX 0xF00000
-                              initrd_read = file.fs->read(&file, INITRD_MAX, 
initrd_more);
-                              initrd_more += initrd_read;
-                              prom_printf("read: %s\n", params.rd.file);
-                              file.fs->close(&file);
-                      }
-                      free(part[0]);
               } else {
               /* normal behaviour */
               result = open_file(&params.rd, &file);
@@ -1271,6 +1304,11 @@
           flat_vmlinux = 0;
           loadaddr = e->e_entry;
      }
+     if ( kernel_position > 0 ) {
+            flat_vmlinux = 1;
+            loadaddr = KERNELADDR;
+            loadinfo->memsize = kernel_size;
+     }
 
      /* On some systems, loadaddr may already be claimed, so try some
       * other nearby addresses before giving up.
@@ -1289,33 +1327,54 @@
      DEBUG_F("    wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
             loadaddr, loadinfo->memsize);
 
-     /* Load the program segments... */
-     p = ph;
-     for (i = 0; i < e->e_phnum; ++i, ++p) {
-         unsigned long offset;
-         if (p->p_type != PT_LOAD || p->p_offset == 0)
-              continue;
-
-         /* Now, we skip to the image itself */
-         if ( ( compressed_file ?
-                 gunzip_seek(p->p_offset) :
-                 (*(file->fs->seek))(file, p->p_offset)
-               ) != FILE_ERR_OK)
-         {
-              prom_printf ("Seek error\n");
-              prom_release(loadinfo->base, loadinfo->memsize);
-              return 0;
-         }
-         offset = p->p_vaddr - loadinfo->load_loc;
-         if ( ( compressed_file ?
-                 gunzip_read(loadinfo->base+offset, p->p_filesz) :
-                 (*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) 
-               ) != p->p_filesz )
-          {
-              prom_printf ("Read failed\n");
-              prom_release(loadinfo->base, loadinfo->memsize);
-              return 0;
-         }
+     if ( kernel_position == 0 ) {
+       /* Load the program segments... */
+       p = ph;
+       for (i = 0; i < e->e_phnum; ++i, ++p) {
+               unsigned long offset;
+               if (p->p_type != PT_LOAD || p->p_offset == 0)
+                       continue;
+
+               /* Now, we skip to the image itself */
+               if ( ( compressed_file ?
+                       gunzip_seek(p->p_offset) :
+                       (*(file->fs->seek))(file, p->p_offset)
+                       ) != FILE_ERR_OK)
+               {
+                       prom_printf ("Seek error\n");
+                       prom_release(loadinfo->base, loadinfo->memsize);
+                       return 0;
+               }
+               offset = p->p_vaddr - loadinfo->load_loc;
+               if ( ( compressed_file ?
+                       gunzip_read(loadinfo->base+offset, p->p_filesz) :
+                       (*(file->fs->read))(file, p->p_filesz, 
loadinfo->base+offset) 
+                       ) != p->p_filesz )
+               {
+                       prom_printf ("Read failed\n");
+                       prom_release(loadinfo->base, loadinfo->memsize);
+                       return 0;
+               }
+       }
+     } else {
+       /* load and uncompress vmlinux binary */
+       if ( (*(file->fs->seek))(file, kernel_position) != FILE_ERR_OK) {
+               prom_printf ("Seek error\n");
+               prom_release(loadinfo->base, loadinfo->memsize);
+               return 0;
+       }
+       gunzip_file = *file;
+       gunzip_test_header();
+       if ( !compressed_file ) {
+               prom_printf ("Error: not compressed data at vmlinux 
position\n");
+               prom_release(loadinfo->base, loadinfo->memsize);
+               return 0;
+       }
+       if ( gunzip_read(loadinfo->base, kernel_size) != kernel_size ) {
+               prom_printf ("Gunzip read failed\n");
+               prom_release(loadinfo->base, loadinfo->memsize);
+               return 0;
+       }       
      }
 
      free(ph);
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to