X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=blobdiff_plain;f=second%2Fyaboot.c;h=ec0c0859d71813be46db27937154583b744c6a2a;hp=ac63c462c36d5cd4af3dda15e93714cc8f80e6bb;hb=677037569e92173195efa04244cd4291721d8f20;hpb=6d1b9adfa92da6ad903544b7497f05462ef8a301 diff --git a/second/yaboot.c b/second/yaboot.c index ac63c46..ec0c085 100644 --- a/second/yaboot.c +++ b/second/yaboot.c @@ -76,6 +76,8 @@ #define KERNEL_LINK_ADDR_PPC32 0xC0000000UL #define KERNEL_LINK_ADDR_PPC64 0xC000000000000000ULL +#define INITRD_CHUNKSIZE 0x100000 + typedef struct { union { Elf32_Ehdr elf32hdr; @@ -167,33 +169,23 @@ extern unsigned char linux_logo_blue[]; #define DEFAULT_TIMEOUT -1 -/* Entry, currently called directly by crt0 (bss not inited) */ - -extern char* __bss_start; -extern char* _end; - int yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5) { int result; void* malloc_base = NULL; - unsigned long addr; prom_handle root; - /* OF seems to do it, but I'm not very confident */ - memset(&__bss_start, 0, &_end - &__bss_start); - /* Initialize OF interface */ prom_init ((prom_entry) r5); + prom_print_available(); + /* Allocate some memory for malloc'ator */ - for (addr = MALLOCADDR; addr <= MALLOCADDR * 16 ;addr+=0x100000) { - malloc_base = prom_claim((void *)addr, MALLOCSIZE, 0); - if (malloc_base != (void *)-1) break; - } + malloc_base = prom_claim_chunk_top(MALLOCSIZE, 0); if (malloc_base == (void *)-1) { - prom_printf("Can't claim malloc buffer (%d bytes at 0x%08x)\n", - MALLOCSIZE, MALLOCADDR); + prom_printf("Can't claim malloc buffer of %d bytes\n", + MALLOCSIZE); return -1; } malloc_init(malloc_base, MALLOCSIZE); @@ -215,6 +207,9 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5) else if (prom_getprop(root, "device_type", model, 256 ) > 0 && !strncmp("chrp", model, 4)) _machine = _MACH_chrp; + else if (prom_getprop(root, "compatible", model, 256 ) > 0 && + strstr(model, "ibm,powernv")) + _machine = _MACH_chrp; else { if (prom_getprop(root, "model", model, 256 ) > 0 && !strncmp(model, "IBM", 3)) @@ -613,7 +608,7 @@ void check_password(char *str) prom_printf ("\n"); #ifdef USE_MD5_PASSWORDS if (!strncmp (password, "$1$", 3)) { - if (!check_md5_password(passwdbuff, password)) + if (!check_md5_password((unsigned char*)passwdbuff, (unsigned char*)password)) return; } else if (!strcmp (password, passwdbuff)) @@ -719,9 +714,10 @@ int get_params(struct boot_param_t* params) if (!imagename) { if (bootoncelabel[0] != 0) imagename = bootoncelabel; - else if (bootlastlabel[0] != 0) - imagename = bootlastlabel; - else + else if (bootlastlabel[0] != 0) { + imagename = bootlastlabel; + word_split(&imagename, ¶ms->args); + } else imagename = cfg_get_default(); } if (imagename) @@ -783,7 +779,13 @@ int get_params(struct boot_param_t* params) imagename = cfg_get_default(); /* write the imagename out so it can be reused on reboot if necessary */ - prom_set_options("boot-last-label", imagename, strlen(imagename)); + strcpy(bootlastlabel, imagename); + if (params->args && params->args[0]) { + strcat(bootlastlabel, " "); + strcat(bootlastlabel, params->args); + } + prom_set_options("boot-last-label", bootlastlabel, + strlen(bootlastlabel) + 1); label = 0; defdevice = boot.dev; @@ -985,7 +987,7 @@ int get_params(struct boot_param_t* params) /* check if user seted to use a initrd file from boot console */ if (!definitrd && p != manualinitrd) { - if (manualinitrd[0] != "/" && (prom_get_devtype(defdevice_bak) != FILE_DEVICE_NET)) { + if (manualinitrd[0] != '/' && (prom_get_devtype(defdevice_bak) != FILE_DEVICE_NET)) { strcpy(initrdpath, "/"); strcat(initrdpath, manualinitrd); } else @@ -1013,8 +1015,6 @@ int get_params(struct boot_param_t* params) void yaboot_text_ui(void) { -#define MAX_HEADERS 32 - struct boot_file_t file; int result; static struct boot_param_t params; @@ -1025,6 +1025,7 @@ yaboot_text_ui(void) loadinfo_t loadinfo; void *initrd_more,*initrd_want; unsigned long initrd_read; + unsigned int len = INITRD_CHUNKSIZE; loadinfo.load_loc = 0; @@ -1114,31 +1115,38 @@ yaboot_text_ui(void) } prom_printf("Loading ramdisk...\n"); result = open_file(¶ms.rd, &file); + if (result == FILE_ERR_OK && file.fs->ino_size) { + result = file.fs->ino_size(&file, &len); + } 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); + /* We add a bit to the actual size so the loop below + * doesn't think there is more to load. + */ + len += 0x1000; + + initrd_base = prom_claim_chunk(loadinfo.base+loadinfo.memsize, len, 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); + initrd_size = file.fs->read(&file, len, 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); + while (initrd_read == len ) { /* need to read more? */ + initrd_want = (void *)((unsigned long)initrd_more+len); + initrd_more = prom_claim(initrd_want, len, 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); + initrd_read = file.fs->read(&file, len, initrd_more); DEBUG_F(" block at %p rc=%lu\n",initrd_more,initrd_read); initrd_size += initrd_read; } @@ -1174,6 +1182,8 @@ yaboot_text_ui(void) DEBUG_F("Entering kernel...\n"); + prom_print_available(); + /* call the kernel with our stack. */ kernel_entry(initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0); continue; @@ -1187,7 +1197,7 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo) { int i; Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr); - Elf32_Phdr *p, *ph; + Elf32_Phdr *p, *ph = NULL; int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident); unsigned long loadaddr; @@ -1211,11 +1221,6 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo) loadinfo->entry = e->e_entry; - if (e->e_phnum > MAX_HEADERS) { - prom_printf ("Can only load kernels with one program header\n"); - goto bail; - } - ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum); if (!ph) { prom_printf ("Malloc error\n"); @@ -1325,7 +1330,7 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo) { int i; Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr); - Elf64_Phdr *p, *ph; + Elf64_Phdr *p, *ph = NULL; int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident); unsigned long loadaddr; @@ -1349,11 +1354,6 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo) loadinfo->entry = e->e_entry; - if (e->e_phnum > MAX_HEADERS) { - prom_printf ("Can only load kernels with one program header\n"); - goto bail; - } - ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum); if (!ph) { prom_printf ("Malloc error\n");