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