Patchwork supporting multiple chained initramfs

login
register
mail settings
Submitter Roman Rakus
Date June 18, 2008, 11:26 a.m.
Message ID <4858F0E1.2050907@redhat.com>
Download mbox | patch
Permalink /patch/22968/
State Superseded
Headers show

Comments

Roman Rakus - June 18, 2008, 11:26 a.m.
Here is my proposed patch. I have tested it and it rocks :)
Paul Nasrat - June 18, 2008, 12:08 p.m.
On 18 Jun 2008, at 12:26, Roman Rakus wrote:

> Here is my proposed patch. I have tested it and it rocks :)
> diff -up yaboot-1.3.14/second/yaboot.c.multird yaboot-1.3.14/second/ 
> yaboot.c

Thanks, it applies cleanly to head, I'll have to test on the weekend.

Can you give a list of what you tested on (JS20, JS21, G5, etc) with  
what size ramdisks and kernels.

Paul
Roman Rakus - June 18, 2008, 12:41 p.m.
Paul Nasrat wrote:
>
> On 18 Jun 2008, at 12:26, Roman Rakus wrote:
>
>> Here is my proposed patch. I have tested it and it rocks :)
>> diff -up yaboot-1.3.14/second/yaboot.c.multird 
>> yaboot-1.3.14/second/yaboot.c
>
> Thanks, it applies cleanly to head, I'll have to test on the weekend.
>
> Can you give a list of what you tested on (JS20, JS21, G5, etc) with 
> what size ramdisks and kernels.
>
> Paul
I have just tested it on iBook G4. Fedora 9 kernel 2.6.25.6-55 and 
2.6.25.4-30. First initrd size 3.8MB, second 385 bytes. Just for 
text-out test.
Forgot to say how looks yaboot.conf: initrds are separated by ';' char :)
Paul Nasrat - June 18, 2008, 6:15 p.m.
On 18 Jun 2008, at 13:41, Roman Rakus wrote:

> Paul Nasrat wrote:
>>
>> On 18 Jun 2008, at 12:26, Roman Rakus wrote:
>>
>>> Here is my proposed patch. I have tested it and it rocks :)
>>> diff -up yaboot-1.3.14/second/yaboot.c.multird yaboot-1.3.14/ 
>>> second/yaboot.c
>>
>> Thanks, it applies cleanly to head, I'll have to test on the weekend.
>>
>> Can you give a list of what you tested on (JS20, JS21, G5, etc)  
>> with what size ramdisks and kernels.
>>
>> Paul
> I have just tested it on iBook G4. Fedora 9 kernel 2.6.25.6-55 and  
> 2.6.25.4-30. First initrd size 3.8MB, second 385 bytes. Just for  
> text-out test.
> Forgot to say how looks yaboot.conf: initrds are separated by ';'  
> char :)

Can you update the man page too and send a new patch.

Paul

Patch

diff -up yaboot-1.3.14/second/yaboot.c.multird yaboot-1.3.14/second/yaboot.c
--- yaboot-1.3.14/second/yaboot.c.multird	2008-06-17 12:35:29.000000000 +0200
+++ yaboot-1.3.14/second/yaboot.c	2008-06-18 12:22:29.000000000 +0200
@@ -58,6 +58,9 @@ 
 #define CONFIG_FILE_NAME	"yaboot.conf"
 #define CONFIG_FILE_MAX		0x8000		/* 32k */
 
+#define INITRD_FILE_SEPARATOR   ';'
+#define INITRD_CHUNKSIZE        0x100000
+
 #ifdef USE_MD5_PASSWORDS
 #include "md5.h"
 #endif /* USE_MD5_PASSWORDS */
@@ -107,6 +110,7 @@  static int	is_elf64(loadinfo_t *loadinfo
 static int      load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo);
 static int      load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo);
 static void     setup_display(void);
+unsigned long   load_ramdisks(struct boot_fspec_t *rd, const void *initrd_base);
 
 /* Locals & globals */
 
@@ -1050,8 +1054,6 @@  yaboot_text_ui(void)
      struct bi_record*	birec;
      char*               loc=NULL;
      loadinfo_t          loadinfo;
-     void                *initrd_more,*initrd_want;
-     unsigned long       initrd_read;
 
      loadinfo.load_loc = 0;
 
@@ -1190,49 +1192,16 @@  yaboot_text_ui(void)
 		    free(params.rd.file);
 		    params.rd.file=loc;
 	       }
