2 * Yaboot - secondary boot loader for Linux on PowerPC.
4 * Copyright (C) 2001, 2002 Ethan Benson
6 * Copyright (C) 1999, 2000, 2001 Benjamin Herrenschmidt
10 * Copyright (C) 2001 Peter Bergner
12 * portions based on poof
14 * Copyright (C) 1999 Marius Vollmer
16 * portions based on quik
18 * Copyright (C) 1996 Paul Mackerras.
20 * Because this program is derived from the corresponding file in the
21 * silo-0.64 distribution, it is also
23 * Copyright (C) 1996 Pete A. Zaitcev
25 * 1996 David S. Miller
26 * 1996 Miguel de Icaza
29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation; either version 2 of the License, or
32 * (at your option) any later version.
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
54 #include "linux/elf.h"
58 #define CONFIG_FILE_NAME "yaboot.conf"
59 #define CONFIG_FILE_MAX 0x8000 /* 32k */
61 #ifdef USE_MD5_PASSWORDS
63 #endif /* USE_MD5_PASSWORDS */
65 /* align addr on a size boundry - adjust address up if needed -- Cort */
66 #define _ALIGN(addr,size) (((addr)+size-1)&(~(size-1)))
68 /* Addresses where the PPC32 and PPC64 vmlinux kernels are linked at.
69 * These are used to determine whether we are booting a vmlinux, in
70 * which case, it will be loaded at KERNELADDR. Otherwise (eg zImage),
71 * we load the binary where it was linked at (ie, e_entry field in
74 #define KERNEL_LINK_ADDR_PPC32 0xC0000000UL
75 #define KERNEL_LINK_ADDR_PPC64 0xC000000000000000ULL
83 unsigned long memsize;
84 unsigned long filesize;
86 unsigned long load_loc;
90 typedef void (*kernel_entry_t)( void *,
96 /* Imported functions */
97 extern unsigned long reloc_offset(void);
98 extern long flush_icache_range(unsigned long start, unsigned long stop);
100 /* Exported functions */
101 int yaboot_start(unsigned long r3, unsigned long r4, unsigned long r5);
103 /* Local functions */
104 static int yaboot_main(void);
105 static int is_elf32(loadinfo_t *loadinfo);
106 static int is_elf64(loadinfo_t *loadinfo);
107 static int load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo);
108 static int load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo);
109 static void setup_display(void);
111 /* Locals & globals */
114 char bootdevice[BOOTDEVSZ];
115 char bootoncelabel[1024];
117 char *password = NULL;
118 struct boot_fspec_t boot;
119 int _machine = _MACH_Pmac;
122 #ifdef CONFIG_COLOR_TEXT
124 /* Color values for text ui */
125 static struct ansi_color_t {
129 } ansi_color_table[] = {
137 { "light-gray", 0, 37 },
138 { "dark-gray", 1, 30 },
139 { "light-blue", 1, 31 },
140 { "light-green", 1, 32 },
141 { "light-cyan", 1, 33 },
142 { "light-red", 1, 34 },
143 { "light-purple", 1, 35 },
149 /* Default colors for text ui */
152 #endif /* CONFIG_COLOR_TEXT */
156 static int test_data = 0;
158 static int pause_after;
159 static char *pause_message = "Type go<return> to continue.\n";
160 static char given_bootargs[1024];
161 static int given_bootargs_by_user = 0;
163 extern unsigned char linux_logo_red[];
164 extern unsigned char linux_logo_green[];
165 extern unsigned char linux_logo_blue[];
167 #define DEFAULT_TIMEOUT -1
169 /* Entry, currently called directly by crt0 (bss not inited) */
171 extern char* __bss_start;
174 static struct first_info *quik_fip = NULL;
177 yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
180 void* malloc_base = NULL;
184 /* OF seems to do it, but I'm not very confident */
185 memset(&__bss_start, 0, &_end - &__bss_start);
187 /* Check for quik first stage bootloader (but I don't think we are
188 * compatible with it anyway, I'll look into backporting to older OF
191 if (r5 == 0xdeadbeef) {
193 quik_fip = (struct first_info *)r4;
196 /* Initialize OF interface */
197 prom_init ((prom_entry) r5);
199 /* Allocate some memory for malloc'ator */
200 for (addr = MALLOCADDR; addr <= MALLOCADDR * 16 ;addr+=0x100000) {
201 malloc_base = prom_claim((void *)addr, MALLOCSIZE, 0);
202 if (malloc_base != (void *)-1) break;
204 if (malloc_base == (void *)-1) {
205 prom_printf("Can't claim malloc buffer (%d bytes at 0x%08x)\n",
206 MALLOCSIZE, MALLOCADDR);
209 malloc_init(malloc_base, MALLOCSIZE);
210 DEBUG_F("Malloc buffer allocated at %p (%d bytes)\n",
211 malloc_base, MALLOCSIZE);
213 /* A few useless DEBUG_F's */
214 DEBUG_F("reloc_offset : %ld (should be 0)\n", reloc_offset());
215 DEBUG_F("test_bss : %d (should be 0)\n", test_bss);
216 DEBUG_F("test_data : %d (should be 0)\n", test_data);
217 DEBUG_F("&test_data : %p\n", &test_data);
218 DEBUG_F("&test_bss : %p\n", &test_bss);
219 DEBUG_F("linked at : 0x%08x\n", TEXTADDR);
221 /* ask the OF info if we're a chrp or pmac */
222 /* we need to set _machine before calling finish_device_tree */
223 root = prom_finddevice("/");
225 static char model[256];
226 if (prom_getprop(root, "CODEGEN,vendor", model, 256) > 0 &&
227 !strncmp("bplan", model, 5))
228 _machine = _MACH_bplan;
229 else if (prom_getprop(root, "device_type", model, 256 ) > 0 &&
230 !strncmp("chrp", model, 4))
231 _machine = _MACH_chrp;
233 if (prom_getprop(root, "model", model, 256 ) > 0 &&
234 !strncmp(model, "IBM", 3))
235 _machine = _MACH_chrp;
239 DEBUG_F("Running on _machine = %d\n", _machine);
243 result = yaboot_main();
245 /* Get rid of malloc pool */
247 prom_release(malloc_base, MALLOCSIZE);
248 DEBUG_F("Malloc buffer released. Exiting with code %d\n",
258 #ifdef CONFIG_COLOR_TEXT
260 * Validify color for text ui
263 check_color_text_ui(char *color)
266 while(ansi_color_table[i].name) {
267 if (!strcmp(color, ansi_color_table[i].name))
273 #endif /* CONFIG_COLOR_TEXT */
276 void print_message_file(char *filename)
280 char *defdev = boot.dev;
281 int defpart = boot.part;
286 struct boot_file_t file;
287 struct boot_fspec_t msgfile;
289 defdev = cfg_get_strg(0, "device");
292 p = cfg_get_strg(0, "partition");
294 n = simple_strtol(p, &endp, 10);
295 if (endp != p && *endp == 0)
299 strncpy(msgpath, filename, sizeof(msgpath));
300 if (!parse_device_path(msgpath, defdev, defpart, "/etc/yaboot.msg", &msgfile)) {
301 prom_printf("%s: Unable to parse\n", msgpath);
305 result = open_file(&msgfile, &file);
306 if (result != FILE_ERR_OK) {
307 prom_printf("%s:%d,", msgfile.dev, msgfile.part);
308 prom_perror(result, msgfile.file);
317 memset(msg, 0, 2001);
319 if (file.fs->read(&file, 2000, msg) <= 0)
322 prom_printf("%s", msg);
326 file.fs->close(&file);
331 /* Currently, the config file must be at the root of the filesystem.
332 * todo: recognize the full path to myself and use it to load the
333 * config file. Handle the "\\" (blessed system folder)
336 load_config_file(struct boot_fspec_t *fspec)
338 char *conf_file = NULL, *p;
339 struct boot_file_t file;
340 int sz, opened = 0, result = 0;
342 /* Allocate a buffer for the config file */
343 conf_file = malloc(CONFIG_FILE_MAX);
345 prom_printf("Can't alloc config file buffer\n");
350 result = open_file(fspec, &file);
351 if (result != FILE_ERR_OK) {
352 prom_printf("%s:%d,", fspec->dev, fspec->part);
353 prom_perror(result, fspec->file);
354 prom_printf("Can't open config file\n");
360 sz = file.fs->read(&file, CONFIG_FILE_MAX, conf_file);
362 prom_printf("Error, can't read config file\n");
365 prom_printf("Config file read, %d bytes\n", sz);
369 file.fs->close(&file);
372 /* Call the parsing code in cfg.c */
373 if (cfg_parse(fspec->file, conf_file, sz) < 0) {
374 prom_printf ("Syntax error or read error config\n");
379 * set the default cf_option to label that has the same MAC addr
380 * it only works if there is a label with the MAC addr on yaboot.conf
382 if (prom_get_devtype(fspec->dev) == FILE_DEVICE_NET) {
383 /* change the variable bellow to get the MAC dinamicaly */
384 char * macaddr = NULL;
387 macaddr = prom_get_mac(prom_get_netinfo());
388 default_mac = cfg_set_default_by_mac(macaddr);
389 if (default_mac >= 1) {
390 prom_printf("Default label was changed to macaddr label.\n");
394 DEBUG_F("Config file successfully parsed, %d bytes\n", sz);
396 /* Now, we do the initialisations stored in the config file */
397 p = cfg_get_strg(0, "init-code");
401 password = cfg_get_strg(0, "password");
403 #ifdef CONFIG_COLOR_TEXT
404 p = cfg_get_strg(0, "fgcolor");
406 DEBUG_F("fgcolor=%s\n", p);
407 fgcolor = check_color_text_ui(p);
409 prom_printf("Invalid fgcolor: \"%s\".\n", p);
412 p = cfg_get_strg(0, "bgcolor");
414 DEBUG_F("bgcolor=%s\n", p);
415 bgcolor = check_color_text_ui(p);
417 prom_printf("Invalid bgcolor: \"%s\".\n", p);
421 sprintf(temp, "%x to background-color", bgcolor);
422 prom_interpret(temp);
429 sprintf(temp, "%x to foreground-color", fgcolor);
430 prom_interpret(temp);
432 #endif /* CONFIG_COLOR_TEXT */
434 p = cfg_get_strg(0, "init-message");
436 prom_printf("%s\n", p);
438 p = cfg_get_strg(0, "message");
440 print_message_file(p);
447 file.fs->close(&file);
456 * Search for config file by MAC address, then by IP address.
457 * Basically copying pxelinux's algorithm.
458 * http://syslinux.zytor.com/pxe.php#config
460 static int load_my_config_file(struct boot_fspec_t *orig_fspec)
462 struct bootp_packet *packet;
464 struct boot_fspec_t fspec = *orig_fspec;
465 char *cfgpath = (_machine == _MACH_chrp || _machine == _MACH_bplan) ? "/etc/" : "";
469 packet = prom_get_netinfo();
472 * First, try to match on mac address with the hardware type
476 /* 3 chars per byte in chaddr + 2 chars for htype + /etc/ +\0 */
477 fspec.file = malloc(packet->hlen * 3 + 2 + 6);
481 sprintf(fspec.file, "%s%02x-", cfgpath, packet->htype);
482 strcat(fspec.file, prom_get_mac(packet));
484 rc = load_config_file(&fspec);
489 * Now try to match on IP.
491 /* no need to realloc for /etc/ + 8 chars in yiaddr + \0 */
492 sprintf(fspec.file, "%s%s", cfgpath, prom_get_ip(packet));
494 for (flen = strlen(fspec.file),
495 minlen = strlen(cfgpath); flen > minlen; flen--) {
496 rc = load_config_file(&fspec);
499 /* Chop one digit off the end, try again */
500 fspec.file[flen - 1] = '\0';
504 if (rc) /* modify original only on success */
505 orig_fspec->file = fspec.file;
511 void maintabfunc (void)
515 prom_printf("boot: %s", cbuff);
520 word_split(char **linep, char **paramsp)
535 while (*p != 0 && *p != ' ')
544 make_params(char *label, char *params)
547 static char buffer[2048];
552 p = cfg_get_strg(label, "literal");
564 p = cfg_get_strg(label, "root");
571 if (cfg_get_flag(label, "read-only")) {
575 if (cfg_get_flag(label, "read-write")) {
579 p = cfg_get_strg(label, "ramdisk");
581 strcpy (q, "ramdisk=");
586 p = cfg_get_strg(label, "initrd-size");
588 strcpy (q, "ramdisk_size=");
593 if (cfg_get_flag(label, "novideo")) {
594 strcpy (q, "video=ofonly");
598 p = cfg_get_strg (label, "append");
605 pause_after = cfg_get_flag (label, "pause-after");
606 p = cfg_get_strg(label, "pause-message");
615 void check_password(char *str)
619 prom_printf("\n%s", str);
620 for (i = 0; i < 3; i++) {
621 prom_printf ("\nPassword: ");
623 cmdedit ((void (*)(void)) 0, 1);
625 #ifdef USE_MD5_PASSWORDS
626 if (!strncmp (password, "$1$", 3)) {
627 if (!check_md5_password(passwdbuff, password))
630 else if (!strcmp (password, passwdbuff))
633 if (!strcmp (password, passwdbuff))
635 #endif /* USE_MD5_PASSWORDS */
638 prom_printf ("Incorrect password. Try again.");
641 prom_printf(" ___________________\n< Permission denied >\n -------------------\n"
642 " \\ ^__^\n \\ (oo)\\_______\n (__)\\ )\\/\\\n"
643 " ||----w |\n || ||\n");
645 prom_interpret("reset-all");
648 int get_params(struct boot_param_t* params)
652 char defdevice_bak[1024];
655 char *imagename = 0, *label;
660 static int first = 1;
661 static char imagepath[1024];
662 static char initrdpath[1024];
663 static char sysmappath[1024];
664 static char manualinitrd[1024];
665 static int definitrd = 1, hasarg = 0;
668 memset(params, 0, sizeof(*params));
670 params->kernel.part = -1;
671 params->rd.part = -1;
672 params->sysmap.part = -1;
679 imagename = bootargs;
680 word_split(&imagename, ¶ms->args);
681 timeout = DEFAULT_TIMEOUT;
683 prom_printf("Default supplied on the command line: %s ", imagename);
685 prom_printf("%s", params->args);
688 if (useconf && (q = cfg_get_strg(0, "timeout")) != 0 && *q != 0)
689 timeout = simple_strtol(q, NULL, 0);
692 prom_printf("boot: ");
697 end = beg + 100 * timeout;
699 c = prom_nbgetchar();
700 } while (c == -1 && prom_getms() <= end);
704 else if (c != '\n' && c != '\t' && c != '\r' && c != '\b' ) {
710 if (c != -1 && c != '\n' && c != '\r') {
713 } else if (c >= ' ') {
716 if ((cfg_get_flag (cbuff, "single-key")) && useconf) {
719 prom_printf("%s\n", cbuff);
724 if (c == '\n' || c == '\r') {
726 if (bootoncelabel[0] != 0)
727 imagename = bootoncelabel;
729 imagename = cfg_get_default();
732 prom_printf("%s", imagename);
734 prom_printf(" %s", params->args);
736 } else if (!singlekey) {
737 cmdedit(maintabfunc, 0);
739 strcpy(given_bootargs, cbuff);
740 given_bootargs_by_user = 1;
742 word_split(&imagename, ¶ms->args);
745 /* initrd setup via cmd console */
746 /* first, check if the user uses it with some label */
747 if (!strncmp(params->args, "initrd=", 7)) {
748 DEBUG_F("params->args: %s\n", params->args);
751 /* after, check if there is the 'initrd=' in the imagename string */
752 if (!strncmp(imagename, "initrd=", 7) || !definitrd) {
754 /* return the value of definitrd to 1 */
758 /* args = "initrd=blah" */
769 /* copy the string after the '=' to manualinitrd */
770 strcpy(manualinitrd, args+7);
772 prom_printf("New initrd file specified: %s\n", manualinitrd);
774 prom_printf("ERROR: no initrd specified!\n");
778 /* set imagename with the default values of the config file */
779 if ((prom_get_devtype(boot.dev) == FILE_DEVICE_NET) && !hasarg)
780 imagename = cfg_get_default();
782 imagename = cfg_get_default();
785 /* chrp gets this wrong, force it -- Cort */
786 if ( useconf && (!imagename || imagename[0] == 0 ))
787 imagename = cfg_get_default();
790 defdevice = boot.dev;
792 strcpy(defdevice_bak,defdevice);
795 defdevice = cfg_get_strg(0, "device");
796 p = cfg_get_strg(0, "partition");
798 n = simple_strtol(p, &endp, 10);
799 if (endp != p && *endp == 0)
802 p = cfg_get_strg(0, "pause-message");
805 if (cfg_get_flag(0, "restricted"))
807 p = cfg_get_strg(imagename, "image");
811 defdevice = cfg_get_strg(label, "device");
812 if(!defdevice) defdevice=boot.dev;
813 p = cfg_get_strg(label, "partition");
815 n = simple_strtol(p, &endp, 10);
816 if (endp != p && *endp == 0)
819 if (cfg_get_flag(label, "restricted"))
822 if (params->args && password && restricted)
823 check_password ("To specify arguments for this image "
824 "you must enter the password.");
825 else if (password && !restricted)
826 check_password ("This image is restricted.");
828 params->args = make_params(label, params->args);
832 if (!strcmp (imagename, "help")) {
833 /* FIXME: defdevice shouldn't need to be reset all over the place */
834 if(!defdevice) defdevice = boot.dev;
836 "\nPress the tab key for a list of defined images.\n"
837 "The label marked with a \"*\" is is the default image, "
838 "press <return> to boot it.\n\n"
839 "To boot any other label simply type its name and press <return>.\n\n"
840 "To boot a kernel image which is not defined in the yaboot configuration \n"
841 "file, enter the kernel image name as [[device:][partno],]/path, where \n"
842 "\"device:\" is the OpenFirmware device path to the disk the image \n"
843 "resides on, and \"partno\" is the partition number the image resides on.\n"
844 "Note that the comma (,) is only required if you specify an OpenFirmware\n"
845 "device, if you only specify a filename you should not start it with a \",\"\n\n"
846 "To boot a alternative initrd file rather than specified in the yaboot\n"
847 "configuration file, use the \"initrd\" command on Yaboot's prompt: \n"
848 "\"initrd=[name.img]\". This will load the \"name.img\" file after the default\n"
849 "kernel image. You can, also, specify a different initrd file to any other\n"
850 "label of the yaboot configuration file. Just type \"label initrd=[name.img]\"\n"
851 "and the specified initrd file will be loaded.\n\n"
852 "To load an alternative config file rather than /etc/yaboot.conf, enter\n"
853 "its device, partno and path, on Open Firmware Prompt:\n"
854 "boot conf=device:partno,/path/to/configfile\n."
855 "To reload the config file or load a new one, use the \"conf\" command\n"
856 "on Yaboot's prompt:\n"
857 "conf [device=device] [partition=partno] [file=/path/to/configfile]\n\n"
858 "If you omit \"device\" and \"partno\", Yaboot will use their current\n"
859 "values. You can check them by entering \"conf\" on Yaboot's prompt.\n");
864 if (!strcmp (imagename, "halt")) {
866 check_password ("Restricted command.");
870 if (!strcmp (imagename, "bye")) {
872 check_password ("Restricted command.");
878 if (!strncmp (imagename, "conf", 4)) {
880 // imagename = "conf file=blah dev=bleh part=blih"
881 DEBUG_F("Loading user-specified config file: %s\n",imagename);
883 check_password ("Restricted command.");
887 // args= "file=blah dev=bleh part=blih"
888 char *args = params->args;
892 // set a pointer to the first space in args
893 char *space = strchr(args,' ');
897 char temp[1024] = "0";
899 // copy next argument to temp
900 strncpy(temp, args, space-args);
902 // parse temp and set boot arguments
903 if (!strncmp (temp, "file=", 5)){
904 DEBUG_F("conf file: %s\n", temp+5);
905 strcpy(boot.file, temp+5);
906 } else if (!strncmp (temp, "device=", 7)){
907 DEBUG_F("conf device: %s\n", temp+7);
908 strcpy(boot.dev, temp+7);
909 } else if (!strncmp (temp, "partition=", 10)){
910 DEBUG_F("conf partition: %s\n", temp+10);
911 boot.part=simple_strtol(temp+10,NULL,10);
915 // set the pointer to the next space in args;
916 // set the loop control variable
917 if (strlen(space)>1){
918 // Go to the next argument
922 if (strchr(args,' ') == NULL)
923 space = &args[strlen(args)];
925 space = strchr(args,' ');
932 prom_printf("Loading config file...\n");
933 useconf = load_config_file(&boot);
935 if ((q = cfg_get_strg(0, "timeout")) != 0 && *q != 0)
936 timeout = simple_strtol(q, NULL, 0);
938 prom_printf("Restoring default values.\n");
939 strcpy(boot.file,"");
940 strcpy(boot.dev, defdevice_bak);
945 prom_printf("Current configuration:\n");
946 prom_printf("device: %s\n", boot.dev);
948 prom_printf("partition: auto\n");
950 prom_printf("partition: %d\n", boot.part);
951 if (strlen(boot.file))
952 prom_printf("file: %s\n", boot.file);
954 prom_printf("file: /etc/%s\n",CONFIG_FILE_NAME);
963 if (imagename[0] == '$') {
964 /* forth command string */
966 check_password ("OpenFirmware commands are restricted.");
967 prom_interpret(imagename+1);
971 strncpy(imagepath, imagename, 1024);
973 if (!label && password)
974 check_password ("To boot a custom image you must enter the password.");
976 if (!parse_device_path(imagepath, defdevice, defpart,
977 "/vmlinux", ¶ms->kernel)) {
978 prom_printf("%s: Unable to parse\n", imagepath);
981 DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev, params->kernel.part, params->kernel.file);
983 p = cfg_get_strg(label, "initrd");
986 /* check if user seted to use a initrd file from boot console */
987 if (!definitrd && p != manualinitrd) {
988 if (manualinitrd[0] != "/" && (prom_get_devtype(defdevice_bak) != FILE_DEVICE_NET)) {
989 strcpy(initrdpath, "/");
990 strcat(initrdpath, manualinitrd);
992 strncpy(initrdpath, manualinitrd, 1024);
994 strncpy(initrdpath, p, 1024);
996 DEBUG_F("Parsing initrd path <%s>\n", initrdpath);
997 if (!parse_device_path(initrdpath, defdevice, defpart,
998 "/root.bin", ¶ms->rd)) {
999 prom_printf("%s: Unable to parse\n", imagepath);
1003 p = cfg_get_strg(label, "sysmap");
1005 DEBUG_F("Parsing sysmap path <%s>\n", p);
1006 strncpy(sysmappath, p, 1024);
1007 if (!parse_device_path(sysmappath, defdevice, defpart,
1008 "/boot/System.map", ¶ms->sysmap)) {
1009 prom_printf("%s: Unable to parse\n", imagepath);
1017 /* This is derived from quik core. To be changed to first parse the headers
1018 * doing lazy-loading, and then claim the memory before loading the kernel
1020 * We also need to add initrd support to this whole mecanism
1023 yaboot_text_ui(void)
1025 #define MAX_HEADERS 32
1027 struct boot_file_t file;
1029 static struct boot_param_t params;
1031 unsigned long initrd_size;
1033 unsigned long sysmap_size;
1034 kernel_entry_t kernel_entry;
1035 struct bi_record* birec;
1037 loadinfo_t loadinfo;
1038 void *initrd_more,*initrd_want;
1039 unsigned long initrd_read;
1041 loadinfo.load_loc = 0;
1049 if (get_params(¶ms))
1051 if (!params.kernel.file)
1054 prom_printf("Please wait, loading kernel...\n");
1056 memset(&file, 0, sizeof(file));
1058 if (strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.kernel.file[0] != '/'
1059 && params.kernel.file[0] != '\\') {
1060 loc=(char*)malloc(strlen(params.kernel.file)+3);
1062 prom_printf ("malloc error\n");
1065 strcpy(loc,boot.file);
1066 strcat(loc,params.kernel.file);
1067 free(params.kernel.file);
1068 params.kernel.file=loc;
1070 result = open_file(¶ms.kernel, &file);
1071 if (result != FILE_ERR_OK) {
1072 prom_printf("%s:%d,", params.kernel.dev, params.kernel.part);
1073 prom_perror(result, params.kernel.file);
1077 /* Read the Elf e_ident, e_type and e_machine fields to
1078 * determine Elf file type
1080 if (file.fs->read(&file, sizeof(Elf_Ident), &loadinfo.elf) < sizeof(Elf_Ident)) {
1081 prom_printf("\nCan't read Elf e_ident/e_type/e_machine info\n");
1082 file.fs->close(&file);
1083 memset(&file, 0, sizeof(file));
1087 if (is_elf32(&loadinfo)) {
1088 if (!load_elf32(&file, &loadinfo)) {
1089 file.fs->close(&file);
1090 memset(&file, 0, sizeof(file));
1093 prom_printf(" Elf32 kernel loaded...\n");
1094 } else if (is_elf64(&loadinfo)) {
1095 if (!load_elf64(&file, &loadinfo)) {
1096 file.fs->close(&file);
1097 memset(&file, 0, sizeof(file));
1100 prom_printf(" Elf64 kernel loaded...\n");
1102 prom_printf ("%s: Not a valid ELF image\n", params.kernel.file);
1103 file.fs->close(&file);
1104 memset(&file, 0, sizeof(file));
1107 file.fs->close(&file);
1108 memset(&file, 0, sizeof(file));
1110 /* If sysmap, load it (only if booting a vmlinux).
1112 if (flat_vmlinux && params.sysmap.file) {
1113 prom_printf("Loading System.map ...\n");
1114 if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.sysmap.file[0] != '/'
1115 && params.sysmap.file[0] != '\\') {
1117 loc=(char*)malloc(strlen(params.sysmap.file)+3);
1119 prom_printf ("malloc error\n");
1122 strcpy(loc,boot.file);
1123 strcat(loc,params.sysmap.file);
1124 free(params.sysmap.file);
1125 params.sysmap.file=loc;
1128 result = open_file(¶ms.sysmap, &file);
1129 if (result != FILE_ERR_OK) {
1130 prom_printf("%s:%d,", params.sysmap.dev, params.sysmap.part);
1131 prom_perror(result, params.sysmap.file);
1134 sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0);
1135 if (sysmap_base == (void *)-1) {
1136 prom_printf("Claim failed for sysmap memory\n");
1140 sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base);
1141 if (sysmap_size == 0)
1144 ((char *)sysmap_base)[sysmap_size++] = 0;
1146 file.fs->close(&file);
1147 memset(&file, 0, sizeof(file));
1150 prom_printf("System.map loaded at %p, size: %lu Kbytes\n",
1151 sysmap_base, sysmap_size >> 10);
1152 loadinfo.memsize += _ALIGN(0x100000, 0x1000);
1154 prom_printf("System.map load failed !\n");
1159 /* If ramdisk, load it (only if booting a vmlinux). For now, we
1160 * can't tell the size it will be so we claim an arbitrary amount
1163 if (flat_vmlinux && params.rd.file) {
1164 if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.rd.file[0] != '/'
1165 && params.kernel.file[0] != '\\')
1168 loc=(char*)malloc(strlen(params.rd.file)+3);
1170 prom_printf ("Malloc error\n");
1173 strcpy(loc,boot.file);
1174 strcat(loc,params.rd.file);
1175 free(params.rd.file);
1178 prom_printf("Loading ramdisk...\n");
1179 result = open_file(¶ms.rd, &file);
1180 if (result != FILE_ERR_OK) {
1181 prom_printf("%s:%d,", params.rd.dev, params.rd.part);
1182 prom_perror(result, params.rd.file);
1185 #define INITRD_CHUNKSIZE 0x100000
1186 initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0);
1187 if (initrd_base == (void *)-1) {
1188 prom_printf("Claim failed for initrd memory\n");
1191 initrd_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_base);
1192 if (initrd_size == 0)
1194 initrd_read = initrd_size;
1195 initrd_more = initrd_base;
1196 while (initrd_read == INITRD_CHUNKSIZE ) { /* need to read more? */
1197 initrd_want = (void *)((unsigned long)initrd_more+INITRD_CHUNKSIZE);
1198 initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0);
1199 if (initrd_more != initrd_want) {
1200 prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more);
1204 initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
1205 DEBUG_F(" block at %p rc=%lu\n",initrd_more,initrd_read);
1206 initrd_size += initrd_read;
1209 file.fs->close(&file);
1210 memset(&file, 0, sizeof(file));
1213 prom_printf("ramdisk loaded at %p, size: %lu Kbytes\n",
1214 initrd_base, initrd_size >> 10);
1216 prom_printf("ramdisk load failed !\n");
1221 DEBUG_F("setting kernel args to: %s\n", params.args);
1222 prom_setargs(params.args);
1223 DEBUG_F("flushing icache...");
1224 flush_icache_range ((long)loadinfo.base, (long)loadinfo.base+loadinfo.memsize);
1229 * Fill new boot infos (only if booting a vmlinux).
1231 * The birec is low on memory, probably inside the malloc pool,
1232 * so we don't write it earlier. At this point, we should not
1233 * use anything coming from the malloc pool.
1235 birec = (struct bi_record *)_ALIGN(loadinfo.filesize+(1<<20)-1,(1<<20));
1237 /* We make sure it's mapped. We map only 64k for now, it's
1238 * plenty enough we don't claim since this precise memory
1239 * range may already be claimed by the malloc pool.
1241 prom_map (birec, birec, 0x10000);
1242 DEBUG_F("birec at %p\n", birec);
1245 birec->tag = BI_FIRST;
1246 birec->size = sizeof(struct bi_record);
1247 birec = (struct bi_record *)((ulong)birec + birec->size);
1249 birec->tag = BI_BOOTLOADER_ID;
1250 sprintf( (char *)birec->data, "yaboot");
1251 birec->size = sizeof(struct bi_record) + strlen("yaboot") + 1;
1252 birec = (struct bi_record *)((ulong)birec + birec->size);
1254 birec->tag = BI_MACHTYPE;
1255 birec->data[0] = _machine;
1256 birec->size = sizeof(struct bi_record) + sizeof(ulong);
1257 birec = (struct bi_record *)((ulong)birec + birec->size);
1260 birec->tag = BI_SYSMAP;
1261 birec->data[0] = (ulong)sysmap_base;
1262 birec->data[1] = sysmap_size;
1263 birec->size = sizeof(struct bi_record) + sizeof(ulong)*2;
1264 birec = (struct bi_record *)((ulong)birec + birec->size);
1266 birec->tag = BI_LAST;
1267 birec->size = sizeof(struct bi_record);
1268 birec = (struct bi_record *)((ulong)birec + birec->size);
1271 /* compute the kernel's entry point. */
1272 kernel_entry = loadinfo.base + loadinfo.entry - loadinfo.load_loc;
1274 DEBUG_F("Kernel entry point = %p\n", kernel_entry);
1275 DEBUG_F("kernel: arg1 = %p,\n"
1276 " arg2 = 0x%08lx,\n"
1280 initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
1282 DEBUG_F("Entering kernel...\n");
1284 /* call the kernel with our stack. */
1285 kernel_entry(initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
1293 load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
1296 Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
1298 int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident);
1299 unsigned long loadaddr;
1301 /* Read the rest of the Elf header... */
1302 if ((*(file->fs->read))(file, size, &e->e_version) < size) {
1303 prom_printf("\nCan't read Elf32 image header\n");
1307 DEBUG_F("Elf32 header:\n");
1308 DEBUG_F(" e.e_type = %d\n", (int)e->e_type);
1309 DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine);
1310 DEBUG_F(" e.e_version = %d\n", (int)e->e_version);
1311 DEBUG_F(" e.e_entry = 0x%08x\n", (int)e->e_entry);
1312 DEBUG_F(" e.e_phoff = 0x%08x\n", (int)e->e_phoff);
1313 DEBUG_F(" e.e_shoff = 0x%08x\n", (int)e->e_shoff);
1314 DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags);
1315 DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize);
1316 DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
1317 DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum);
1319 loadinfo->entry = e->e_entry;
1321 if (e->e_phnum > MAX_HEADERS) {
1322 prom_printf ("Can only load kernels with one program header\n");
1326 ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum);
1328 prom_printf ("Malloc error\n");
1332 /* Now, we read the section header */
1333 if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
1334 prom_printf ("seek error\n");
1337 if ((*(file->fs->read))(file, sizeof(Elf32_Phdr) * e->e_phnum, ph) !=
1338 sizeof(Elf32_Phdr) * e->e_phnum) {
1339 prom_printf ("read error\n");
1343 /* Scan through the program header
1344 * HACK: We must return the _memory size of the kernel image, not the
1345 * file size (because we have to leave room before other boot
1346 * infos. This code works as a side effect of the fact that
1347 * we have one section and vaddr == p_paddr
1349 loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
1351 for (i = 0; i < e->e_phnum; ++i, ++p) {
1352 if (p->p_type != PT_LOAD || p->p_offset == 0)
1354 if (loadinfo->memsize == 0) {
1355 loadinfo->offset = p->p_offset;
1356 loadinfo->memsize = p->p_memsz;
1357 loadinfo->filesize = p->p_filesz;
1358 loadinfo->load_loc = p->p_vaddr;
1360 loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
1361 loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
1365 if (loadinfo->memsize == 0) {
1366 prom_printf("Can't find a loadable segment !\n");
1370 /* leave some room (1Mb) for boot infos */
1371 loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
1372 /* Claim OF memory */
1373 DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
1375 /* Determine whether we are trying to boot a vmlinux or some
1376 * other binary image (eg, zImage). We load vmlinux's at
1377 * KERNELADDR and all other binaries at their e_entry value.
1379 if (e->e_entry == KERNEL_LINK_ADDR_PPC32) {
1381 loadaddr = KERNELADDR;
1384 loadaddr = loadinfo->load_loc;
1387 loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0);
1388 if (loadinfo->base == (void *)-1) {
1389 prom_printf("Claim error, can't allocate kernel memory\n");
1393 DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
1394 loadinfo->base, loadinfo->memsize);
1395 DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
1396 loadaddr, loadinfo->memsize);
1398 /* Load the program segments... */
1400 for (i = 0; i < e->e_phnum; ++i, ++p) {
1401 unsigned long offset;
1402 if (p->p_type != PT_LOAD || p->p_offset == 0)
1405 /* Now, we skip to the image itself */
1406 if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
1407 prom_printf ("Seek error\n");
1408 prom_release(loadinfo->base, loadinfo->memsize);
1411 offset = p->p_vaddr - loadinfo->load_loc;
1412 if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
1413 prom_printf ("Read failed\n");
1414 prom_release(loadinfo->base, loadinfo->memsize);
1421 /* Return success at loading the Elf32 kernel */
1431 load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
1434 Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
1436 int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident);
1437 unsigned long loadaddr;
1439 /* Read the rest of the Elf header... */
1440 if ((*(file->fs->read))(file, size, &e->e_version) < size) {
1441 prom_printf("\nCan't read Elf64 image header\n");
1445 DEBUG_F("Elf64 header:\n");
1446 DEBUG_F(" e.e_type = %d\n", (int)e->e_type);
1447 DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine);
1448 DEBUG_F(" e.e_version = %d\n", (int)e->e_version);
1449 DEBUG_F(" e.e_entry = 0x%016lx\n", (long)e->e_entry);
1450 DEBUG_F(" e.e_phoff = 0x%016lx\n", (long)e->e_phoff);
1451 DEBUG_F(" e.e_shoff = 0x%016lx\n", (long)e->e_shoff);
1452 DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags);
1453 DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize);
1454 DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
1455 DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum);
1457 loadinfo->entry = e->e_entry;
1459 if (e->e_phnum > MAX_HEADERS) {
1460 prom_printf ("Can only load kernels with one program header\n");
1464 ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum);
1466 prom_printf ("Malloc error\n");
1470 /* Now, we read the section header */
1471 if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
1472 prom_printf ("Seek error\n");
1475 if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) !=
1476 sizeof(Elf64_Phdr) * e->e_phnum) {
1477 prom_printf ("Read error\n");
1481 /* Scan through the program header
1482 * HACK: We must return the _memory size of the kernel image, not the
1483 * file size (because we have to leave room before other boot
1484 * infos. This code works as a side effect of the fact that
1485 * we have one section and vaddr == p_paddr
1487 loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
1489 for (i = 0; i < e->e_phnum; ++i, ++p) {
1490 if (p->p_type != PT_LOAD || p->p_offset == 0)
1492 if (loadinfo->memsize == 0) {
1493 loadinfo->offset = p->p_offset;
1494 loadinfo->memsize = p->p_memsz;
1495 loadinfo->filesize = p->p_filesz;
1496 loadinfo->load_loc = p->p_vaddr;
1498 loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
1499 loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
1503 if (loadinfo->memsize == 0) {
1504 prom_printf("Can't find a loadable segment !\n");
1508 /* leave some room (1Mb) for boot infos */
1509 loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
1510 /* Claim OF memory */
1511 DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
1513 /* Determine whether we are trying to boot a vmlinux or some
1514 * other binary image (eg, zImage). We load vmlinux's at
1515 * KERNELADDR and all other binaries at their e_entry value.
1517 if (e->e_entry == KERNEL_LINK_ADDR_PPC64) {
1519 loadaddr = KERNELADDR;
1522 loadaddr = e->e_entry;
1525 loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0);
1526 if (loadinfo->base == (void *)-1) {
1527 prom_printf("Claim error, can't allocate kernel memory\n");
1531 DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
1532 loadinfo->base, loadinfo->memsize);
1533 DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
1534 loadaddr, loadinfo->memsize);
1536 /* Load the program segments... */
1538 for (i = 0; i < e->e_phnum; ++i, ++p) {
1539 unsigned long offset;
1540 if (p->p_type != PT_LOAD || p->p_offset == 0)
1543 /* Now, we skip to the image itself */
1544 if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
1545 prom_printf ("Seek error\n");
1546 prom_release(loadinfo->base, loadinfo->memsize);
1549 offset = p->p_vaddr - loadinfo->load_loc;
1550 if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
1551 prom_printf ("Read failed\n");
1552 prom_release(loadinfo->base, loadinfo->memsize);
1559 /* Return success at loading the Elf64 kernel */
1569 is_elf32(loadinfo_t *loadinfo)
1571 Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
1573 return (e->e_ident[EI_MAG0] == ELFMAG0 &&
1574 e->e_ident[EI_MAG1] == ELFMAG1 &&
1575 e->e_ident[EI_MAG2] == ELFMAG2 &&
1576 e->e_ident[EI_MAG3] == ELFMAG3 &&
1577 e->e_ident[EI_CLASS] == ELFCLASS32 &&
1578 e->e_ident[EI_DATA] == ELFDATA2MSB &&
1579 e->e_type == ET_EXEC &&
1580 e->e_machine == EM_PPC);
1584 is_elf64(loadinfo_t *loadinfo)
1586 Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
1588 return (e->e_ident[EI_MAG0] == ELFMAG0 &&
1589 e->e_ident[EI_MAG1] == ELFMAG1 &&
1590 e->e_ident[EI_MAG2] == ELFMAG2 &&
1591 e->e_ident[EI_MAG3] == ELFMAG3 &&
1592 e->e_ident[EI_CLASS] == ELFCLASS64 &&
1593 e->e_ident[EI_DATA] == ELFDATA2MSB &&
1594 e->e_type == ET_EXEC &&
1595 e->e_machine == EM_PPC64);
1601 #ifdef CONFIG_SET_COLORMAP
1602 static unsigned char default_colors[] = {
1621 prom_handle scrn = PROM_INVALID_HANDLE;
1623 /* Try Apple's mac-boot screen ihandle */
1624 result = (int)call_prom_return("interpret", 1, 2,
1625 "\" _screen-ihandle\" $find if execute else 0 then", &scrn);
1626 DEBUG_F("Trying to get screen ihandle, result: %d, scrn: %p\n", result, scrn);
1628 if (scrn == 0 || scrn == PROM_INVALID_HANDLE) {
1630 /* Hrm... check to see if stdout is a display */
1631 scrn = call_prom ("instance-to-package", 1, 1, prom_stdout);
1632 DEBUG_F("instance-to-package of stdout is: %p\n", scrn);
1633 if (prom_getprop(scrn, "device_type", type, 32) > 0 && !strncmp(type, "display", 7)) {
1634 DEBUG_F("got it ! stdout is a screen\n");
1637 /* Else, we try to open the package */
1638 scrn = (prom_handle)call_prom( "open", 1, 1, "screen" );
1639 DEBUG_F("Open screen result: %p\n", scrn);
1643 if (scrn == PROM_INVALID_HANDLE) {
1644 prom_printf("No screen device found !\n");
1648 prom_set_color(scrn, i, default_colors[i*3],
1649 default_colors[i*3+1], default_colors[i*3+2]);
1651 prom_printf("\x1b[1;37m\x1b[2;40m");
1653 for (i=0;i<16; i++) {
1654 prom_printf("\x1b[%d;%dm\x1b[1;47m%s \x1b[2;40m %s\n",
1655 ansi_color_table[i].index,
1656 ansi_color_table[i].value,
1657 ansi_color_table[i].name,
1658 ansi_color_table[i].name);
1659 prom_printf("\x1b[%d;%dm\x1b[1;37m%s \x1b[2;30m %s\n",
1660 ansi_color_table[i].index,
1661 ansi_color_table[i].value+10,
1662 ansi_color_table[i].name,
1663 ansi_color_table[i].name);
1665 prom_printf("\x1b[1;37m\x1b[2;40m");
1666 #endif /* COLOR_TEST */
1672 #endif /* CONFIG_SET_COLORMAP */
1680 char conf_path[1024];
1682 if (_machine == _MACH_Pmac)
1685 prom_get_chosen("bootargs", bootargs, sizeof(bootargs));
1686 DEBUG_F("/chosen/bootargs = %s\n", bootargs);
1687 prom_get_chosen("bootpath", bootdevice, BOOTDEVSZ);
1688 DEBUG_F("/chosen/bootpath = %s\n", bootdevice);
1690 /* If conf= specified on command line, it overrides
1691 Usage: conf=device:partition,/path/to/conffile
1692 Example: On Open Firmware Prompt, type
1693 boot conf=/pci@8000000f8000000/pci@1/pci1014,028C@1/scsi@0/sd@1,0:3,/etc/yaboot.conf */
1695 if (!strncmp(bootargs, "conf=", 5)) {
1696 DEBUG_F("Using conf argument in Open Firmware\n");
1697 char *end = strchr(bootargs,' ');
1701 strcpy(bootdevice, bootargs + 5);
1703 DEBUG_F("Using conf=%s\n", bootdevice);
1705 /* Remove conf=xxx from bootargs */
1707 memmove(bootargs, end+1, strlen(end+1)+1);
1711 if (bootdevice[0] == 0) {
1712 prom_get_options("boot-device", bootdevice, BOOTDEVSZ);
1713 DEBUG_F("boot-device = %s\n", bootdevice);
1715 if (bootdevice[0] == 0) {
1716 prom_printf("Couldn't determine boot device\n");
1720 if (bootoncelabel[0] == 0) {
1721 prom_get_options("boot-once", bootoncelabel,
1722 sizeof(bootoncelabel));
1723 if (bootoncelabel[0] != 0)
1724 DEBUG_F("boot-once: [%s]\n", bootoncelabel);
1726 prom_set_options("boot-once", NULL, 0);
1728 if (!parse_device_path(bootdevice, NULL, -1, "", &boot)) {
1729 prom_printf("%s: Unable to parse\n", bootdevice);
1732 if (_machine == _MACH_bplan)
1734 DEBUG_F("After parse_device_path: dev=%s, part=%d, file=%s\n",
1735 boot.dev, boot.part, boot.file);
1738 if (_machine == _MACH_chrp || _machine == _MACH_bplan)
1739 boot.file = "/etc/";
1740 else if (strlen(boot.file)) {
1741 if (!strncmp(boot.file, "\\\\", 2))
1745 p = last = boot.file;
1755 if (strlen(boot.file))
1756 strcat(boot.file, "\\");
1759 strcpy(conf_path, boot.file);
1760 strcat(conf_path, CONFIG_FILE_NAME);
1761 boot.file = conf_path;
1762 DEBUG_F("After path kludgeup: dev=%s, part=%d, file=%s\n",
1763 boot.dev, boot.part, boot.file);
1767 * If we're doing a netboot, first look for one which matches our
1770 if (prom_get_devtype(boot.dev) == FILE_DEVICE_NET) {
1771 prom_printf("Try to netboot\n");
1772 useconf = load_my_config_file(&boot);
1776 useconf = load_config_file(&boot);
1778 prom_printf("Welcome to yaboot version " VERSION "\n");
1779 prom_printf("Enter \"help\" to get some basic usage information\n");
1781 /* I am fed up with lusers using the wrong partition type and
1782 mailing me *when* it breaks */
1784 if (_machine == _MACH_Pmac) {
1785 char *entry = cfg_get_strg(0, "ptypewarning");
1788 warn = strcmp(entry,
1789 "I_know_the_partition_type_is_wrong_and_will_NOT_send_mail_when_booting_breaks");
1791 ptype = get_part_type(boot.dev, boot.part);
1792 if ((ptype != NULL) && (strcmp(ptype, "Apple_Bootstrap")))
1793 prom_printf("\nWARNING: Bootstrap partition type is wrong: \"%s\"\n"
1794 " type should be: \"Apple_Bootstrap\"\n\n", ptype);
1802 prom_printf("Bye.\n");
1808 * c-file-style: "k&r"