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