Patchwork supporting multiple chained initramfs

login
register
mail settings
Submitter Roman Rakus
Date June 19, 2008, 12:54 p.m.
Message ID <485A571D.40007@redhat.com>
Download mbox | patch
Permalink /patch/22969/
State Under Review
Headers show

Comments

Roman Rakus - June 19, 2008, 12:54 p.m.
Paul Nasrat wrote:
>
> 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
yep
Roman Rakus - June 10, 2009, 11:02 a.m.
On 06/19/2008 02:54 PM, Roman Rakus wrote:
> Paul Nasrat wrote:
>>
>> 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
> yep
> ------------------------------------------------------------------------
>
> _______________________________________________
> Yaboot-devel mailing list
> Yaboot-devel@ozlabs.org
> https://ozlabs.org/mailman/listinfo/yaboot-devel
>    
As there is new maintainer,

Tony Breeds, will this be included?
RR
Tony Breeds - June 11, 2009, 6:43 a.m.
On Wed, Jun 10, 2009 at 01:02:32PM +0200, Roman Rakus wrote:
    
> As there is new maintainer,
>
> Tony Breeds, will this be included?

Looking at the patch it looks likely and a cool feature to have :)

I'll start a branch for .16 RSN

Thanks Roman

Yours Tony

Patch

diff -up yaboot-1.3.14/man/yaboot.conf.5.multird yaboot-1.3.14/man/yaboot.conf.5
--- yaboot-1.3.14/man/yaboot.conf.5.multird	2008-06-19 13:55:54.000000000 +0200
+++ yaboot-1.3.14/man/yaboot.conf.5	2008-06-19 14:07:24.000000000 +0200
@@ -525,16 +525,10 @@  Example:
 yaboot will not decompress the initial ramdisk, the Linux kernel will do that.
 If the initial ramdisk does not fit on one media (usually floppy), you can
 split it into several pieces and separate the filenames in the list by
-\fI|\fP characters. In this case, you have to provide a non-zero
-\fIinitrd-size\fP and, if the images reside on different medias,
-\fIinitrd-prompt\fP as well.
-Example (on the first floppy is initrd1.img, on the second initrd2.img
-always in the root directory and the sum of both image sizes is 1700000
-bytes):
+\fI;\fP characters.
+Example:
 
-  initrd=/initrd1.img|/initrd2.img
-  initrd-size=1700000
-  initrd-prompt
+  initrd="/initrd1.img;/initrd2.img"
 .TP
 .BI "initrd-size=" size
 When more than one initial ramdisk part is specified in the \fIinitrd\fP
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-19 13:55:55.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)