X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=blobdiff_plain;f=second%2Fyaboot.c;h=6eabb427dc20863f73b0d1bfa1d38d9eba89a070;hp=4bb67e29337b568cd173d7ec1fbb9bca84ead38f;hb=6f4d7a802c09ee20526db5eeba7357d52444a42c;hpb=8d5a42062f8b88eaea91434e53973ce9f55589d9 diff --git a/second/yaboot.c b/second/yaboot.c index 4bb67e2..6eabb42 100644 --- a/second/yaboot.c +++ b/second/yaboot.c @@ -12,7 +12,7 @@ Because this program is derived from the corresponding file in the silo-0.64 distribution, it is also -sys + Copyright (C) 1996 Pete A. Zaitcev 1996 Maurizio Plaza 1996 David S. Miller @@ -46,6 +46,7 @@ sys #include "yaboot.h" #include "linux/elf.h" #include "bootinfo.h" +#include "debug.h" #define CONFIG_FILE_NAME "yaboot.conf" #define CONFIG_FILE_MAX 0x8000 /* 32k */ @@ -67,16 +68,16 @@ sys #define KERNEL_LINK_ADDR_PPC64 0xC000000000000000ULL typedef struct { - union { - Elf32_Ehdr elf32hdr; - Elf64_Ehdr elf64hdr; - } elf; - void* base; - unsigned long memsize; - unsigned long filesize; - unsigned long offset; - unsigned long load_loc; - unsigned long entry; + union { + Elf32_Ehdr elf32hdr; + Elf64_Ehdr elf64hdr; + } elf; + void* base; + unsigned long memsize; + unsigned long filesize; + unsigned long offset; + unsigned long load_loc; + unsigned long entry; } loadinfo_t; typedef void (*kernel_entry_t)( void *, @@ -104,9 +105,7 @@ static void setup_display(void); int useconf = 0; char bootdevice[1024]; -//char *bootpath = NULL; char *password = NULL; -//int bootpartition = -1; struct boot_fspec_t boot; int _machine = _MACH_Pmac; @@ -114,27 +113,27 @@ int _machine = _MACH_Pmac; /* Color values for text ui */ static struct ansi_color_t { - char* name; - int index; - int value; + char* name; + int index; + int value; } ansi_color_table[] = { - { "black", 2, 30 }, - { "blue", 0, 31 }, - { "green", 0, 32 }, - { "cyan", 0, 33 }, - { "red", 0, 34 }, - { "purple", 0, 35 }, - { "brown", 0, 36 }, - { "light-gray", 0, 37 }, - { "dark-gray", 1, 30 }, - { "light-blue", 1, 31 }, - { "light-green", 1, 32 }, - { "light-cyan", 1, 33 }, - { "light-red", 1, 34 }, - { "light-purple", 1, 35 }, - { "yellow", 1, 36 }, - { "white", 1, 37 }, - { NULL, 0, 0 }, + { "black", 2, 30 }, + { "blue", 0, 31 }, + { "green", 0, 32 }, + { "cyan", 0, 33 }, + { "red", 0, 34 }, + { "purple", 0, 35 }, + { "brown", 0, 36 }, + { "light-gray", 0, 37 }, + { "dark-gray", 1, 30 }, + { "light-blue", 1, 31 }, + { "light-green", 1, 32 }, + { "light-cyan", 1, 33 }, + { "light-red", 1, 34 }, + { "light-purple", 1, 35 }, + { "yellow", 1, 36 }, + { "white", 1, 37 }, + { NULL, 0, 0 }, }; /* Default colors for text ui */ @@ -167,75 +166,75 @@ static struct first_info *quik_fip = NULL; int yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5) { - int result; - void* malloc_base = NULL; - prom_handle root; + int result; + void* malloc_base = NULL; + prom_handle root; - /* OF seems to do it, but I'm not very confident */ - memset(&__bss_start, 0, &_end - &__bss_start); + /* OF seems to do it, but I'm not very confident */ + memset(&__bss_start, 0, &_end - &__bss_start); - /* Check for quik first stage bootloader (but I don't think we are - * compatible with it anyway, I'll look into backporting to older OF - * versions later - */ - if (r5 == 0xdeadbeef) { - r5 = r3; - quik_fip = (struct first_info *)r4; - } - - /* Initialize OF interface */ - prom_init ((prom_entry) r5); + /* Check for quik first stage bootloader (but I don't think we are + * compatible with it anyway, I'll look into backporting to older OF + * versions later + */ + if (r5 == 0xdeadbeef) { + r5 = r3; + quik_fip = (struct first_info *)r4; + } + + /* Initialize OF interface */ + prom_init ((prom_entry) r5); - /* Allocate some memory for malloc'ator */ - malloc_base = prom_claim((void *)MALLOCADDR, MALLOCSIZE, 0); - if (malloc_base == (void *)-1) { - prom_printf("Can't claim malloc buffer (%d bytes at 0x%08x)\n", - MALLOCSIZE, MALLOCADDR); - return -1; - } - malloc_init(malloc_base, MALLOCSIZE); - DEBUG_F("Malloc buffer allocated at %p (%d bytes)\n", - malloc_base, MALLOCSIZE); + /* Allocate some memory for malloc'ator */ + malloc_base = prom_claim((void *)MALLOCADDR, MALLOCSIZE, 0); + if (malloc_base == (void *)-1) { + prom_printf("Can't claim malloc buffer (%d bytes at 0x%08x)\n", + MALLOCSIZE, MALLOCADDR); + return -1; + } + malloc_init(malloc_base, MALLOCSIZE); + DEBUG_F("Malloc buffer allocated at %p (%d bytes)\n", + malloc_base, MALLOCSIZE); - /* A few useless DEBUG_F's */ - DEBUG_F("reloc_offset : %ld (should be 0)\n", reloc_offset()); - DEBUG_F("test_bss : %d (should be 0)\n", test_bss); - DEBUG_F("test_data : %d (should be 0)\n", test_data); - DEBUG_F("&test_data : %p\n", &test_data); - DEBUG_F("&test_bss : %p\n", &test_bss); - DEBUG_F("linked at : 0x%08x\n", TEXTADDR); - - /* ask the OF info if we're a chrp or pmac */ - /* we need to set _machine before calling finish_device_tree */ - root = prom_finddevice("/"); - if (root != 0) { - static char model[256]; - if (prom_getprop(root, "device_type", model, 256 ) > 0 && - !strncmp("chrp", model, 4)) - _machine = _MACH_chrp; - else { - if (prom_getprop(root, "model", model, 256 ) > 0 && - !strncmp(model, "IBM", 3)) - _machine = _MACH_chrp; - } - } + /* A few useless DEBUG_F's */ + DEBUG_F("reloc_offset : %ld (should be 0)\n", reloc_offset()); + DEBUG_F("test_bss : %d (should be 0)\n", test_bss); + DEBUG_F("test_data : %d (should be 0)\n", test_data); + DEBUG_F("&test_data : %p\n", &test_data); + DEBUG_F("&test_bss : %p\n", &test_bss); + DEBUG_F("linked at : 0x%08x\n", TEXTADDR); + + /* ask the OF info if we're a chrp or pmac */ + /* we need to set _machine before calling finish_device_tree */ + root = prom_finddevice("/"); + if (root != 0) { + static char model[256]; + if (prom_getprop(root, "device_type", model, 256 ) > 0 && + !strncmp("chrp", model, 4)) + _machine = _MACH_chrp; + else { + if (prom_getprop(root, "model", model, 256 ) > 0 && + !strncmp(model, "IBM", 3)) + _machine = _MACH_chrp; + } + } - DEBUG_F("Running on _machine = %d\n", _machine); - DEBUG_SLEEP; + DEBUG_F("Running on _machine = %d\n", _machine); + DEBUG_SLEEP; - /* Call out main */ - result = yaboot_main(); + /* Call out main */ + result = yaboot_main(); - /* Get rid of malloc pool */ - malloc_dispose(); - prom_release(malloc_base, MALLOCSIZE); - DEBUG_F("Malloc buffer released. Exiting with code %d\n", - result); + /* Get rid of malloc pool */ + malloc_dispose(); + prom_release(malloc_base, MALLOCSIZE); + DEBUG_F("Malloc buffer released. Exiting with code %d\n", + result); - /* Return to OF */ - prom_exit(); + /* Return to OF */ + prom_exit(); - return result; + return result; } @@ -246,16 +245,72 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5) static int check_color_text_ui(char *color) { - int i = 0; - while(ansi_color_table[i].name) { - if (!strcmp(color, ansi_color_table[i].name)) - return i; - i++; - } - return -1; + int i = 0; + while(ansi_color_table[i].name) { + if (!strcmp(color, ansi_color_table[i].name)) + return i; + i++; + } + return -1; } #endif /* CONFIG_COLOR_TEXT */ + +void print_message_file(char *filename) +{ + char *msg = NULL; + char *p, *endp; + char *defdev = boot.dev; + int defpart = boot.part; + char msgpath[1024]; + int opened = 0; + int result = 0; + int n; + struct boot_file_t file; + struct boot_fspec_t msgfile; + + defdev = cfg_get_strg(0, "device"); + if (!defdev) + defdev = boot.dev; + p = cfg_get_strg(0, "partition"); + if (p) { + n = simple_strtol(p, &endp, 10); + if (endp != p && *endp == 0) + defpart = n; + } + + strncpy(msgpath, filename, sizeof(msgpath)); + if (!parse_device_path(msgpath, defdev, defpart, "/etc/yaboot.msg", &msgfile)) { + prom_printf("%s: Unable to parse\n", msgpath); + goto done; + } + + result = open_file(&msgfile, &file); + if (result != FILE_ERR_OK) { + prom_printf("%s:%d,", msgfile.dev, msgfile.part); + prom_perror(result, msgfile.file); + goto done; + } else + opened = 1; + + msg = malloc(2001); + if (!msg) + goto done; + else + memset(msg, 0, 2001); + + if (file.fs->read(&file, 2000, msg) <= 0) + goto done; + else + prom_printf("%s", msg); + +done: + if (opened) + file.fs->close(&file); + if (msg) + free(msg); +} + /* Currently, the config file must be at the root of the filesystem. * todo: recognize the full path to myself and use it to load the * config file. Handle the "\\" (blessed system folder) @@ -263,463 +318,466 @@ check_color_text_ui(char *color) static int load_config_file(char *device, char* path, int partition) { - char *conf_file = NULL, *p; - struct boot_file_t file; - int sz, opened = 0, result = 0; - char conf_path[512]; - struct boot_fspec_t fspec; - - /* Allocate a buffer for the config file */ - conf_file = malloc(CONFIG_FILE_MAX); - if (!conf_file) { - prom_printf("Can't alloc config file buffer\n"); - goto bail; - } - - /* Build the path to the file */ - if (path) - strcpy(conf_path, path); - else if ( _machine == _MACH_chrp ) - strcpy(conf_path, "/etc/"); - else - conf_path[0] = 0; - strcat(conf_path, CONFIG_FILE_NAME); - - /* Open it */ - fspec.dev = device; - fspec.file = conf_path; - fspec.part = partition; - result = open_file(&fspec, &file); - if (result != FILE_ERR_OK) { - prom_printf("Can't open config file '%s', err: %d\n", conf_path, result); - goto bail; - } - opened = 1; - - /* Read it */ - sz = file.fs->read(&file, CONFIG_FILE_MAX, conf_file); - if (sz <= 0) { - prom_printf("Error, can't read config file\n"); - goto bail; - } - prom_printf("Config file read, %d bytes\n", sz); - - /* Close the file */ - if (opened) - file.fs->close(&file); - opened = 0; - - /* Call the parsing code in cfg.c */ - if (cfg_parse(conf_path, conf_file, sz) < 0) { - prom_printf ("Syntax error or read error config\n"); - goto bail; - } - - DEBUG_F("Config file successfully parsed, %d bytes\n", sz); - - /* Now, we do the initialisations stored in the config file */ - p = cfg_get_strg(0, "init-code"); - if (p) - prom_interpret(p); - - password = cfg_get_strg(0, "password"); + char *conf_file = NULL, *p; + struct boot_file_t file; + int sz, opened = 0, result = 0; + char conf_path[512]; + struct boot_fspec_t fspec; + + /* Allocate a buffer for the config file */ + conf_file = malloc(CONFIG_FILE_MAX); + if (!conf_file) { + prom_printf("Can't alloc config file buffer\n"); + goto bail; + } + + /* Build the path to the file */ + if (path) + strcpy(conf_path, path); + else if ( _machine == _MACH_chrp ) + strcpy(conf_path, "/etc/"); + else + conf_path[0] = 0; + strcat(conf_path, CONFIG_FILE_NAME); + + /* Open it */ + fspec.dev = device; + fspec.file = conf_path; + fspec.part = partition; + result = open_file(&fspec, &file); + if (result != FILE_ERR_OK) { + prom_printf("%s:%d,", fspec.dev, fspec.part); + prom_perror(result, fspec.file); + prom_printf("Can't open config file\n"); + goto bail; + } + opened = 1; + + /* Read it */ + sz = file.fs->read(&file, CONFIG_FILE_MAX, conf_file); + if (sz <= 0) { + prom_printf("Error, can't read config file\n"); + goto bail; + } + prom_printf("Config file read, %d bytes\n", sz); + + /* Close the file */ + if (opened) + file.fs->close(&file); + opened = 0; + + /* Call the parsing code in cfg.c */ + if (cfg_parse(conf_path, conf_file, sz) < 0) { + prom_printf ("Syntax error or read error config\n"); + goto bail; + } + + DEBUG_F("Config file successfully parsed, %d bytes\n", sz); + + /* Now, we do the initialisations stored in the config file */ + p = cfg_get_strg(0, "init-code"); + if (p) + prom_interpret(p); + + password = cfg_get_strg(0, "password"); #ifdef CONFIG_COLOR_TEXT - p = cfg_get_strg(0, "fgcolor"); - if (p) { - DEBUG_F("fgcolor=%s\n", p); - fgcolor = check_color_text_ui(p); - if (fgcolor == -1) { - prom_printf("Invalid fgcolor: \"%s\".\n", p); - } - } - p = cfg_get_strg(0, "bgcolor"); - if (p) { - DEBUG_F("bgcolor=%s\n", p); - bgcolor = check_color_text_ui(p); - if (bgcolor == -1) - prom_printf("Invalid bgcolor: \"%s\".\n", p); - } - if (bgcolor >= 0) { - char temp[64]; - sprintf(temp, "%x to background-color", bgcolor); - prom_interpret(temp); + p = cfg_get_strg(0, "fgcolor"); + if (p) { + DEBUG_F("fgcolor=%s\n", p); + fgcolor = check_color_text_ui(p); + if (fgcolor == -1) { + prom_printf("Invalid fgcolor: \"%s\".\n", p); + } + } + p = cfg_get_strg(0, "bgcolor"); + if (p) { + DEBUG_F("bgcolor=%s\n", p); + bgcolor = check_color_text_ui(p); + if (bgcolor == -1) + prom_printf("Invalid bgcolor: \"%s\".\n", p); + } + if (bgcolor >= 0) { + char temp[64]; + sprintf(temp, "%x to background-color", bgcolor); + prom_interpret(temp); #if !DEBUG - prom_printf("\xc"); + prom_printf("\xc"); #endif /* !DEBUG */ - } - if (fgcolor >= 0) { - char temp[64]; - sprintf(temp, "%x to foreground-color", fgcolor); - prom_interpret(temp); - } + } + if (fgcolor >= 0) { + char temp[64]; + sprintf(temp, "%x to foreground-color", fgcolor); + prom_interpret(temp); + } #endif /* CONFIG_COLOR_TEXT */ - p = cfg_get_strg(0, "init-message"); - if (p) - prom_printf("%s\n", p); -#if 0 - p = cfg_get_strg(0, "message"); - if (p) - print_message_file(p); -#endif - - result = 1; + p = cfg_get_strg(0, "init-message"); + if (p) + prom_printf("%s\n", p); + + p = cfg_get_strg(0, "message"); + if (p) + print_message_file(p); + + result = 1; bail: - if (opened) - file.fs->close(&file); + if (opened) + file.fs->close(&file); - if (result != 1 && conf_file) - free(conf_file); + if (result != 1 && conf_file) + free(conf_file); - return result; + return result; } void maintabfunc (void) { - if (useconf) { - cfg_print_images(); - prom_printf("boot: %s", cbuff); - } + if (useconf) { + cfg_print_images(); + prom_printf("boot: %s", cbuff); + } } void word_split(char **linep, char **paramsp) { - char *p; - - *paramsp = 0; - p = *linep; - if (p == 0) - return; - while (*p == ' ') - ++p; - if (*p == 0) { - *linep = 0; - return; - } - *linep = p; - while (*p != 0 && *p != ' ') - ++p; - while (*p == ' ') - *p++ = 0; - if (*p != 0) - *paramsp = p; + char *p; + + *paramsp = 0; + p = *linep; + if (p == 0) + return; + while (*p == ' ') + ++p; + if (*p == 0) { + *linep = 0; + return; + } + *linep = p; + while (*p != 0 && *p != ' ') + ++p; + while (*p == ' ') + *p++ = 0; + if (*p != 0) + *paramsp = p; } char * make_params(char *label, char *params) { - char *p, *q; - static char buffer[2048]; - - q = buffer; - *q = 0; - - p = cfg_get_strg(label, "literal"); - if (p) { - strcpy(q, p); - q = strchr(q, 0); - if (params) { - if (*p) - *q++ = ' '; - strcpy(q, params); - } - return buffer; - } - - p = cfg_get_strg(label, "root"); - if (p) { - strcpy (q, "root="); - strcpy (q + 5, p); - q = strchr (q, 0); - *q++ = ' '; - } - if (cfg_get_flag(label, "read-only")) { - strcpy (q, "ro "); - q += 3; - } - if (cfg_get_flag(label, "read-write")) { - strcpy (q, "rw "); - q += 3; - } - p = cfg_get_strg(label, "ramdisk"); - if (p) { - strcpy (q, "ramdisk="); - strcpy (q + 8, p); - q = strchr (q, 0); - *q++ = ' '; - } - p = cfg_get_strg(label, "initrd-size"); - if (p) { - strcpy (q, "ramdisk_size="); - strcpy (q + 13, p); - q = strchr (q, 0); - *q++ = ' '; - } - if (cfg_get_flag(label, "novideo")) { - strcpy (q, "video=ofonly"); - q = strchr (q, 0); - *q++ = ' '; - } - p = cfg_get_strg (label, "append"); - if (p) { - strcpy (q, p); - q = strchr (q, 0); - *q++ = ' '; - } - *q = 0; - pause_after = cfg_get_flag (label, "pause-after"); - p = cfg_get_strg(label, "pause-message"); - if (p) - pause_message = p; - if (params) - strcpy(q, params); - - return buffer; + char *p, *q; + static char buffer[2048]; + + q = buffer; + *q = 0; + + p = cfg_get_strg(label, "literal"); + if (p) { + strcpy(q, p); + q = strchr(q, 0); + if (params) { + if (*p) + *q++ = ' '; + strcpy(q, params); + } + return buffer; + } + + p = cfg_get_strg(label, "root"); + if (p) { + strcpy (q, "root="); + strcpy (q + 5, p); + q = strchr (q, 0); + *q++ = ' '; + } + if (cfg_get_flag(label, "read-only")) { + strcpy (q, "ro "); + q += 3; + } + if (cfg_get_flag(label, "read-write")) { + strcpy (q, "rw "); + q += 3; + } + p = cfg_get_strg(label, "ramdisk"); + if (p) { + strcpy (q, "ramdisk="); + strcpy (q + 8, p); + q = strchr (q, 0); + *q++ = ' '; + } + p = cfg_get_strg(label, "initrd-size"); + if (p) { + strcpy (q, "ramdisk_size="); + strcpy (q + 13, p); + q = strchr (q, 0); + *q++ = ' '; + } + if (cfg_get_flag(label, "novideo")) { + strcpy (q, "video=ofonly"); + q = strchr (q, 0); + *q++ = ' '; + } + p = cfg_get_strg (label, "append"); + if (p) { + strcpy (q, p); + q = strchr (q, 0); + *q++ = ' '; + } + *q = 0; + pause_after = cfg_get_flag (label, "pause-after"); + p = cfg_get_strg(label, "pause-message"); + if (p) + pause_message = p; + if (params) + strcpy(q, params); + + return buffer; } void check_password(char *str) { - int i; + int i; - for (i = 0; i < 3; i++) { - prom_printf ("\n%sassword: ", str); - passwdbuff[0] = 0; - cmdedit ((void (*)(void)) 0, 1); - prom_printf ("\n"); + for (i = 0; i < 3; i++) { + prom_printf ("\n%sassword: ", str); + passwdbuff[0] = 0; + cmdedit ((void (*)(void)) 0, 1); + prom_printf ("\n"); #ifdef USE_MD5_PASSWORDS - if (!strncmp (password, "$1$", 3)) { - if (!check_md5_password(passwdbuff, password)) + if (!strncmp (password, "$1$", 3)) { + if (!check_md5_password(passwdbuff, password)) + return; + } + else if (!strcmp (password, passwdbuff)) return; - } - else if (!strcmp (password, passwdbuff)) - return; #else /* !MD5 */ - if (!strcmp (password, passwdbuff)) - return; + if (!strcmp (password, passwdbuff)) + return; #endif /* USE_MD5_PASSWORDS */ - if (i < 2) - prom_printf ("Password incorrect. Please try again..."); - } - prom_printf ("Seems like you don't know the access password. Go away!\n"); - prom_sleep(3); - prom_interpret("reset-all"); + if (i < 2) + prom_printf ("Password incorrect. Please try again..."); + } + prom_printf ("Seems like you don't know the access password. Go away!\n"); + prom_sleep(3); + prom_interpret("reset-all"); } int get_params(struct boot_param_t* params) { - int defpart; - char *defdevice = 0; - char *p, *q, *endp; - int c, n; - char *imagename = 0, *label; - int timeout = -1; - int beg = 0, end; - int singlekey = 0; - int restricted = 0; - static int first = 1; - static char bootargs[1024]; - static char imagepath[1024]; - static char initrdpath[1024]; - static char sysmappath[1024]; - - pause_after = 0; - memset(params, 0, sizeof(*params)); - params->args = ""; - params->kernel.part = -1; - params->rd.part = -1; - params->sysmap.part = -1; - defpart = boot.part; + int defpart; + char *defdevice = 0; + char *p, *q, *endp; + int c, n; + char *imagename = 0, *label; + int timeout = -1; + int beg = 0, end; + int singlekey = 0; + int restricted = 0; + static int first = 1; + static char bootargs[1024]; + static char imagepath[1024]; + static char initrdpath[1024]; + static char sysmappath[1024]; + + pause_after = 0; + memset(params, 0, sizeof(*params)); + params->args = ""; + params->kernel.part = -1; + params->rd.part = -1; + params->sysmap.part = -1; + defpart = boot.part; - cmdinit(); - - if (first) { - first = 0; - prom_get_chosen("bootargs", bootargs, sizeof(bootargs)); - imagename = bootargs; - word_split(&imagename, ¶ms->args); - timeout = DEFAULT_TIMEOUT; - if (imagename) { - prom_printf("Default supplied on the command line: %s ", imagename); - if (params->args) - prom_printf("%s", params->args); - prom_printf("\n"); - } - if (useconf && (q = cfg_get_strg(0, "timeout")) != 0 && *q != 0) - timeout = simple_strtol(q, NULL, 0); - } - - prom_printf("boot: "); - c = -1; - if (timeout != -1) { - beg = prom_getms(); - if (timeout > 0) { - end = beg + 100 * timeout; - do { - c = prom_nbgetchar(); - } while (c == -1 && prom_getms() <= end); - } - if (c == -1) - c = '\n'; - else if (c != '\n' && c != '\t' && c != '\r' && c != '\b' ) { - cbuff[0] = c; - cbuff[1] = 0; - } - } - - if (c != -1 && c != '\n' && c != '\r') { - if (c == '\t') { - maintabfunc (); - } else if (c >= ' ') { - cbuff[0] = c; - cbuff[1] = 0; - if ((cfg_get_flag (cbuff, "single-key")) && useconf) { - imagename = cbuff; - singlekey = 1; - prom_printf("%s\n", cbuff); - } - } - } - - if (c == '\n' || c == '\r') { - if (!imagename) - imagename = cfg_get_default(); - if (imagename) - prom_printf("%s", imagename); - if (params->args) - prom_printf(" %s", params->args); - prom_printf("\n"); - } else if (!singlekey) { - cmdedit(maintabfunc, 0); - prom_printf("\n"); - strcpy(given_bootargs, cbuff); - given_bootargs_by_user = 1; - imagename = cbuff; - word_split(&imagename, ¶ms->args); - } - - /* chrp gets this wrong, force it -- Cort */ - if ( useconf && (!imagename || imagename[0] == 0 )) - imagename = cfg_get_default(); - - label = 0; - defdevice = boot.dev; - - if (useconf) { - defdevice = cfg_get_strg(0, "device"); - p = cfg_get_strg(0, "partition"); - if (p) { - n = simple_strtol(p, &endp, 10); - if (endp != p && *endp == 0) - defpart = n; - } - p = cfg_get_strg(0, "pause-message"); - if (p) - pause_message = p; - if (cfg_get_flag(0, "restricted")) - restricted = 1; - p = cfg_get_strg(imagename, "image"); - if (p && *p) { - label = imagename; - imagename = p; - defdevice = cfg_get_strg(label, "device"); - if(!defdevice) defdevice=boot.dev; - p = cfg_get_strg(label, "partition"); - if (p) { - n = simple_strtol(p, &endp, 10); - if (endp != p && *endp == 0) + cmdinit(); + + if (first) { + first = 0; + prom_get_chosen("bootargs", bootargs, sizeof(bootargs)); + imagename = bootargs; + word_split(&imagename, ¶ms->args); + timeout = DEFAULT_TIMEOUT; + if (imagename) { + prom_printf("Default supplied on the command line: %s ", imagename); + if (params->args) + prom_printf("%s", params->args); + prom_printf("\n"); + } + if (useconf && (q = cfg_get_strg(0, "timeout")) != 0 && *q != 0) + timeout = simple_strtol(q, NULL, 0); + } + + prom_printf("boot: "); + c = -1; + if (timeout != -1) { + beg = prom_getms(); + if (timeout > 0) { + end = beg + 100 * timeout; + do { + c = prom_nbgetchar(); + } while (c == -1 && prom_getms() <= end); + } + if (c == -1) + c = '\n'; + else if (c != '\n' && c != '\t' && c != '\r' && c != '\b' ) { + cbuff[0] = c; + cbuff[1] = 0; + } + } + + if (c != -1 && c != '\n' && c != '\r') { + if (c == '\t') { + maintabfunc (); + } else if (c >= ' ') { + cbuff[0] = c; + cbuff[1] = 0; + if ((cfg_get_flag (cbuff, "single-key")) && useconf) { + imagename = cbuff; + singlekey = 1; + prom_printf("%s\n", cbuff); + } + } + } + + if (c == '\n' || c == '\r') { + if (!imagename) + imagename = cfg_get_default(); + if (imagename) + prom_printf("%s", imagename); + if (params->args) + prom_printf(" %s", params->args); + prom_printf("\n"); + } else if (!singlekey) { + cmdedit(maintabfunc, 0); + prom_printf("\n"); + strcpy(given_bootargs, cbuff); + given_bootargs_by_user = 1; + imagename = cbuff; + word_split(&imagename, ¶ms->args); + } + + /* chrp gets this wrong, force it -- Cort */ + if ( useconf && (!imagename || imagename[0] == 0 )) + imagename = cfg_get_default(); + + label = 0; + defdevice = boot.dev; + + if (useconf) { + defdevice = cfg_get_strg(0, "device"); + p = cfg_get_strg(0, "partition"); + if (p) { + n = simple_strtol(p, &endp, 10); + if (endp != p && *endp == 0) defpart = n; - } - if (cfg_get_flag(label, "restricted")) - restricted = 1; - if (label) { - if (params->args && password && restricted) - check_password ("To specify image arguments you must enter the p"); - else if (password && !restricted) - check_password ("P"); - } - params->args = make_params(label, params->args); - } - } - - if (!strcmp (imagename, "help")) { - prom_printf( - "\nPress the tab key for a list of defined images.\n" - "The label marked with a \"*\" is is the default image, " - "press to boot it.\n\n" - "To boot any other label simply type its name and press .\n\n" - "To boot a kernel image which is not defined in the yaboot configuration \n" - "file, enter the kernel image name as [device:][partno],/path, where \n" - "\"device:\" is the OpenFirmware device path to the disk the image \n" - "resides on, and \"partno\" is the partition number the image resides on.\n\n" - "If you omit \"device:\" and \"partno\" yaboot will use the values of \n" - "\"device=\" and \"partition=\" in yaboot.conf, right now those are set to: \n" - "device=%s\n" - "partition=%d\n\n", defdevice, defpart); - return 0; - } - - if (!strcmp (imagename, "halt")) { - if (password) - check_password ("P"); - prom_pause(); - return 0; - } - if (!strcmp (imagename, "bye")) { - if (password) { - check_password ("P"); - return 1; - } - return 1; - } - - if (imagename[0] == '$') { - /* forth command string */ - if (password) - check_password ("P"); - prom_interpret(imagename+1); - return 0; - } - - strncpy(imagepath, imagename, 1024); - - if (!label && password) - check_password ("To boot a custom image you must enter the p"); - - if (!parse_device_path(imagepath, defdevice, defpart, - "/vmlinux", ¶ms->kernel)) { - prom_printf("%s: Unable to parse\n", imagepath); - return 0; - } - DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev, - params->kernel.part, params->kernel.file); - - if (useconf) { - p = cfg_get_strg(label, "initrd"); - if (p && *p) { - DEBUG_F("Parsing initrd path <%s>\n", p); - strncpy(initrdpath, p, 1024); - if (!parse_device_path(initrdpath, defdevice, defpart, - "/root.bin", ¶ms->rd)) { - prom_printf("%s: Unable to parse\n", imagepath); - return 0; - } - } - p = cfg_get_strg(label, "sysmap"); - if (p && *p) { - DEBUG_F("Parsing sysmap path <%s>\n", p); - strncpy(sysmappath, p, 1024); - if (!parse_device_path(sysmappath, defdevice, defpart, - "/boot/System.map", ¶ms->sysmap)) { - prom_printf("%s: Unable to parse\n", imagepath); - return 0; - } - } - } - return 0; + } + p = cfg_get_strg(0, "pause-message"); + if (p) + pause_message = p; + if (cfg_get_flag(0, "restricted")) + restricted = 1; + p = cfg_get_strg(imagename, "image"); + if (p && *p) { + label = imagename; + imagename = p; + defdevice = cfg_get_strg(label, "device"); + if(!defdevice) defdevice=boot.dev; + p = cfg_get_strg(label, "partition"); + if (p) { + n = simple_strtol(p, &endp, 10); + if (endp != p && *endp == 0) + defpart = n; + } + if (cfg_get_flag(label, "restricted")) + restricted = 1; + if (label) { + if (params->args && password && restricted) + check_password ("To specify image arguments you must enter the p"); + else if (password && !restricted) + check_password ("P"); + } + params->args = make_params(label, params->args); + } + } + + if (!strcmp (imagename, "help")) { + prom_printf( + "\nPress the tab key for a list of defined images.\n" + "The label marked with a \"*\" is is the default image, " + "press to boot it.\n\n" + "To boot any other label simply type its name and press .\n\n" + "To boot a kernel image which is not defined in the yaboot configuration \n" + "file, enter the kernel image name as [[device:][partno],]/path, where \n" + "\"device:\" is the OpenFirmware device path to the disk the image \n" + "resides on, and \"partno\" is the partition number the image resides on.\n" + "Note that the comma (,) is only required if you specify an OpenFirmware\n" + "device, if you only specify a filename you should not start it with a \",\"\n\n" + "If you omit \"device:\" and \"partno\" yaboot will use the values of \n" + "\"device=\" and \"partition=\" in yaboot.conf, right now those are set to: \n" + "device=%s\n" + "partition=%d\n\n", defdevice, defpart); + return 0; + } + + if (!strcmp (imagename, "halt")) { + if (password) + check_password ("P"); + prom_pause(); + return 0; + } + if (!strcmp (imagename, "bye")) { + if (password) { + check_password ("P"); + return 1; + } + return 1; + } + + if (imagename[0] == '$') { + /* forth command string */ + if (password) + check_password ("P"); + prom_interpret(imagename+1); + return 0; + } + + strncpy(imagepath, imagename, 1024); + + if (!label && password) + check_password ("To boot a custom image you must enter the p"); + + if (!parse_device_path(imagepath, defdevice, defpart, + "/vmlinux", ¶ms->kernel)) { + prom_printf("%s: Unable to parse\n", imagepath); + return 0; + } + DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev, + params->kernel.part, params->kernel.file); + + if (useconf) { + p = cfg_get_strg(label, "initrd"); + if (p && *p) { + DEBUG_F("Parsing initrd path <%s>\n", p); + strncpy(initrdpath, p, 1024); + if (!parse_device_path(initrdpath, defdevice, defpart, + "/root.bin", ¶ms->rd)) { + prom_printf("%s: Unable to parse\n", imagepath); + return 0; + } + } + p = cfg_get_strg(label, "sysmap"); + if (p && *p) { + DEBUG_F("Parsing sysmap path <%s>\n", p); + strncpy(sysmappath, p, 1024); + if (!parse_device_path(sysmappath, defdevice, defpart, + "/boot/System.map", ¶ms->sysmap)) { + prom_printf("%s: Unable to parse\n", imagepath); + return 0; + } + } + } + return 0; } /* This is derived from quik core. To be changed to first parse the headers @@ -732,625 +790,625 @@ yaboot_text_ui(void) { #define MAX_HEADERS 32 - struct boot_file_t file; - int result; - static struct boot_param_t params; - void *initrd_base; - unsigned long initrd_size; - void *sysmap_base; - unsigned long sysmap_size; - kernel_entry_t kernel_entry; - struct bi_record* birec; - char* loc=NULL; - loadinfo_t loadinfo; - void *initrd_more,*initrd_want; - unsigned long initrd_read; + struct boot_file_t file; + int result; + static struct boot_param_t params; + void *initrd_base; + unsigned long initrd_size; + void *sysmap_base; + unsigned long sysmap_size; + kernel_entry_t kernel_entry; + struct bi_record* birec; + char* loc=NULL; + loadinfo_t loadinfo; + void *initrd_more,*initrd_want; + unsigned long initrd_read; - loadinfo.load_loc = 0; + loadinfo.load_loc = 0; - for (;;) { - initrd_size = 0; - initrd_base = 0; - sysmap_base = 0; - sysmap_size = 0; + for (;;) { + initrd_size = 0; + initrd_base = 0; + sysmap_base = 0; + sysmap_size = 0; - if (get_params(¶ms)) - return; - if (!params.kernel.file) - continue; + if (get_params(¶ms)) + return; + if (!params.kernel.file) + continue; - prom_printf("Please wait, loading kernel...\n"); - - memset(&file, 0, sizeof(file)); - - if (strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.kernel.file[0] != '/' - && params.kernel.file[0] != '\\') { - loc=(char*)malloc(strlen(params.kernel.file)+3); - if (!loc) { - prom_printf ("malloc error\n"); - goto next; - } - strcpy(loc,boot.file); - strcat(loc,params.kernel.file); - free(params.kernel.file); - params.kernel.file=loc; - } - result = open_file(¶ms.kernel, &file); - if (result != FILE_ERR_OK) { - prom_printf("%s:%d,", params.kernel.dev, params.kernel.part); - prom_perror(result, params.kernel.file); - goto next; - } - - /* Read the Elf e_ident, e_type and e_machine fields to - * determine Elf file type - */ - if (file.fs->read(&file, sizeof(Elf_Ident), &loadinfo.elf) < sizeof(Elf_Ident)) { - prom_printf("\nCan't read Elf e_ident/e_type/e_machine info\n"); - file.fs->close(&file); - memset(&file, 0, sizeof(file)); - goto next; - } - - if (is_elf32(&loadinfo)) { - if (!load_elf32(&file, &loadinfo)) { - file.fs->close(&file); - memset(&file, 0, sizeof(file)); - goto next; - } - prom_printf(" Elf32 kernel loaded...\n"); - } else if (is_elf64(&loadinfo)) { - if (!load_elf64(&file, &loadinfo)) { - file.fs->close(&file); - memset(&file, 0, sizeof(file)); - goto next; - } - prom_printf(" Elf64 kernel loaded...\n"); - } else { - prom_printf ("%s: Not a valid ELF image\n", params.kernel.file); - file.fs->close(&file); - memset(&file, 0, sizeof(file)); - goto next; - } - file.fs->close(&file); - memset(&file, 0, sizeof(file)); - - /* If sysmap, load it. - */ - if (params.sysmap.file) { - prom_printf("Loading System.map ...\n"); - if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.sysmap.file[0] != '/' - && params.sysmap.file[0] != '\\') { - if (loc) free(loc); - loc=(char*)malloc(strlen(params.sysmap.file)+3); - if (!loc) { - prom_printf ("malloc error\n"); - goto next; - } - strcpy(loc,boot.file); - strcat(loc,params.sysmap.file); - free(params.sysmap.file); - params.sysmap.file=loc; - } - - result = open_file(¶ms.sysmap, &file); - if (result != FILE_ERR_OK) { - prom_printf("%s:%d,", params.sysmap.dev, params.sysmap.part); - prom_perror(result, params.sysmap.file); - } - else { - sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0); - if (sysmap_base == (void *)-1) { - prom_printf("Claim failed for sysmap memory\n"); - sysmap_base = 0; - } else { - sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base); - if (sysmap_size == 0) - sysmap_base = 0; - else - ((char *)sysmap_base)[sysmap_size++] = 0; - } - file.fs->close(&file); - memset(&file, 0, sizeof(file)); - } - if (sysmap_base) { - prom_printf("System.map loaded at %p, size: %lu Kbytes\n", - sysmap_base, sysmap_size >> 10); - loadinfo.memsize += _ALIGN(0x100000, 0x1000); - } else { - prom_printf("System.map load failed !\n"); - prom_pause(); - } - } - - /* If ramdisk, load it. For now, we can't tell the size it will be - * so we claim an arbitrary amount of 4Mb - */ - if (params.rd.file) { - if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.rd.file[0] != '/' - && params.kernel.file[0] != '\\') - { - if (loc) free(loc); - loc=(char*)malloc(strlen(params.rd.file)+3); - if (!loc) { - prom_printf ("Malloc error\n"); + prom_printf("Please wait, loading kernel...\n"); + + memset(&file, 0, sizeof(file)); + + if (strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.kernel.file[0] != '/' + && params.kernel.file[0] != '\\') { + loc=(char*)malloc(strlen(params.kernel.file)+3); + if (!loc) { + prom_printf ("malloc error\n"); + goto next; + } + strcpy(loc,boot.file); + strcat(loc,params.kernel.file); + free(params.kernel.file); + params.kernel.file=loc; + } + result = open_file(¶ms.kernel, &file); + if (result != FILE_ERR_OK) { + prom_printf("%s:%d,", params.kernel.dev, params.kernel.part); + prom_perror(result, params.kernel.file); + goto next; + } + + /* Read the Elf e_ident, e_type and e_machine fields to + * determine Elf file type + */ + if (file.fs->read(&file, sizeof(Elf_Ident), &loadinfo.elf) < sizeof(Elf_Ident)) { + prom_printf("\nCan't read Elf e_ident/e_type/e_machine info\n"); + file.fs->close(&file); + memset(&file, 0, sizeof(file)); + goto next; + } + + if (is_elf32(&loadinfo)) { + if (!load_elf32(&file, &loadinfo)) { + file.fs->close(&file); + memset(&file, 0, sizeof(file)); goto next; - } - strcpy(loc,boot.file); - strcat(loc,params.rd.file); - 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 { + } + prom_printf(" Elf32 kernel loaded...\n"); + } else if (is_elf64(&loadinfo)) { + if (!load_elf64(&file, &loadinfo)) { + file.fs->close(&file); + memset(&file, 0, sizeof(file)); + goto next; + } + prom_printf(" Elf64 kernel loaded...\n"); + } else { + prom_printf ("%s: Not a valid ELF image\n", params.kernel.file); + file.fs->close(&file); + memset(&file, 0, sizeof(file)); + goto next; + } + file.fs->close(&file); + memset(&file, 0, sizeof(file)); + + /* If sysmap, load it. + */ + if (params.sysmap.file) { + prom_printf("Loading System.map ...\n"); + if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.sysmap.file[0] != '/' + && params.sysmap.file[0] != '\\') { + if (loc) free(loc); + loc=(char*)malloc(strlen(params.sysmap.file)+3); + if (!loc) { + prom_printf ("malloc error\n"); + goto next; + } + strcpy(loc,boot.file); + strcat(loc,params.sysmap.file); + free(params.sysmap.file); + params.sysmap.file=loc; + } + + result = open_file(¶ms.sysmap, &file); + if (result != FILE_ERR_OK) { + prom_printf("%s:%d,", params.sysmap.dev, params.sysmap.part); + prom_perror(result, params.sysmap.file); + } + else { + sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0); + if (sysmap_base == (void *)-1) { + prom_printf("Claim failed for sysmap memory\n"); + sysmap_base = 0; + } else { + sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base); + if (sysmap_size == 0) + sysmap_base = 0; + else + ((char *)sysmap_base)[sysmap_size++] = 0; + } + file.fs->close(&file); + memset(&file, 0, sizeof(file)); + } + if (sysmap_base) { + prom_printf("System.map loaded at %p, size: %lu Kbytes\n", + sysmap_base, sysmap_size >> 10); + loadinfo.memsize += _ALIGN(0x100000, 0x1000); + } else { + prom_printf("System.map load failed !\n"); + prom_pause(); + } + } + + /* If ramdisk, load it. For now, we can't tell the size it will be + * so we claim an arbitrary amount of 4Mb + */ + if (params.rd.file) { + if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.rd.file[0] != '/' + && params.kernel.file[0] != '\\') + { + if (loc) free(loc); + loc=(char*)malloc(strlen(params.rd.file)+3); + if (!loc) { + prom_printf ("Malloc error\n"); + goto next; + } + strcpy(loc,boot.file); + strcat(loc,params.rd.file); + 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 0x400000 - 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); - 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; + 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); + 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(); - } - } - - DEBUG_F("setting kernel args to: %s\n", params.args); - prom_setargs(params.args); - DEBUG_F("flushing icache..."); - flush_icache_range ((long)loadinfo.base, (long)loadinfo.base+loadinfo.memsize); - DEBUG_F(" done\n"); - - /* - * Fill mew boot infos - * - * The birec is low on memory, probably inside the malloc pool, so - * we don't write it earlier. At this point, we should not use anything - * coming from the malloc pool - */ - birec = (struct bi_record *)_ALIGN(loadinfo.filesize+(1<<20)-1,(1<<20)); - - /* We make sure it's mapped. We map only 64k for now, it's plenty enough - * we don't claim since this precise memory range may already be claimed - * by the malloc pool - */ - prom_map (birec, birec, 0x10000); - DEBUG_F("birec at %p\n", birec); - DEBUG_SLEEP; - - birec->tag = BI_FIRST; - birec->size = sizeof(struct bi_record); - birec = (struct bi_record *)((unsigned long)birec + birec->size); + 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(); + } + } + + DEBUG_F("setting kernel args to: %s\n", params.args); + prom_setargs(params.args); + DEBUG_F("flushing icache..."); + flush_icache_range ((long)loadinfo.base, (long)loadinfo.base+loadinfo.memsize); + DEBUG_F(" done\n"); + +/* + * Fill mew boot infos + * + * The birec is low on memory, probably inside the malloc pool, so + * we don't write it earlier. At this point, we should not use anything + * coming from the malloc pool + */ + birec = (struct bi_record *)_ALIGN(loadinfo.filesize+(1<<20)-1,(1<<20)); + +/* We make sure it's mapped. We map only 64k for now, it's plenty enough + * we don't claim since this precise memory range may already be claimed + * by the malloc pool + */ + prom_map (birec, birec, 0x10000); + DEBUG_F("birec at %p\n", birec); + DEBUG_SLEEP; + + birec->tag = BI_FIRST; + birec->size = sizeof(struct bi_record); + birec = (struct bi_record *)((unsigned long)birec + birec->size); - birec->tag = BI_BOOTLOADER_ID; - sprintf( (char *)birec->data, "yaboot"); - birec->size = sizeof(struct bi_record) + strlen("yaboot") + 1; - birec = (struct bi_record *)((unsigned long)birec + birec->size); + birec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)birec->data, "yaboot"); + birec->size = sizeof(struct bi_record) + strlen("yaboot") + 1; + birec = (struct bi_record *)((unsigned long)birec + birec->size); - birec->tag = BI_MACHTYPE; - birec->data[0] = _machine; - birec->size = sizeof(struct bi_record) + sizeof(unsigned long); - birec = (struct bi_record *)((unsigned long)birec + birec->size); - - if (sysmap_base) { - birec->tag = BI_SYSMAP; - birec->data[0] = (unsigned long)sysmap_base; - birec->data[1] = sysmap_size; - birec->size = sizeof(struct bi_record) + sizeof(unsigned long)*2; - birec = (struct bi_record *)((unsigned long)birec + birec->size); - } - birec->tag = BI_LAST; - birec->size = sizeof(struct bi_record); - birec = (struct bi_record *)((unsigned long)birec + birec->size); - - /* compute the kernel's entry point. */ - kernel_entry = loadinfo.base + loadinfo.entry - loadinfo.load_loc; - - DEBUG_F("Kernel entry point = %p\n", kernel_entry); - DEBUG_F("kernel: arg1 = %p,\n" - " arg2 = 0x%08lx,\n" - " prom = %p,\n" - " arg4 = %d,\n" - " arg5 = %d\n\n", - initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0); - - DEBUG_F("Entering kernel...\n"); - - /* call the kernel with our stack. */ - kernel_entry(initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0); - continue; -next: - ; /* do nothing */ - } + birec->tag = BI_MACHTYPE; + birec->data[0] = _machine; + birec->size = sizeof(struct bi_record) + sizeof(unsigned long); + birec = (struct bi_record *)((unsigned long)birec + birec->size); + + if (sysmap_base) { + birec->tag = BI_SYSMAP; + birec->data[0] = (unsigned long)sysmap_base; + birec->data[1] = sysmap_size; + birec->size = sizeof(struct bi_record) + sizeof(unsigned long)*2; + birec = (struct bi_record *)((unsigned long)birec + birec->size); + } + birec->tag = BI_LAST; + birec->size = sizeof(struct bi_record); + birec = (struct bi_record *)((unsigned long)birec + birec->size); + + /* compute the kernel's entry point. */ + kernel_entry = loadinfo.base + loadinfo.entry - loadinfo.load_loc; + + DEBUG_F("Kernel entry point = %p\n", kernel_entry); + DEBUG_F("kernel: arg1 = %p,\n" + " arg2 = 0x%08lx,\n" + " prom = %p,\n" + " arg4 = %d,\n" + " arg5 = %d\n\n", + initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0); + + DEBUG_F("Entering kernel...\n"); + + /* call the kernel with our stack. */ + kernel_entry(initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0); + continue; + next: + ; /* do nothing */ + } } static int load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo) { - int i; - Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr); - Elf32_Phdr *p, *ph; - int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident); - unsigned long addr, loadaddr; - - /* Read the rest of the Elf header... */ - if ((*(file->fs->read))(file, size, &e->e_version) < size) { - prom_printf("\nCan't read Elf32 image header\n"); - return 0; - } - - DEBUG_F("Elf32 header:\n"); - DEBUG_F(" e.e_type = %d\n", (int)e->e_type); - DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine); - DEBUG_F(" e.e_version = %d\n", (int)e->e_version); - DEBUG_F(" e.e_entry = 0x%08x\n", (int)e->e_entry); - DEBUG_F(" e.e_phoff = 0x%08x\n", (int)e->e_phoff); - DEBUG_F(" e.e_shoff = 0x%08x\n", (int)e->e_shoff); - DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags); - DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize); - DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize); - DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum); - - loadinfo->entry = e->e_entry; - - if (e->e_phnum > MAX_HEADERS) { - prom_printf ("Can only load kernels with one program header\n"); - return 0; - } - - ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum); - if (!ph) { - prom_printf ("Malloc error\n"); - return 0; - } - - /* Now, we read the section header */ - if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) { - prom_printf ("seek error\n"); - return 0; - } - if ((*(file->fs->read))(file, sizeof(Elf32_Phdr) * e->e_phnum, ph) != - sizeof(Elf32_Phdr) * e->e_phnum) { - prom_printf ("read error\n"); - return 0; - } - - /* Scan through the program header - * HACK: We must return the _memory size of the kernel image, not the - * file size (because we have to leave room before other boot - * infos. This code works as a side effect of the fact that - * we have one section and vaddr == p_paddr - */ - loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0; - p = ph; - for (i = 0; i < e->e_phnum; ++i, ++p) { - if (p->p_type != PT_LOAD || p->p_offset == 0) - continue; - if (loadinfo->memsize == 0) { - loadinfo->offset = p->p_offset; - loadinfo->memsize = p->p_memsz; - loadinfo->filesize = p->p_filesz; - loadinfo->load_loc = p->p_vaddr; - } else { - loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */ - loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset; - } - } - - if (loadinfo->memsize == 0) { - prom_printf("Can't find a loadable segment !\n"); - return 0; - } - - /* leave some room (1Mb) for boot infos */ - loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000; - /* Claim OF memory */ - DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize); - - /* On some systems, loadaddr may already be claimed, so try some - * other nearby addresses before giving up. - */ - loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC32 || - e->e_entry == 0) ? KERNELADDR : e->e_entry; - for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) { - loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0); - if (loadinfo->base != (void *)-1) break; - } - if (loadinfo->base == (void *)-1) { - prom_printf("Claim error, can't allocate kernel memory\n"); - return 0; - } - - DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n", - loadinfo->base, loadinfo->memsize); - DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n", - loadaddr, loadinfo->memsize); - - /* Load the program segments... */ - p = ph; - for (i = 0; i < e->e_phnum; ++i, ++p) { - unsigned long offset; - if (p->p_type != PT_LOAD || p->p_offset == 0) - continue; - - /* Now, we skip to the image itself */ - if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) { - prom_printf ("Seek error\n"); - prom_release(loadinfo->base, loadinfo->memsize); - return 0; - } - offset = p->p_vaddr - loadinfo->load_loc; - if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) { - prom_printf ("Read failed\n"); - prom_release(loadinfo->base, loadinfo->memsize); - return 0; - } - } - - free(ph); + int i; + Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr); + Elf32_Phdr *p, *ph; + int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident); + unsigned long addr, loadaddr; + + /* Read the rest of the Elf header... */ + if ((*(file->fs->read))(file, size, &e->e_version) < size) { + prom_printf("\nCan't read Elf32 image header\n"); + return 0; + } + + DEBUG_F("Elf32 header:\n"); + DEBUG_F(" e.e_type = %d\n", (int)e->e_type); + DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine); + DEBUG_F(" e.e_version = %d\n", (int)e->e_version); + DEBUG_F(" e.e_entry = 0x%08x\n", (int)e->e_entry); + DEBUG_F(" e.e_phoff = 0x%08x\n", (int)e->e_phoff); + DEBUG_F(" e.e_shoff = 0x%08x\n", (int)e->e_shoff); + DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags); + DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize); + DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize); + DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum); + + loadinfo->entry = e->e_entry; + + if (e->e_phnum > MAX_HEADERS) { + prom_printf ("Can only load kernels with one program header\n"); + return 0; + } + + ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum); + if (!ph) { + prom_printf ("Malloc error\n"); + return 0; + } + + /* Now, we read the section header */ + if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) { + prom_printf ("seek error\n"); + return 0; + } + if ((*(file->fs->read))(file, sizeof(Elf32_Phdr) * e->e_phnum, ph) != + sizeof(Elf32_Phdr) * e->e_phnum) { + prom_printf ("read error\n"); + return 0; + } + + /* Scan through the program header + * HACK: We must return the _memory size of the kernel image, not the + * file size (because we have to leave room before other boot + * infos. This code works as a side effect of the fact that + * we have one section and vaddr == p_paddr + */ + loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0; + p = ph; + for (i = 0; i < e->e_phnum; ++i, ++p) { + if (p->p_type != PT_LOAD || p->p_offset == 0) + continue; + if (loadinfo->memsize == 0) { + loadinfo->offset = p->p_offset; + loadinfo->memsize = p->p_memsz; + loadinfo->filesize = p->p_filesz; + loadinfo->load_loc = p->p_vaddr; + } else { + loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */ + loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset; + } + } + + if (loadinfo->memsize == 0) { + prom_printf("Can't find a loadable segment !\n"); + return 0; + } + + /* leave some room (1Mb) for boot infos */ + loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000; + /* Claim OF memory */ + DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize); + + /* On some systems, loadaddr may already be claimed, so try some + * other nearby addresses before giving up. + */ + loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC32 || + e->e_entry == 0) ? KERNELADDR : e->e_entry; + for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) { + loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0); + if (loadinfo->base != (void *)-1) break; + } + if (loadinfo->base == (void *)-1) { + prom_printf("Claim error, can't allocate kernel memory\n"); + return 0; + } + + DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n", + loadinfo->base, loadinfo->memsize); + DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n", + loadaddr, loadinfo->memsize); + + /* Load the program segments... */ + p = ph; + for (i = 0; i < e->e_phnum; ++i, ++p) { + unsigned long offset; + if (p->p_type != PT_LOAD || p->p_offset == 0) + continue; + + /* Now, we skip to the image itself */ + if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) { + prom_printf ("Seek error\n"); + prom_release(loadinfo->base, loadinfo->memsize); + return 0; + } + offset = p->p_vaddr - loadinfo->load_loc; + if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) { + prom_printf ("Read failed\n"); + prom_release(loadinfo->base, loadinfo->memsize); + return 0; + } + } + + free(ph); - /* Return success at loading the Elf32 kernel */ - return 1; + /* Return success at loading the Elf32 kernel */ + return 1; } static int load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo) { - int i; - Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr); - Elf64_Phdr *p, *ph; - int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident); - unsigned long addr, loadaddr; - - /* Read the rest of the Elf header... */ - if ((*(file->fs->read))(file, size, &e->e_version) < size) { - prom_printf("\nCan't read Elf64 image header\n"); - return 0; - } - - DEBUG_F("Elf64 header:\n"); - DEBUG_F(" e.e_type = %d\n", (int)e->e_type); - DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine); - DEBUG_F(" e.e_version = %d\n", (int)e->e_version); - DEBUG_F(" e.e_entry = 0x%016lx\n", (long)e->e_entry); - DEBUG_F(" e.e_phoff = 0x%016lx\n", (long)e->e_phoff); - DEBUG_F(" e.e_shoff = 0x%016lx\n", (long)e->e_shoff); - DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags); - DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize); - DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize); - DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum); - - loadinfo->entry = e->e_entry; - - if (e->e_phnum > MAX_HEADERS) { - prom_printf ("Can only load kernels with one program header\n"); - return 0; - } - - ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum); - if (!ph) { - prom_printf ("Malloc error\n"); - return 0; - } - - /* Now, we read the section header */ - if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) { - prom_printf ("Seek error\n"); - return 0; - } - if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) != - sizeof(Elf64_Phdr) * e->e_phnum) { - prom_printf ("Read error\n"); - return 0; - } - - /* Scan through the program header - * HACK: We must return the _memory size of the kernel image, not the - * file size (because we have to leave room before other boot - * infos. This code works as a side effect of the fact that - * we have one section and vaddr == p_paddr - */ - loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0; - p = ph; - for (i = 0; i < e->e_phnum; ++i, ++p) { - if (p->p_type != PT_LOAD || p->p_offset == 0) - continue; - if (loadinfo->memsize == 0) { - loadinfo->offset = p->p_offset; - loadinfo->memsize = p->p_memsz; - loadinfo->filesize = p->p_filesz; - loadinfo->load_loc = p->p_vaddr; - } else { - loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */ - loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset; - } - } - - if (loadinfo->memsize == 0) { - prom_printf("Can't find a loadable segment !\n"); - return 0; - } - - /* leave some room (1Mb) for boot infos */ - loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000; - /* Claim OF memory */ - DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize); - - /* On some systems, loadaddr may already be claimed, so try some - * other nearby addresses before giving up. - */ - loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC64) ? KERNELADDR : e->e_entry; - for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) { - loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0); - if (loadinfo->base != (void *)-1) break; - } - if (loadinfo->base == (void *)-1) { - prom_printf("Claim error, can't allocate kernel memory\n"); - return 0; - } - - DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n", - loadinfo->base, loadinfo->memsize); - DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n", - loadaddr, loadinfo->memsize); - - /* Load the program segments... */ - p = ph; - for (i = 0; i < e->e_phnum; ++i, ++p) { - unsigned long offset; - if (p->p_type != PT_LOAD || p->p_offset == 0) - continue; - - /* Now, we skip to the image itself */ - if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) { - prom_printf ("Seek error\n"); - prom_release(loadinfo->base, loadinfo->memsize); - return 0; - } - offset = p->p_vaddr - loadinfo->load_loc; - if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) { - prom_printf ("Read failed\n"); - prom_release(loadinfo->base, loadinfo->memsize); - return 0; - } - } - - free(ph); + int i; + Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr); + Elf64_Phdr *p, *ph; + int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident); + unsigned long addr, loadaddr; + + /* Read the rest of the Elf header... */ + if ((*(file->fs->read))(file, size, &e->e_version) < size) { + prom_printf("\nCan't read Elf64 image header\n"); + return 0; + } + + DEBUG_F("Elf64 header:\n"); + DEBUG_F(" e.e_type = %d\n", (int)e->e_type); + DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine); + DEBUG_F(" e.e_version = %d\n", (int)e->e_version); + DEBUG_F(" e.e_entry = 0x%016lx\n", (long)e->e_entry); + DEBUG_F(" e.e_phoff = 0x%016lx\n", (long)e->e_phoff); + DEBUG_F(" e.e_shoff = 0x%016lx\n", (long)e->e_shoff); + DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags); + DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize); + DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize); + DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum); + + loadinfo->entry = e->e_entry; + + if (e->e_phnum > MAX_HEADERS) { + prom_printf ("Can only load kernels with one program header\n"); + return 0; + } + + ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum); + if (!ph) { + prom_printf ("Malloc error\n"); + return 0; + } + + /* Now, we read the section header */ + if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) { + prom_printf ("Seek error\n"); + return 0; + } + if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) != + sizeof(Elf64_Phdr) * e->e_phnum) { + prom_printf ("Read error\n"); + return 0; + } + + /* Scan through the program header + * HACK: We must return the _memory size of the kernel image, not the + * file size (because we have to leave room before other boot + * infos. This code works as a side effect of the fact that + * we have one section and vaddr == p_paddr + */ + loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0; + p = ph; + for (i = 0; i < e->e_phnum; ++i, ++p) { + if (p->p_type != PT_LOAD || p->p_offset == 0) + continue; + if (loadinfo->memsize == 0) { + loadinfo->offset = p->p_offset; + loadinfo->memsize = p->p_memsz; + loadinfo->filesize = p->p_filesz; + loadinfo->load_loc = p->p_vaddr; + } else { + loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */ + loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset; + } + } + + if (loadinfo->memsize == 0) { + prom_printf("Can't find a loadable segment !\n"); + return 0; + } + + /* leave some room (1Mb) for boot infos */ + loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000; + /* Claim OF memory */ + DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize); + + /* On some systems, loadaddr may already be claimed, so try some + * other nearby addresses before giving up. + */ + loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC64) ? KERNELADDR : e->e_entry; + for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) { + loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0); + if (loadinfo->base != (void *)-1) break; + } + if (loadinfo->base == (void *)-1) { + prom_printf("Claim error, can't allocate kernel memory\n"); + return 0; + } + + DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n", + loadinfo->base, loadinfo->memsize); + DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n", + loadaddr, loadinfo->memsize); + + /* Load the program segments... */ + p = ph; + for (i = 0; i < e->e_phnum; ++i, ++p) { + unsigned long offset; + if (p->p_type != PT_LOAD || p->p_offset == 0) + continue; + + /* Now, we skip to the image itself */ + if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) { + prom_printf ("Seek error\n"); + prom_release(loadinfo->base, loadinfo->memsize); + return 0; + } + offset = p->p_vaddr - loadinfo->load_loc; + if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) { + prom_printf ("Read failed\n"); + prom_release(loadinfo->base, loadinfo->memsize); + return 0; + } + } + + free(ph); - /* Return success at loading the Elf64 kernel */ - return 1; + /* Return success at loading the Elf64 kernel */ + return 1; } static int is_elf32(loadinfo_t *loadinfo) { - Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr); - - return (e->e_ident[EI_MAG0] == ELFMAG0 && - e->e_ident[EI_MAG1] == ELFMAG1 && - e->e_ident[EI_MAG2] == ELFMAG2 && - e->e_ident[EI_MAG3] == ELFMAG3 && - e->e_ident[EI_CLASS] == ELFCLASS32 && - e->e_ident[EI_DATA] == ELFDATA2MSB && - e->e_type == ET_EXEC && - e->e_machine == EM_PPC); + Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr); + + return (e->e_ident[EI_MAG0] == ELFMAG0 && + e->e_ident[EI_MAG1] == ELFMAG1 && + e->e_ident[EI_MAG2] == ELFMAG2 && + e->e_ident[EI_MAG3] == ELFMAG3 && + e->e_ident[EI_CLASS] == ELFCLASS32 && + e->e_ident[EI_DATA] == ELFDATA2MSB && + e->e_type == ET_EXEC && + e->e_machine == EM_PPC); } static int is_elf64(loadinfo_t *loadinfo) { - Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr); - - return (e->e_ident[EI_MAG0] == ELFMAG0 && - e->e_ident[EI_MAG1] == ELFMAG1 && - e->e_ident[EI_MAG2] == ELFMAG2 && - e->e_ident[EI_MAG3] == ELFMAG3 && - e->e_ident[EI_CLASS] == ELFCLASS64 && - e->e_ident[EI_DATA] == ELFDATA2MSB && - e->e_type == ET_EXEC && - e->e_machine == EM_PPC64); + Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr); + + return (e->e_ident[EI_MAG0] == ELFMAG0 && + e->e_ident[EI_MAG1] == ELFMAG1 && + e->e_ident[EI_MAG2] == ELFMAG2 && + e->e_ident[EI_MAG3] == ELFMAG3 && + e->e_ident[EI_CLASS] == ELFCLASS64 && + e->e_ident[EI_DATA] == ELFDATA2MSB && + e->e_type == ET_EXEC && + e->e_machine == EM_PPC64); } static void setup_display(void) { #ifdef CONFIG_SET_COLORMAP - static unsigned char default_colors[] = { - 0x00, 0x00, 0x00, - 0x00, 0x00, 0xaa, - 0x00, 0xaa, 0x00, - 0x00, 0xaa, 0xaa, - 0xaa, 0x00, 0x00, - 0xaa, 0x00, 0xaa, - 0xaa, 0x55, 0x00, - 0xaa, 0xaa, 0xaa, - 0x55, 0x55, 0x55, - 0x55, 0x55, 0xff, - 0x55, 0xff, 0x55, - 0x55, 0xff, 0xff, - 0xff, 0x55, 0x55, - 0xff, 0x55, 0xff, - 0xff, 0xff, 0x55, - 0xff, 0xff, 0xff - }; - int i, result; - prom_handle scrn = PROM_INVALID_HANDLE; - - /* Try Apple's mac-boot screen ihandle */ - result = (int)call_prom_return("interpret", 1, 2, - "\" _screen-ihandle\" $find if execute else 0 then", &scrn); - DEBUG_F("Trying to get screen ihandle, result: %d, scrn: %p\n", result, scrn); - - if (scrn == 0 || scrn == PROM_INVALID_HANDLE) { - char type[32]; - /* Hrm... check to see if stdout is a display */ - scrn = call_prom ("instance-to-package", 1, 1, prom_stdout); - DEBUG_F("instance-to-package of stdout is: %p\n", scrn); - if (prom_getprop(scrn, "device_type", type, 32) > 0 && !strncmp(type, "display", 7)) { - DEBUG_F("got it ! stdout is a screen\n"); - scrn = prom_stdout; - } else { - /* Else, we try to open the package */ - scrn = (prom_handle)call_prom( "open", 1, 1, "screen" ); - DEBUG_F("Open screen result: %p\n", scrn); - } - } + static unsigned char default_colors[] = { + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xaa, + 0x00, 0xaa, 0x00, + 0x00, 0xaa, 0xaa, + 0xaa, 0x00, 0x00, + 0xaa, 0x00, 0xaa, + 0xaa, 0x55, 0x00, + 0xaa, 0xaa, 0xaa, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0xff, + 0x55, 0xff, 0x55, + 0x55, 0xff, 0xff, + 0xff, 0x55, 0x55, + 0xff, 0x55, 0xff, + 0xff, 0xff, 0x55, + 0xff, 0xff, 0xff + }; + int i, result; + prom_handle scrn = PROM_INVALID_HANDLE; + + /* Try Apple's mac-boot screen ihandle */ + result = (int)call_prom_return("interpret", 1, 2, + "\" _screen-ihandle\" $find if execute else 0 then", &scrn); + DEBUG_F("Trying to get screen ihandle, result: %d, scrn: %p\n", result, scrn); + + if (scrn == 0 || scrn == PROM_INVALID_HANDLE) { + char type[32]; + /* Hrm... check to see if stdout is a display */ + scrn = call_prom ("instance-to-package", 1, 1, prom_stdout); + DEBUG_F("instance-to-package of stdout is: %p\n", scrn); + if (prom_getprop(scrn, "device_type", type, 32) > 0 && !strncmp(type, "display", 7)) { + DEBUG_F("got it ! stdout is a screen\n"); + scrn = prom_stdout; + } else { + /* Else, we try to open the package */ + scrn = (prom_handle)call_prom( "open", 1, 1, "screen" ); + DEBUG_F("Open screen result: %p\n", scrn); + } + } - if (scrn == PROM_INVALID_HANDLE) { - prom_printf("No screen device found !/n"); - return; - } - for(i=0;i<16;i++) { - prom_set_color(scrn, i, default_colors[i*3], - default_colors[i*3+1], default_colors[i*3+2]); - } - prom_printf("\x1b[1;37m\x1b[2;40m"); + if (scrn == PROM_INVALID_HANDLE) { + prom_printf("No screen device found !/n"); + return; + } + for(i=0;i<16;i++) { + prom_set_color(scrn, i, default_colors[i*3], + default_colors[i*3+1], default_colors[i*3+2]); + } + prom_printf("\x1b[1;37m\x1b[2;40m"); #ifdef COLOR_TEST - for (i=0;i<16; i++) { - prom_printf("\x1b[%d;%dm\x1b[1;47m%s \x1b[2;40m %s\n", - ansi_color_table[i].index, - ansi_color_table[i].value, - ansi_color_table[i].name, - ansi_color_table[i].name); - prom_printf("\x1b[%d;%dm\x1b[1;37m%s \x1b[2;30m %s\n", - ansi_color_table[i].index, - ansi_color_table[i].value+10, - ansi_color_table[i].name, - ansi_color_table[i].name); - } - prom_printf("\x1b[1;37m\x1b[2;40m"); + for (i=0;i<16; i++) { + prom_printf("\x1b[%d;%dm\x1b[1;47m%s \x1b[2;40m %s\n", + ansi_color_table[i].index, + ansi_color_table[i].value, + ansi_color_table[i].name, + ansi_color_table[i].name); + prom_printf("\x1b[%d;%dm\x1b[1;37m%s \x1b[2;30m %s\n", + ansi_color_table[i].index, + ansi_color_table[i].value+10, + ansi_color_table[i].name, + ansi_color_table[i].name); + } + prom_printf("\x1b[1;37m\x1b[2;40m"); #endif /* COLOR_TEST */ #if !DEBUG - prom_printf("\xc"); + prom_printf("\xc"); #endif /* !DEBUG */ #endif /* CONFIG_SET_COLORMAP */ @@ -1359,61 +1417,81 @@ setup_display(void) int yaboot_main(void) { - if (_machine == _MACH_Pmac) - setup_display(); - - prom_get_chosen("bootpath", bootdevice, sizeof(bootdevice)); - DEBUG_F("/chosen/bootpath = %s\n", bootdevice); - if (bootdevice[0] == 0) - prom_get_options("boot-device", bootdevice, sizeof(bootdevice)); - if (bootdevice[0] == 0) { - prom_printf("Couldn't determine boot device\n"); - return -1; - } - - if (!parse_device_path(bootdevice, (_machine == _MACH_Pmac) ? "hd" : "disc", - -1, "", &boot)) { - prom_printf("%s: Unable to parse\n", bootdevice); - return -1; - } - DEBUG_F("After parse_device_path: dev=%s, part=%d, file=%s\n", - boot.dev, boot.part, boot.file); - - if (strlen(boot.file)) { - if (!strncmp(boot.file, "\\\\", 2)) - boot.file = "\\\\"; - else { - char *p, *last; - p = last = boot.file; - while(*p) { - if (*p == '\\') - last = p; - p++; - } - if (p) - *(last) = 0; - else - boot.file = ""; - if (strlen(boot.file)) - strcat(boot.file, "\\"); - } - } - DEBUG_F("After path fixup: dev=%s, part=%d, file=%s\n", - boot.dev, boot.part, boot.file); - - useconf = load_config_file(boot.dev, boot.file, boot.part); - - prom_printf("Welcome to yaboot version " VERSION "\n"); - prom_printf("Enter \"help\" to get some basic usage information\n"); + char *ptype; + + if (_machine == _MACH_Pmac) + setup_display(); - yaboot_text_ui(); + prom_get_chosen("bootpath", bootdevice, sizeof(bootdevice)); + DEBUG_F("/chosen/bootpath = %s\n", bootdevice); + if (bootdevice[0] == 0) + prom_get_options("boot-device", bootdevice, sizeof(bootdevice)); + if (bootdevice[0] == 0) { + prom_printf("Couldn't determine boot device\n"); + return -1; + } + + if (!parse_device_path(bootdevice, (_machine == _MACH_Pmac) ? "hd" : "disc", + -1, "", &boot)) { + prom_printf("%s: Unable to parse\n", bootdevice); + return -1; + } + DEBUG_F("After parse_device_path: dev=%s, part=%d, file=%s\n", + boot.dev, boot.part, boot.file); + + if (strlen(boot.file)) { + if (!strncmp(boot.file, "\\\\", 2)) + boot.file = "\\\\"; + else { + char *p, *last; + p = last = boot.file; + while(*p) { + if (*p == '\\') + last = p; + p++; + } + if (p) + *(last) = 0; + else + boot.file = ""; + if (strlen(boot.file)) + strcat(boot.file, "\\"); + } + } + DEBUG_F("After path fixup: dev=%s, part=%d, file=%s\n", + boot.dev, boot.part, boot.file); + + useconf = load_config_file(boot.dev, boot.file, boot.part); + + prom_printf("Welcome to yaboot version " VERSION "\n"); + prom_printf("Enter \"help\" to get some basic usage information\n"); + + /* I am fed up with lusers using the wrong partition type and + mailing me *when* it breaks */ + + if (_machine == _MACH_Pmac) { + char *entry = cfg_get_strg(0, "ptypewarning"); + int warn = 1; + if (entry) + warn = strcmp(entry, + "I_know_the_partition_type_is_wrong_and_will_NOT_send_mail_when_booting_breaks"); + if (warn) { + ptype = get_part_type(boot.dev, boot.part); + if ((ptype != NULL) && (strcmp(ptype, "Apple_Bootstrap"))) + prom_printf("\nWARNING: Bootstrap partition type is wrong: \"%s\"\n" + " type should be: \"Apple_Bootstrap\"\n\n", ptype); + } + } + + yaboot_text_ui(); - prom_printf("Bye.\n"); - return 0; + prom_printf("Bye.\n"); + return 0; } + /* * Local variables: - * c-file-style: "K&R" + * c-file-style: "k&r" * c-basic-offset: 5 * End: */