From patchwork Thu Jun 19 12:54:53 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roman Rakus X-Patchwork-Id: 22969 Return-Path: X-Original-To: yaboot-devel@ozlabs.org Delivered-To: yaboot-devel@ozlabs.org Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by ozlabs.org (Postfix) with ESMTP id 7345DDE00D for ; Thu, 19 Jun 2008 22:58:42 +1000 (EST) Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m5JCweVi017494; Thu, 19 Jun 2008 08:58:40 -0400 Received: from pobox.stuttgart.redhat.com (pobox.stuttgart.redhat.com [172.16.2.10]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m5JCwCnC011122; Thu, 19 Jun 2008 08:58:26 -0400 Received: from dhcp-lab-179.englab.brq.redhat.com (dhcp-lab-179.englab.brq.redhat.com [10.34.33.179]) by pobox.stuttgart.redhat.com (8.13.1/8.13.1) with ESMTP id m5JCwCVT006949; Thu, 19 Jun 2008 08:58:12 -0400 Message-ID: <485A571D.40007@redhat.com> Date: Thu, 19 Jun 2008 14:54:53 +0200 From: Roman Rakus User-Agent: Thunderbird 2.0.0.14 (X11/20080501) MIME-Version: 1.0 To: Paul Nasrat Subject: Re: supporting multiple chained initramfs References: <48527B9F.3010900@redhat.com> <4852857D.7030604@redhat.com> <4858F0E1.2050907@redhat.com> <86C001E6-86AE-4DAC-BC84-92421F2B427F@googlemail.com> <48590280.90100@redhat.com> <32750922-CCCE-4272-A05F-62393D1DB5CA@googlemail.com> In-Reply-To: <32750922-CCCE-4272-A05F-62393D1DB5CA@googlemail.com> X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 Cc: yaboot devel X-BeenThere: yaboot-devel@ozlabs.org X-Mailman-Version: 2.1.10 Precedence: list List-Id: Technical and development discussion regarding yaboot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Jun 2008 12:58:44 -0000 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 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(¶ms.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(¶ms.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)