From 68ce19afa3b7334cf071383e33d3483e5cb56e18 Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Tue, 22 Apr 2008 14:45:25 +0000 Subject: [PATCH] -Revise yaboot patch to suppress spurious DHCP attempts on QS blades. --- yaboot/yaboot-fixes.patch | 3002 +------------------------------------ 1 file changed, 11 insertions(+), 2991 deletions(-) diff --git a/yaboot/yaboot-fixes.patch b/yaboot/yaboot-fixes.patch index 3d4f45b..9237cd0 100644 --- a/yaboot/yaboot-fixes.patch +++ b/yaboot/yaboot-fixes.patch @@ -1,6 +1,6 @@ diff -urN yaboot-1.3.14/include/prom.h yaboot-1.3.14-fixes/include/prom.h --- yaboot-1.3.14/include/prom.h 2007-08-17 10:29:26.000000000 -0400 -+++ yaboot-1.3.14-fixes/include/prom.h 2008-01-15 13:32:06.000000000 -0500 ++++ yaboot-1.3.14-fixes/include/prom.h 2008-04-22 10:40:59.000000000 -0400 @@ -37,6 +37,9 @@ #define PROM_INVALID_HANDLE ((prom_handle)-1UL) #define BOOTDEVSZ (2048) /* iscsi args can be in excess of 1040 bytes */ @@ -28,175 +28,9 @@ diff -urN yaboot-1.3.14/include/prom.h yaboot-1.3.14-fixes/include/prom.h +char * prom_get_giaddr (struct bootp_packet * packet); #endif -diff -urN yaboot-1.3.14/include/prom.h.orig yaboot-1.3.14-fixes/include/prom.h.orig ---- yaboot-1.3.14/include/prom.h.orig 1969-12-31 19:00:00.000000000 -0500 -+++ yaboot-1.3.14-fixes/include/prom.h.orig 2008-01-15 13:32:06.000000000 -0500 -@@ -0,0 +1,162 @@ -+/* -+ * prom.h - Routines for talking to the Open Firmware PROM -+ * -+ * Copyright (C) 2001 Ethan Benson -+ * -+ * Copyright (C) 1999 Benjamin Herrenschmidt -+ * -+ * Copyright (C) 1999 Marius Vollmer -+ * -+ * Copyright (C) 1996 Paul Mackerras. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#ifndef PROM_H -+#define PROM_H -+ -+#include "types.h" -+#include "stdarg.h" -+ -+typedef void *prom_handle; -+typedef void *ihandle; -+typedef void *phandle; -+ -+#define PROM_INVALID_HANDLE ((prom_handle)-1UL) -+#define BOOTDEVSZ (2048) /* iscsi args can be in excess of 1040 bytes */ -+#define TOK_ISCSI "iscsi" -+#define PROM_CLAIM_MAX_ADDR 0x8000000 -+#define BOOTLASTSZ 1024 -+#define FW_NBR_REBOOTSZ 4 -+ -+struct prom_args; -+typedef int (*prom_entry)(struct prom_args *); -+ -+extern void prom_init (prom_entry pe); -+ -+extern prom_entry prom; -+ -+/* I/O */ -+ -+extern prom_handle prom_stdin; -+extern prom_handle prom_stdout; -+ -+prom_handle prom_open (char *spec); -+int prom_read (prom_handle file, void *buf, int len); -+int prom_write (prom_handle file, void *buf, int len); -+int prom_seek (prom_handle file, int pos); -+int prom_lseek (prom_handle file, unsigned long long pos); -+int prom_readblocks (prom_handle file, int blockNum, int blockCount, void *buffer); -+void prom_close (prom_handle file); -+int prom_getblksize (prom_handle file); -+int prom_loadmethod (prom_handle device, void* addr); -+ -+#define K_UP 0x141 -+#define K_DOWN 0x142 -+#define K_LEFT 0x144 -+#define K_RIGHT 0x143 -+ -+int prom_getchar (); -+void prom_putchar (char); -+int prom_nbgetchar(); -+ -+#ifdef __GNUC__ -+void prom_vprintf (char *fmt, va_list ap) __attribute__ ((format (printf, 1, 0))); -+void prom_fprintf (prom_handle dev, char *fmt, ...) __attribute__ ((format (printf, 2, 3))); -+void prom_printf (char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -+#else -+void prom_vprintf (char *fmt, va_list ap); -+void prom_fprintf (prom_handle dev, char *fmt, ...); -+void prom_printf (char *fmt, ...); -+#endif -+ -+void prom_perror (int error, char *filename); -+void prom_readline (char *prompt, char *line, int len); -+int prom_set_color(prom_handle device, int color, int r, int g, int b); -+ -+/* memory */ -+ -+void *prom_claim_chunk(void *virt, unsigned int size, unsigned int align); -+void *prom_claim (void *virt, unsigned int size, unsigned int align); -+void prom_release(void *virt, unsigned int size); -+void prom_map (void *phys, void *virt, int size); -+ -+/* packages and device nodes */ -+ -+prom_handle prom_finddevice (char *name); -+prom_handle prom_findpackage (char *path); -+int prom_getprop (prom_handle dev, char *name, void *buf, int len); -+int prom_setprop (prom_handle dev, char *name, void *buf, int len); -+int prom_getproplen(prom_handle, const char *); -+int prom_get_devtype (char *device); -+ -+/* misc */ -+ -+char *prom_getargs (); -+void prom_setargs (char *args); -+ -+void prom_exit (); -+void prom_abort (char *fmt, ...); -+void prom_sleep (int seconds); -+ -+int prom_interpret (char *forth); -+ -+int prom_get_chosen (char *name, void *mem, int len); -+int prom_get_options (char *name, void *mem, int len); -+int prom_set_options (char *name, void *mem, int len); -+ -+extern int prom_getms(void); -+extern void prom_pause(void); -+ -+extern void *call_prom (const char *service, int nargs, int nret, ...); -+extern void *call_prom_return (const char *service, int nargs, int nret, ...); -+ -+/* Netboot stuffs */ -+ -+/* -+ * "bootp-response" is the property name which is specified in -+ * the recommended practice doc for obp-tftp. However, pmac -+ * provides a "dhcp-response" property and chrp provides a -+ * "bootpreply-packet" property. The latter appears to begin the -+ * bootp packet at offset 0x2a in the property for some reason. -+ */ -+ -+struct bootp_property_offset { -+ char *name; /* property name */ -+ int offset; /* offset into property where bootp packet occurs */ -+}; -+ -+static const struct bootp_property_offset bootp_response_properties[] = { -+ { .name = "bootp-response", .offset = 0 }, -+ { .name = "dhcp-response", .offset = 0 }, -+ { .name = "bootpreply-packet", .offset = 0x2a }, -+}; -+ -+struct bootp_packet { -+ __u8 op, htype, hlen, hops; -+ __u32 xid; -+ __u16 secs, flags; -+ __u32 ciaddr, yiaddr, siaddr, giaddr; -+ unsigned char chaddr[16]; -+ unsigned char sname[64]; -+ unsigned char file[128]; -+ /* vendor options go here if we need them */ -+}; -+ -+struct bootp_packet * prom_get_netinfo (void); -+char * prom_get_mac (struct bootp_packet * packet); -+char * prom_get_ip (struct bootp_packet * packet); -+ -+#endif diff -urN yaboot-1.3.14/second/fs_of.c yaboot-1.3.14-fixes/second/fs_of.c --- yaboot-1.3.14/second/fs_of.c 2007-08-17 10:29:26.000000000 -0400 -+++ yaboot-1.3.14-fixes/second/fs_of.c 2008-01-15 13:32:06.000000000 -0500 ++++ yaboot-1.3.14-fixes/second/fs_of.c 2008-04-22 10:43:43.000000000 -0400 @@ -44,9 +44,8 @@ #include "errors.h" #include "debug.h" @@ -218,7 +52,7 @@ diff -urN yaboot-1.3.14/second/fs_of.c yaboot-1.3.14-fixes/second/fs_of.c struct fs_t of_filesystem = { -@@ -131,6 +132,30 @@ +@@ -131,6 +132,34 @@ return FILE_ERR_OK; } @@ -232,6 +66,9 @@ diff -urN yaboot-1.3.14/second/fs_of.c yaboot-1.3.14-fixes/second/fs_of.c + * tftp and 0 if not. + */ +static int of_supports_real_tftp() { ++ of_net_use_tftp=1; ++ return(of_net_use_tftp); ++/* + prom_handle h; + if(of_net_use_tftp>=0) return(of_net_use_tftp); + @@ -243,13 +80,14 @@ diff -urN yaboot-1.3.14/second/fs_of.c yaboot-1.3.14-fixes/second/fs_of.c + of_net_use_tftp=0; + } + return(of_net_use_tftp); ++*/ +} + + static int of_net_open(struct boot_file_t* file, const char* dev_name, struct partition_t* part, const char* file_name) -@@ -138,18 +163,33 @@ +@@ -138,18 +167,33 @@ static char buffer[1024]; char *filename; char *p; @@ -283,7 +121,7 @@ diff -urN yaboot-1.3.14/second/fs_of.c yaboot-1.3.14-fixes/second/fs_of.c free(filename); } -@@ -166,7 +206,9 @@ +@@ -166,7 +210,9 @@ return FILE_ERR_BAD_FSYS; } @@ -294,275 +132,9 @@ diff -urN yaboot-1.3.14/second/fs_of.c yaboot-1.3.14-fixes/second/fs_of.c if (file->buffer == (void *)-1) { prom_printf("Can't claim memory for TFTP download\n"); prom_close(file->of_device); -diff -urN yaboot-1.3.14/second/fs_of.c.orig yaboot-1.3.14-fixes/second/fs_of.c.orig ---- yaboot-1.3.14/second/fs_of.c.orig 1969-12-31 19:00:00.000000000 -0500 -+++ yaboot-1.3.14-fixes/second/fs_of.c.orig 2008-01-15 13:32:06.000000000 -0500 -@@ -0,0 +1,262 @@ -+/* -+ * fs_of.c - an implementation for OpenFirmware supported filesystems -+ * -+ * Copyright (C) 2001, 2002 Ethan Benson -+ * -+ * Copyright (C) 1999 Benjamin Herrenschmidt -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+/* -+ * BrokenFirmware cannot "read" from the network. We use tftp "load" -+ * method for network boot for now, we may provide our own NFS -+ * implementation in a later version. That means that we allocate a -+ * huge block of memory for the entire file before loading it. We use -+ * the location where the kernel puts RTAS, it's not used by the -+ * bootloader and if freed when the kernel is booted. This will have -+ * to be changed if we plan to instanciate RTAS in the bootloader -+ * itself -+ */ -+ -+#include "ctype.h" -+#include "types.h" -+#include "stddef.h" -+#include "stdlib.h" -+#include "file.h" -+#include "prom.h" -+#include "string.h" -+#include "partition.h" -+#include "fdisk-part.h" -+#include "fs.h" -+#include "errors.h" -+#include "debug.h" -+ -+#define LOAD_BUFFER_POS 0x1000000 -+#define LOAD_BUFFER_SIZE 0x1000000 -+ -+static int of_open(struct boot_file_t* file, const char* dev_name, -+ struct partition_t* part, const char* file_name); -+static int of_read(struct boot_file_t* file, unsigned int size, void* buffer); -+static int of_seek(struct boot_file_t* file, unsigned int newpos); -+static int of_close(struct boot_file_t* file); -+ -+ -+static int of_net_open(struct boot_file_t* file, const char* dev_name, -+ struct partition_t* part, const char* file_name); -+static int of_net_read(struct boot_file_t* file, unsigned int size, void* buffer); -+static int of_net_seek(struct boot_file_t* file, unsigned int newpos); -+ -+ -+struct fs_t of_filesystem = -+{ -+ "built-in", -+ of_open, -+ of_read, -+ of_seek, -+ of_close -+}; -+ -+struct fs_t of_net_filesystem = -+{ -+ "built-in network", -+ of_net_open, -+ of_net_read, -+ of_net_seek, -+ of_close -+}; -+ -+static int -+of_open(struct boot_file_t* file, const char* dev_name, -+ struct partition_t* part, const char* file_name) -+{ -+ static char buffer[1024]; -+ char *filename; -+ char *p; -+ -+ DEBUG_ENTER; -+ DEBUG_OPEN; -+ -+ strncpy(buffer, dev_name, 768); -+ strcat(buffer, ":"); -+ if (part) { -+ if (part->sys_ind == LINUX_RAID) { -+ DEBUG_F("skipping because partition is marked LINUX_RAID\n"); -+ DEBUG_LEAVE(FILE_ERR_BAD_FSYS); -+ return FILE_ERR_BAD_FSYS; -+ } -+ char pn[3]; -+ sprintf(pn, "%02d", part->part_number); -+ strcat(buffer, pn); -+ } -+ if (file_name && strlen(file_name)) { -+ if (part) -+ strcat(buffer, ","); -+ filename = strdup(file_name); -+ for (p = filename; *p; p++) -+ if (*p == '/') -+ *p = '\\'; -+ strcat(buffer, filename); -+ free(filename); -+ } -+ -+ DEBUG_F("opening: \"%s\"\n", buffer); -+ -+ file->of_device = prom_open(buffer); -+ -+ DEBUG_F("file->of_device = %p\n", file->of_device); -+ -+ file->pos = 0; -+ file->buffer = NULL; -+ if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0)) -+ { -+ DEBUG_LEAVE(FILE_ERR_BAD_FSYS); -+ return FILE_ERR_BAD_FSYS; -+ } -+ -+ DEBUG_LEAVE(FILE_ERR_OK); -+ return FILE_ERR_OK; -+} -+ -+static int -+of_net_open(struct boot_file_t* file, const char* dev_name, -+ struct partition_t* part, const char* file_name) -+{ -+ static char buffer[1024]; -+ char *filename; -+ char *p; -+ struct bootp_packet *packet; -+ -+ DEBUG_ENTER; -+ DEBUG_OPEN; -+ -+ packet = prom_get_netinfo(); -+ -+ strncpy(buffer, dev_name, 768); -+ if (file_name && strlen(file_name)) { -+ strcat(buffer, prom_get_siaddr(packet)); -+ strcat(buffer, ","); -+ filename = strdup(file_name); -+ for (p = filename; *p; p++) -+ if (*p == '/') -+ *p = '\\'; -+ strcat(buffer, filename); -+ strcat(buffer, ","); -+ strcat(buffer, prom_get_yiaddr(packet)); -+ strcat(buffer, ","); -+ /* Hack required since giaddr not returned on some systems -+ and required to boot on those systems. This should work -+ for the client and server on the same subnet. */ -+ strcat(buffer, prom_get_siaddr(packet)); -+ free(filename); -+ } -+ -+ DEBUG_F("Opening: \"%s\"\n", buffer); -+ -+ file->of_device = prom_open(buffer); -+ -+ DEBUG_F("file->of_device = %p\n", file->of_device); -+ -+ file->pos = 0; -+ if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0)) -+ { -+ DEBUG_LEAVE(FILE_ERR_BAD_FSYS); -+ return FILE_ERR_BAD_FSYS; -+ } -+ -+ -+ file->buffer = prom_claim_chunk((void *)LOAD_BUFFER_POS, -+ LOAD_BUFFER_SIZE, 0); -+ if (file->buffer == (void *)-1) { -+ prom_printf("Can't claim memory for TFTP download\n"); -+ prom_close(file->of_device); -+ DEBUG_LEAVE(FILE_IOERR); -+ return FILE_IOERR; -+ } -+ memset(file->buffer, 0, LOAD_BUFFER_SIZE); -+ -+ DEBUG_F("TFP...\n"); -+ -+ file->len = prom_loadmethod(file->of_device, file->buffer); -+ -+ DEBUG_F("result: %Ld\n", file->len); -+ -+ DEBUG_LEAVE(FILE_ERR_OK); -+ return FILE_ERR_OK; -+} -+ -+static int -+of_read(struct boot_file_t* file, unsigned int size, void* buffer) -+{ -+ unsigned int count; -+ -+ count = prom_read(file->of_device, buffer, size); -+ file->pos += count; -+ return count; -+} -+ -+static int -+of_net_read(struct boot_file_t* file, unsigned int size, void* buffer) -+{ -+ unsigned int count, av; -+ -+ av = file->len - file->pos; -+ count = size > av ? av : size; -+ memcpy(buffer, file->buffer + file->pos, count); -+ file->pos += count; -+ return count; -+} -+ -+static int -+of_seek(struct boot_file_t* file, unsigned int newpos) -+{ -+ if (prom_seek(file->of_device, newpos)) { -+ file->pos = newpos; -+ return FILE_ERR_OK; -+ } -+ -+ return FILE_CANT_SEEK; -+} -+ -+static int -+of_net_seek(struct boot_file_t* file, unsigned int newpos) -+{ -+ file->pos = (newpos > file->len) ? file->len : newpos; -+ return FILE_ERR_OK; -+} -+ -+static int -+of_close(struct boot_file_t* file) -+{ -+ -+ DEBUG_ENTER; -+ DEBUG_F("<@%p>\n", file->of_device); -+ -+ if (file->buffer) { -+ prom_release(file->buffer, LOAD_BUFFER_SIZE); -+ } -+ prom_close(file->of_device); -+ DEBUG_F("of_close called\n"); -+ -+ DEBUG_LEAVE(0); -+ return 0; -+} -+ -+/* -+ * Local variables: -+ * c-file-style: "k&r" -+ * c-basic-offset: 5 -+ * End: -+ */ diff -urN yaboot-1.3.14/second/prom.c yaboot-1.3.14-fixes/second/prom.c --- yaboot-1.3.14/second/prom.c 2007-08-17 10:29:26.000000000 -0400 -+++ yaboot-1.3.14-fixes/second/prom.c 2008-01-15 13:32:06.000000000 -0500 ++++ yaboot-1.3.14-fixes/second/prom.c 2008-04-22 10:40:59.000000000 -0400 @@ -568,6 +568,25 @@ while (prom_getms() <= end); } @@ -668,791 +240,9 @@ diff -urN yaboot-1.3.14/second/prom.c yaboot-1.3.14-fixes/second/prom.c * Local variables: * c-file-style: "k&r" * c-basic-offset: 5 -diff -urN yaboot-1.3.14/second/prom.c.orig yaboot-1.3.14-fixes/second/prom.c.orig ---- yaboot-1.3.14/second/prom.c.orig 1969-12-31 19:00:00.000000000 -0500 -+++ yaboot-1.3.14-fixes/second/prom.c.orig 2008-01-15 13:32:06.000000000 -0500 -@@ -0,0 +1,778 @@ -+/* -+ * prom.c - Routines for talking to the Open Firmware PROM -+ * -+ * Copyright (C) 2001, 2002 Ethan Benson -+ * -+ * Copyright (C) 1999 Benjamin Herrenschmidt -+ * -+ * Copyright (C) 1999 Marius Vollmer -+ * -+ * Copyright (C) 1996 Paul Mackerras. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#include "prom.h" -+#include "stdarg.h" -+#include "stddef.h" -+#include "stdlib.h" -+#include "types.h" -+#include "ctype.h" -+#include "asm/processor.h" -+#include "errors.h" -+#include "debug.h" -+#include "string.h" -+ -+#define READ_BLOCKS_USE_READ 1 -+ -+prom_entry prom; -+ -+ihandle prom_stdin, prom_stdout; -+ -+//extern int vsprintf(char *buf, const char *fmt, va_list args); -+ -+static ihandle prom_mem, prom_mmu; -+static ihandle prom_chosen, prom_options; -+ -+struct prom_args { -+ const char *service; -+ int nargs; -+ int nret; -+ void *args[10]; -+}; -+ -+void * -+call_prom (const char *service, int nargs, int nret, ...) -+{ -+ va_list list; -+ int i; -+ struct prom_args prom_args; -+ -+ prom_args.service = service; -+ prom_args.nargs = nargs; -+ prom_args.nret = nret; -+ va_start (list, nret); -+ for (i = 0; i < nargs; ++i) -+ prom_args.args[i] = va_arg(list, void *); -+ va_end(list); -+ for (i = 0; i < nret; ++i) -+ prom_args.args[i + nargs] = 0; -+ prom (&prom_args); -+ if (nret > 0) -+ return prom_args.args[nargs]; -+ else -+ return 0; -+} -+ -+void * -+call_prom_return (const char *service, int nargs, int nret, ...) -+{ -+ va_list list; -+ int i; -+ void* result; -+ struct prom_args prom_args; -+ -+ prom_args.service = service; -+ prom_args.nargs = nargs; -+ prom_args.nret = nret; -+ va_start (list, nret); -+ for (i = 0; i < nargs; ++i) -+ prom_args.args[i] = va_arg(list, void *); -+ for (i = 0; i < nret; ++i) -+ prom_args.args[i + nargs] = 0; -+ if (prom (&prom_args) != 0) -+ return PROM_INVALID_HANDLE; -+ if (nret > 0) { -+ result = prom_args.args[nargs]; -+ for (i=1; i for device: %s\n", device); -+ return FILE_ERR_BADDEV; -+ } -+ tmp[result] = 0; -+ if (!strcmp(tmp, "block")) -+ return FILE_DEVICE_BLOCK; -+ else if (!strcmp(tmp, "network")) -+ return FILE_DEVICE_NET; -+ else { -+ prom_printf("Unkown device type <%s>\n", tmp); -+ return FILE_ERR_BADDEV; -+ } -+} -+ -+void -+prom_init (prom_entry pp) -+{ -+ prom = pp; -+ -+ prom_chosen = prom_finddevice ("/chosen"); -+ if (prom_chosen == (void *)-1) -+ prom_exit (); -+ prom_options = prom_finddevice ("/options"); -+ if (prom_get_chosen ("stdout", &prom_stdout, sizeof(prom_stdout)) <= 0) -+ prom_exit(); -+ if (prom_get_chosen ("stdin", &prom_stdin, sizeof(prom_stdin)) <= 0) -+ prom_abort ("\nCan't open stdin"); -+ if (prom_get_chosen ("memory", &prom_mem, sizeof(prom_mem)) <= 0) -+ prom_abort ("\nCan't get mem handle"); -+ if (prom_get_chosen ("mmu", &prom_mmu, sizeof(prom_mmu)) <= 0) -+ prom_abort ("\nCan't get mmu handle"); -+ -+ // move cursor to fresh line -+ prom_printf ("\n"); -+ -+ /* Add a few OF methods (thanks Darwin) */ -+#if DEBUG -+ prom_printf ("Adding OF methods...\n"); -+#endif -+ -+ prom_interpret ( -+ /* All values in this forth code are in hex */ -+ "hex " -+ /* Those are a few utilities ripped from Apple */ -+ ": D2NIP decode-int nip nip ;\r" // A useful function to save space -+ ": GPP$ get-package-property 0= ;\r" // Another useful function to save space -+ ": ^on0 0= if -1 throw then ;\r" // Bail if result zero -+ ": $CM $call-method ;\r" -+ ); -+ -+ /* Some forth words used by the release method */ -+ prom_interpret ( -+ " \" /chosen\" find-package if " -+ "dup \" memory\" rot GPP$ if " -+ "D2NIP swap " // ( MEMORY-ihandle "/chosen"-phandle ) -+ "\" mmu\" rot GPP$ if " -+ "D2NIP " // ( MEMORY-ihandle MMU-ihandle ) -+ "else " -+ "0 " // ( MEMORY-ihandle 0 ) -+ "then " -+ "else " -+ "0 0 " // ( 0 0 ) -+ "then " -+ "else " -+ "0 0 " // ( 0 0 ) -+ "then\r" -+ "value mmu# " -+ "value mem# " -+ ); -+ -+ prom_interpret ( -+ ": ^mem mem# $CM ; " -+ ": ^mmu mmu# $CM ; " -+ ); -+ -+ DEBUG_F("OF interface initialized.\n"); -+} -+ -+prom_handle -+prom_open (char *spec) -+{ -+ return call_prom ("open", 1, 1, spec, strlen(spec)); -+} -+ -+void -+prom_close (prom_handle file) -+{ -+ call_prom ("close", 1, 0, file); -+} -+ -+int -+prom_read (prom_handle file, void *buf, int n) -+{ -+ int result = 0; -+ int retries = 10; -+ -+ if (n == 0) -+ return 0; -+ while(--retries) { -+ result = (int)call_prom ("read", 3, 1, file, buf, n); -+ if (result != 0) -+ break; -+ call_prom("interpret", 1, 1, " 10 ms"); -+ } -+ -+ return result; -+} -+ -+int -+prom_write (prom_handle file, void *buf, int n) -+{ -+ return (int)call_prom ("write", 3, 1, file, buf, n); -+} -+ -+int -+prom_seek (prom_handle file, int pos) -+{ -+ int status = (int)call_prom ("seek", 3, 1, file, 0, pos); -+ return status == 0 || status == 1; -+} -+ -+int -+prom_lseek (prom_handle file, unsigned long long pos) -+{ -+ int status = (int)call_prom ("seek", 3, 1, file, -+ (unsigned int)(pos >> 32), (unsigned int)(pos & 0xffffffffUL)); -+ return status == 0 || status == 1; -+} -+ -+int -+prom_loadmethod (prom_handle device, void* addr) -+{ -+ return (int)call_method_1 ("load", device, 1, addr); -+} -+ -+int -+prom_getblksize (prom_handle file) -+{ -+ return (int)call_method_1 ("block-size", file, 0); -+} -+ -+int -+prom_readblocks (prom_handle dev, int blockNum, int blockCount, void *buffer) -+{ -+#if READ_BLOCKS_USE_READ -+ int status; -+ unsigned int blksize; -+ -+ blksize = prom_getblksize(dev); -+ if (blksize <= 1) -+ blksize = 512; -+ status = prom_seek(dev, blockNum * blksize); -+ if (status != 1) { -+ return 0; -+ prom_printf("Can't seek to 0x%x\n", blockNum * blksize); -+ } -+ -+ status = prom_read(dev, buffer, blockCount * blksize); -+// prom_printf("prom_readblocks, bl: %d, cnt: %d, status: %d\n", -+// blockNum, blockCount, status); -+ -+ return status == (blockCount * blksize); -+#else -+ int result; -+ int retries = 10; -+ -+ if (blockCount == 0) -+ return blockCount; -+ while(--retries) { -+ result = call_method_1 ("read-blocks", dev, 3, buffer, blockNum, blockCount); -+ if (result != 0) -+ break; -+ call_prom("interpret", 1, 1, " 10 ms"); -+ } -+ -+ return result; -+#endif -+} -+ -+int -+prom_getchar () -+{ -+ char c[4]; -+ int a; -+ -+ while ((a = (int)call_prom ("read", 3, 1, prom_stdin, c, 4)) == 0) -+ ; -+ if (a == -1) -+ prom_abort ("EOF on console\n"); -+ if (a == 3 && c[0] == '\e' && c[1] == '[') -+ return 0x100 | c[2]; -+ return c[0]; -+} -+ -+int -+prom_nbgetchar() -+{ -+ char ch; -+ -+ return (int) call_prom("read", 3, 1, prom_stdin, &ch, 1) > 0? ch: -1; -+} -+ -+void -+prom_putchar (char c) -+{ -+ if (c == '\n') -+ call_prom ("write", 3, 1, prom_stdout, "\r\n", 2); -+ else -+ call_prom ("write", 3, 1, prom_stdout, &c, 1); -+} -+ -+void -+prom_puts (prom_handle file, char *s) -+{ -+ const char *p, *q; -+ -+ for (p = s; *p != 0; p = q) -+ { -+ for (q = p; *q != 0 && *q != '\n'; ++q) -+ ; -+ if (q > p) -+ call_prom ("write", 3, 1, file, p, q - p); -+ if (*q != 0) -+ { -+ ++q; -+ call_prom ("write", 3, 1, file, "\r\n", 2); -+ } -+ } -+} -+ -+void -+prom_vfprintf (prom_handle file, char *fmt, va_list ap) -+{ -+ static char printf_buf[2048]; -+ vsprintf (printf_buf, fmt, ap); -+ prom_puts (file, printf_buf); -+} -+ -+void -+prom_vprintf (char *fmt, va_list ap) -+{ -+ static char printf_buf[2048]; -+ vsprintf (printf_buf, fmt, ap); -+ prom_puts (prom_stdout, printf_buf); -+} -+ -+void -+prom_fprintf (prom_handle file, char *fmt, ...) -+{ -+ va_list ap; -+ va_start (ap, fmt); -+ prom_vfprintf (file, fmt, ap); -+ va_end (ap); -+} -+ -+void -+prom_printf (char *fmt, ...) -+{ -+ va_list ap; -+ va_start (ap, fmt); -+ prom_vfprintf (prom_stdout, fmt, ap); -+ va_end (ap); -+} -+ -+void -+prom_perror (int error, char *filename) -+{ -+ if (error == FILE_ERR_EOF) -+ prom_printf("%s: Unexpected End Of File\n", filename); -+ else if (error == FILE_ERR_NOTFOUND) -+ prom_printf("%s: No such file or directory\n", filename); -+ else if (error == FILE_CANT_SEEK) -+ prom_printf("%s: Seek error\n", filename); -+ else if (error == FILE_IOERR) -+ prom_printf("%s: Input/output error\n", filename); -+ else if (error == FILE_BAD_PATH) -+ prom_printf("%s: Path too long\n", filename); -+ else if (error == FILE_ERR_BAD_TYPE) -+ prom_printf("%s: Not a regular file\n", filename); -+ else if (error == FILE_ERR_NOTDIR) -+ prom_printf("%s: Not a directory\n", filename); -+ else if (error == FILE_ERR_BAD_FSYS) -+ prom_printf("%s: Unknown or corrupt filesystem\n", filename); -+ else if (error == FILE_ERR_SYMLINK_LOOP) -+ prom_printf("%s: Too many levels of symbolic links\n", filename); -+ else if (error == FILE_ERR_LENGTH) -+ prom_printf("%s: File too large\n", filename); -+ else if (error == FILE_ERR_FSBUSY) -+ prom_printf("%s: Filesystem busy\n", filename); -+ else if (error == FILE_ERR_BADDEV) -+ prom_printf("%s: Unable to open file, Invalid device\n", filename); -+ else -+ prom_printf("%s: Unknown error\n", filename); -+} -+ -+void -+prom_readline (char *prompt, char *buf, int len) -+{ -+ int i = 0; -+ int c; -+ -+ if (prompt) -+ prom_puts (prom_stdout, prompt); -+ -+ while (i < len-1 && (c = prom_getchar ()) != '\r') -+ { -+ if (c >= 0x100) -+ continue; -+ if (c == 8) -+ { -+ if (i > 0) -+ { -+ prom_puts (prom_stdout, "\b \b"); -+ i--; -+ } -+ else -+ prom_putchar ('\a'); -+ } -+ else if (isprint (c)) -+ { -+ prom_putchar (c); -+ buf[i++] = c; -+ } -+ else -+ prom_putchar ('\a'); -+ } -+ prom_putchar ('\n'); -+ buf[i] = 0; -+} -+ -+#ifdef CONFIG_SET_COLORMAP -+int prom_set_color(prom_handle device, int color, int r, int g, int b) -+{ -+ return (int)call_prom( "call-method", 6, 1, "color!", device, color, b, g, r ); -+} -+#endif /* CONFIG_SET_COLORMAP */ -+ -+void -+prom_exit () -+{ -+ call_prom ("exit", 0, 0); -+} -+ -+void -+prom_abort (char *fmt, ...) -+{ -+ va_list ap; -+ va_start (ap, fmt); -+ prom_vfprintf (prom_stdout, fmt, ap); -+ va_end (ap); -+ prom_exit (); -+} -+ -+void -+prom_sleep (int seconds) -+{ -+ int end; -+ end = (prom_getms() + (seconds * 1000)); -+ while (prom_getms() <= end); -+} -+ -+/* if address given is claimed look for other addresses to get the needed -+ * space before giving up -+ */ -+void * -+prom_claim_chunk(void *virt, unsigned int size, unsigned int align) -+{ -+ void *found, *addr; -+ for(addr=virt; addr <= (void*)PROM_CLAIM_MAX_ADDR; -+ addr+=(0x100000/sizeof(addr))) { -+ found = prom_claim(addr, size, 0); -+ if (found != (void *)-1) { -+ DEBUG_F("claimed %i at 0x%x (0x%x)\n",size,(int)found,(int)virt); -+ return(found); -+ } -+ } -+ prom_printf("Claim error, can't allocate %x at 0x%x\n",size,(int)virt); -+ return((void*)-1); -+} -+ -+void * -+prom_claim (void *virt, unsigned int size, unsigned int align) -+{ -+ return call_prom ("claim", 3, 1, virt, size, align); -+} -+ -+void -+prom_release(void *virt, unsigned int size) -+{ -+ call_prom ("release", 2, 0, virt, size); -+#if 0 /* this is bullshit, newworld OF RELEASE method works fine. */ -+ -+ /* release in not enough, it needs also an unmap call. This bit of forth -+ * code inspired from Darwin's bootloader but could be replaced by direct -+ * calls to the MMU package if needed -+ */ -+ call_prom ("interpret", 3, 1, -+#if DEBUG -+ ".\" ReleaseMem:\" 2dup . . cr " -+#endif -+ "over \" translate\" ^mmu " // Find out physical base -+ "^on0 " // Bail if translation failed -+ "drop " // Leaving phys on top of stack -+ "2dup \" unmap\" ^mmu " // Unmap the space first -+ "2dup \" release\" ^mmu " // Then free the virtual pages -+ "\" release\" ^mem " // Then free the physical pages -+ ,size, virt -+ ); -+#endif /* bullshit */ -+} -+ -+void -+prom_map (void *phys, void *virt, int size) -+{ -+ unsigned long msr = mfmsr(); -+ -+ /* Only create a mapping if we're running with relocation enabled. */ -+ if ( (msr & MSR_IR) && (msr & MSR_DR) ) -+ call_method_1 ("map", prom_mmu, 4, -1, size, virt, phys); -+} -+ -+void -+prom_unmap (void *phys, void *virt, int size) -+{ -+ unsigned long msr = mfmsr(); -+ -+ /* Only unmap if we're running with relocation enabled. */ -+ if ( (msr & MSR_IR) && (msr & MSR_DR) ) -+ call_method_1 ("map", prom_mmu, 4, -1, size, virt, phys); -+} -+ -+char * -+prom_getargs () -+{ -+ static char args[256]; -+ int l; -+ -+ l = prom_get_chosen ("bootargs", args, 255); -+ args[l] = '\0'; -+ return args; -+} -+ -+void -+prom_setargs (char *args) -+{ -+ int l = strlen (args)+1; -+ if ((int)call_prom ("setprop", 4, 1, prom_chosen, "bootargs", args, l) != l) -+ prom_printf ("can't set args\n"); -+} -+ -+int prom_interpret (char *forth) -+{ -+ return (int)call_prom("interpret", 1, 1, forth); -+} -+ -+int -+prom_getms(void) -+{ -+ return (int) call_prom("milliseconds", 0, 1); -+} -+ -+void -+prom_pause(void) -+{ -+ call_prom("enter", 0, 0); -+} -+ -+/* -+ * prom_get_netinfo() -+ * returns the packet with all needed info for netboot -+ */ -+struct bootp_packet * prom_get_netinfo (void) -+{ -+ void *bootp_response = NULL; -+ char *propname; -+ struct bootp_packet *packet; -+ int i = 0, size, offset = 0; -+ prom_handle chosen; -+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -+ -+ chosen = prom_finddevice("/chosen"); -+ if (chosen < 0) { -+ DEBUG_F("chosen=%d\n", chosen); -+ return 0; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(bootp_response_properties); i++) { -+ propname = bootp_response_properties[i].name; -+ size = prom_getproplen(chosen, propname); -+ if (size <= 0) -+ continue; -+ -+ DEBUG_F("using /chosen/%s\n", propname); -+ offset = bootp_response_properties[i].offset; -+ break; -+ } -+ -+ if (size <= 0) -+ return NULL; -+ -+ if (sizeof(*packet) > size - offset) { -+ prom_printf("Malformed %s property?\n", propname); -+ return NULL; -+ } -+ -+ bootp_response = malloc(size); -+ if (!bootp_response) -+ return NULL; -+ -+ if (prom_getprop(chosen, propname, bootp_response, size) < 0) -+ return NULL; -+ -+ packet = bootp_response + offset; -+ return packet; -+} -+ -+/* -+ * prom_get_mac() -+ * returns the mac addr of an net card -+ */ -+char * prom_get_mac (struct bootp_packet * packet) -+{ -+ char * conf_path; -+ int i; -+ -+ if (!packet) -+ return NULL; -+ -+ /* 3 chars per byte in chaddr + \0 */ -+ conf_path = malloc(packet->hlen * 3 + 1); -+ if (!conf_path) -+ return NULL; -+ sprintf(conf_path, "%02x", packet->chaddr[0]); -+ -+ for (i = 1; i < packet->hlen; i++) { -+ char tmp[4]; -+ sprintf(tmp, "-%02x", packet->chaddr[i]); -+ strcat(conf_path, tmp); -+ } -+ -+ return conf_path; -+} -+ -+/* -+ * prom_get_ip() -+ * returns the ip addr of an net card -+ */ -+char * prom_get_ip (struct bootp_packet * packet) -+{ -+ char * conf_path; -+ -+ if (!packet) -+ return NULL; -+ -+ /* 8 chars in yiaddr + \0 */ -+ conf_path = malloc(9); -+ if (!conf_path) -+ return NULL; -+ sprintf(conf_path, "%08x", packet->yiaddr); -+ -+ return conf_path; -+} -+ -+/* -+ * Local variables: -+ * c-file-style: "k&r" -+ * c-basic-offset: 5 -+ * End: -+ */ diff -urN yaboot-1.3.14/second/yaboot.c yaboot-1.3.14-fixes/second/yaboot.c --- yaboot-1.3.14/second/yaboot.c 2007-08-17 10:29:26.000000000 -0400 -+++ yaboot-1.3.14-fixes/second/yaboot.c 2008-01-15 13:32:06.000000000 -0500 ++++ yaboot-1.3.14-fixes/second/yaboot.c 2008-04-22 10:40:59.000000000 -0400 @@ -114,6 +114,9 @@ char bootdevice[BOOTDEVSZ]; char bootoncelabel[1024]; @@ -1578,1773 +368,3 @@ diff -urN yaboot-1.3.14/second/yaboot.c yaboot-1.3.14-fixes/second/yaboot.c /* If conf= specified on command line, it overrides Usage: conf=device:partition,/path/to/conffile -diff -urN yaboot-1.3.14/second/yaboot.c.orig yaboot-1.3.14-fixes/second/yaboot.c.orig ---- yaboot-1.3.14/second/yaboot.c.orig 1969-12-31 19:00:00.000000000 -0500 -+++ yaboot-1.3.14-fixes/second/yaboot.c.orig 2008-01-15 13:32:06.000000000 -0500 -@@ -0,0 +1,1766 @@ -+/* -+ * Yaboot - secondary boot loader for Linux on PowerPC. -+ * -+ * Copyright (C) 2001, 2002 Ethan Benson -+ * -+ * Copyright (C) 1999, 2000, 2001 Benjamin Herrenschmidt -+ * -+ * IBM CHRP support -+ * -+ * Copyright (C) 2001 Peter Bergner -+ * -+ * portions based on poof -+ * -+ * Copyright (C) 1999 Marius Vollmer -+ * -+ * portions based on quik -+ * -+ * Copyright (C) 1996 Paul Mackerras. -+ * -+ * Because this program is derived from the corresponding file in the -+ * silo-0.64 distribution, it is also -+ * -+ * Copyright (C) 1996 Pete A. Zaitcev -+ * 1996 Maurizio Plaza -+ * 1996 David S. Miller -+ * 1996 Miguel de Icaza -+ * 1996 Jakub Jelinek -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#include "stdarg.h" -+#include "string.h" -+#include "ctype.h" -+#include "stdlib.h" -+#include "prom.h" -+#include "file.h" -+#include "errors.h" -+#include "cfg.h" -+#include "cmdline.h" -+#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 */ -+ -+#ifdef USE_MD5_PASSWORDS -+#include "md5.h" -+#endif /* USE_MD5_PASSWORDS */ -+ -+/* align addr on a size boundry - adjust address up if needed -- Cort */ -+#define _ALIGN(addr,size) (((addr)+size-1)&(~(size-1))) -+ -+/* Addresses where the PPC32 and PPC64 vmlinux kernels are linked at. -+ * These are used to determine whether we are booting a vmlinux, in -+ * which case, it will be loaded at KERNELADDR. Otherwise (eg zImage), -+ * we load the binary where it was linked at (ie, e_entry field in -+ * the ELF header). -+ */ -+#define KERNEL_LINK_ADDR_PPC32 0xC0000000UL -+#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; -+} loadinfo_t; -+ -+typedef void (*kernel_entry_t)( void *, -+ unsigned long, -+ prom_entry, -+ unsigned long, -+ unsigned long ); -+ -+/* Imported functions */ -+extern unsigned long reloc_offset(void); -+extern long flush_icache_range(unsigned long start, unsigned long stop); -+ -+/* Exported functions */ -+int yaboot_start(unsigned long r3, unsigned long r4, unsigned long r5); -+ -+/* Local functions */ -+static int yaboot_main(void); -+static int is_elf32(loadinfo_t *loadinfo); -+static int is_elf64(loadinfo_t *loadinfo); -+static int load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo); -+static int load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo); -+static void setup_display(void); -+ -+/* Locals & globals */ -+ -+int useconf = 0; -+char bootdevice[BOOTDEVSZ]; -+char bootoncelabel[1024]; -+char bootargs[1024]; -+char bootlastlabel[BOOTLASTSZ] = {0}; -+char fw_nbr_reboots[FW_NBR_REBOOTSZ] = {0}; -+long fw_reboot_cnt = 0; -+char *password = NULL; -+struct boot_fspec_t boot; -+int _machine = _MACH_Pmac; -+int flat_vmlinux; -+ -+#ifdef CONFIG_COLOR_TEXT -+ -+/* Color values for text ui */ -+static struct ansi_color_t { -+ 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 }, -+}; -+ -+/* Default colors for text ui */ -+int fgcolor = 15; -+int bgcolor = 0; -+#endif /* CONFIG_COLOR_TEXT */ -+ -+#if DEBUG -+static int test_bss; -+static int test_data = 0; -+#endif -+static int pause_after; -+static char *pause_message = "Type go to continue.\n"; -+static char given_bootargs[1024]; -+static int given_bootargs_by_user = 0; -+ -+extern unsigned char linux_logo_red[]; -+extern unsigned char linux_logo_green[]; -+extern unsigned char linux_logo_blue[]; -+ -+#define DEFAULT_TIMEOUT -1 -+ -+/* Entry, currently called directly by crt0 (bss not inited) */ -+ -+extern char* __bss_start; -+extern char* _end; -+ -+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; -+ -+ /* 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); -+ -+ /* 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; -+ } -+ } -+ -+ DEBUG_F("Running on _machine = %d\n", _machine); -+ DEBUG_SLEEP; -+ -+ /* 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); -+ -+ /* Return to OF */ -+ prom_exit(); -+ -+ return result; -+ -+} -+ -+#ifdef CONFIG_COLOR_TEXT -+/* -+ * Validify color for text ui -+ */ -+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; -+} -+#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) -+ */ -+static int -+load_config_file(struct boot_fspec_t *fspec) -+{ -+ char *conf_file = NULL, *p; -+ struct boot_file_t file; -+ int sz, opened = 0, result = 0; -+ -+ /* 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; -+ } -+ -+ /* Open it */ -+ 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(fspec->file, conf_file, sz) < 0) { -+ prom_printf ("Syntax error or read error config\n"); -+ goto bail; -+ } -+ -+ /* -+ * set the default cf_option to label that has the same MAC addr -+ * it only works if there is a label with the MAC addr on yaboot.conf -+ */ -+ if (prom_get_devtype(fspec->dev) == FILE_DEVICE_NET) { -+ /* change the variable bellow to get the MAC dinamicaly */ -+ char * macaddr = NULL; -+ int default_mac = 0; -+ -+ macaddr = prom_get_mac(prom_get_netinfo()); -+ default_mac = cfg_set_default_by_mac(macaddr); -+ if (default_mac >= 1) { -+ prom_printf("Default label was changed to macaddr label.\n"); -+ } -+ } -+ -+ 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); -+#if !DEBUG -+ prom_printf("\xc"); -+#endif /* !DEBUG */ -+ } -+ 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); -+ -+ p = cfg_get_strg(0, "message"); -+ if (p) -+ print_message_file(p); -+ -+ result = 1; -+ -+bail: -+ -+ if (opened) -+ file.fs->close(&file); -+ -+ if (conf_file) -+ free(conf_file); -+ -+ return result; -+} -+ -+/* -+ * Search for config file by MAC address, then by IP address. -+ * Basically copying pxelinux's algorithm. -+ * http://syslinux.zytor.com/pxe.php#config -+ */ -+static int load_my_config_file(struct boot_fspec_t *orig_fspec) -+{ -+ struct bootp_packet *packet; -+ int rc = 0; -+ struct boot_fspec_t fspec = *orig_fspec; -+ char *cfgpath = (_machine == _MACH_chrp) ? "/etc/" : ""; -+ int flen; -+ int minlen; -+ -+ packet = prom_get_netinfo(); -+ -+ /* -+ * First, try to match on mac address with the hardware type -+ * prepended. -+ */ -+ -+ /* 3 chars per byte in chaddr + 2 chars for htype + /etc/ +\0 */ -+ fspec.file = malloc(packet->hlen * 3 + 2 + 6); -+ if (!fspec.file) -+ goto out; -+ -+ sprintf(fspec.file, "%s%02x-", cfgpath, packet->htype); -+ strcat(fspec.file, prom_get_mac(packet)); -+ -+ rc = load_config_file(&fspec); -+ if (rc) -+ goto out; -+ -+ /* -+ * Now try to match on IP. -+ */ -+ /* no need to realloc for /etc/ + 8 chars in yiaddr + \0 */ -+ sprintf(fspec.file, "%s%s", cfgpath, prom_get_ip(packet)); -+ -+ for (flen = strlen(fspec.file), -+ minlen = strlen(cfgpath); flen > minlen; flen--) { -+ rc = load_config_file(&fspec); -+ if (rc) -+ goto out; -+ /* Chop one digit off the end, try again */ -+ fspec.file[flen - 1] = '\0'; -+ } -+ -+ out: -+ if (rc) /* modify original only on success */ -+ orig_fspec->file = fspec.file; -+ else -+ free(fspec.file); -+ return rc; -+} -+ -+void maintabfunc (void) -+{ -+ 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 * -+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; -+} -+ -+void check_password(char *str) -+{ -+ int i; -+ -+ prom_printf("\n%s", str); -+ for (i = 0; i < 3; i++) { -+ prom_printf ("\nPassword: "); -+ 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)) -+ return; -+ } -+ else if (!strcmp (password, passwdbuff)) -+ return; -+#else /* !MD5 */ -+ if (!strcmp (password, passwdbuff)) -+ return; -+#endif /* USE_MD5_PASSWORDS */ -+ if (i < 2) { -+ prom_sleep(1); -+ prom_printf ("Incorrect password. Try again."); -+ } -+ } -+ prom_printf(" ___________________\n< Permission denied >\n -------------------\n" -+ " \\ ^__^\n \\ (oo)\\_______\n (__)\\ )\\/\\\n" -+ " ||----w |\n || ||\n"); -+ prom_sleep(4); -+ prom_interpret("reset-all"); -+} -+ -+int get_params(struct boot_param_t* params) -+{ -+ int defpart; -+ char *defdevice = 0; -+ char defdevice_bak[1024]; -+ 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 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 && !fw_reboot_cnt) { -+ first = 0; -+ 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); -+ } -+ -+ /* If this is a reboot due to FW detecting CAS changes then -+ * set timeout to 1. The last kernel booted will be booted -+ * again automatically. It should seem seamless to the user -+ */ -+ if (fw_reboot_cnt) -+ timeout = 1; -+ -+ 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) { -+ if (bootoncelabel[0] != 0) -+ imagename = bootoncelabel; -+ else if (bootlastlabel[0] != 0) -+ imagename = bootlastlabel; -+ else -+ 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(); -+ -+ /* write the imagename out so it can be reused on reboot if necessary */ -+ prom_set_options("boot-last-label", imagename, strlen(imagename)); -+ -+ label = 0; -+ defdevice = boot.dev; -+ -+ strcpy(defdevice_bak,defdevice); -+ -+ 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) -+ defpart = n; -+ } -+ if (cfg_get_flag(label, "restricted")) -+ restricted = 1; -+ if (label) { -+ if (params->args && password && restricted) -+ check_password ("To specify arguments for this image " -+ "you must enter the password."); -+ else if (password && !restricted) -+ check_password ("This image is restricted."); -+ } -+ params->args = make_params(label, params->args); -+ } -+ } -+ -+ if (!strcmp (imagename, "help")) { -+ /* FIXME: defdevice shouldn't need to be reset all over the place */ -+ if(!defdevice) defdevice = boot.dev; -+ 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" -+ "To load an alternative config file rather than /etc/yaboot.conf, enter\n" -+ "its device, partno and path, on Open Firmware Prompt:\n" -+ "boot conf=device:partno,/path/to/configfile\n." -+ "To reload the config file or load a new one, use the \"conf\" command\n" -+ "on Yaboot's prompt:\n" -+ "conf [device=device] [partition=partno] [file=/path/to/configfile]\n\n" -+ "If you omit \"device\" and \"partno\", Yaboot will use their current\n" -+ "values. You can check them by entering \"conf\" on Yaboot's prompt.\n"); -+ -+ return 0; -+ } -+ -+ if (!strcmp (imagename, "halt")) { -+ if (password) -+ check_password ("Restricted command."); -+ prom_pause(); -+ return 0; -+ } -+ if (!strcmp (imagename, "bye")) { -+ if (password) { -+ check_password ("Restricted command."); -+ return 1; -+ } -+ return 1; -+ } -+ -+ if (!strncmp (imagename, "conf", 4)) { -+ -+ // imagename = "conf file=blah dev=bleh part=blih" -+ DEBUG_F("Loading user-specified config file: %s\n",imagename); -+ if (password) { -+ check_password ("Restricted command."); -+ return 1; -+ } -+ -+ // args= "file=blah dev=bleh part=blih" -+ char *args = params->args; -+ -+ if (strlen(args)){ -+ -+ // set a pointer to the first space in args -+ char *space = strchr(args,' '); -+ -+ int loop = 3; -+ while (loop > 0){ -+ char temp[1024] = "0"; -+ -+ // copy next argument to temp -+ strncpy(temp, args, space-args); -+ -+ // parse temp and set boot arguments -+ if (!strncmp (temp, "file=", 5)){ -+ DEBUG_F("conf file: %s\n", temp+5); -+ strcpy(boot.file, temp+5); -+ } else if (!strncmp (temp, "device=", 7)){ -+ DEBUG_F("conf device: %s\n", temp+7); -+ strcpy(boot.dev, temp+7); -+ } else if (!strncmp (temp, "partition=", 10)){ -+ DEBUG_F("conf partition: %s\n", temp+10); -+ boot.part=simple_strtol(temp+10,NULL,10); -+ } else -+ space = NULL; -+ -+ // set the pointer to the next space in args; -+ // set the loop control variable -+ if (strlen(space)>1){ -+ // Go to the next argument -+ args = space+1; -+ -+ loop--; -+ if (strchr(args,' ') == NULL) -+ space = &args[strlen(args)]; -+ else -+ space = strchr(args,' '); -+ } else { -+ loop = -1; -+ space = NULL; -+ } -+ } -+ -+ prom_printf("Loading config file...\n"); -+ useconf = load_config_file(&boot); -+ if (useconf > 0){ -+ if ((q = cfg_get_strg(0, "timeout")) != 0 && *q != 0) -+ timeout = simple_strtol(q, NULL, 0); -+ } else { -+ prom_printf("Restoring default values.\n"); -+ strcpy(boot.file,""); -+ strcpy(boot.dev, defdevice_bak); -+ boot.part = defpart; -+ } -+ -+ } else { -+ prom_printf("Current configuration:\n"); -+ prom_printf("device: %s\n", boot.dev); -+ if (boot.part < 0) -+ prom_printf("partition: auto\n"); -+ else -+ prom_printf("partition: %d\n", boot.part); -+ if (strlen(boot.file)) -+ prom_printf("file: %s\n", boot.file); -+ else -+ prom_printf("file: /etc/%s\n",CONFIG_FILE_NAME); -+ } -+ -+ imagename = "\0"; -+ params->args = "\0"; -+ -+ return 0; -+ } -+ -+ if (imagename[0] == '$') { -+ /* forth command string */ -+ if (password) -+ check_password ("OpenFirmware commands are restricted."); -+ prom_interpret(imagename+1); -+ return 0; -+ } -+ -+ strncpy(imagepath, imagename, 1024); -+ -+ if (!label && password) -+ check_password ("To boot a custom image you must enter the password."); -+ -+ 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 -+ * doing lazy-loading, and then claim the memory before loading the kernel -+ * to it -+ * We also need to add initrd support to this whole mecanism -+ */ -+void -+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; -+ -+ loadinfo.load_loc = 0; -+ -+ for (;;) { -+ initrd_size = 0; -+ initrd_base = 0; -+ sysmap_base = 0; -+ sysmap_size = 0; -+ -+ 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 (only if booting a vmlinux). -+ */ -+ if (flat_vmlinux && 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"); -+ prom_pause(); -+ 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 (only if booting a vmlinux). For now, we -+ * can't tell the size it will be so we claim an arbitrary amount -+ * of 4Mb. -+ */ -+ if (flat_vmlinux && 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 0x100000 -+ initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0); -+ if (initrd_base == (void *)-1) { -+ prom_printf("Claim failed for initrd memory\n"); -+ initrd_base = 0; -+ } else { -+ initrd_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_base); -+ if (initrd_size == 0) -+ initrd_base = 0; -+ initrd_read = initrd_size; -+ initrd_more = initrd_base; -+ while (initrd_read == INITRD_CHUNKSIZE ) { /* need to read more? */ -+ initrd_want = (void *)((unsigned long)initrd_more+INITRD_CHUNKSIZE); -+ initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0); -+ if (initrd_more != initrd_want) { -+ prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more); -+ prom_pause(); -+ break; -+ } -+ initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more); -+ DEBUG_F(" block at %p rc=%lu\n",initrd_more,initrd_read); -+ initrd_size += initrd_read; -+ } -+ } -+ file.fs->close(&file); -+ memset(&file, 0, sizeof(file)); -+ } -+ if (initrd_base) -+ prom_printf("ramdisk loaded at %p, size: %lu Kbytes\n", -+ initrd_base, initrd_size >> 10); -+ else { -+ prom_printf("ramdisk load failed !\n"); -+ prom_pause(); -+ } -+ } -+ -+ 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"); -+ -+ if (flat_vmlinux) { -+ /* -+ * Fill new boot infos (only if booting a vmlinux). -+ * -+ * 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 *)((ulong)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 *)((ulong)birec + birec->size); -+ -+ birec->tag = BI_MACHTYPE; -+ birec->data[0] = _machine; -+ birec->size = sizeof(struct bi_record) + sizeof(ulong); -+ birec = (struct bi_record *)((ulong)birec + birec->size); -+ -+ if (sysmap_base) { -+ birec->tag = BI_SYSMAP; -+ birec->data[0] = (ulong)sysmap_base; -+ birec->data[1] = sysmap_size; -+ birec->size = sizeof(struct bi_record) + sizeof(ulong)*2; -+ birec = (struct bi_record *)((ulong)birec + birec->size); -+ } -+ birec->tag = BI_LAST; -+ birec->size = sizeof(struct bi_record); -+ birec = (struct bi_record *)((ulong)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 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"); -+ goto bail; -+ } -+ -+ 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"); -+ goto bail; -+ } -+ -+ ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum); -+ if (!ph) { -+ prom_printf ("Malloc error\n"); -+ goto bail; -+ } -+ -+ /* Now, we read the section header */ -+ if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) { -+ prom_printf ("seek error\n"); -+ goto bail; -+ } -+ if ((*(file->fs->read))(file, sizeof(Elf32_Phdr) * e->e_phnum, ph) != -+ sizeof(Elf32_Phdr) * e->e_phnum) { -+ prom_printf ("read error\n"); -+ goto bail; -+ } -+ -+ /* 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"); -+ goto bail; -+ } -+ -+ /* 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); -+ -+ /* Determine whether we are trying to boot a vmlinux or some -+ * other binary image (eg, zImage). We load vmlinux's at -+ * KERNELADDR and all other binaries at their e_entry value. -+ */ -+ if (e->e_entry == KERNEL_LINK_ADDR_PPC32) { -+ flat_vmlinux = 1; -+ loadaddr = KERNELADDR; -+ } else { -+ flat_vmlinux = 0; -+ loadaddr = loadinfo->load_loc; -+ } -+ -+ loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0); -+ if (loadinfo->base == (void *)-1) { -+ prom_printf("Claim error, can't allocate kernel memory\n"); -+ goto bail; -+ } -+ -+ 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); -+ goto bail; -+ } -+ 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); -+ goto bail; -+ } -+ } -+ -+ free(ph); -+ -+ /* Return success at loading the Elf32 kernel */ -+ return 1; -+ -+bail: -+ if (ph) -+ free(ph); -+ return 0; -+} -+ -+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 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"); -+ goto bail; -+ } -+ -+ 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"); -+ goto bail; -+ } -+ -+ ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum); -+ if (!ph) { -+ prom_printf ("Malloc error\n"); -+ goto bail; -+ } -+ -+ /* Now, we read the section header */ -+ if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) { -+ prom_printf ("Seek error\n"); -+ goto bail; -+ } -+ if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) != -+ sizeof(Elf64_Phdr) * e->e_phnum) { -+ prom_printf ("Read error\n"); -+ goto bail; -+ } -+ -+ /* 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"); -+ goto bail; -+ } -+ -+ /* 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); -+ -+ /* Determine whether we are trying to boot a vmlinux or some -+ * other binary image (eg, zImage). We load vmlinux's at -+ * KERNELADDR and all other binaries at their e_entry value. -+ */ -+ if (e->e_entry == KERNEL_LINK_ADDR_PPC64) { -+ flat_vmlinux = 1; -+ loadaddr = KERNELADDR; -+ } else { -+ flat_vmlinux = 0; -+ loadaddr = e->e_entry; -+ } -+ -+ loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0); -+ if (loadinfo->base == (void *)-1) { -+ prom_printf("Claim error, can't allocate kernel memory\n"); -+ goto bail; -+ } -+ -+ 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); -+ goto bail; -+ } -+ 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); -+ goto bail; -+ } -+ } -+ -+ free(ph); -+ -+ /* Return success at loading the Elf64 kernel */ -+ return 1; -+ -+bail: -+ if (ph) -+ free(ph); -+ return 0; -+} -+ -+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); -+} -+ -+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); -+} -+ -+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); -+ } -+ } -+ -+ 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"); -+#endif /* COLOR_TEST */ -+ -+#if !DEBUG -+ prom_printf("\xc"); -+#endif /* !DEBUG */ -+ -+#endif /* CONFIG_SET_COLORMAP */ -+} -+ -+int -+yaboot_main(void) -+{ -+ char *ptype; -+ char *endp; -+ int conf_given = 0; -+ char conf_path[1024]; -+ -+ if (_machine == _MACH_Pmac) -+ setup_display(); -+ -+ prom_get_chosen("bootargs", bootargs, sizeof(bootargs)); -+ DEBUG_F("/chosen/bootargs = %s\n", bootargs); -+ prom_get_chosen("bootpath", bootdevice, BOOTDEVSZ); -+ DEBUG_F("/chosen/bootpath = %s\n", bootdevice); -+ prom_get_options("ibm,fw-nbr-reboots",fw_nbr_reboots, FW_NBR_REBOOTSZ); -+ fw_reboot_cnt = simple_strtol(fw_nbr_reboots,&endp,10); -+ if (fw_reboot_cnt > 0L) -+ prom_get_options("boot-last-label", bootlastlabel, BOOTLASTSZ); -+ -+ /* If conf= specified on command line, it overrides -+ Usage: conf=device:partition,/path/to/conffile -+ Example: On Open Firmware Prompt, type -+ boot conf=/pci@8000000f8000000/pci@1/pci1014,028C@1/scsi@0/sd@1,0:3,/etc/yaboot.conf */ -+ -+ if (!strncmp(bootargs, "conf=", 5)) { -+ DEBUG_F("Using conf argument in Open Firmware\n"); -+ char *end = strchr(bootargs,' '); -+ if (end) -+ *end = 0; -+ -+ strcpy(bootdevice, bootargs + 5); -+ conf_given = 1; -+ DEBUG_F("Using conf=%s\n", bootdevice); -+ -+ /* Remove conf=xxx from bootargs */ -+ if (end) -+ memmove(bootargs, end+1, strlen(end+1)+1); -+ else -+ bootargs[0] = 0; -+ } -+ if (bootdevice[0] == 0) { -+ prom_get_options("boot-device", bootdevice, BOOTDEVSZ); -+ DEBUG_F("boot-device = %s\n", bootdevice); -+ } -+ if (bootdevice[0] == 0) { -+ prom_printf("Couldn't determine boot device\n"); -+ return -1; -+ } -+ -+ if (bootoncelabel[0] == 0) { -+ prom_get_options("boot-once", bootoncelabel, -+ sizeof(bootoncelabel)); -+ if (bootoncelabel[0] != 0) -+ DEBUG_F("boot-once: [%s]\n", bootoncelabel); -+ } -+ prom_set_options("boot-once", NULL, 0); -+ -+ if (!parse_device_path(bootdevice, NULL, -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 (!conf_given) { -+ if (_machine == _MACH_chrp) -+ boot.file = "/etc/"; -+ else 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, "\\"); -+ } -+ } -+ strcpy(conf_path, boot.file); -+ strcat(conf_path, CONFIG_FILE_NAME); -+ boot.file = conf_path; -+ DEBUG_F("After path kludgeup: dev=%s, part=%d, file=%s\n", -+ boot.dev, boot.part, boot.file); -+ } -+ -+ /* -+ * If we're doing a netboot, first look for one which matches our -+ * MAC address. -+ */ -+ if (prom_get_devtype(boot.dev) == FILE_DEVICE_NET) { -+ prom_printf("Try to netboot\n"); -+ useconf = load_my_config_file(&boot); -+ } -+ -+ if (!useconf) -+ useconf = load_config_file(&boot); -+ -+ 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); -+ if (ptype) -+ free(ptype); -+ } -+ } -+ -+ yaboot_text_ui(); -+ -+ prom_printf("Bye.\n"); -+ return 0; -+} -+ -+/* -+ * Local variables: -+ * c-file-style: "k&r" -+ * c-basic-offset: 5 -+ * End: -+ */