-	       prom_printf("Loading ramdisk...\n");
-	       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);
-	       }
-	       else {
-#define INITRD_CHUNKSIZE 0x100000
-		    initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0);
-		    if (initrd_base == (void *)-1) {
-			 prom_printf("Claim failed for initrd memory\n");
-			 initrd_base = 0;
-		    } else {
-			 initrd_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_base);
-			 if (initrd_size == 0)
-			      initrd_base = 0;
-			 initrd_read = initrd_size;
-			 initrd_more = initrd_base;
-			 while (initrd_read == INITRD_CHUNKSIZE ) { /* need to read more? */
-			      initrd_want = (void *)((unsigned long)initrd_more+INITRD_CHUNKSIZE);
-			      initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0);
-			      if (initrd_more != initrd_want) {
-				   prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more);
-				   prom_pause();
-				   break;
-			      }
-			      initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
-			      DEBUG_F("  block at %p rc=%lu\n",initrd_more,initrd_read);
-			      initrd_size += initrd_read;
-			 }
-		    }
-		    file.fs->close(&file);
-		    memset(&file, 0, sizeof(file));
-	       }
-	       if (initrd_base)
-		    prom_printf("ramdisk loaded at %p, size: %lu Kbytes\n",
-				initrd_base, initrd_size >> 10);
-	       else {
-		    prom_printf("ramdisk load failed !\n");
-		    prom_pause();
-	       }
+               initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0);
+               if (initrd_base == (void *)-1) {
+                    prom_printf("Claim failed for initrd memory\n");
+                    initrd_base = 0;
+               }
+               else {
+	            prom_printf("Loading ramdisks...\n");
+                    initrd_size = load_ramdisks(&params.rd, initrd_base);
+               }
 	  }
-
 	  DEBUG_F("setting kernel args to: %s\n", params.args);
 	  prom_setargs(params.args);
 	  DEBUG_F("flushing icache...");
@@ -1686,6 +1655,94 @@  setup_display(void)
 
 #endif /* CONFIG_SET_COLORMAP */
 }
+unsigned long
+load_ramdisks(struct boot_fspec_t *rd, const void *initrd_base)
+{
+     void *initrd_more = 0, *initrd_want = 0;
+     
+     char          *separator               = NULL;
+     int           index                    = 0;
+     char          buff[1024]               = "";
+     char          *ptr                     = buff;
+     unsigned long initrd_read              = 0;
+     unsigned long initrd_file_size         = 0;
+     unsigned long initrd_size              = 0;
+     int           result                   = 0;
+     
+
+     struct boot_file_t file;
+     memset(&file, 0, sizeof(file));
+
+     
+     initrd_more = initrd_base;
+
+     strncpy(buff, rd->file, sizeof(buff));
+
+     do {
+          /* get next separator position */
+          separator = strchr(ptr, INITRD_FILE_SEPARATOR);
+          if(separator) {
+               /* Get file name before separator */
+               index = separator - ptr;
+               rd->file = strncpy(rd->file, ptr, index);
+               rd->file[index] = '\0';
+               /* Move to next filename after separator*/
+               ptr = separator + 1;
+          } else { /* last ramdisk */
+               rd->file = strncpy(rd->file, ptr, sizeof(rd->file));
+          }
+
+          /* try to open it */
+          result = open_file(rd, &file);
+          if(result != FILE_ERR_OK) {
+               prom_printf("%s:%d,", rd->dev, rd->part);
+               prom_perror(result, rd->file);
+          } else {
+               initrd_file_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
+               DEBUG_F("  block at %p rc=%lu\n",initrd_more,initrd_file_size);
+               if (initrd_file_size == 0)
+                    initrd_more = 0;
+               initrd_read = initrd_file_size;
+               while (initrd_read == INITRD_CHUNKSIZE) { /* need to read more? */
+                    initrd_want = (void *)((unsigned long)initrd_more + INITRD_CHUNKSIZE);
+                    initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0);
+                    if (initrd_more != initrd_want) {
+                         prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more);
+                         prom_pause();
+                         break;
+                    }
+                    initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
+                    DEBUG_F("  block at %p rc=%lu\n",initrd_more,initrd_read);
+                    initrd_file_size += initrd_read;
+               }
+               if (initrd_more) {
+                    prom_printf("ramdisk loaded at %p, size: %lu Kbytes\n",
+			initrd_base, initrd_file_size >> 10);
+                    initrd_size += initrd_file_size;
+                    if(separator) { /* if more files, free unused memory */
+                         initrd_more += initrd_read;
+                         prom_release(initrd_more, INITRD_CHUNKSIZE - initrd_read);
+                    }
+               } else {
+                    prom_printf("ramdisk load failed !\n");
+                    prom_pause();
+                    break;
+               }
+	       file.fs->close(&file);
+	       memset(&file, 0, sizeof(file));
+          }
+          DEBUG_F ("Ramdisk %s loaded\n",rd->file);
+     } while (separator);
+
+     if (initrd_more) {
+          prom_printf("ramdisks loaded at %p, size: %lu Kbytes\n",
+               initrd_base, initrd_size >> 10);
+     } else {
+          prom_printf("ramdisks load failed !\n");
+          prom_pause();
+     }
+     return initrd_size;
+}
 
 int
 yaboot_main(void)