ppcrcd/yaboot: cfg.c yaboot.c

sparky cvs at pld-linux.org
Sat Oct 8 02:21:30 CEST 2005


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);



More information about the pld-cvs-commit mailing list