From patchwork Wed Jun 18 11:26:25 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roman Rakus X-Patchwork-Id: 22968 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 D76C3DDE0E for ; Wed, 18 Jun 2008 21:29:48 +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 m5IBTkMc005221 for ; Wed, 18 Jun 2008 07:29:46 -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 m5IBTjn3003559 for ; Wed, 18 Jun 2008 07:29:45 -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 m5IBTiGG020316 for ; Wed, 18 Jun 2008 07:29:45 -0400 Message-ID: <4858F0E1.2050907@redhat.com> Date: Wed, 18 Jun 2008 13:26:25 +0200 From: Roman Rakus User-Agent: Thunderbird 2.0.0.14 (X11/20080501) MIME-Version: 1.0 To: yaboot devel Subject: Re: supporting multiple chained initramfs References: <48527B9F.3010900@redhat.com> <4852857D.7030604@redhat.com> In-Reply-To: <4852857D.7030604@redhat.com> X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 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: Wed, 18 Jun 2008 11:29:49 -0000 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 --- 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(¶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)