ppcrcd/yaboot: . Makefile cache.S cfg.c cmdline.c crt0.S file.c fs.c fs_ext2.c fs_iso.c fs_of.c fs_r...

sparky cvs at pld-linux.org
Wed Jun 15 22:40:43 CEST 2005


Author: sparky
Date: Wed Jun 15 22:40:03 2005
New Revision: 6089

Added:
   ppcrcd/yaboot/
   ppcrcd/yaboot/Makefile
   ppcrcd/yaboot/cache.S
   ppcrcd/yaboot/cfg.c
   ppcrcd/yaboot/cmdline.c
   ppcrcd/yaboot/crt0.S
   ppcrcd/yaboot/file.c
   ppcrcd/yaboot/fs.c
   ppcrcd/yaboot/fs_ext2.c
   ppcrcd/yaboot/fs_iso.c
   ppcrcd/yaboot/fs_of.c
   ppcrcd/yaboot/fs_reiserfs.c
   ppcrcd/yaboot/fs_xfs.c
   ppcrcd/yaboot/include/
   ppcrcd/yaboot/include/asm/
   ppcrcd/yaboot/include/asm/elf.h
   ppcrcd/yaboot/include/asm/ppc_asm.tmpl
   ppcrcd/yaboot/include/asm/processor.h
   ppcrcd/yaboot/include/bootinfo.h
   ppcrcd/yaboot/include/byteorder.h
   ppcrcd/yaboot/include/cfg.h
   ppcrcd/yaboot/include/cmdline.h
   ppcrcd/yaboot/include/ctype.h
   ppcrcd/yaboot/include/debug.h
   ppcrcd/yaboot/include/errors.h
   ppcrcd/yaboot/include/et/
   ppcrcd/yaboot/include/et/com_err.h
   ppcrcd/yaboot/include/ext2fs/
   ppcrcd/yaboot/include/ext2fs/bitops.h
   ppcrcd/yaboot/include/ext2fs/ext2_err.h
   ppcrcd/yaboot/include/ext2fs/ext2_io.h
   ppcrcd/yaboot/include/ext2fs/ext2fs.h
   ppcrcd/yaboot/include/fdisk-part.h
   ppcrcd/yaboot/include/file.h
   ppcrcd/yaboot/include/fs.h
   ppcrcd/yaboot/include/linux/
   ppcrcd/yaboot/include/linux/elf.h
   ppcrcd/yaboot/include/linux/ext2_fs.h
   ppcrcd/yaboot/include/linux/iso_fs.h
   ppcrcd/yaboot/include/linux/stat.h
   ppcrcd/yaboot/include/linux/types.h
   ppcrcd/yaboot/include/mac-part.h
   ppcrcd/yaboot/include/md5.h
   ppcrcd/yaboot/include/partition.h
   ppcrcd/yaboot/include/prom.h
   ppcrcd/yaboot/include/reiserfs/
   ppcrcd/yaboot/include/reiserfs/reiserfs.h
   ppcrcd/yaboot/include/setjm2.h
   ppcrcd/yaboot/include/setjmp.h
   ppcrcd/yaboot/include/stdlib.h
   ppcrcd/yaboot/include/string.h
   ppcrcd/yaboot/include/swab.h
   ppcrcd/yaboot/include/types.h
   ppcrcd/yaboot/include/xfs/
   ppcrcd/yaboot/include/xfs/xfs.h
   ppcrcd/yaboot/include/yaboot.h
   ppcrcd/yaboot/iso_util.c
   ppcrcd/yaboot/lib/
   ppcrcd/yaboot/lib/ctype.c
   ppcrcd/yaboot/lib/malloc.c
   ppcrcd/yaboot/lib/nosys.c
   ppcrcd/yaboot/lib/string.S
   ppcrcd/yaboot/lib/strstr.c
   ppcrcd/yaboot/lib/strtol.c
   ppcrcd/yaboot/lib/vsprintf.c
   ppcrcd/yaboot/md5.c
   ppcrcd/yaboot/partition.c
   ppcrcd/yaboot/prom.c
   ppcrcd/yaboot/setjmp.S
   ppcrcd/yaboot/yaboot.c
Log:
- almost unchanged yaboot's second stage source


Added: ppcrcd/yaboot/Makefile
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/Makefile	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,90 @@
+## Setup
+
+CONFIG_COLOR_TEXT       :=      y
+CONFIG_SET_COLORMAP     :=      y
+USE_MD5_PASSWORDS       :=      n
+CONFIG_FS_XFS           :=      y
+CONFIG_FS_REISERFS      :=      y
+
+VERSION = 1.3.13-ppcrcd
+
+# Debug mode (spam/verbose)
+DEBUG = 0
+# We use fixed addresses to avoid overlap when relocating
+# and other trouble with initrd
+
+# Load the bootstrap at 2Mb
+TEXTADDR	= 0x200000
+# Malloc block at 3Mb -> 5Mb
+MALLOCADDR	= 0x300000
+MALLOCSIZE	= 0x200000
+# Load kernel at 20Mb and ramdisk just after
+KERNELADDR	= 0x01400000
+
+# The flags for the yaboot binary.
+#
+YBCFLAGS = -Os $(CFLAGS) -nostdinc -Wall -isystem `gcc -print-file-name=include` -fsigned-char
+YBCFLAGS += -DVERSION=\"${VERSION}\"	#"
+YBCFLAGS += -DTEXTADDR=$(TEXTADDR) -DDEBUG=$(DEBUG)
+YBCFLAGS += -DMALLOCADDR=$(MALLOCADDR) -DMALLOCSIZE=$(MALLOCSIZE)
+YBCFLAGS += -DKERNELADDR=$(KERNELADDR)
+YBCFLAGS += -I ./include
+
+YBCFLAGS += -DCONFIG_COLOR_TEXT
+YBCFLAGS += -DCONFIG_SET_COLORMAP
+
+YBCFLAGS += -DCONFIG_FS_XFS
+YBCFLAGS += -DCONFIG_FS_REISERFS
+
+
+# Link flags
+#
+LFLAGS = -Ttext $(TEXTADDR) -Bstatic 
+
+# Libraries
+#
+LLIBS = /usr/lib/libext2fs.a
+	#lib/libext2fs.a
+
+# For compiling build-tools that run on the host.
+#
+HOSTCC = gcc
+HOSTCFLAGS = -O2 $(CFLAGS) -Wall -I/usr/include
+
+## End of configuration section
+
+OBJS = crt0.o yaboot.o cache.o prom.o file.o \
+	partition.o fs.o cfg.o setjmp.o cmdline.o \
+	fs_of.o fs_ext2.o fs_iso.o iso_util.o \
+	fs_xfs.o fs_reiserfs.o \
+	lib/nosys.o lib/string.o lib/strtol.o lib/vsprintf.o \
+	lib/ctype.o lib/malloc.o lib/strstr.o
+
+
+lgcc = `$(CC) -print-libgcc-file-name`
+
+all: yaboot strip
+
+yaboot: $(OBJS)
+	@echo "	[LD]		$@"
+	@$(LD) $(LFLAGS) $(OBJS) $(LLIBS) $(lgcc) -o $@
+	@chmod -x yaboot
+
+
+%.o: %.c
+	@echo "	[CC]		$@"
+	@$(CC) $(YBCFLAGS) -c -o $@ $<
+
+%.o: %.S
+	@echo "	[ASM]		$@"
+	@$(CC) $(YBCFLAGS) -D__ASSEMBLY__  -c -o $@ $<
+	
+strip: yaboot
+	@echo "	[STRIP]		$<"
+	@strip $<
+	@strip --remove-section=.comment $<
+	@#/lib/yaboot/addnote $<
+
+clean:
+	-rm *.o lib/*.o
+	-rm yaboot

Added: ppcrcd/yaboot/cache.S
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/cache.S	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,79 @@
+/*
+ *  cache.S - PowerPC version 
+ *
+ *  Copyright (C) 1995-1996 Gary Thomas (gdt at linuxppc.org)
+ *
+ *  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 "asm/ppc_asm.tmpl"
+#include "asm/processor.h"
+	
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ * This is a no-op on the 601.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ */
+
+CACHE_LINE_SIZE = 32
+LG_CACHE_LINE_SIZE = 5
+
+	.text
+	.globl	flush_icache_range
+	.type	flush_icache_range, at function
+flush_icache_range:
+	mfspr	r5,PVR
+	rlwinm	r5,r5,16,16,31
+	cmpi	0,r5,1
+	beqlr				/* for 601, do nothing */
+	li	r5,CACHE_LINE_SIZE-1
+	andc	r3,r3,r5
+	subf	r4,r3,r4
+	add	r4,r4,r5
+	srwi.	r4,r4,LG_CACHE_LINE_SIZE
+	beqlr
+	mtctr	r4
+	mr	r6,r3
+1:	dcbst	0,r3
+	addi	r3,r3,CACHE_LINE_SIZE
+	bdnz	1b
+	sync				/* wait for dcbst's to get to ram */
+	mtctr	r4
+2:	icbi	0,r6
+	addi	r6,r6,CACHE_LINE_SIZE
+	bdnz	2b
+	sync
+	isync
+	blr
+
+	.text
+	.globl	turn_off_mmu
+	.type	turn_off_mmu, at function
+turn_off_mmu:
+	lis	r0,1f at h
+	ori	r0,r0,1f at l
+	mtspr	SRR0,r0
+	mfmsr	r0
+	lis	r2,(~(MSR_DR|MSR_IR))@h
+	ori	r2,r2,(~(MSR_DR|MSR_IR))@l
+	and	r0,r0,r2
+	mtspr	SRR1,r0
+	rfi
+1:
+	blr

Added: ppcrcd/yaboot/cfg.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/cfg.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,463 @@
+/*
+ *  cfg.c - Handling and parsing of yaboot.conf
+ *
+ *  Copyright (C) 1995 Werner Almesberger
+ *                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 "setjmp.h"
+#include "stdarg.h"
+#include "stdlib.h"
+#include "string.h"
+#include "types.h"
+#include "prom.h"
+
+/* Imported functions */
+extern int strcasecmp(const char *s1, const char *s2);
+
+typedef enum {
+     cft_strg, cft_flag, cft_end
+} CONFIG_TYPE;
+
+typedef struct {
+     CONFIG_TYPE type;
+     char *name;
+     void *data;
+} CONFIG;
+
+#define MAX_TOKEN 200
+#define MAX_VAR_NAME MAX_TOKEN
+#define EOF -1
+
+CONFIG cf_options[] =
+{
+     {cft_strg, "device", NULL},
+     {cft_strg, "partition", NULL},
+     {cft_strg, "default", NULL},
+     {cft_strg, "timeout", NULL},
+     {cft_strg, "password", NULL},
+     {cft_flag, "restricted", NULL},
+     {cft_strg, "message", NULL},
+     {cft_strg, "root", NULL},
+     {cft_strg, "ramdisk", NULL},
+     {cft_flag, "read-only", NULL},
+     {cft_flag, "read-write", NULL},
+     {cft_strg, "append", NULL},
+     {cft_strg, "initrd", NULL},
+     {cft_flag, "initrd-prompt", NULL},
+     {cft_strg, "initrd-size", NULL},
+     {cft_flag, "pause-after", NULL},
+     {cft_strg, "pause-message", NULL},
+     {cft_strg, "init-code", NULL},
+     {cft_strg, "init-message", NULL},
+     {cft_strg, "fgcolor", NULL},
+     {cft_strg, "bgcolor", NULL},
+     {cft_strg, "ptypewarning", NULL},
+     {cft_end, NULL, NULL}};
+
+CONFIG cf_image[] =
+{
+     {cft_strg, "image", NULL},
+     {cft_strg, "label", NULL},
+     {cft_strg, "alias", NULL},
+     {cft_flag, "single-key", NULL},
+     {cft_flag, "restricted", NULL},
+     {cft_strg, "device", NULL},
+     {cft_strg, "partition", NULL},
+     {cft_strg, "root", NULL},
+     {cft_strg, "ramdisk", NULL},
+     {cft_flag, "read-only", NULL},
+     {cft_flag, "read-write", NULL},
+     {cft_strg, "append", NULL},
+     {cft_strg, "literal", NULL},
+     {cft_strg, "initrd", NULL},
+     {cft_flag, "initrd-prompt", NULL},
+     {cft_strg, "initrd-size", NULL},
+     {cft_flag, "pause-after", NULL},
+     {cft_strg, "pause-message", NULL},
+     {cft_flag, "novideo", NULL},
+     {cft_strg, "sysmap", NULL},
+     {cft_end, NULL, NULL}};
+
+static char flag_set;
+static char *last_token = NULL, *last_item = NULL, *last_value = NULL;
+static int line_num;
+static int back = 0;		/* can go back by one char */
+static char *currp = NULL;
+static char *endp = NULL;
+static char *file_name = NULL;
+static CONFIG *curr_table = cf_options;
+static jmp_buf env;
+
+static struct IMAGES {
+     CONFIG table[sizeof (cf_image) / sizeof (cf_image[0])];
+     struct IMAGES *next;
+} *images = NULL;
+
+void cfg_error (char *msg,...)
+{
+     va_list ap;
+
+     va_start (ap, msg);
+     prom_printf ("Config file error: ");
+     prom_vprintf (msg, ap);
+     va_end (ap);
+     prom_printf (" near line %d in file %s\n", line_num, file_name);
+     longjmp (env, 1);
+}
+
+void cfg_warn (char *msg,...)
+{
+     va_list ap;
+
+     va_start (ap, msg);
+     prom_printf ("Config file warning: ");
+     prom_vprintf (msg, ap);
+     va_end (ap);
+     prom_printf (" near line %d in file %s\n", line_num, file_name);
+}
+
+inline int getc ()
+{
+     if (currp == endp)
+	  return EOF;
+     return *currp++;
+}
+
+#define next_raw next
+static int next (void)
+{
+     int ch;
+
+     if (!back)
+	  return getc ();
+     ch = back;
+     back = 0;
+     return ch;
+}
+
+static void again (int ch)
+{
+     back = ch;
+}
+
+static char *cfg_get_token (void)
+{
+     char buf[MAX_TOKEN + 1];
+     char *here;
+     int ch, escaped;
+
+     if (last_token) {
+	  here = last_token;
+	  last_token = NULL;
+	  return here;
+     }
+     while (1) {
+	  while (ch = next (), ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
+	       if (ch == '\n' || ch == '\r')
+		    line_num++;
+	  if (ch == EOF || ch == (int)NULL)
+	       return NULL;
+	  if (ch != '#')
+	       break;
+	  while (ch = next_raw (), (ch != '\n' && ch != '\r'))
+	       if (ch == EOF)
+		    return NULL;
+	  line_num++;
+     }
+     if (ch == '=')
+	  return strdup ("=");
+     if (ch == '"') {
+	  here = buf;
+	  while (here - buf < MAX_TOKEN) {
+	       if ((ch = next ()) == EOF)
+		    cfg_error ("EOF in quoted string");
+	       if (ch == '"') {
+		    *here = 0;
+		    return strdup (buf);
+	       }
+	       if (ch == '\\') {
+		    ch = next ();
+		    switch (ch) {
+		    case '"':
+		    case '\\':
+			 break;
+		    case '\n':
+		    case '\r':
+			 while ((ch = next ()), ch == ' ' || ch == '\t');
+			 if (!ch)
+			      continue;
+			 again (ch);
+			 ch = ' ';
+			 break;
+		    case 'n':
+			 ch = '\n';
+			 break;
+		    default:
+			 cfg_error ("Bad use of \\ in quoted string");
+		    }
+	       } else if ((ch == '\n') || (ch == '\r'))
+		    cfg_error ("newline is not allowed in quoted strings");
+	       *here++ = ch;
+	  }
+	  cfg_error ("Quoted string is too long");
+	  return 0;		/* not reached */
+     }
+     here = buf;
+     escaped = 0;
+     while (here - buf < MAX_TOKEN) {
+	  if (escaped) {
+	       if (ch == EOF)
+		    cfg_error ("\\ precedes EOF");
+	       if (ch == '\n')
+		    line_num++;
+	       else
+		    *here++ = ch == '\t' ? ' ' : ch;
+	       escaped = 0;
+	  } else {
+	       if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '#' ||
+		   ch == '=' || ch == EOF) {
+		    again (ch);
+		    *here = 0;
+		    return strdup (buf);
+	       }
+	       if (!(escaped = (ch == '\\')))
+		    *here++ = ch;
+	  }
+	  ch = next ();
+     }
+     cfg_error ("Token is too long");
+     return 0;			/* not reached */
+}
+
+static void cfg_return_token (char *token)
+{
+     last_token = token;
+}
+
+static int cfg_next (char **item, char **value)
+{
+     char *this;
+
+     if (last_item) {
+	  *item = last_item;
+	  *value = last_value;
+	  last_item = NULL;
+	  return 1;
+     }
+     *value = NULL;
+     if (!(*item = cfg_get_token ()))
+	  return 0;
+     if (!strcmp (*item, "="))
+	  cfg_error ("Syntax error");
+     if (!(this = cfg_get_token ()))
+	  return 1;
+     if (strcmp (this, "=")) {
+	  cfg_return_token (this);
+	  return 1;
+     }
+     if (!(*value = cfg_get_token ()))
+	  cfg_error ("Value expected at EOF");
+     if (!strcmp (*value, "="))
+	  cfg_error ("Syntax error after %s", *item);
+     return 1;
+}
+
+#if 0
+// The one and only call to this procedure is commented out
+// below, so we don't need this unless we decide to use it again.
+static void cfg_return (char *item, char *value)
+{
+     last_item = item;
+     last_value = value;
+}
+#endif
+
+static int cfg_set (char *item, char *value)
+{
+     CONFIG *walk;
+
+     if (!strcasecmp (item, "image")) {
+	  struct IMAGES **p = &images;
+
+	  while (*p)
+	       p = &((*p)->next);
+	  *p = (struct IMAGES *)malloc (sizeof (struct IMAGES));
+	  if (*p == NULL) {
+	       prom_printf("malloc error in cfg_set\n");
+	       return -1;
+	  }
+	  (*p)->next = 0;
+	  curr_table = ((*p)->table);
+	  memcpy (curr_table, cf_image, sizeof (cf_image));
+     }
+     for (walk = curr_table; walk->type != cft_end; walk++) {
+	  if (walk->name && !strcasecmp (walk->name, item)) {
+	       if (value && walk->type != cft_strg)
+		    cfg_warn ("'%s' doesn't have a value", walk->name);
+	       else if (!value && walk->type == cft_strg)
+		    cfg_warn ("Value expected for '%s'", walk->name);
+	       else {
+		    if (walk->data)
+			 cfg_warn ("Duplicate entry '%s'", walk->name);
+		    if (walk->type == cft_flag)
+			 walk->data = &flag_set;
+		    else if (walk->type == cft_strg)
+			 walk->data = value;
+	       }
+	       break;
+	  }
+     }
+     if (walk->type != cft_end)
+	  return 1;
+//    cfg_return (item, value);
+     return 0;
+}
+
+int cfg_parse (char *cfg_file, char *buff, int len)
+{
+     char *item, *value;
+
+     file_name = cfg_file;
+     currp = buff;
+     endp = currp + len;
+
+     if (setjmp (env))
+	  return -1;
+     while (1) {
+	  if (!cfg_next (&item, &value))
+	       return 0;
+	  if (!cfg_set (item, value)) {
+#if DEBUG
+	       prom_printf("Can't set item %s to value %s\n", item, value);
+#endif	    
+	  }
+	  free (item);
+     }
+}
+
+static char *cfg_get_strg_i (CONFIG * table, char *item)
+{
+     CONFIG *walk;
+
+     for (walk = table; walk->type != cft_end; walk++)
+	  if (walk->name && !strcasecmp (walk->name, item))
+	       return walk->data;
+     return 0;
+}
+
+char *cfg_get_strg (char *image, char *item)
+{
+     struct IMAGES *p;
+     char *label, *alias;
+     char *ret;
+
+     if (!image)
+	  return cfg_get_strg_i (cf_options, item);
+     for (p = images; p; p = p->next) {
+	  label = cfg_get_strg_i (p->table, "label");
+	  if (!label) {
+	       label = cfg_get_strg_i (p->table, "image");
+	       alias = strrchr (label, '/');
+	       if (alias)
+		    label = alias + 1;
+	  }
+	  alias = cfg_get_strg_i (p->table, "alias");
+	  if (!strcmp (label, image) || (alias && !strcmp (alias, image))) {
+	       ret = cfg_get_strg_i (p->table, item);
+	       if (!ret)
+		    ret = cfg_get_strg_i (cf_options, item);
+	       return ret;
+	  }
+     }
+     return 0;
+}
+
+int cfg_get_flag (char *image, char *item)
+{
+     return !!cfg_get_strg (image, item);
+}
+
+static int printl_count = 0;
+static void printlabel (char *label, int defflag)
+{
+     int len = strlen (label);
+
+     if (!printl_count)
+	  prom_printf ("\n");
+     prom_printf ("%s %s",defflag?"*":" ", label);
+     while (len++ < 25)
+	  prom_putchar (' ');
+     printl_count++;
+     if (printl_count == 3)
+	  printl_count = 0;
+}
+
+void cfg_print_images (void)
+{
+     struct IMAGES *p;
+     char *label, *alias;
+
+     char *ret = cfg_get_strg_i (cf_options, "default");
+     int defflag=0;
+
+     printl_count = 0;
+     for (p = images; p; p = p->next) {
+	  label = cfg_get_strg_i (p->table, "label");
+	  if (!label) {
+	       label = cfg_get_strg_i (p->table, "image");
+	       alias = strrchr (label, '/');
+	       if (alias)
+		    label = alias + 1;
+	  }
+	  if(!strcmp(ret,label))
+	       defflag=1;
+	  else
+	       defflag=0;
+	  alias = cfg_get_strg_i (p->table, "alias");
+	  printlabel (label, defflag);
+	  if (alias)
+	       printlabel (alias, 0);
+     }
+     prom_printf("\n");
+}
+
+char *cfg_get_default (void)
+{
+     char *label;
+     char *ret = cfg_get_strg_i (cf_options, "default");
+
+     if (ret)
+	  return ret;
+     if (!images)
+	  return 0;
+     ret = cfg_get_strg_i (images->table, "label");
+     if (!ret) {
+	  ret = cfg_get_strg_i (images->table, "image");
+	  label = strrchr (ret, '/');
+	  if (label)
+	       ret = label + 1;
+     }
+     return ret;
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/cmdline.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/cmdline.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,88 @@
+/*
+ *  cmdline.c - Prompt handling
+ *
+ *  Copyright (C) 2001, 2002 Ethan Benson
+ *
+ *  Adapted from SILO
+ *
+ *  Copyright (C) 1996 Maurizio Plaza
+ *                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 "types.h"
+#include "stdarg.h"
+#include "prom.h"
+#include "string.h"
+#include "cfg.h"
+
+#define CMD_LENG	512
+char cbuff[CMD_LENG];
+char passwdbuff[CMD_LENG];
+extern int useconf;
+
+void cmdinit()
+{
+    cbuff[0] = 0;
+    passwdbuff[0] = 0;
+}
+
+void cmdedit (void (*tabfunc) (void), int password)
+{
+     int x, c;
+     char *buff = password ? passwdbuff : cbuff;
+     for (x = 0; x < CMD_LENG - 1; x++) {
+	  if (buff[x] == 0)
+	       break;
+	  else if (password)
+	       prom_printf("*");
+     }
+     if (!password)
+	  prom_printf(buff, x);
+     
+     for (;;) {
+	  c = prom_getchar ();
+	  if (c == -1)
+	       break;
+	  if (c == '\n' || c == '\r') {
+	       break;
+	  }
+	  if (c == '\t' && !x && tabfunc)
+	       (*tabfunc) ();
+	  if (c == '\b' || c == 0x7F) {
+	       if (x > 0) {
+		    --x;
+		    buff[x] = 0;
+		    prom_printf("\b \b");
+	       }
+	  } else if ((c & 0xE0) != 0) {
+	       if (x < CMD_LENG - 1) {
+		    buff[x] = c;
+		    buff[x + 1] = 0;
+		    if (password)
+			 prom_printf("*");
+		    else
+			 prom_printf(buff + x);
+		    x++;
+	       }
+	       if (x == 1 && !password && useconf) {
+		    if (cfg_get_flag (cbuff, "single-key"))
+			 break;
+	       }
+	  }
+     }
+     buff[x] = 0;
+}

Added: ppcrcd/yaboot/crt0.S
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/crt0.S	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,32 @@
+#include "asm/ppc_asm.tmpl"
+#include "asm/processor.h"
+
+/*
+ * Main entry point. should add code to clear BSS and more ...
+ */
+_GLOBAL(_start)
+	lis	r10,edata at h
+	ori	r10,r10,edata at l
+	lis	r11,end at h
+	ori	r11,r11,end at l
+	subi	r10,r10,4
+	subi	r11,r11,4
+	li	r0, 0
+1:	stwu	r0,4(r10)
+	cmp	0,0,r10,r11
+	bne	1b
+	b	yaboot_start
+
+/*
+ * Returns (address we're running at) - (address we were linked at)
+ * for use before the text and data are mapped to KERNELBASE.
+ */
+_GLOBAL(reloc_offset)
+	mflr	r0
+	bl	1f
+1:	mflr	r3
+	lis	r4,1b at ha
+	addi	r4,r4,1b at l
+	subf	r3,r4,r3
+	mtlr	r0
+	blr

Added: ppcrcd/yaboot/file.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/file.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,272 @@
+/*
+ *  file.c - Filesystem related interfaces
+ *
+ *  Copyright (C) 2001, 2002 Ethan Benson
+ *
+ *  parse_device_path()
+ *
+ *  Copyright (C) 2001 Colin Walters
+ *
+ *  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.
+ */
+
+#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 "fs.h"
+#include "errors.h"
+#include "debug.h"
+
+extern char bootdevice[1024];
+
+/* This function follows the device path in the devtree and separates
+   the device name, partition number, and other datas (mostly file name)
+   the string passed in parameters is changed since 0 are put in place
+   of some separators to terminate the various strings.  
+
+   when a default device is supplied imagepath will be assumed to be a
+   plain filename unless it contains a : otherwise if defaultdev is
+   NULL imagepath will be assumed to be a device path.
+
+   returns 1 on success 0 on failure.
+
+   Supported examples:
+    - /pci at 80000000/pci-bridge at d/ADPT,2930CU at 2/@1:4
+    - /pci at 80000000/pci-bridge at d/ADPT,2930CU at 2/@1:4,/boot/vmlinux
+    - hd:3,/boot/vmlinux
+    - enet:10.0.0.1,/tftpboot/vmlinux
+    - enet:,/tftpboot/vmlinux
+    - enet:bootp
+    - enet:0
+   Supported only if defdevice == NULL
+    - disc
+    - any other device path lacking a :
+   Unsupported examples:
+    - hd:2,\\:tbxi <- no filename will be detected due to the extra :
+    - enet:192.168.2.1,bootme,c-iaddr,g-iaddr,subnet-mask,bootp-retries,tftp-retries */
+
+int
+parse_device_path(char *imagepath, char *defdevice, int defpart,
+		  char *deffile, struct boot_fspec_t *result)
+{
+     char *ptr;
+     char *ipath = NULL;
+     char *defdev = NULL;
+
+     result->dev = NULL;
+     result->part = -1;
+     result->file = NULL;
+
+     if (!imagepath)
+	  return 0;
+     else
+	  ipath = strdup(imagepath);
+
+     if (defdevice)
+	  defdev = strdup(defdevice);
+
+     if (defdev) {
+	  if (!strstr(defdev, "ethernet") && !strstr(defdev, "enet")) {
+	       if ((ptr = strrchr(defdev, ':')) != NULL)
+		    *ptr = 0; /* remove trailing : from defdevice if necessary */
+	  }
+     }
+
+     /* if there is no : then there is no filename or partition.  must
+        use strrchr() since enet:,10.0.0.1,file is legal */
+
+     if (strchr(ipath, ':') != NULL) {
+	  if ((ptr = strrchr(ipath, ',')) != NULL) {
+	       char *colon = strrchr(ipath, ':');
+	       /* If a ':' occurs *after* a ',', then we assume that there is
+		  no filename */
+	       if (!colon || colon < ptr) {
+		    result->file = strdup(ptr+1);
+		    /* Trim the filename off */
+		    *ptr = 0;
+	       }
+	  }
+     }
+
+     if (strstr(ipath, "ethernet") || strstr(ipath, "enet"))
+	  if ((ptr = strstr(ipath, "bootp")) != NULL) { /* `n' key booting boots enet:bootp */
+	       *ptr = 0;
+	       result->dev = strdup(ipath);
+	  } else
+	       result->dev = strdup(ipath);
+     else if ((ptr = strchr(ipath, ':')) != NULL) {
+	  *ptr = 0;
+	  result->dev = strdup(ipath);
+	  if (*(ptr+1))
+	       result->part = simple_strtol(ptr+1, NULL, 10);
+     } else if (!defdev) {
+	  result->dev = strdup(ipath); 
+     } else if (strlen(ipath)) {
+          result->file = strdup(ipath);
+     } else {
+	  return 0;
+     }
+
+     if (!result->dev && defdev)
+	  result->dev = strdup(defdev);
+     
+     if (result->part < 0)
+	  result->part = defpart;
+     
+     if (!result->file)
+	  result->file = strdup(deffile);
+
+     free(ipath);
+     if (defdev)
+	  free(defdev);
+     return 1;
+}
+
+
+static int
+file_block_open(	struct boot_file_t*	file,
+			const char*		dev_name,
+			const char*		file_name,
+			int			partition)
+{
+     struct partition_t*	parts;
+     struct partition_t*	p;
+     struct partition_t*	found;
+	
+     parts = partitions_lookup(dev_name);
+     found = NULL;
+			
+#if DEBUG
+     if (parts)
+	  prom_printf("partitions:\n");
+     else
+	  prom_printf("no partitions found.\n");
+#endif
+     for (p = parts; p && !found; p=p->next) {
+	  DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n",
+		  p->part_number, p->part_start, p->part_size );
+	  if (partition == -1) {
+	       file->fs = fs_open( file, dev_name, p, file_name );
+	       if (file->fs == NULL || fserrorno != FILE_ERR_OK)
+		    continue;
+	       else {
+		    partition = p->part_number;
+		    goto done;
+	       }
+	  }
+	  if ((partition >= 0) && (partition == p->part_number))
+	       found = p;
+#if DEBUG
+	  if (found)
+	       prom_printf(" (match)\n");
+#endif						
+     }
+
+     /* Note: we don't skip when found is NULL since we can, in some
+      * cases, let OF figure out a default partition.
+      */
+     DEBUG_F( "Using OF defaults.. (found = %p)\n", found );
+     file->fs = fs_open( file, dev_name, found, file_name );
+
+done:
+     if (parts)
+	  partitions_free(parts);
+
+     return fserrorno;
+}
+
+static int
+file_net_open(	struct boot_file_t*	file,
+		const char*		dev_name,
+		const char*		file_name)
+{
+     file->fs = fs_of_netboot;
+     return fs_of_netboot->open(file, dev_name, NULL, file_name);
+}
+
+static int
+default_read(	struct boot_file_t*	file,
+		unsigned int		size,
+		void*			buffer)
+{
+     prom_printf("WARNING ! default_read called !\n");
+     return FILE_ERR_EOF;
+}
+
+static int
+default_seek(	struct boot_file_t*	file,
+		unsigned int		newpos)
+{
+     prom_printf("WARNING ! default_seek called !\n");
+     return FILE_ERR_EOF;
+}
+
+static int
+default_close(	struct boot_file_t*	file)
+{
+     prom_printf("WARNING ! default_close called !\n");
+     return FILE_ERR_OK;
+}
+
+static struct fs_t fs_default =
+{
+     "defaults",
+     NULL,
+     default_read,
+     default_seek,
+     default_close
+};
+
+
+int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file)
+{
+     int result;
+	
+     memset(file, 0, sizeof(struct boot_file_t*));
+     file->fs        = &fs_default;
+
+     DEBUG_F("dev_path = %s\nfile_name = %s\npartition = %d\n",
+	     spec->dev, spec->file, spec->part);
+
+     result = prom_get_devtype(spec->dev);
+     if (result > 0)
+	  file->device_kind = result;
+     else
+	  return result;
+	
+     switch(file->device_kind) {
+     case FILE_DEVICE_BLOCK:
+	  DEBUG_F("device is a block device\n");
+	  return file_block_open(file, spec->dev, spec->file, spec->part);
+     case FILE_DEVICE_NET:
+	  DEBUG_F("device is a network device\n");
+	  return file_net_open(file, spec->dev, spec->file);
+     }
+     return 0;
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/fs.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/fs.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,75 @@
+/*
+ *  fs.c - Filesystem common definitions
+ *
+ *  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.
+ */
+
+#include "stdlib.h"
+#include "fs.h"
+#include "errors.h"
+
+extern const struct fs_t	of_filesystem;
+extern const struct fs_t	of_net_filesystem;
+extern const struct fs_t	ext2_filesystem;
+//extern const struct fs_t	iso_filesystem;
+
+/* Configurable filesystems */
+
+#ifdef CONFIG_FS_XFS
+extern const struct fs_t        xfs_filesystem;
+#endif /* CONFIG_FS_XFS */
+
+#ifdef CONFIG_FS_REISERFS
+extern const struct fs_t        reiserfs_filesystem;
+#endif /* CONFIG_FS_REISERFS */
+
+/* Filesystem handlers yaboot knows about */
+static const struct fs_t *block_filesystems[] = {
+     &ext2_filesystem,		/* ext2 */
+#ifdef CONFIG_FS_XFS
+     &xfs_filesystem,                /* XFS */
+#endif /* CONFIG_FS_XFS */
+#ifdef CONFIG_FS_REISERFS
+     &reiserfs_filesystem,		/* reiserfs */
+#endif /* CONFIG_FS_REISERFS */
+     &of_filesystem,			/* HFS/HFS+, ISO9660, UDF, UFS */
+     NULL
+};
+
+const struct fs_t *fs_of = &of_filesystem;              /* needed by ISO9660 */
+const struct fs_t *fs_of_netboot = &of_net_filesystem;  /* needed by file.c */
+
+const struct fs_t *
+fs_open(struct boot_file_t *file, const char *dev_name,
+	struct partition_t *part, const char *file_name)
+{
+     const struct fs_t **fs;
+     for (fs = block_filesystems; *fs; fs++)
+	  if ((fserrorno = (*fs)->open(file, dev_name, part, file_name)) != FILE_ERR_BAD_FSYS)
+	       break;
+
+     return *fs;
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/fs_ext2.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/fs_ext2.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,627 @@
+/*
+ *  fs_ext2.c - an implementation for the Ext2/Ext3 filesystem
+ *
+ *  Copyright (C) 2001, 2002 Ethan Benson
+ *
+ *  Copyright (C) 1999 Benjamin Herrenschmidt
+ *
+ *  Adapted from quik/silo
+ *
+ *  Copyright (C) 1996 Maurizio Plaza
+ *                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 "ctype.h"
+#include "types.h"
+#include "stddef.h"
+#include "file.h"
+#include "prom.h"
+#include "string.h"
+#include "partition.h"
+#include "fs.h"
+#include "errors.h"
+#include "debug.h"
+
+#define FAST_VERSION
+#define MAX_READ_RANGE	256
+#undef VERBOSE_DEBUG
+
+typedef int FILE;
+#include "linux/ext2_fs.h"
+#include "ext2fs/ext2fs.h"
+
+static int ext2_open(	struct boot_file_t*	file,
+			const char*		dev_name,
+			struct partition_t*	part,
+			const char*		file_name);
+static int ext2_read(	struct boot_file_t*	file,
+			unsigned int		size,
+			void*			buffer);
+static int ext2_seek(	struct boot_file_t*	file,
+			unsigned int		newpos);
+static int ext2_close(	struct boot_file_t*	file);
+
+struct fs_t ext2_filesystem =
+{
+     "ext2",
+     ext2_open,
+     ext2_read,
+     ext2_seek,
+     ext2_close
+};
+
+/* IO manager structure for the ext2 library */
+ 
+static errcode_t linux_open (const char *name, int flags, io_channel * channel);
+static errcode_t linux_close (io_channel channel);
+static errcode_t linux_set_blksize (io_channel channel, int blksize);
+static errcode_t linux_read_blk (io_channel channel, unsigned long block, int count, void *data);
+static errcode_t linux_write_blk (io_channel channel, unsigned long block, int count, const void *data);
+static errcode_t linux_flush (io_channel channel);
+
+static struct struct_io_manager struct_linux_manager =
+{
+     EXT2_ET_MAGIC_IO_MANAGER,
+     "linux I/O Manager",
+     linux_open,
+     linux_close,
+     linux_set_blksize,
+     linux_read_blk,
+     linux_write_blk,
+     linux_flush
+};
+
+static io_manager linux_io_manager = &struct_linux_manager;
+
+/* Currently, we have a mess between what is in the file structure
+ * and what is stored globally here. I'll clean this up later
+ */
+static int opened = 0;		/* We can't open twice ! */
+static unsigned int bs;		/* Blocksize */
+static unsigned long long doff;	/* Byte offset where partition starts */
+static ino_t root,cwd;
+static ext2_filsys fs = 0;
+static struct boot_file_t* cur_file;
+static char *block_buffer = NULL;
+
+#ifdef FAST_VERSION
+static unsigned long read_range_start;
+static unsigned long read_range_count;
+static unsigned long read_last_logical;
+static unsigned long read_total;
+static unsigned long read_max;
+static struct boot_file_t* read_cur_file;
+static errcode_t read_result;
+static char* read_buffer;
+
+static int read_dump_range(void);
+static int read_iterator(ext2_filsys fs, blk_t *blocknr, int lg_block, void *private);
+#else /* FAST_VERSION */
+static struct ext2_inode cur_inode;
+#endif /* FAST_VERSION */
+
+void com_err (const char *a, long i, const char *fmt,...)
+{
+     prom_printf ((char *) fmt);
+}
+
+static int
+ext2_open(	struct boot_file_t*	file,
+		const char*		dev_name,
+		struct partition_t*	part,
+		const char*		file_name)
+{
+     int result = 0;
+     int error = FILE_ERR_NOTFOUND;
+     static char buffer[1024];
+     int ofopened = 0;
+	
+     DEBUG_ENTER;
+     DEBUG_OPEN;
+
+     if (opened) {
+	  DEBUG_LEAVE(FILE_ERR_FSBUSY);
+	  return FILE_ERR_FSBUSY;
+     }
+     if (file->device_kind != FILE_DEVICE_BLOCK) {
+	  DEBUG_LEAVE(FILE_ERR_BADDEV);
+	  return FILE_ERR_BADDEV;
+     }
+
+     fs = NULL;
+	
+     /* We don't care too much about the device block size since we run
+      * thru the deblocker. We may have to change that is we plan to be
+      * compatible with older versions of OF
+      */
+     bs = 1024;
+     doff = 0;
+     if (part)
+	  doff = (unsigned long long)(part->part_start) * part->blocksize;
+     cur_file = file;
+
+
+     DEBUG_F("partition offset: %Lu\n", doff);
+
+     /* Open the OF device for the entire disk */
+     strncpy(buffer, dev_name, 1020);
+     strcat(buffer, ":0");
+
+     DEBUG_F("<%s>\n", buffer);
+
+     file->of_device = prom_open(buffer);
+
+     DEBUG_F("file->of_device = %p\n", file->of_device);
+
+     if (file->of_device == PROM_INVALID_HANDLE) {
+
+	  DEBUG_F("Can't open device %p\n", file->of_device);
+	  DEBUG_LEAVE(FILE_IOERR);
+	  return FILE_IOERR;
+     }
+     ofopened = 1;
+	
+     /* Open the ext2 filesystem */
+     result = ext2fs_open (buffer, EXT2_FLAG_RW, 0, 0, linux_io_manager, &fs);
+     if (result) {
+
+	  if(result == EXT2_ET_BAD_MAGIC)
+	  {
+	       DEBUG_F( "ext2fs_open returned bad magic loading file %p\n",
+			file );
+	  }
+	  else
+	  {
+	       DEBUG_F( "ext2fs_open error #%d while loading file %s\n",
+			result, file_name);
+	  }
+	  error = FILE_ERR_BAD_FSYS;
+	  goto bail;
+     }
+
+     /* Allocate the block buffer */
+     block_buffer = malloc(fs->blocksize * 2);
+     if (!block_buffer) {
+
+	  DEBUG_F("ext2fs: can't alloc block buffer (%d bytes)\n", fs->blocksize * 2);
+	  error = FILE_IOERR;
+	  goto bail;
+     }
+	
+     /* Lookup file by pathname */
+     root = cwd = EXT2_ROOT_INO;
+     result = ext2fs_namei_follow(fs, root, cwd, file_name, &file->inode);
+     if (result) {
+
+	  DEBUG_F("ext2fs_namei error #%d while loading file %s\n", result, file_name);
+	  if (result == EXT2_ET_SYMLINK_LOOP)
+	       error = FILE_ERR_SYMLINK_LOOP;
+	  else if (result == EXT2_ET_FILE_NOT_FOUND)
+	       error = FILE_ERR_NOTFOUND;
+	  else
+	       error = FILE_IOERR;
+	  goto bail;
+     }
+
+#if 0
+     result = ext2fs_follow_link(fs, root, cwd,  file->inode, &file->inode);
+     if (result) {
+
+	  DEBUG_F("ext2fs_follow_link error #%d while loading file %s\n", result, file_name);
+	  error = FILE_ERR_NOTFOUND;
+	  goto bail;
+     }
+#endif	
+
+#ifndef FAST_VERSION
+     result = ext2fs_read_inode(fs, file->inode, &cur_inode);
+     if (result) {
+
+	  DEBUG_F("ext2fs_read_inode error #%d while loading file %s\n", result, file_name);
+	  if (result == EXT2_ET_FILE_TOO_BIG)
+	       error = FILE_ERR_LENGTH;
+	  else if (result == EXT2_ET_LLSEEK_FAILED)
+	       error = FILE_CANT_SEEK;
+	  else if (result ==  EXT2_ET_FILE_NOT_FOUND)
+	       error = FILE_ERR_NOTFOUND;
+	  else
+	       error = FILE_IOERR;
+	  goto bail;
+     }
+#endif /* FAST_VERSION */
+     file->pos = 0;
+	
+     opened = 1;
+bail:
+     if (!opened) {
+	  if (fs)
+	       ext2fs_close(fs);
+	  fs = NULL;
+	  if (ofopened)
+	       prom_close(file->of_device);
+	  if (block_buffer)
+	       free(block_buffer);
+	  block_buffer = NULL;
+	  cur_file = NULL;
+	    
+	  DEBUG_LEAVE_F(error);
+	  return error;
+     }
+
+     DEBUG_LEAVE(FILE_ERR_OK);
+     return FILE_ERR_OK;
+}
+
+#ifdef FAST_VERSION
+
+static int
+read_dump_range(void)
+{
+     int count = read_range_count;
+     int size;
+
+#ifdef VERBOSE_DEBUG
+     DEBUG_F("   dumping range: start: 0x%x count: 0x%x\n",
+	     read_range_count, read_range_start);
+#endif
+     /* Check if we need to handle a special case for the last block */
+     if ((count * bs) > read_max)
+	  count--;
+     if (count) {
+	  size = count * bs;	
+	  read_result = io_channel_read_blk(fs->io, read_range_start, count, read_buffer);
+	  if (read_result)
+	       return BLOCK_ABORT;
+	  read_buffer += size;
+	  read_max -= size;
+	  read_total += size;
+	  read_cur_file->pos += size;
+	  read_range_count -= count;
+	  read_range_start += count;
+	  read_last_logical += count;
+     }	
+     /* Handle remaining block */
+     if (read_max && read_range_count) {
+	  read_result = io_channel_read_blk(fs->io, read_range_start, 1, block_buffer);
+	  if (read_result)
+	       return BLOCK_ABORT;
+	  memcpy(read_buffer, block_buffer, read_max);
+	  read_cur_file->pos += read_max;
+	  read_total += read_max;
+	  read_max = 0;
+     }
+     read_range_count = read_range_start = 0;
+
+     return (read_max == 0) ? BLOCK_ABORT : 0;
+}
+
+static int
+read_iterator(ext2_filsys fs, blk_t *blocknr, int lg_block, void *private)
+{
+#ifdef VERBOSE_DEBUG
+     DEBUG_F("read_it: p_bloc: 0x%x, l_bloc: 0x%x, f_pos: 0x%x, rng_pos: 0x%x   ",
+	     *blocknr, lg_block, read_cur_file->pos, read_last_logical);
+#endif
+     if (lg_block < 0) {
+#ifdef VERBOSE_DEBUG
+	  DEBUG_F(" <skip lg>\n");
+#endif
+	  return 0;
+     }
+
+     /* If we have not reached the start block yet, we skip */
+     if (lg_block < read_cur_file->pos / bs) {
+#ifdef VERBOSE_DEBUG
+	  DEBUG_F(" <skip pos>\n");
+#endif
+	  return 0;
+     }
+
+     /* If block is contiguous to current range, just extend range,
+      * exit if we pass the remaining bytes count to read
+      */
+     if (read_range_start && read_range_count < MAX_READ_RANGE
+	 && (*blocknr == read_range_start + read_range_count)
+	 && (lg_block == read_last_logical + read_range_count)) {
+#ifdef VERBOSE_DEBUG
+	  DEBUG_F(" block in range\n");
+#endif
+	  ++read_range_count;
+	  return ((read_range_count * bs) >= read_max) ? BLOCK_ABORT : 0;
+     }
+    
+     /* Range doesn't match. Dump existing range */
+     if (read_range_start) {
+#ifdef VERBOSE_DEBUG
+	  DEBUG_F(" calling dump range \n");
+#endif
+	  if (read_dump_range())
+	       return BLOCK_ABORT;
+     }
+
+     /* Here we handle holes in the file */
+     if (lg_block && lg_block != read_last_logical) {
+	  unsigned long nzero;
+#ifdef VERBOSE_DEBUG
+	  DEBUG_F(" hole from lg_bloc 0x%x\n", read_last_logical);
+#endif
+	  if (read_cur_file->pos % bs) {
+	       int offset = read_cur_file->pos % bs;
+	       int size = bs - offset;
+	       if (size > read_max)
+		    size = read_max;
+	       memset(read_buffer, 0, size);
+	       read_max -= size;
+	       read_total += size;
+	       read_buffer += size;
+	       read_cur_file->pos += size;
+	       ++read_last_logical;
+	       if (read_max == 0)
+		    return BLOCK_ABORT;
+	  }
+	  nzero = (lg_block - read_last_logical) * bs;
+	  if (nzero) {
+	       if (nzero > read_max)
+		    nzero = read_max;
+	       memset(read_buffer, 0, nzero);
+	       read_max -= nzero;
+	       read_total += nzero;
+	       read_buffer += nzero;
+	       read_cur_file->pos += nzero;
+	       if (read_max == 0)
+		    return BLOCK_ABORT;
+	  }
+	  read_last_logical = lg_block;
+     }
+
+     /* If we are not aligned, handle that case */
+     if (read_cur_file->pos % bs) {
+	  int offset = read_cur_file->pos % bs;
+	  int size = bs - offset;
+#ifdef VERBOSE_DEBUG
+	  DEBUG_F(" handle unaligned start\n");
+#endif
+	  read_result = io_channel_read_blk(fs->io, *blocknr, 1, block_buffer);
+	  if (read_result)
+	       return BLOCK_ABORT;
+	  if (size > read_max)
+	       size = read_max;
+	  memcpy(read_buffer, block_buffer + offset, size);
+	  read_cur_file->pos += size;
+	  read_max -= size;
+	  read_total += size;
+	  read_buffer += size;
+	  read_last_logical = lg_block + 1;
+	  return (read_max == 0) ? BLOCK_ABORT : 0;
+     }
+
+     /* If there is still a physical block to add, then create a new range */
+     if (*blocknr) {
+#ifdef VERBOSE_DEBUG
+	  DEBUG_F(" new range\n");
+#endif
+	  read_range_start = *blocknr;
+	  read_range_count = 1;
+	  return (bs >= read_max) ? BLOCK_ABORT : 0;
+     }
+    
+#ifdef VERBOSE_DEBUG
+     DEBUG_F("\n");
+#endif
+     return 0;
+}
+
+#endif /* FAST_VERSION */
+
+static int
+ext2_read(	struct boot_file_t*	file,
+		unsigned int		size,
+		void*			buffer)
+{
+     errcode_t retval;
+
+#ifdef FAST_VERSION
+     if (!opened)
+	  return FILE_IOERR;
+
+
+     DEBUG_F("ext_read() from pos 0x%Lx, size: 0x%ux\n", file->pos, size);
+
+
+     read_cur_file = file;
+     read_range_start = 0;
+     read_range_count = 0;
+     read_last_logical = file->pos / bs;
+     read_total = 0;
+     read_max = size;
+     read_buffer = (unsigned char*)buffer;
+     read_result = 0;
+    
+     retval = ext2fs_block_iterate(fs, file->inode, 0, 0, read_iterator, 0);
+     if (retval == BLOCK_ABORT)
+	  retval = read_result;
+     if (!retval && read_range_start) {
+#ifdef VERBOSE_DEBUG
+	  DEBUG_F("on exit: range_start is 0x%x, calling dump...\n",
+		  read_range_start);
+#endif
+	  read_dump_range();
+	  retval = read_result;
+     }
+     if (retval)
+	  prom_printf ("ext2: i/o error %ld in read\n", (long) retval);
+		
+     return read_total;
+
+#else /* FAST_VERSION */
+     int status;
+     unsigned int read = 0;
+	
+     if (!opened)
+	  return FILE_IOERR;
+
+
+     DEBUG_F("ext_read() from pos 0x%x, size: 0x%x\n", file->pos, size);
+
+
+     while(size) {	
+	  blk_t fblock = file->pos / bs;
+	  blk_t pblock;
+	  unsigned int blkorig, s, b;
+	
+	  pblock = 0;
+	  status = ext2fs_bmap(fs, file->inode, &cur_inode,
+			       block_buffer, 0, fblock, &pblock);
+	  if (status) {
+
+	       DEBUG_F("ext2fs_bmap(fblock:%d) return: %d\n", fblock, status);
+	       return read;
+	  }
+	  blkorig = fblock * bs;
+	  b = file->pos - blkorig;
+	  s = ((bs - b) > size) ? size : (bs - b);
+	  if (pblock) {
+	       unsigned long long pos =
+		    ((unsigned long long)pblock) * (unsigned long long)bs;
+	       pos += doff;
+	       prom_lseek(file->of_device, pos);
+	       status = prom_read(file->of_device, block_buffer, bs);
+	       if (status != bs) {
+		    prom_printf("ext2: io error in read, ex: %d, got: %d\n",
+				bs, status);
+		    return read;
+	       }
+	  } else
+	       memset(block_buffer, 0, bs);
+
+	  memcpy(buffer, block_buffer + b, s);
+	  read += s;
+	  size -= s;
+	  buffer += s;
+	  file->pos += s;
+     }
+     return read;
+#endif /* FAST_VERSION */	
+}
+
+static int
+ext2_seek(	struct boot_file_t*	file,
+		unsigned int		newpos)
+{
+     if (!opened)
+	  return FILE_CANT_SEEK;
+
+     file->pos = newpos;
+     return FILE_ERR_OK;
+}
+
+static int
+ext2_close(	struct boot_file_t*	file)
+{
+     if (!opened)
+	  return FILE_IOERR;
+
+     if (block_buffer)
+	  free(block_buffer);
+     block_buffer = NULL;
+
+     if (fs)
+	  ext2fs_close(fs);
+     fs = NULL;
+	
+     prom_close(file->of_device);
+     DEBUG_F("ext2_close called\n");
+
+     opened = 0;
+	    
+     return 0;
+}
+
+static errcode_t linux_open (const char *name, int flags, io_channel * channel)
+{
+     io_channel io;
+
+
+     if (!name)
+	  return EXT2_ET_BAD_DEVICE_NAME;
+     io = (io_channel) malloc (sizeof (struct struct_io_channel));
+     if (!io)
+	  return EXT2_ET_BAD_DEVICE_NAME;
+     memset (io, 0, sizeof (struct struct_io_channel));
+     io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
+     io->manager = linux_io_manager;
+     io->name = (char *) malloc (strlen (name) + 1);
+     strcpy (io->name, name);
+     io->block_size = bs;
+     io->read_error = 0;
+     io->write_error = 0;
+     *channel = io;
+
+     return 0;
+}
+
+static errcode_t linux_close (io_channel channel)
+{
+     free(channel);
+     return 0;
+}
+
+static errcode_t linux_set_blksize (io_channel channel, int blksize)
+{
+     channel->block_size = bs = blksize;
+     if (block_buffer) {
+	  free(block_buffer);
+	  block_buffer = malloc(bs * 2);
+     }	
+     return 0;
+}
+
+static errcode_t linux_read_blk (io_channel channel, unsigned long block, int count, void *data)
+{
+     int size;
+     unsigned long long tempb;
+
+     if (count == 0)
+	  return 0;
+    
+     tempb = (((unsigned long long) block) *
+	      ((unsigned long long)bs)) + (unsigned long long)doff;
+     size = (count < 0) ? -count : count * bs;
+     prom_lseek(cur_file->of_device, tempb);
+     if (prom_read(cur_file->of_device, data, size) != size) {
+	  DEBUG_F("\nRead error on block %ld\n", block);
+	  return EXT2_ET_SHORT_READ;
+     }
+     return 0;
+}
+
+static errcode_t linux_write_blk (io_channel channel, unsigned long block, int count, const void *data)
+{
+     return 0;
+}
+
+static errcode_t linux_flush (io_channel channel)
+{
+     return 0;
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/fs_iso.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/fs_iso.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,86 @@
+/*
+ *  fs_iso.c - a non-implementation for the ISO9660 filesystem
+ *
+ *  Copyright (C) 1999 Benjamin Herrenschnidt
+ *
+ *  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 "ctype.h"
+#include "types.h"
+#include "stddef.h"
+#include "file.h"
+#include "prom.h"
+#include "string.h"
+#include "partition.h"
+#include "fs.h"
+#include "errors.h"
+
+static int iso_open(	struct boot_file_t*	file,
+			const char*		dev_name,
+			struct partition_t*	part,
+			const char*		file_name);
+static int iso_read(	struct boot_file_t*	file,
+			unsigned int		size,
+			void*			buffer);
+static int iso_seek(	struct boot_file_t*	file,
+			unsigned int		newpos);
+static int iso_close(	struct boot_file_t*	file);
+
+struct fs_t iso_filesystem =
+{
+     "iso9660",
+     iso_open,
+     iso_read,
+     iso_seek,
+     iso_close
+};
+
+static int
+iso_open(	struct boot_file_t*	file,
+		const char*		dev_name,
+		struct partition_t*	part,
+		const char*		file_name)
+{
+     return FILE_ERR_BAD_FSYS;
+}
+
+static int
+iso_read(	struct boot_file_t*	file,
+		unsigned int		size,
+		void*			buffer)
+{
+     return FILE_ERR_BAD_FSYS;
+}
+
+static int
+iso_seek(	struct boot_file_t*	file,
+		unsigned int		newpos)
+{
+     return FILE_ERR_BAD_FSYS;
+}
+
+static int
+iso_close(	struct boot_file_t*	file)
+{
+     return 0;
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/fs_of.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/fs_of.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,244 @@
+/*
+ *  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 "fs.h"
+#include "errors.h"
+#include "debug.h"
+
+#define LOAD_BUFFER_POS		0x600000
+/* this cannot be safely increased any further */
+#define LOAD_BUFFER_SIZE	0x600000
+
+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) {
+	  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;
+
+     DEBUG_ENTER;
+     DEBUG_OPEN;
+
+     strncpy(buffer, dev_name, 768);
+     if (file_name && strlen(file_name)) {
+	  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;
+     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((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:
+ */

Added: ppcrcd/yaboot/fs_reiserfs.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/fs_reiserfs.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,1055 @@
+/*
+ *  fs_reiserfs.c - an implementation for the Reiser filesystem
+ *
+ *  Copyright (C) 2001 Jeffrey Mahoney (jeffm at suse.com)
+ *
+ *  Adapted from Grub
+ *
+ *  Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ *
+ *  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 "types.h"
+#include "ctype.h"
+#include "string.h"
+#include "stdlib.h"
+#include "fs.h"
+#include "errors.h"
+#include "debug.h"
+#include "reiserfs/reiserfs.h"
+
+/* Exported in struct fs_t */
+static int reiserfs_open( struct boot_file_t *file, const char *dev_name,
+			  struct partition_t *part, const char *file_name );
+static int reiserfs_read( struct boot_file_t *file, unsigned int size,
+
+			  void *buffer );
+static int reiserfs_seek( struct boot_file_t *file, unsigned int newpos );
+static int reiserfs_close( struct boot_file_t *file );
+
+struct fs_t reiserfs_filesystem = {
+     name:"reiserfs",
+     open:reiserfs_open,
+     read:reiserfs_read,
+     seek:reiserfs_seek,
+     close:reiserfs_close
+};
+
+static int reiserfs_read_super( void );
+static int reiserfs_open_file( char *dirname );
+static int reiserfs_read_data( char *buf, __u32 len );
+
+
+static struct reiserfs_state reiserfs;
+static struct reiserfs_state *INFO = &reiserfs;
+
+/* Adapted from GRUB: */
+static char FSYS_BUF[FSYSREISER_CACHE_SIZE];
+int errnum;
+
+
+static int
+reiserfs_open( struct boot_file_t *file, const char *dev_name,
+               struct partition_t *part, const char *file_name )
+{
+     static char buffer[1024];
+
+     DEBUG_ENTER;
+     DEBUG_OPEN;
+
+     memset( INFO, 0, sizeof(struct reiserfs_state) );
+     INFO->file = file;
+
+     if (part)
+     {
+	  DEBUG_F( "Determining offset for partition %d\n", part->part_number );
+	  INFO->partition_offset = ((uint64_t)part->part_start) * part->blocksize;
+	  DEBUG_F( "%Lu = %lu * %hu\n", INFO->partition_offset,
+		   part->part_start,
+		   part->blocksize );
+     }
+     else
+	  INFO->partition_offset = 0;
+
+     sprintf( buffer, "%s:%d", dev_name, 0 ); /* 0 is full disk in OF */
+     file->of_device = prom_open( buffer );
+     DEBUG_F( "Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
+	      buffer, file_name, INFO->partition_offset );
+
+     if ( file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL )
+     {
+	  DEBUG_F( "Can't open device %p\n", file->of_device );
+	  DEBUG_LEAVE(FILE_ERR_BADDEV);
+	  return FILE_ERR_BADDEV;
+     }
+
+     DEBUG_F("%p was successfully opened\n", file->of_device);
+
+     if ( reiserfs_read_super() != 1 )
+     {
+	  DEBUG_F( "Couldn't open ReiserFS @ %s/%Lu\n", buffer, INFO->partition_offset );
+	  prom_close( file->of_device );
+	  DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+	  return FILE_ERR_BAD_FSYS;
+     }
+
+     DEBUG_F( "Attempting to open %s\n", file_name );
+     strcpy(buffer, file_name); /* reiserfs_open_file modifies argument */
+     if (reiserfs_open_file(buffer) == 0)
+     {
+	  DEBUG_F( "reiserfs_open_file failed. errnum = %d\n", errnum );
+	  prom_close( file->of_device );
+	  DEBUG_LEAVE_F(errnum);
+	  return errnum;
+     }
+
+     DEBUG_F( "Successfully opened %s\n", file_name );
+
+     DEBUG_LEAVE(FILE_ERR_OK);
+     DEBUG_SLEEP;
+     return FILE_ERR_OK;
+}
+
+static int
+reiserfs_read( struct boot_file_t *file, unsigned int size, void *buffer )
+{
+     return reiserfs_read_data( buffer, size );
+}
+
+static int
+reiserfs_seek( struct boot_file_t *file, unsigned int newpos )
+{
+     file->pos = newpos;
+     return FILE_ERR_OK;
+}
+
+static int
+reiserfs_close( struct boot_file_t *file )
+{
+     if( file->of_device )
+     {
+	  prom_close(file->of_device);
+	  file->of_device = 0;
+	  DEBUG_F("reiserfs_close called\n");
+     }
+     return FILE_ERR_OK;
+}
+
+
+static __inline__ __u32
+log2( __u32 word )
+{
+     int i = 0;
+     while( word && (word & (1 << ++i)) == 0 );
+     return i;
+}
+
+static __inline__ int
+is_power_of_two( unsigned long word )
+{
+     return ( word & -word ) == word;
+}
+
+static int
+read_disk_block( struct boot_file_t *file, __u32 block, __u32 start,
+                 __u32 length, void *buf )
+{
+     __u16 fs_blocksize = INFO->blocksize == 0 ? REISERFS_OLD_BLOCKSIZE
+	  : INFO->blocksize;
+     unsigned long long pos = (unsigned long long)block * (unsigned long long)fs_blocksize;
+     pos += (unsigned long long)INFO->partition_offset + (unsigned long long)start;
+     DEBUG_F( "Reading %u bytes, starting at block %u, disk offset %Lu\n",
+	      length, block, pos );
+     if (!prom_lseek( file->of_device, pos )) {
+	  DEBUG_F("prom_lseek failed\n");
+	  return 0;
+     }
+     return prom_read( file->of_device, buf, length );
+}
+
+
+static int
+journal_read( __u32 block, __u32 len, char *buffer )
+{
+     return read_disk_block( INFO->file,
+			     (INFO->journal_block + block), 0,
+			     len, buffer );
+}
+
+/* Read a block from ReiserFS file system, taking the journal into
+ * account.  If the block nr is in the journal, the block from the
+ * journal taken.  
+ */
+static int
+block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
+{
+     __u32 transactions = INFO->journal_transactions;
+     __u32 desc_block = INFO->journal_first_desc;
+     __u32 journal_mask = INFO->journal_block_count - 1;
+     __u32 translatedNr = blockNr;
+     __u32 *journal_table = JOURNAL_START;
+
+//    DEBUG_F( "block_read( %u, %u, %u, ..)\n", blockNr, start, len );
+
+     while ( transactions-- > 0 )
+     {
+	  int i = 0;
+	  int j_len;
+
+	  if ( *journal_table != 0xffffffff )
+	  {
+	       /* Search for the blockNr in cached journal */
+	       j_len = le32_to_cpu(*journal_table++);
+	       while ( i++ < j_len )
+	       {
+		    if ( le32_to_cpu(*journal_table++) == blockNr )
+		    {
+			 journal_table += j_len - i;
+			 goto found;
+		    }
+	       }
+	  }
+	  else
+	  {
+	       /* This is the end of cached journal marker.  The remaining
+		* transactions are still on disk. */
+	       struct reiserfs_journal_desc desc;
+	       struct reiserfs_journal_commit commit;
+
+	       if ( !journal_read( desc_block, sizeof(desc), (char *) &desc ) )
+		    return 0;
+
+	       j_len = le32_to_cpu(desc.j_len);
+	       while ( i < j_len && i < JOURNAL_TRANS_HALF )
+		    if ( le32_to_cpu(desc.j_realblock[i++]) == blockNr )
+			 goto found;
+
+	       if ( j_len >= JOURNAL_TRANS_HALF )
+	       {
+		    int commit_block = ( desc_block + 1 + j_len ) & journal_mask;
+
+		    if ( !journal_read( commit_block,
+					sizeof(commit), (char *) &commit ) )
+			 return 0;
+
+		    while ( i < j_len )
+			 if ( le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr )
+			      goto found;
+	       }
+	  }
+	  goto not_found;
+
+     found:
+	  translatedNr =
+	       INFO->journal_block + ( ( desc_block + i ) & journal_mask );
+
+	  DEBUG_F( "block_read: block %u is mapped to journal block %u.\n",
+		   blockNr, translatedNr - INFO->journal_block );
+
+	  /* We must continue the search, as this block may be overwritten in 
+	   * later transactions. */
+     not_found:
+	  desc_block = (desc_block + 2 + j_len) & journal_mask;
+     }
+
+     return read_disk_block( INFO->file, translatedNr, start, len, buffer );
+}
+
+/* Init the journal data structure.  We try to cache as much as
+ * possible in the JOURNAL_START-JOURNAL_END space, but if it is full
+ * we can still read the rest from the disk on demand.
+ *
+ * The first number of valid transactions and the descriptor block of the
+ * first valid transaction are held in INFO.  The transactions are all 
+ * adjacent, but we must take care of the journal wrap around. 
+ */
+static int
+journal_init( void )
+{
+     struct reiserfs_journal_header header;
+     struct reiserfs_journal_desc desc;
+     struct reiserfs_journal_commit commit;
+     __u32 block_count = INFO->journal_block_count;
+     __u32 desc_block;
+     __u32 commit_block;
+     __u32 next_trans_id;
+     __u32 *journal_table = JOURNAL_START;
+
+     journal_read( block_count, sizeof ( header ), ( char * ) &header );
+     desc_block = le32_to_cpu(header.j_first_unflushed_offset);
+     if ( desc_block >= block_count )
+	  return 0;
+
+     INFO->journal_transactions = 0;
+     INFO->journal_first_desc = desc_block;
+     next_trans_id = le32_to_cpu(header.j_last_flush_trans_id) + 1;
+
+     DEBUG_F( "journal_init: last flushed %u\n", le32_to_cpu(header.j_last_flush_trans_id) );
+
+     while ( 1 )
+     {
+	  journal_read( desc_block, sizeof(desc), (char *) &desc );
+	  if ( strcmp( JOURNAL_DESC_MAGIC, desc.j_magic ) != 0
+	       || desc.j_trans_id != next_trans_id
+	       || desc.j_mount_id != header.j_mount_id )
+	       /* no more valid transactions */
+	       break;
+
+	  commit_block = ( desc_block + le32_to_cpu(desc.j_len) + 1 ) & ( block_count - 1 );
+	  journal_read( commit_block, sizeof(commit), (char *) &commit );
+	  if ( desc.j_trans_id != commit.j_trans_id
+	       || desc.j_len != commit.j_len )
+	       /* no more valid transactions */
+	       break;
+
+
+	  DEBUG_F( "Found valid transaction %u/%u at %u.\n",
+		   le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
+		   desc_block );
+
+
+	  next_trans_id++;
+	  if ( journal_table < JOURNAL_END )
+	  {
+	       if ( ( journal_table + 1 + le32_to_cpu(desc.j_len) ) >= JOURNAL_END )
+	       {
+		    /* The table is almost full; mark the end of the cached * *
+		     * journal. */
+		    *journal_table = 0xffffffff;
+		    journal_table = JOURNAL_END;
+	       }
+	       else
+	       {
+		    int i;
+
+		    /* Cache the length and the realblock numbers in the table. * 
+		     * The block number of descriptor can easily be computed. *
+		     * and need not to be stored here. */
+		    *journal_table++ = desc.j_len;
+		    for ( i = 0; i < le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++ )
+		    {
+			 *journal_table++ = desc.j_realblock[i];
+
+			 DEBUG_F( "block %u is in journal %u.\n",
+				  le32_to_cpu(desc.j_realblock[i]), desc_block );
+
+		    }
+		    for ( ; i < le32_to_cpu(desc.j_len); i++ )
+		    {
+			 *journal_table++ =
+			      commit.j_realblock[i - JOURNAL_TRANS_HALF];
+
+			 DEBUG_F( "block %u is in journal %u.\n",
+				  le32_to_cpu(commit.j_realblock[i - JOURNAL_TRANS_HALF]),
+				  desc_block );
+
+		    }
+	       }
+	  }
+	  desc_block = (commit_block + 1) & (block_count - 1);
+     }
+
+     DEBUG_F( "Transaction %u/%u at %u isn't valid.\n",
+	      le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
+	      desc_block );
+
+
+     INFO->journal_transactions
+	  = next_trans_id - le32_to_cpu(header.j_last_flush_trans_id) - 1;
+     return (errnum == 0);
+}
+
+/* check filesystem types and read superblock into memory buffer */
+static int
+reiserfs_read_super( void )
+{
+     struct reiserfs_super_block super;
+     __u64 superblock = REISERFS_SUPERBLOCK_BLOCK;
+
+     if (read_disk_block(INFO->file, superblock, 0, sizeof(super), &super) != sizeof(super)) {
+	  DEBUG_F("read_disk_block failed!\n");
+	  return 0;
+     }
+
+     DEBUG_F( "Found super->magic: \"%s\"\n", super.s_magic );
+
+     if( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
+	 strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
+     {
+	  /* Try old super block position */
+	  superblock = REISERFS_OLD_SUPERBLOCK_BLOCK;
+
+	  if (read_disk_block( INFO->file, superblock, 0, sizeof (super),  &super ) != sizeof(super)) {
+	       DEBUG_F("read_disk_block failed!\n");
+	       return 0;
+	  }
+
+	  if ( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
+	       strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
+	  {
+	       /* pre journaling super block - untested */
+	       if ( strcmp( REISERFS_SUPER_MAGIC_STRING,
+			    (char *) ((__u32) &super + 20 ) ) != 0 )
+		    return 0;
+
+	       super.s_blocksize = cpu_to_le16(REISERFS_OLD_BLOCKSIZE);
+	       super.s_journal_block = 0;
+	       super.s_version = 0;
+	  }
+     }
+
+     DEBUG_F( "ReiserFS superblock data:\n" );
+     DEBUG_F( "Block count: %u\n", le32_to_cpu(super.s_block_count) )
+	  DEBUG_F( "Free blocks: %u\n", le32_to_cpu(super.s_free_blocks) );
+     DEBUG_F( "Journal block: %u\n", le32_to_cpu(super.s_journal_block) );
+     DEBUG_F( "Journal size (in blocks): %u\n",
+	      le32_to_cpu(super.s_orig_journal_size) );
+     DEBUG_F( "Root block: %u\n\n", le32_to_cpu(super.s_root_block) );
+
+
+     INFO->version = le16_to_cpu(super.s_version);
+     INFO->blocksize = le16_to_cpu(super.s_blocksize);
+     INFO->blocksize_shift = log2( INFO->blocksize );
+
+     INFO->journal_block = le32_to_cpu(super.s_journal_block);
+     INFO->journal_block_count = le32_to_cpu(super.s_orig_journal_size);
+
+     INFO->cached_slots = (FSYSREISER_CACHE_SIZE >> INFO->blocksize_shift) - 1;
+
+     /* At this point, we've found a valid superblock. If we run into problems
+      * mounting the FS, the user should probably know. */
+
+     /* A few sanity checks ... */
+     if ( INFO->version > REISERFS_MAX_SUPPORTED_VERSION )
+     {
+	  prom_printf( "ReiserFS: Unsupported version field: %u\n",
+		       INFO->version );
+	  return 0;
+     }
+
+     if ( INFO->blocksize < FSYSREISER_MIN_BLOCKSIZE
+	  || INFO->blocksize > FSYSREISER_MAX_BLOCKSIZE )
+     {
+	  prom_printf( "ReiserFS: Unsupported block size: %u\n",
+		       INFO->blocksize );
+	  return 0;
+     }
+
+     /* Setup the journal.. */
+     if ( INFO->journal_block != 0 )
+     {
+	  if ( !is_power_of_two( INFO->journal_block_count ) )
+	  {
+	       prom_printf( "ReiserFS: Unsupported journal size, "
+			    "not a power of 2: %u\n",
+			    INFO->journal_block_count );
+	       return 0;
+	  }
+
+	  journal_init();
+	  /* Read in super block again, maybe it is in the journal */
+	  block_read( superblock, 0, sizeof (struct reiserfs_super_block),
+		      (char *) &super );
+     }
+
+     /* Read in the root block */
+     if ( !block_read( le32_to_cpu(super.s_root_block), 0,
+		       INFO->blocksize, ROOT ) )
+     {
+	  prom_printf( "ReiserFS: Failed to read in root block\n" );
+	  return 0;
+     }
+
+     /* The root node is always the "deepest", so we can
+	determine the hieght of the tree using it. */
+     INFO->tree_depth = blkh_level(BLOCKHEAD(ROOT));
+
+
+     DEBUG_F( "root read_in: block=%u, depth=%u\n",
+	      le32_to_cpu(super.s_root_block), INFO->tree_depth );
+
+     if ( INFO->tree_depth >= REISERFS_MAX_TREE_HEIGHT )
+     {
+	  prom_printf( "ReiserFS: Unsupported tree depth (too deep): %u\n",
+		       INFO->tree_depth );
+	  return 0;
+     }
+
+     if ( INFO->tree_depth == BLKH_LEVEL_LEAF )
+     {
+	  /* There is only one node in the whole filesystem, which is
+	     simultanously leaf and root */
+	  memcpy( LEAF, ROOT, INFO->blocksize );
+     }
+     return 1;
+}
+
+/***************** TREE ACCESSING METHODS *****************************/
+
+/* I assume you are familiar with the ReiserFS tree, if not go to
+ * http://devlinux.com/projects/reiserfs/
+ *
+ * My tree node cache is organized as following
+ *   0   ROOT node
+ *   1   LEAF node  (if the ROOT is also a LEAF it is copied here
+ *   2-n other nodes on current path from bottom to top.  
+ *       if there is not enough space in the cache, the top most are
+ *       omitted.
+ *
+ * I have only two methods to find a key in the tree:
+ *   search_stat(dir_id, objectid) searches for the stat entry (always
+ *       the first entry) of an object.
+ *   next_key() gets the next key in tree order.
+ *
+ * This means, that I can only sequential reads of files are
+ * efficient, but this really doesn't hurt for grub.  
+ */
+
+/* Read in the node at the current path and depth into the node cache.
+ * You must set INFO->blocks[depth] before.
+ */
+static char *
+read_tree_node( __u32 blockNr, __u16 depth )
+{
+     char *cache = CACHE(depth);
+     int num_cached = INFO->cached_slots;
+     errnum = 0;
+
+     if ( depth < num_cached )
+     {
+	  /* This is the cached part of the path.
+	     Check if same block is needed. */
+	  if ( blockNr == INFO->blocks[depth] )
+	       return cache;
+     }
+     else
+	  cache = CACHE(num_cached);
+
+     DEBUG_F( "  next read_in: block=%u (depth=%u)\n", blockNr, depth );
+
+     if ( !block_read( blockNr, 0, INFO->blocksize, cache ) )
+     {
+	  DEBUG_F( "block_read failed\n" );
+	  return 0;
+     }
+
+     DEBUG_F( "FOUND: blk_level=%u, blk_nr_item=%u, blk_free_space=%u\n",
+	      blkh_level(BLOCKHEAD(cache)),
+	      blkh_nr_item(BLOCKHEAD(cache)),
+	      le16_to_cpu(BLOCKHEAD(cache)->blk_free_space) );
+
+     /* Make sure it has the right node level */
+     if ( blkh_level(BLOCKHEAD(cache)) != depth )
+     {
+	  DEBUG_F( "depth = %u != %u\n", blkh_level(BLOCKHEAD(cache)), depth );
+	  DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+	  errnum = FILE_ERR_BAD_FSYS;
+	  return 0;
+     }
+
+     INFO->blocks[depth] = blockNr;
+     return cache;
+}
+
+/* Get the next key, i.e. the key following the last retrieved key in
+ * tree order.  INFO->current_ih and 
+ * INFO->current_info are adapted accordingly.  */
+static int
+next_key( void )
+{
+     __u16 depth;
+     struct item_head *ih = INFO->current_ih + 1;
+     char *cache;
+
+
+     DEBUG_F( "next_key:\n  old ih: key %u:%u:%u:%u version:%u\n",
+	      le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
+	      le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
+	      le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
+	      le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
+	      ih_version(INFO->current_ih) );
+
+
+     if ( ih == &ITEMHEAD[blkh_nr_item(BLOCKHEAD( LEAF ))] )
+     {
+	  depth = BLKH_LEVEL_LEAF;
+	  /* The last item, was the last in the leaf node. * Read in the next
+	   * * block */
+	  do
+	  {
+	       if ( depth == INFO->tree_depth )
+	       {
+		    /* There are no more keys at all. * Return a dummy item with
+		     * * MAX_KEY */
+		    ih =
+			 ( struct item_head * )
+			 &BLOCKHEAD( LEAF )->blk_right_delim_key;
+		    goto found;
+	       }
+	       depth++;
+
+	       DEBUG_F( "  depth=%u, i=%u\n", depth, INFO->next_key_nr[depth] );
+
+	  }
+	  while ( INFO->next_key_nr[depth] == 0 );
+
+	  if ( depth == INFO->tree_depth )
+	       cache = ROOT;
+	  else if ( depth <= INFO->cached_slots )
+	       cache = CACHE( depth );
+	  else
+	  {
+	       cache = read_tree_node( INFO->blocks[depth], --depth );
+	       if ( !cache )
+		    return 0;
+	  }
+
+	  do
+	  {
+	       __u16 nr_item = blkh_nr_item(BLOCKHEAD( cache ));
+	       int key_nr = INFO->next_key_nr[depth]++;
+
+
+	       DEBUG_F( "  depth=%u, i=%u/%u\n", depth, key_nr, nr_item );
+
+	       if ( key_nr == nr_item )
+		    /* This is the last item in this block, set the next_key_nr * 
+		     * to 0 */
+		    INFO->next_key_nr[depth] = 0;
+
+	       cache =
+		    read_tree_node( dc_block_number( &(DC( cache )[key_nr])),
+				    --depth );
+	       if ( !cache )
+		    return 0;
+	  }
+	  while ( depth > BLKH_LEVEL_LEAF );
+
+	  ih = ITEMHEAD;
+     }
+found:
+     INFO->current_ih = ih;
+     INFO->current_item = &LEAF[ih_location(ih)];
+
+     DEBUG_F( "  new ih: key %u:%u:%u:%u version:%u\n",
+	      le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
+	      le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
+	      le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
+	      le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
+	      ih_version(INFO->current_ih) );
+
+     return 1;
+}
+
+/* preconditions: reiserfs_read_super already executed, therefore 
+ *   INFO block is valid
+ * returns: 0 if error (errnum is set), 
+ *   nonzero iff we were able to find the key successfully.
+ * postconditions: on a nonzero return, the current_ih and 
+ *   current_item fields describe the key that equals the
+ *   searched key.  INFO->next_key contains the next key after
+ *   the searched key.
+ * side effects: messes around with the cache.
+ */
+static int
+search_stat( __u32 dir_id, __u32 objectid )
+{
+     char *cache;
+     int depth;
+     int nr_item;
+     int i;
+     struct item_head *ih;
+     errnum = 0;
+
+     DEBUG_F( "search_stat:\n  key %u:%u:0:0\n", le32_to_cpu(dir_id),
+	      le32_to_cpu(objectid) );
+
+
+     depth = INFO->tree_depth;
+     cache = ROOT;
+
+     DEBUG_F( "depth = %d\n", depth );
+     while ( depth > BLKH_LEVEL_LEAF )
+     {
+	  struct key *key;
+
+	  nr_item = blkh_nr_item(BLOCKHEAD( cache ));
+
+	  key = KEY( cache );
+
+	  for ( i = 0; i < nr_item; i++ )
+	  {
+	       if (le32_to_cpu(key->k_dir_id) > le32_to_cpu(dir_id)
+		   || (key->k_dir_id == dir_id
+		       && (le32_to_cpu(key->k_objectid) > le32_to_cpu(objectid)
+			   || (key->k_objectid == objectid
+			       && (key->u.k_offset_v1.k_offset
+				   | key->u.k_offset_v1.k_uniqueness) > 0))))
+		    break;
+	       key++;
+	  }
+
+
+	  DEBUG_F( "  depth=%d, i=%d/%d\n", depth, i, nr_item );
+
+	  INFO->next_key_nr[depth] = ( i == nr_item ) ? 0 : i + 1;
+	  cache = read_tree_node( dc_block_number(&(DC(cache)[i])), --depth );
+	  if ( !cache )
+	       return 0;
+     }
+
+     /* cache == LEAF */
+     nr_item = blkh_nr_item(BLOCKHEAD(LEAF));
+     ih = ITEMHEAD;
+     DEBUG_F( "nr_item = %d\n", nr_item );
+     for ( i = 0; i < nr_item; i++ )
+     {
+	  if ( ih->ih_key.k_dir_id == dir_id
+	       && ih->ih_key.k_objectid == objectid
+	       && ih->ih_key.u.k_offset_v1.k_offset == 0
+	       && ih->ih_key.u.k_offset_v1.k_uniqueness == 0 )
+	  {
+
+	       DEBUG_F( "  depth=%d, i=%d/%d\n", depth, i, nr_item );
+
+	       INFO->current_ih = ih;
+	       INFO->current_item = &LEAF[ih_location(ih)];
+
+	       return 1;
+	  }
+
+	  ih++;
+     }
+
+     DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+     errnum = FILE_ERR_BAD_FSYS;
+     return 0;
+}
+
+static int
+reiserfs_read_data( char *buf, __u32 len )
+{
+     __u32 blocksize;
+     __u32 offset;
+     __u32 to_read;
+     char *prev_buf = buf;
+     errnum = 0;
+
+     DEBUG_F( "reiserfs_read_data: INFO->file->pos=%Lu len=%u, offset=%Lu\n",
+	      INFO->file->pos, len, (__u64) IH_KEY_OFFSET(INFO->current_ih) - 1 );
+
+
+     if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
+	  || IH_KEY_OFFSET( INFO->current_ih ) > INFO->file->pos + 1 )
+     {
+	  search_stat( INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid );
+	  goto get_next_key;
+     }
+
+     while ( errnum == 0 )
+     {
+	  if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid )
+	       break;
+
+	  offset = INFO->file->pos - IH_KEY_OFFSET( INFO->current_ih ) + 1;
+	  blocksize = ih_item_len(INFO->current_ih);
+
+
+	  DEBUG_F( "  loop: INFO->file->pos=%Lu len=%u, offset=%u blocksize=%u\n",
+		   INFO->file->pos, len, offset, blocksize );
+
+
+	  if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_DIRECT )
+	       && offset < blocksize )
+	  {
+	       to_read = blocksize - offset;
+	       if ( to_read > len )
+		    to_read = len;
+
+	       memcpy( buf, INFO->current_item + offset, to_read );
+	       goto update_buf_len;
+	  }
+	  else if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_INDIRECT ) )
+	  {
+	       blocksize = ( blocksize >> 2 ) << INFO->blocksize_shift;
+
+	       while ( offset < blocksize )
+	       {
+		    __u32 blocknr = le32_to_cpu(((__u32 *)
+						 INFO->current_item)[offset >> INFO->blocksize_shift]);
+
+		    int blk_offset = offset & (INFO->blocksize - 1);
+
+		    to_read = INFO->blocksize - blk_offset;
+		    if ( to_read > len )
+			 to_read = len;
+
+		    /* Journal is only for meta data.
+		       Data blocks can be read directly without using block_read */
+		    read_disk_block( INFO->file, blocknr, blk_offset, to_read,
+				     buf );
+
+	       update_buf_len:
+		    len -= to_read;
+		    buf += to_read;
+		    offset += to_read;
+		    INFO->file->pos += to_read;
+		    if ( len == 0 )
+			 goto done;
+	       }
+	  }
+     get_next_key:
+	  next_key();
+     }
+done:
+     return (errnum != 0) ? 0 : buf - prev_buf;
+}
+
+
+/* preconditions: reiserfs_read_super already executed, therefore 
+ *   INFO block is valid
+ * returns: 0 if error, nonzero iff we were able to find the file successfully
+ * postconditions: on a nonzero return, INFO->fileinfo contains the info
+ *   of the file we were trying to look up, filepos is 0 and filemax is 
+ *   the size of the file.
+ */
+static int
+reiserfs_open_file( char *dirname )
+{
+     struct reiserfs_de_head *de_head;
+     char *rest, ch;
+     __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
+
+     char linkbuf[PATH_MAX];	/* buffer for following symbolic links */
+     int link_count = 0;
+     int mode;
+     errnum = 0;
+
+     dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
+     objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
+
+     while ( 1 )
+     {
+
+	  DEBUG_F( "dirname=%s\n", dirname );
+
+	  /* Search for the stat info first. */
+	  if ( !search_stat( dir_id, objectid ) )
+	       return 0;
+
+
+	  DEBUG_F( "sd_mode=0%o sd_size=%Lu\n",
+		   sd_mode((struct stat_data *) INFO->current_item ),
+		   sd_size(INFO->current_ih, INFO->current_item ));
+
+
+	  mode = sd_mode((struct stat_data *)INFO->current_item);
+
+	  /* If we've got a symbolic link, then chase it. */
+	  if ( S_ISLNK( mode ) )
+	  {
+	       int len = 0;
+
+	       DEBUG_F("link count = %d\n", link_count);
+	       DEBUG_SLEEP;
+	       if ( ++link_count > MAX_LINK_COUNT )
+	       {
+		    DEBUG_F("Symlink loop\n");
+		    errnum = FILE_ERR_SYMLINK_LOOP;
+		    return 0;
+	       }
+
+	       /* Get the symlink size. */
+	       INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
+
+	       /* Find out how long our remaining name is. */
+	       while ( dirname[len] && !isspace( dirname[len] ) )
+		    len++;
+
+	       if ( INFO->file->len + len > sizeof ( linkbuf ) - 1 )
+	       {
+		    errnum = FILE_ERR_LENGTH;
+		    return 0;
+	       }
+
+	       /* Copy the remaining name to the end of the symlink data. Note * 
+		* that DIRNAME and LINKBUF may overlap! */
+	       memmove( linkbuf + INFO->file->len, dirname, len + 1 );
+
+	       INFO->fileinfo.k_dir_id = dir_id;
+	       INFO->fileinfo.k_objectid = objectid;
+	       INFO->file->pos = 0;
+	       if ( !next_key()
+		    || reiserfs_read_data( linkbuf, INFO->file->len ) != INFO->file->len ) {
+		    DEBUG_F("reiserfs_open_file - if !next_key || reiserfs_read_data\n");
+		    DEBUG_SLEEP;
+		    errnum = FILE_IOERR;
+		    return 0;
+	       }
+
+
+	       DEBUG_F( "symlink=%s\n", linkbuf );
+	       DEBUG_SLEEP;
+
+	       dirname = linkbuf;
+	       if ( *dirname == '/' )
+	       {
+		    /* It's an absolute link, so look it up in root. */
+		    dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
+		    objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
+	       }
+	       else
+	       {
+		    /* Relative, so look it up in our parent directory. */
+		    dir_id = parent_dir_id;
+		    objectid = parent_objectid;
+	       }
+
+	       /* Now lookup the new name. */
+	       continue;
+	  }
+
+	  /* if we have a real file (and we're not just printing *
+	   * possibilities), then this is where we want to exit */
+
+	  if ( !*dirname || isspace( *dirname ) )
+	  {
+	       if ( !S_ISREG( mode ) )
+	       {
+		    errnum = FILE_ERR_BAD_TYPE;
+		    return 0;
+	       }
+
+	       INFO->file->pos = 0;
+	       INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
+
+	       INFO->fileinfo.k_dir_id = dir_id;
+	       INFO->fileinfo.k_objectid = objectid;
+	       return next_key();
+	  }
+
+	  /* continue with the file/directory name interpretation */
+	  while ( *dirname == '/' )
+	       dirname++;
+	  if ( !S_ISDIR( mode ) )
+	  {
+	       errnum = FILE_ERR_NOTDIR;
+	       return 0;
+	  }
+	  for ( rest = dirname; ( ch = *rest ) && !isspace( ch ) && ch != '/';
+		rest++ ) ;
+	  *rest = 0;
+
+	  while ( 1 )
+	  {
+	       char *name_end;
+	       int num_entries;
+
+	       if ( !next_key() )
+		    return 0;
+
+	       if ( INFO->current_ih->ih_key.k_objectid != objectid )
+		    break;
+
+	       name_end = INFO->current_item + ih_item_len(INFO->current_ih);
+	       de_head = ( struct reiserfs_de_head * ) INFO->current_item;
+	       num_entries = ih_entry_count(INFO->current_ih);
+	       while ( num_entries > 0 )
+	       {
+		    char *filename = INFO->current_item + deh_location(de_head);
+		    char tmp = *name_end;
+
+		    if( deh_state(de_head) & (1 << DEH_Visible))
+		    {
+			 int cmp;
+
+			 /* Directory names in ReiserFS are not null * terminated. 
+			  * We write a temporary 0 behind it. * NOTE: that this
+			  * may overwrite the first block in * the tree cache.
+			  * That doesn't hurt as long as we * don't call next_key
+			  * () in between. */
+			 *name_end = 0;
+			 cmp = strcmp( dirname, filename );
+			 *name_end = tmp;
+			 if ( cmp == 0 )
+			      goto found;
+		    }
+		    /* The beginning of this name marks the end of the next name. 
+		     */
+		    name_end = filename;
+		    de_head++;
+		    num_entries--;
+	       }
+	  }
+
+	  errnum = FILE_ERR_NOTFOUND;
+	  *rest = ch;
+	  return 0;
+
+     found:
+	  *rest = ch;
+	  dirname = rest;
+
+	  parent_dir_id = dir_id;
+	  parent_objectid = objectid;
+	  dir_id = de_head->deh_dir_id; /* LE */
+	  objectid = de_head->deh_objectid; /* LE */
+     }
+}
+
+
+
+#ifndef __LITTLE_ENDIAN
+typedef union {
+     struct offset_v2 offset_v2;
+     __u64 linear;
+} offset_v2_esafe_overlay;
+
+inline __u16
+offset_v2_k_type( struct offset_v2 *v2 )
+{
+     offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
+     tmp.linear = le64_to_cpu( tmp.linear );
+     return tmp.offset_v2.k_type;
+}
+ 
+inline loff_t
+offset_v2_k_offset( struct offset_v2 *v2 )
+{
+     offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
+     tmp.linear = le64_to_cpu( tmp.linear );
+     return tmp.offset_v2.k_offset;
+}
+#endif
+
+inline int
+uniqueness2type (__u32 uniqueness)
+{
+     switch (uniqueness) {
+     case V1_SD_UNIQUENESS: return TYPE_STAT_DATA;
+     case V1_INDIRECT_UNIQUENESS: return TYPE_INDIRECT;
+     case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT;
+     case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY;
+     }
+     return TYPE_ANY;
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/fs_xfs.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/fs_xfs.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,786 @@
+/*
+ *  fs_xfs.c - an implementation for the SGI XFS file system
+ *
+ *  Copyright (C) 2001, 2002 Ethan Benson
+ *
+ *  Adapted from Grub
+ *
+ *  Copyright (C) 2001 Serguei Tzukanov
+ *
+ *  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 "types.h"
+#include "ctype.h"
+#include "string.h"
+#include "stdlib.h"
+#include "fs.h"
+#include "xfs/xfs.h"
+#include "errors.h"
+#include "debug.h"
+
+#define SECTOR_BITS 9
+
+int xfs_mount (void);
+int xfs_read_data (char *buf, int len);
+int xfs_dir (char *dirname);
+
+/* Exported in struct fs_t */
+static int xfs_open(struct boot_file_t *file, const char *dev_name,
+		    struct partition_t *part, const char *file_name);
+static int xfs_read(struct boot_file_t *file, unsigned int size, void *buffer);
+static int xfs_seek(struct boot_file_t *file, unsigned int newpos);
+static int xfs_close(struct boot_file_t *file);
+
+struct fs_t xfs_filesystem = {
+	name:"xfs",
+	open:xfs_open,
+	read:xfs_read,
+	seek:xfs_seek,
+	close:xfs_close
+};
+
+struct boot_file_t *xfs_file;
+static char FSYS_BUF[32768];
+uint64_t partition_offset;
+int errnum;
+
+static int
+xfs_open(struct boot_file_t *file, const char *dev_name,
+	 struct partition_t *part, const char *file_name)
+{
+	static char buffer[1024];
+
+	DEBUG_ENTER;
+	DEBUG_OPEN;
+
+	if (part)
+	{
+		DEBUG_F("Determining offset for partition %d\n", part->part_number);
+		partition_offset = ((uint64_t) part->part_start) * part->blocksize;
+		DEBUG_F("%Lu = %lu * %hu\n", partition_offset,
+			part->part_start,
+			part->blocksize);
+	}
+	else
+		partition_offset = 0;
+
+	sprintf(buffer, "%s:%d", dev_name, 0); /* 0 is full disk in OF */
+	DEBUG_F("Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
+		buffer, file_name, partition_offset);
+	file->of_device = prom_open(buffer);
+
+	if (file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL)
+	{
+		DEBUG_F("Can't open device %p\n", file->of_device);
+		DEBUG_LEAVE(FILE_ERR_BADDEV);
+		return FILE_ERR_BADDEV;
+	}
+
+	DEBUG_F("%p was successfully opened\n", file->of_device);
+
+	xfs_file = file;
+    
+	if (xfs_mount() != 1)
+	{
+		DEBUG_F("Couldn't open XFS @ %s/%Lu\n", buffer, partition_offset);
+		prom_close(file->of_device);
+		DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+		DEBUG_SLEEP;
+		return FILE_ERR_BAD_FSYS;
+	}
+
+	DEBUG_F("Attempting to open %s\n", file_name);
+	strcpy(buffer, file_name); /* xfs_dir modifies argument */
+	if(!xfs_dir(buffer))
+	{
+		DEBUG_F("xfs_dir() failed. errnum = %d\n", errnum);
+		prom_close( file->of_device );
+		DEBUG_LEAVE_F(errnum);
+		DEBUG_SLEEP;
+		return errnum;
+	}
+
+	DEBUG_F("Successfully opened %s\n", file_name);
+
+	DEBUG_LEAVE(FILE_ERR_OK);
+	return FILE_ERR_OK;
+}
+
+static int
+xfs_read(struct boot_file_t *file, unsigned int size, void *buffer)
+{
+	return xfs_read_data(buffer, size);
+}
+
+static int
+xfs_seek(struct boot_file_t *file, unsigned int newpos)
+{
+	file->pos = newpos;
+	return FILE_ERR_OK;
+}
+
+static int
+xfs_close(struct boot_file_t *file)
+{
+	if(file->of_device)
+	{
+		prom_close(file->of_device);
+		file->of_device = 0;
+		DEBUG_F("xfs_close called\n");
+	}
+	return FILE_ERR_OK;
+}
+
+static int
+read_disk_block(struct boot_file_t *file, uint64_t block, int start,
+		int length, void *buf)
+{
+	uint64_t pos = block * 512;
+	pos += partition_offset + start;
+	DEBUG_F("Reading %d bytes, starting at block %Lu, disk offset %Lu\n",
+		length, block, pos);
+	if (!prom_lseek(file->of_device, pos)) {
+		DEBUG_F("prom_lseek failed\n");
+		return 0;
+	}
+	return prom_read(file->of_device, buf, length);
+}
+
+#define MAX_LINK_COUNT	8
+
+typedef struct xad {
+	xfs_fileoff_t offset;
+	xfs_fsblock_t start;
+	xfs_filblks_t len;
+} xad_t;
+
+struct xfs_info {
+	int bsize;
+	int dirbsize;
+	int isize;
+	unsigned int agblocks;
+	int bdlog;
+	int blklog;
+	int inopblog;
+	int agblklog;
+	int agnolog;
+	int dirblklog;
+	unsigned int nextents;
+	xfs_daddr_t next;
+	xfs_daddr_t daddr;
+	xfs_dablk_t forw;
+	xfs_dablk_t dablk;
+	xfs_bmbt_rec_32_t *xt;
+	xfs_bmbt_ptr_t ptr0;
+	int btnode_ptr0_off;
+	int i8param;
+	int dirpos;
+	int dirmax;
+	int blkoff;
+	int fpos;
+	xfs_ino_t rootino;
+};
+
+static struct xfs_info xfs;
+
+#define dirbuf		((char *)FSYS_BUF)
+#define filebuf		((char *)FSYS_BUF + 4096)
+#define inode		((xfs_dinode_t *)((char *)FSYS_BUF + 8192))
+#define icore		(inode->di_core)
+
+#define	mask32lo(n)	(((__uint32_t)1 << (n)) - 1)
+
+#define	XFS_INO_MASK(k)		((__uint32_t)((1ULL << (k)) - 1))
+#define	XFS_INO_OFFSET_BITS	xfs.inopblog
+#define	XFS_INO_AGBNO_BITS	xfs.agblklog
+#define	XFS_INO_AGINO_BITS	(xfs.agblklog + xfs.inopblog)
+#define	XFS_INO_AGNO_BITS	xfs.agnolog
+
+static inline xfs_agblock_t
+agino2agbno (xfs_agino_t agino)
+{
+	return agino >> XFS_INO_OFFSET_BITS;
+}
+
+static inline xfs_agnumber_t
+ino2agno (xfs_ino_t ino)
+{
+	return ino >> XFS_INO_AGINO_BITS;
+}
+
+static inline xfs_agino_t
+ino2agino (xfs_ino_t ino)
+{
+	return ino & XFS_INO_MASK(XFS_INO_AGINO_BITS);
+}
+
+static inline int
+ino2offset (xfs_ino_t ino)
+{
+	return ino & XFS_INO_MASK(XFS_INO_OFFSET_BITS);
+}
+
+/* XFS is big endian, powerpc is big endian */
+#define le16(x) (x)
+#define le32(x) (x)
+#define le64(x) (x)
+
+static xfs_fsblock_t
+xt_start (xfs_bmbt_rec_32_t *r)
+{
+	return (((xfs_fsblock_t)(le32 (r->l1) & mask32lo(9))) << 43) | 
+	       (((xfs_fsblock_t)le32 (r->l2)) << 11) |
+	       (((xfs_fsblock_t)le32 (r->l3)) >> 21);
+}
+
+static xfs_fileoff_t
+xt_offset (xfs_bmbt_rec_32_t *r)
+{
+	return (((xfs_fileoff_t)le32 (r->l0) &
+		mask32lo(31)) << 23) |
+		(((xfs_fileoff_t)le32 (r->l1)) >> 9);
+}
+
+static xfs_filblks_t
+xt_len (xfs_bmbt_rec_32_t *r)
+{
+	return le32(r->l3) & mask32lo(21);
+}
+
+static const char xfs_highbit[256] = {
+       -1, 0, 1, 1, 2, 2, 2, 2,			/* 00 .. 07 */
+	3, 3, 3, 3, 3, 3, 3, 3,			/* 08 .. 0f */
+	4, 4, 4, 4, 4, 4, 4, 4,			/* 10 .. 17 */
+	4, 4, 4, 4, 4, 4, 4, 4,			/* 18 .. 1f */
+	5, 5, 5, 5, 5, 5, 5, 5,			/* 20 .. 27 */
+	5, 5, 5, 5, 5, 5, 5, 5,			/* 28 .. 2f */
+	5, 5, 5, 5, 5, 5, 5, 5,			/* 30 .. 37 */
+	5, 5, 5, 5, 5, 5, 5, 5,			/* 38 .. 3f */
+	6, 6, 6, 6, 6, 6, 6, 6,			/* 40 .. 47 */
+	6, 6, 6, 6, 6, 6, 6, 6,			/* 48 .. 4f */
+	6, 6, 6, 6, 6, 6, 6, 6,			/* 50 .. 57 */
+	6, 6, 6, 6, 6, 6, 6, 6,			/* 58 .. 5f */
+	6, 6, 6, 6, 6, 6, 6, 6,			/* 60 .. 67 */
+	6, 6, 6, 6, 6, 6, 6, 6,			/* 68 .. 6f */
+	6, 6, 6, 6, 6, 6, 6, 6,			/* 70 .. 77 */
+	6, 6, 6, 6, 6, 6, 6, 6,			/* 78 .. 7f */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* 80 .. 87 */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* 88 .. 8f */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* 90 .. 97 */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* 98 .. 9f */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* a0 .. a7 */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* a8 .. af */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* b0 .. b7 */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* b8 .. bf */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* c0 .. c7 */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* c8 .. cf */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* d0 .. d7 */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* d8 .. df */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* e0 .. e7 */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* e8 .. ef */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* f0 .. f7 */
+	7, 7, 7, 7, 7, 7, 7, 7,			/* f8 .. ff */
+};
+
+static int
+xfs_highbit32(__uint32_t v)
+{
+	int		i;
+
+	if (v & 0xffff0000)
+		if (v & 0xff000000)
+			i = 24;
+		else
+			i = 16;
+	else if (v & 0x0000ffff)
+		if (v & 0x0000ff00)
+			i = 8;
+		else
+			i = 0;
+	else
+		return -1;
+	return i + xfs_highbit[(v >> i) & 0xff];
+}
+
+static int
+isinxt (xfs_fileoff_t key, xfs_fileoff_t offset, xfs_filblks_t len)
+{
+	return (key >= offset) ? (key < offset + len ? 1 : 0) : 0;
+}
+
+static xfs_daddr_t
+agb2daddr (xfs_agnumber_t agno, xfs_agblock_t agbno)
+{
+	return ((xfs_fsblock_t)agno*xfs.agblocks + agbno) << xfs.bdlog;
+}
+
+static xfs_daddr_t
+fsb2daddr (xfs_fsblock_t fsbno)
+{
+	return agb2daddr ((xfs_agnumber_t)(fsbno >> xfs.agblklog),
+			 (xfs_agblock_t)(fsbno & mask32lo(xfs.agblklog)));
+}
+
+static inline int
+btroot_maxrecs (void)
+{
+	int tmp = icore.di_forkoff ? (icore.di_forkoff << 3) : xfs.isize;
+
+	return (tmp - sizeof(xfs_bmdr_block_t) -
+		(int)((char *)&inode->di_u - (char*)inode)) /
+		(sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t));
+}
+
+static int
+di_read (xfs_ino_t ino)
+{
+	xfs_agino_t agino;
+	xfs_agnumber_t agno;
+	xfs_agblock_t agbno;
+	xfs_daddr_t daddr;
+	int offset;
+
+	agno = ino2agno (ino);
+	agino = ino2agino (ino);
+	agbno = agino2agbno (agino);
+	offset = ino2offset (ino);
+	daddr = agb2daddr (agno, agbno);
+
+	read_disk_block(xfs_file, daddr, offset*xfs.isize, xfs.isize, (char *)inode);
+
+	xfs.ptr0 = *(xfs_bmbt_ptr_t *)
+		    (inode->di_u.di_c + sizeof(xfs_bmdr_block_t)
+		    + btroot_maxrecs ()*sizeof(xfs_bmbt_key_t));
+
+	return 1;
+}
+
+static void
+init_extents (void)
+{
+	xfs_bmbt_ptr_t ptr0;
+	xfs_btree_lblock_t h;
+
+	switch (icore.di_format) {
+	case XFS_DINODE_FMT_EXTENTS:
+		xfs.xt = inode->di_u.di_bmx;
+		xfs.nextents = le32 (icore.di_nextents);
+		break;
+	case XFS_DINODE_FMT_BTREE:
+		ptr0 = xfs.ptr0;
+		for (;;) {
+			xfs.daddr = fsb2daddr (le64(ptr0));
+			read_disk_block(xfs_file, xfs.daddr, 0,
+					sizeof(xfs_btree_lblock_t), (char *)&h);
+			if (!h.bb_level) {
+				xfs.nextents = le16(h.bb_numrecs);
+				xfs.next = fsb2daddr (le64(h.bb_leftsib));
+				xfs.fpos = sizeof(xfs_btree_block_t);
+				return;
+			}
+			read_disk_block(xfs_file, xfs.daddr, xfs.btnode_ptr0_off,
+				 sizeof(xfs_bmbt_ptr_t), (char *)&ptr0);
+		}
+	}
+}
+
+static xad_t *
+next_extent (void)
+{
+	static xad_t xad;
+
+	switch (icore.di_format) {
+	case XFS_DINODE_FMT_EXTENTS:
+		if (xfs.nextents == 0)
+			return NULL;
+		break;
+	case XFS_DINODE_FMT_BTREE:
+		if (xfs.nextents == 0) {
+			xfs_btree_lblock_t h;
+			if (xfs.next == 0)
+				return NULL;
+			xfs.daddr = xfs.next;
+			read_disk_block(xfs_file, xfs.daddr, 0,
+					sizeof(xfs_btree_lblock_t), (char *)&h);
+			xfs.nextents = le16(h.bb_numrecs);
+			xfs.next = fsb2daddr (le64(h.bb_leftsib));
+			xfs.fpos = sizeof(xfs_btree_block_t);
+		}
+		/* Yeah, I know that's slow, but I really don't care */
+		read_disk_block(xfs_file, xfs.daddr, xfs.fpos,
+				sizeof(xfs_bmbt_rec_t), filebuf);
+		xfs.xt = (xfs_bmbt_rec_32_t *)filebuf;
+		xfs.fpos += sizeof(xfs_bmbt_rec_32_t);
+		break;
+	default:
+		return NULL;
+	}
+	xad.offset = xt_offset (xfs.xt);
+	xad.start = xt_start (xfs.xt);
+	xad.len = xt_len (xfs.xt);
+	++xfs.xt;
+	--xfs.nextents;
+
+	return &xad;
+}
+
+/*
+ * Name lies - the function reads only first 100 bytes
+ */
+static void
+xfs_dabread (void)
+{
+	xad_t *xad;
+	xfs_fileoff_t offset;;
+
+	init_extents ();
+	while ((xad = next_extent ())) {
+		offset = xad->offset;
+		if (isinxt (xfs.dablk, offset, xad->len)) {
+			read_disk_block(xfs_file, fsb2daddr (xad->start + xfs.dablk - offset),
+					0, 100, dirbuf);
+			break;
+		}
+	}
+}
+
+static inline xfs_ino_t
+sf_ino (char *sfe, int namelen)
+{
+	void *p = sfe + namelen + 3;
+
+	return (xfs.i8param == 0)
+		? le64(*(xfs_ino_t *)p) : le32(*(__uint32_t *)p);
+}
+
+static inline xfs_ino_t
+sf_parent_ino (void)
+{
+	return (xfs.i8param == 0)
+		? le64(*(xfs_ino_t *)(&inode->di_u.di_dir2sf.hdr.parent))
+		: le32(*(__uint32_t *)(&inode->di_u.di_dir2sf.hdr.parent));
+}
+
+static inline int
+roundup8 (int n)
+{
+	return ((n+7)&~7);
+}
+
+static char *
+next_dentry (xfs_ino_t *ino)
+{
+	int namelen = 1;
+	int toread;
+	static char *usual[2] = {".", ".."};
+	static xfs_dir2_sf_entry_t *sfe;
+	char *name = usual[0];
+
+	if (xfs.dirpos >= xfs.dirmax) {
+		if (xfs.forw == 0)
+			return NULL;
+		xfs.dablk = xfs.forw;
+		xfs_dabread ();
+#define h	((xfs_dir2_leaf_hdr_t *)dirbuf)
+		xfs.dirmax = le16 (h->count) - le16 (h->stale);
+		xfs.forw = le32 (h->info.forw);
+#undef h
+		xfs.dirpos = 0;
+	}
+
+	switch (icore.di_format) {
+	case XFS_DINODE_FMT_LOCAL:
+		switch (xfs.dirpos) {
+		case -2:
+			*ino = 0;
+			break;
+		case -1:
+			*ino = sf_parent_ino ();
+			++name;
+			++namelen;
+			sfe = (xfs_dir2_sf_entry_t *)
+				(inode->di_u.di_c 
+				 + sizeof(xfs_dir2_sf_hdr_t)
+				 - xfs.i8param);
+			break;
+		default:
+			namelen = sfe->namelen;
+			*ino = sf_ino ((char *)sfe, namelen);
+			name = sfe->name;
+			sfe = (xfs_dir2_sf_entry_t *)
+				  ((char *)sfe + namelen + 11 - xfs.i8param);
+		}
+		break;
+	case XFS_DINODE_FMT_BTREE:
+	case XFS_DINODE_FMT_EXTENTS:
+#define dau	((xfs_dir2_data_union_t *)dirbuf)
+		for (;;) {
+			if (xfs.blkoff >= xfs.dirbsize) {
+				xfs.blkoff = sizeof(xfs_dir2_data_hdr_t);
+				xfs_file->pos &= ~(xfs.dirbsize - 1);
+				xfs_file->pos |= xfs.blkoff;
+			}
+			xfs_read_data (dirbuf, 4);
+			xfs.blkoff += 4;
+			if (dau->unused.freetag == XFS_DIR2_DATA_FREE_TAG) {
+				toread = roundup8 (le16(dau->unused.length)) - 4;
+				xfs.blkoff += toread;
+				xfs_file->pos += toread;
+				continue;
+			}
+			break;
+		}
+		xfs_read_data ((char *)dirbuf + 4, 5);
+		*ino = le64 (dau->entry.inumber);
+		namelen = dau->entry.namelen;
+#undef dau
+		toread = roundup8 (namelen + 11) - 9;
+		xfs_read_data (dirbuf, toread);
+		name = (char *)dirbuf;
+		xfs.blkoff += toread + 5;
+		break;
+	}
+	++xfs.dirpos;
+	name[namelen] = 0;
+
+	return name;
+}
+
+static char *
+first_dentry (xfs_ino_t *ino)
+{
+	xfs.forw = 0;
+	switch (icore.di_format) {
+	case XFS_DINODE_FMT_LOCAL:
+		xfs.dirmax = inode->di_u.di_dir2sf.hdr.count;
+		xfs.i8param = inode->di_u.di_dir2sf.hdr.i8count ? 0 : 4;
+		xfs.dirpos = -2;
+		break;
+	case XFS_DINODE_FMT_EXTENTS:
+	case XFS_DINODE_FMT_BTREE:
+		xfs_file->pos = 0;
+		xfs_file->len = le64 (icore.di_size);
+		xfs_read_data (dirbuf, sizeof(xfs_dir2_data_hdr_t));
+		if (((xfs_dir2_data_hdr_t *)dirbuf)->magic == le32(XFS_DIR2_BLOCK_MAGIC)) {
+#define tail		((xfs_dir2_block_tail_t *)dirbuf)
+			xfs_file->pos = xfs.dirbsize - sizeof(*tail);
+			xfs_read_data (dirbuf, sizeof(*tail));
+			xfs.dirmax = le32 (tail->count) - le32 (tail->stale);
+#undef tail
+		} else {
+			xfs.dablk = (1ULL << 35) >> xfs.blklog;
+#define h		((xfs_dir2_leaf_hdr_t *)dirbuf)
+#define n		((xfs_da_intnode_t *)dirbuf)
+			for (;;) {
+				xfs_dabread ();
+				if ((n->hdr.info.magic == le16(XFS_DIR2_LEAFN_MAGIC))
+				    || (n->hdr.info.magic == le16(XFS_DIR2_LEAF1_MAGIC))) {
+					xfs.dirmax = le16 (h->count) - le16 (h->stale);
+					xfs.forw = le32 (h->info.forw);
+					break;
+				}
+				xfs.dablk = le32 (n->btree[0].before);
+			}
+#undef n
+#undef h
+		}
+		xfs.blkoff = sizeof(xfs_dir2_data_hdr_t);
+		xfs_file->pos = xfs.blkoff;
+		xfs.dirpos = 0;
+		break;
+	}
+	return next_dentry (ino);
+}
+
+int
+xfs_mount (void)
+{
+	xfs_sb_t super;
+
+	if (read_disk_block(xfs_file, 0, 0, sizeof(super), &super) != sizeof(super)) {
+		DEBUG_F("read_disk_block failed!\n");
+		return 0;
+	} else if (super.sb_magicnum != XFS_SB_MAGIC) {
+		DEBUG_F("xfs_mount: Bad magic: %x\n", super.sb_magicnum);
+		return 0;
+	} else if ((super.sb_versionnum & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4) {
+		DEBUG_F("xfs_mount: Bad version: %x\n", super.sb_versionnum);
+		return 0;
+	}
+
+	xfs.bsize = le32 (super.sb_blocksize);
+	xfs.blklog = super.sb_blocklog;
+	xfs.bdlog = xfs.blklog - SECTOR_BITS;
+	xfs.rootino = le64 (super.sb_rootino);
+	xfs.isize = le16 (super.sb_inodesize);
+	xfs.agblocks = le32 (super.sb_agblocks);
+	xfs.dirblklog = super.sb_dirblklog;
+	xfs.dirbsize = xfs.bsize << super.sb_dirblklog;
+
+	xfs.inopblog = super.sb_inopblog;
+	xfs.agblklog = super.sb_agblklog;
+	xfs.agnolog = xfs_highbit32 (le32 (super.sb_agcount) - 1) + 1;
+
+	xfs.btnode_ptr0_off =
+		((xfs.bsize - sizeof(xfs_btree_block_t)) /
+		(sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t)))
+		 * sizeof(xfs_bmbt_key_t) + sizeof(xfs_btree_block_t);
+
+	return 1;
+}
+
+int
+xfs_read_data (char *buf, int len)
+{
+	xad_t *xad;
+	xfs_fileoff_t endofprev, endofcur, offset;
+	xfs_filblks_t xadlen;
+	int toread, startpos, endpos;
+
+	if (icore.di_format == XFS_DINODE_FMT_LOCAL) {
+		memmove(buf, inode->di_u.di_c + xfs_file->pos, len);
+		xfs_file->pos += len;
+		return len;
+	}
+
+	startpos = xfs_file->pos;
+	endpos = xfs_file->pos + len;
+	if (endpos > xfs_file->len)
+		endpos = xfs_file->len;
+	endofprev = (xfs_fileoff_t)-1;
+	init_extents ();
+	while (len > 0 && (xad = next_extent ())) {
+		offset = xad->offset;
+		xadlen = xad->len;
+		if (isinxt (xfs_file->pos >> xfs.blklog, offset, xadlen)) {
+			endofcur = (offset + xadlen) << xfs.blklog; 
+			toread = (endofcur >= endpos)
+				  ? len : (endofcur - xfs_file->pos);
+			read_disk_block(xfs_file, fsb2daddr (xad->start),
+					xfs_file->pos - (offset << xfs.blklog), toread, buf);
+			buf += toread;
+			len -= toread;
+			xfs_file->pos += toread;
+		} else if (offset > endofprev) {
+			toread = ((offset << xfs.blklog) >= endpos)
+				  ? len : ((offset - endofprev) << xfs.blklog);
+			len -= toread;
+			xfs_file->pos += toread;
+			for (; toread; toread--) {
+				*buf++ = 0;
+			}
+			continue;
+		}
+		endofprev = offset + xadlen; 
+	}
+
+	return xfs_file->pos - startpos;
+}
+
+int
+xfs_dir (char *dirname)
+{
+	xfs_ino_t ino, parent_ino, new_ino;
+	xfs_fsize_t di_size;
+	int di_mode;
+	int cmp, n, link_count;
+	char linkbuf[xfs.bsize];
+	char *rest, *name, ch;
+
+	DEBUG_ENTER;
+
+	parent_ino = ino = xfs.rootino;
+	link_count = 0;
+	for (;;) {
+		di_read (ino);
+		di_size = le64 (icore.di_size);
+		di_mode = le16 (icore.di_mode);
+
+		DEBUG_F("di_mode: %o\n", di_mode);
+		if ((di_mode & IFMT) == IFLNK) {
+			if (++link_count > MAX_LINK_COUNT) {
+				errnum = FILE_ERR_SYMLINK_LOOP;
+				DEBUG_LEAVE(FILE_ERR_SYMLINK_LOOP);
+				return 0;
+			}
+			if (di_size < xfs.bsize - 1) {
+				xfs_file->pos = 0;
+				xfs_file->len = di_size;
+				n = xfs_read_data (linkbuf, xfs_file->len);
+			} else {
+				errnum = FILE_ERR_LENGTH;
+				DEBUG_LEAVE(FILE_ERR_LENGTH);
+				return 0;
+			}
+
+			ino = (linkbuf[0] == '/') ? xfs.rootino : parent_ino;
+			while (n < (xfs.bsize - 1) && (linkbuf[n++] = *dirname++));
+			linkbuf[n] = 0;
+			dirname = linkbuf;
+			continue;
+		}
+
+		DEBUG_F("*dirname: %s\n", dirname);
+		if (!*dirname || isspace (*dirname)) {
+			if ((di_mode & IFMT) != IFREG) {
+				errnum = FILE_ERR_BAD_TYPE;
+				DEBUG_LEAVE(FILE_ERR_BAD_TYPE);
+				return 0;
+			}
+			xfs_file->pos = 0;
+			xfs_file->len = di_size;
+			DEBUG_LEAVE(1);
+			return 1;
+		}
+
+		if ((di_mode & IFMT) != IFDIR) {
+			errnum = FILE_ERR_NOTDIR;
+			DEBUG_LEAVE(FILE_ERR_NOTDIR);
+			return 0;
+		}
+
+		for (; *dirname == '/'; dirname++);
+
+		for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+		*rest = 0;
+
+		name = first_dentry (&new_ino);
+		for (;;) {
+			cmp = (!*dirname) ? -1 : strcmp(dirname, name);
+			if (cmp == 0) {
+				parent_ino = ino;
+				if (new_ino)
+					ino = new_ino;
+		        	*(dirname = rest) = ch;
+				break;
+			}
+			name = next_dentry (&new_ino);
+			if (name == NULL) {
+				errnum = FILE_ERR_NOTFOUND;
+				DEBUG_LEAVE(FILE_ERR_NOTFOUND);
+				*rest = ch;
+				return 0;
+			}
+		}
+	}
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 8
+ * End:
+ */

Added: ppcrcd/yaboot/include/asm/elf.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/asm/elf.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,57 @@
+#ifndef __PPC_ELF_H
+#define __PPC_ELF_H
+
+#define ELF_NGREG	48	/* includes nip, msr, lr, etc. */
+#define ELF_NFPREG	33	/* includes fpscr */
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x) == EM_PPC)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_ARCH	EM_PPC
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	4096
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         (0x08000000)
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+#define ELF_CORE_COPY_REGS(gregs, regs) \
+	memcpy(gregs, regs, \
+	       sizeof(struct pt_regs) < sizeof(elf_gregset_t)? \
+	       sizeof(struct pt_regs): sizeof(elf_gregset_t));
+
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  This could be done in userspace,
+   but it's not easy, and we've already done it here.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM	(NULL)
+
+
+#endif

Added: ppcrcd/yaboot/include/asm/ppc_asm.tmpl
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/asm/ppc_asm.tmpl	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,66 @@
+/* Register names */
+#define	r0	0
+#define	r1	1
+#define	r2	2
+#define	r3	3
+#define	r4	4
+#define	r5	5
+#define	r6	6
+#define	r7	7
+#define	r8	8
+#define	r9	9
+#define	r10	10
+#define	r11	11
+#define	r12	12
+#define	r13	13
+#define	r14	14
+#define	r15	15
+#define	r16	16
+#define	r17	17
+#define	r18	18
+#define	r19	19
+#define	r20	20
+#define	r21	21
+#define	r22	22
+#define	r23	23
+#define	r24	24
+#define	r25	25
+#define	r26	26
+#define	r27	27
+#define	r28	28
+#define	r29	29
+#define	r30	30
+#define	r31	31
+
+#define	fr0	0
+#define	fr1	1
+#define	fr2	2
+#define	fr3	3
+#define	fr4	4
+#define	fr5	5
+#define	fr6	6
+#define	fr7	7
+#define	fr8	8
+#define	fr9	9
+#define	fr10	10
+#define	fr11	11
+#define	fr12	12
+#define	fr13	13
+#define	fr14	14
+#define	fr15	15
+#define	fr16	16
+#define	fr17	17
+#define	fr18	18
+#define	fr19	19
+#define	fr20	20
+#define	fr21	21
+#define	fr22	22
+#define	fr23	23
+#define	fr24	24
+#define	fr25	25
+#define	fr26	26
+#define	fr27	27
+#define	fr28	28
+#define	fr29	29
+#define	fr30	30
+#define	fr31	31

Added: ppcrcd/yaboot/include/asm/processor.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/asm/processor.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,142 @@
+#ifndef __ASM_PPC_PROCESSOR_H
+#define __ASM_PPC_PROCESSOR_H
+
+/* Bit encodings for Machine State Register (MSR) */
+#define MSR_POW		(1<<18)		/* Enable Power Management */
+#define MSR_TGPR	(1<<17)		/* TLB Update registers in use */
+#define MSR_ILE		(1<<16)		/* Interrupt Little-Endian enable */
+#define MSR_EE		(1<<15)		/* External Interrupt enable */
+#define MSR_PR		(1<<14)		/* Supervisor/User privilege */
+#define MSR_FP		(1<<13)		/* Floating Point enable */
+#define MSR_ME		(1<<12)		/* Machine Check enable */
+#define MSR_FE0		(1<<11)		/* Floating Exception mode 0 */
+#define MSR_SE		(1<<10)		/* Single Step */
+#define MSR_BE		(1<<9)		/* Branch Trace */
+#define MSR_FE1		(1<<8)		/* Floating Exception mode 1 */
+#define MSR_IP		(1<<6)		/* Exception prefix 0x000/0xFFF */
+#define MSR_IR		(1<<5)		/* Instruction MMU enable */
+#define MSR_DR		(1<<4)		/* Data MMU enable */
+#define MSR_RI		(1<<1)		/* Recoverable Exception */
+#define MSR_LE		(1<<0)		/* Little-Endian enable */
+
+/* Bit encodings for Hardware Implementation Register (HID0)
+   on PowerPC 603, 604, etc. processors (not 601). */
+#define HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
+#define HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
+#define HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
+#define HID0_SBCLK	(1<<27)
+#define HID0_EICE	(1<<26)
+#define HID0_ECLK	(1<<25)
+#define HID0_PAR	(1<<24)
+#define HID0_DOZE	(1<<23)
+#define HID0_NAP	(1<<22)
+#define HID0_SLEEP	(1<<21)
+#define HID0_DPM	(1<<20)
+#define HID0_ICE	(1<<15)		/* Instruction Cache Enable */
+#define HID0_DCE	(1<<14)		/* Data Cache Enable */
+#define HID0_ILOCK	(1<<13)		/* Instruction Cache Lock */
+#define HID0_DLOCK	(1<<12)		/* Data Cache Lock */
+#define HID0_ICFI	(1<<11)		/* Instruction Cache Flash Invalidate */
+#define HID0_DCI	(1<<10)		/* Data Cache Invalidate */
+#define HID0_SPD	(1<<9)		/* Speculative disable */
+#define HID0_SIED	(1<<7)		/* Serial Instruction Execution [Disable] */
+#define HID0_BHTE	(1<<2)		/* Branch History Table Enable */
+#define HID0_BTCD	(1<<1)		/* Branch target cache disable */
+
+/* fpscr settings */
+#define FPSCR_FX        (1<<31)
+#define FPSCR_FEX       (1<<30)
+
+#define _GLOBAL(n)\
+	.globl n;\
+n:
+
+#define	TBRU	269	/* Time base Upper/Lower (Reading) */
+#define	TBRL	268
+#define TBWU	284	/* Time base Upper/Lower (Writing) */
+#define TBWL	285
+#define	XER	1
+#define LR	8
+#define CTR	9
+#define HID0	1008	/* Hardware Implementation */
+#define PVR	287	/* Processor Version */
+#define IBAT0U	528	/* Instruction BAT #0 Upper/Lower */
+#define IBAT0L	529
+#define IBAT1U	530	/* Instruction BAT #1 Upper/Lower */
+#define IBAT1L	531
+#define IBAT2U	532	/* Instruction BAT #2 Upper/Lower */
+#define IBAT2L	533
+#define IBAT3U	534	/* Instruction BAT #3 Upper/Lower */
+#define IBAT3L	535
+#define DBAT0U	536	/* Data BAT #0 Upper/Lower */
+#define DBAT0L	537
+#define DBAT1U	538	/* Data BAT #1 Upper/Lower */
+#define DBAT1L	539
+#define DBAT2U	540	/* Data BAT #2 Upper/Lower */
+#define DBAT2L	541
+#define DBAT3U	542	/* Data BAT #3 Upper/Lower */
+#define DBAT3L	543
+#define DMISS	976	/* TLB Lookup/Refresh registers */
+#define DCMP	977
+#define HASH1	978
+#define HASH2	979
+#define IMISS	980
+#define ICMP	981
+#define RPA	982
+#define SDR1	25	/* MMU hash base register */
+#define DAR	19	/* Data Address Register */
+#define SPR0	272	/* Supervisor Private Registers */
+#define SPRG0   272
+#define SPR1	273
+#define SPRG1   273
+#define SPR2	274
+#define SPRG2   274
+#define SPR3	275
+#define SPRG3   275
+#define DSISR	18
+#define SRR0	26	/* Saved Registers (exception) */
+#define SRR1	27
+#define IABR	1010	/* Instruction Address Breakpoint */
+#define DEC	22	/* Decrementer */
+#define EAR	282	/* External Address Register */
+#define L2CR	1017    /* PPC 750 L2 control register */
+
+#define THRM1	1020
+#define THRM2	1021
+#define THRM3	1022
+#define THRM1_TIN 0x1
+#define THRM1_TIV 0x2
+#define THRM1_THRES (0x7f<<2)
+#define THRM1_TID (1<<29)
+#define THRM1_TIE (1<<30)
+#define THRM1_V   (1<<31)
+#define THRM3_E   (1<<31)
+
+/* Segment Registers */
+#define SR0	0
+#define SR1	1
+#define SR2	2
+#define SR3	3
+#define SR4	4
+#define SR5	5
+#define SR6	6
+#define SR7	7
+#define SR8	8
+#define SR9	9
+#define SR10	10
+#define SR11	11
+#define SR12	12
+#define SR13	13
+#define SR14	14
+#define SR15	15
+
+#ifndef __ASSEMBLY__
+static __inline__ unsigned long mfmsr(void)
+{
+	unsigned long msr;
+	__asm__ __volatile__("mfmsr %0" : "=r" (msr));
+	return msr;
+}
+#endif
+  
+#endif /* __ASM_PPC_PROCESSOR_H */

Added: ppcrcd/yaboot/include/bootinfo.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/bootinfo.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,59 @@
+/*
+ *  bootinfo.h - Non-machine dependent bootinfo structure.  Basic idea from m68k
+ *
+ *  Copyright (C) 1999 Cort Dougan <cort at ppc.kernel.org>
+ *
+ *  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 _PPC_BOOTINFO_H
+#define _PPC_BOOTINFO_H
+
+#define _MACH_prep	0x00000001
+#define _MACH_Pmac	0x00000002	/* pmac or pmac clone (non-chrp) */
+#define _MACH_chrp	0x00000004	/* chrp machine */
+#define _MACH_mbx	0x00000008	/* Motorola MBX board */
+#define _MACH_apus	0x00000010	/* amiga with phase5 powerup */
+#define _MACH_fads	0x00000020	/* Motorola FADS board */
+#define _MACH_rpxlite	0x00000040	/* RPCG RPX-Lite 8xx board */
+#define _MACH_bseip	0x00000080	/* Bright Star Engineering ip-Engine */
+#define _MACH_yk	0x00000100	/* Motorola Yellowknife */
+#define _MACH_gemini	0x00000200	/* Synergy Microsystems gemini board */
+#define _MACH_classic	0x00000400	/* RPCG RPX-Classic 8xx board */
+#define _MACH_oak	0x00000800	/* IBM "Oak" 403 eval. board */
+#define _MACH_walnut	0x00001000	/* IBM "Walnut" 405GP eval. board */
+
+struct bi_record {
+     unsigned long tag;			/* tag ID */
+     unsigned long size;			/* size of record (in bytes) */
+     unsigned long data[0];		/* data */
+};
+
+#define BI_FIRST		0x1010  /* first record - marker */
+#define BI_LAST			0x1011	/* last record - marker */
+#define BI_CMD_LINE		0x1012
+#define BI_BOOTLOADER_ID	0x1013
+#define BI_INITRD		0x1014
+#define BI_SYSMAP		0x1015
+#define BI_MACHTYPE		0x1016
+
+#endif /* _PPC_BOOTINFO_H */
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/include/byteorder.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/byteorder.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,13 @@
+#ifndef _BYTEORDER_H_
+#define _BYTEORDER_H_
+
+#include "swab.h"
+
+# define le64_to_cpu(x)  swab64((x))
+# define cpu_to_le64(x)  swab64((x))
+# define le32_to_cpu(x)  swab32((x))
+# define cpu_to_le32(x)  swab32((x))
+# define le16_to_cpu(x)  swab16((x))
+# define cpu_to_le16(x)  swab16((x))
+
+#endif /* _BYTEORDER_H_ */

Added: ppcrcd/yaboot/include/cfg.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/cfg.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,32 @@
+/*
+ *  cfg.h - config file parsing definitions
+ *
+ *  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.
+ */
+
+#ifndef CFG_H
+#define CFG_H
+
+#include "types.h"
+
+extern int	cfg_parse(char *cfg_file, char *buff, int len);
+extern char*	cfg_get_strg(char *image, char *item);
+extern int	cfg_get_flag(char *image, char *item);
+extern void	cfg_print_images(void);
+extern char*	cfg_get_default(void);
+
+#endif

Added: ppcrcd/yaboot/include/cmdline.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/cmdline.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,33 @@
+/*
+ *  cmdline.h - Prompt handling
+ *
+ *  Copyright (C) 2001 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.
+ */
+
+#ifndef CMDLINE_H
+#define CMDLINE_H
+
+#include "types.h"
+
+extern void	cmdinit();
+extern void	cmdedit(void (*tabfunc) (void), int password);
+
+extern char	cbuff[];
+extern char	passwdbuff[];
+#endif

Added: ppcrcd/yaboot/include/ctype.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/ctype.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,61 @@
+#ifndef _LINUX_CTYPE_H
+#define _LINUX_CTYPE_H
+
+/*
+ * NOTE! This ctype does not handle EOF like the standard C
+ * library is required to.
+ */
+
+#define _U	0x01	/* upper */
+#define _L	0x02	/* lower */
+#define _D	0x04	/* digit */
+#define _C	0x08	/* cntrl */
+#define _P	0x10	/* punct */
+#define _S	0x20	/* white space (space/lf/tab) */
+#define _X	0x40	/* hex digit */
+#define _SP	0x80	/* hard space (0x20) */
+
+extern unsigned char _ctype[];
+
+#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
+
+#define isalnum(c)	((__ismask(c)&(_U|_L|_D)) != 0)
+#define isalpha(c)	((__ismask(c)&(_U|_L)) != 0)
+#define iscntrl(c)	((__ismask(c)&(_C)) != 0)
+#define isdigit(c)	((__ismask(c)&(_D)) != 0)
+#define isgraph(c)	((__ismask(c)&(_P|_U|_L|_D)) != 0)
+#define islower(c)	((__ismask(c)&(_L)) != 0)
+#define isprint(c)	((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
+#define ispunct(c)	((__ismask(c)&(_P)) != 0)
+#define isspace(c)	((__ismask(c)&(_S)) != 0)
+#define isupper(c)	((__ismask(c)&(_U)) != 0)
+#define isxdigit(c)	((__ismask(c)&(_D|_X)) != 0)
+
+#define isascii(c) (((unsigned char)(c))<=0x7f)
+#define toascii(c) (((unsigned char)(c))&0x7f)
+
+static inline unsigned char __tolower(unsigned char c)
+{
+     if (isupper(c))
+	  c -= 'A'-'a';
+     return c;
+}
+
+static inline unsigned char __toupper(unsigned char c)
+{
+     if (islower(c))
+	  c -= 'a'-'A';
+     return c;
+}
+
+#define tolower(c) __tolower(c)
+#define toupper(c) __toupper(c)
+
+#endif
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/include/debug.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/debug.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,52 @@
+/*
+ *  Debug defines
+ *
+ *  Copyright (C) 2001 Ethan Benson
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if DEBUG
+# define DEBUG_ENTER prom_printf( "--> %s\n", __PRETTY_FUNCTION__ )
+# define DEBUG_LEAVE(str) \
+    prom_printf( "<-- %s - %s\n", __PRETTY_FUNCTION__, #str )
+# define DEBUG_LEAVE_F(args...)\
+{\
+    prom_printf( "<-- %s - %d\n", __PRETTY_FUNCTION__, ## args );\
+}
+# define DEBUG_F(fmt, args...)\
+{\
+    prom_printf( "    %s - ", __PRETTY_FUNCTION__ );\
+    prom_printf( fmt, ## args );\
+}
+# define DEBUG_OPEN DEBUG_F( "dev=%s, part=0x%p (%d), file_name=%s\n",\
+                             dev_name, part, part ? part->part_number : -1,\
+                             file_name)
+# define DEBUG_SLEEP prom_sleep(3)
+#else
+#define DEBUG_ENTER
+#define DEBUG_LEAVE(x)
+#define DEBUG_LEAVE_F(args...)
+#define DEBUG_F(fmt, args...)
+#define DEBUG_OPEN
+#define DEBUG_SLEEP
+#endif
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/include/errors.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/errors.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,40 @@
+/*
+ *  errors.h - Definitions of error numbers returned by filesystems
+ *
+ *  Copyright (C) 2001 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Simple error codes */
+#define FILE_ERR_OK             0
+#define FILE_ERR_EOF            -1
+#define FILE_ERR_NOTFOUND       -2
+#define FILE_CANT_SEEK          -3
+#define FILE_IOERR              -4
+#define FILE_BAD_PATH           -5
+#define FILE_ERR_BAD_TYPE       -6
+#define FILE_ERR_NOTDIR         -7
+#define FILE_ERR_BAD_FSYS       -8
+#define FILE_ERR_SYMLINK_LOOP   -9
+#define FILE_ERR_LENGTH         -10
+#define FILE_ERR_FSBUSY         -11
+#define FILE_ERR_BADDEV         -12
+
+/* Device kind */
+#define FILE_DEVICE_BLOCK       1
+#define FILE_DEVICE_NET         2

Added: ppcrcd/yaboot/include/et/com_err.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/et/com_err.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,40 @@
+/*
+ * Header file for common error description library.
+ *
+ * Copyright 1988, Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * For copyright and distribution info, see the documentation supplied
+ * with this package.
+ */
+
+#ifndef __COM_ERR_H
+
+typedef long errcode_t;
+
+#ifdef __STDC__
+#include <stdarg.h>
+
+/* ANSI C -- use prototypes etc */
+void com_err (const char *, long, const char *, ...);
+void com_err_va (const char *whoami, errcode_t code, const char *fmt,
+		 va_list args);
+char const *error_message (long);
+extern void (*com_err_hook) (const char *, long, const char *, va_list);
+void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list)))
+    (const char *, long, const char *, va_list);
+void (*reset_com_err_hook (void)) (const char *, long, const char *, va_list);
+int init_error_table(const char * const *msgs, int base, int count);
+#else
+/* no prototypes */
+void com_err ();
+void com_err_va ();
+char *error_message ();
+extern void (*com_err_hook) ();
+void (*set_com_err_hook ()) ();
+void (*reset_com_err_hook ()) ();
+int init_error_table();
+#endif
+
+#define __COM_ERR_H
+#endif /* ! defined(__COM_ERR_H) */

Added: ppcrcd/yaboot/include/ext2fs/bitops.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/ext2fs/bitops.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,715 @@
+/*
+ * bitops.h --- Bitmap frobbing code.  The byte swapping routines are
+ * 	also included here.
+ * 
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ * 
+ * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
+ * Linus Torvalds.
+ */
+
+
+extern int ext2fs_set_bit(int nr,void * addr);
+extern int ext2fs_clear_bit(int nr, void * addr);
+extern int ext2fs_test_bit(int nr, const void * addr);
+extern __u16 ext2fs_swab16(__u16 val);
+extern __u32 ext2fs_swab32(__u32 val);
+
+/*
+ * EXT2FS bitmap manipulation routines.
+ */
+
+/* Support for sending warning messages from the inline subroutines */
+extern const char *ext2fs_block_string;
+extern const char *ext2fs_inode_string;
+extern const char *ext2fs_mark_string;
+extern const char *ext2fs_unmark_string;
+extern const char *ext2fs_test_string;
+extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
+			       const char *description);
+extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+				int code, unsigned long arg);
+
+extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
+extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+				       blk_t block);
+extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
+
+extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
+extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+				       ext2_ino_t inode);
+extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
+
+extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+					  blk_t block);
+extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+					    blk_t block);
+extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
+					 blk_t block);
+
+extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					  ext2_ino_t inode);
+extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					    ext2_ino_t inode);
+extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					 ext2_ino_t inode);
+extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
+extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
+extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
+extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
+
+extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+					   blk_t block, int num);
+extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+					     blk_t block, int num);
+extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+					  blk_t block, int num);
+extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+						blk_t block, int num);
+extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+						  blk_t block, int num);
+extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+					       blk_t block, int num);
+extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
+
+/*
+ * The inline routines themselves...
+ * 
+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
+ * functions at all; they will be included as normal functions in
+ * inline.c
+ */
+#ifdef NO_INLINE_FUNCS
+#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
+			   defined(__i586__) || defined(__mc68000__) || \
+			   defined(__sparc__)))
+	/* This prevents bitops.c from trying to include the C */
+	/* function version of these functions */
+#define _EXT2_HAVE_ASM_BITOPS_
+#endif
+#endif /* NO_INLINE_FUNCS */
+
+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
+#ifdef INCLUDE_INLINE_FUNCS
+#define _INLINE_ extern
+#else
+#ifdef __GNUC__
+#define _INLINE_ extern __inline__
+#else				/* For Watcom C */
+#define _INLINE_ extern inline
+#endif
+#endif
+
+#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
+     (defined(__i386__) || defined(__i486__) || defined(__i586__)))
+
+#define _EXT2_HAVE_ASM_BITOPS_
+#define _EXT2_HAVE_ASM_SWAB_
+#define _EXT2_HAVE_ASM_FINDBIT_
+
+/*
+ * These are done by inline assembly for speed reasons.....
+ *
+ * All bitoperations return 0 if the bit was cleared before the
+ * operation and != 0 if it was not.  Bit 0 is the LSB of addr; bit 32
+ * is the LSB of (addr+1).
+ */
+
+/*
+ * Some hacks to defeat gcc over-optimizations..
+ */
+struct __dummy_h { unsigned long a[100]; };
+#define EXT2FS_ADDR (*(struct __dummy_h *) addr)
+#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)	
+
+_INLINE_ int ext2fs_set_bit(int nr, void * addr)
+{
+	int oldbit;
+
+	__asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit),"=m" (EXT2FS_ADDR)
+		:"r" (nr));
+	return oldbit;
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+	int oldbit;
+
+	__asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit),"=m" (EXT2FS_ADDR)
+		:"r" (nr));
+	return oldbit;
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+	int oldbit;
+
+	__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
+		:"=r" (oldbit)
+		:"m" (EXT2FS_CONST_ADDR),"r" (nr));
+	return oldbit;
+}
+
+#if 0
+_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
+{
+	int d0, d1, d2;
+	int res;
+
+	if (!size)
+		return 0;
+	/* This looks at memory. Mark it volatile to tell gcc not to move it around */
+	__asm__ __volatile__(
+		"cld\n\t"			     
+		"xorl %%eax,%%eax\n\t"
+		"xorl %%edx,%%edx\n\t"
+		"repe; scasl\n\t"
+		"je 1f\n\t"
+		"movl -4(%%edi),%%eax\n\t"
+		"subl $4,%%edi\n\t"
+		"bsfl %%eax,%%edx\n"
+		"1:\tsubl %%esi,%%edi\n\t"
+		"shll $3,%%edi\n\t"
+		"addl %%edi,%%edx"
+		:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
+		:"1" ((size + 31) >> 5), "2" (addr), "S" (addr));
+	return res;
+}
+
+_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
+{
+	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
+	int set = 0, bit = offset & 31, res;
+	
+	if (bit) {
+		/*
+		 * Look for zero in first byte
+		 */
+		__asm__("bsfl %1,%0\n\t"
+			"jne 1f\n\t"
+			"movl $32, %0\n"
+			"1:"
+			: "=r" (set)
+			: "r" (*p >> bit));
+		if (set < (32 - bit))
+			return set + offset;
+		set = 32 - bit;
+		p++;
+	}
+	/*
+	 * No bit found yet, search remaining full bytes for a bit
+	 */
+	res = ext2fs_find_first_bit_set(p, size - 32 * (p - (unsigned long *) addr));
+	return (offset + set + res);
+}
+#endif
+
+#ifdef EXT2FS_ENABLE_SWAPFS
+_INLINE_ __u32 ext2fs_swab32(__u32 val)
+{
+#ifdef EXT2FS_REQUIRE_486
+	__asm__("bswap %0" : "=r" (val) : "0" (val));
+#else
+	__asm__("xchgb %b0,%h0\n\t"	/* swap lower bytes	*/
+		"rorl $16,%0\n\t"	/* swap words		*/
+		"xchgb %b0,%h0"		/* swap higher bytes	*/
+		:"=q" (val)
+		: "0" (val));
+#endif
+	return val;
+}
+
+_INLINE_ __u16 ext2fs_swab16(__u16 val)
+{
+	__asm__("xchgb %b0,%h0"		/* swap bytes		*/ \
+		: "=q" (val) \
+		:  "0" (val)); \
+		return val;
+}
+#endif
+
+#undef EXT2FS_ADDR
+
+#endif	/* i386 */
+
+#ifdef __mc68000__
+
+#define _EXT2_HAVE_ASM_BITOPS_
+
+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
+{
+	char retval;
+
+	__asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
+	     : "=d" (retval) : "d" (nr^7), "a" (addr));
+
+	return retval;
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+	char retval;
+
+	__asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
+	     : "=d" (retval) : "d" (nr^7), "a" (addr));
+
+	return retval;
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+	char retval;
+
+	__asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
+	     : "=d" (retval) : "d" (nr^7), "a" (addr));
+
+	return retval;
+}
+
+#endif /* __mc68000__ */
+
+#ifdef __sparc__
+
+#define _EXT2_HAVE_ASM_BITOPS_
+
+#ifndef EXT2_OLD_BITOPS
+
+/*
+ * Do the bitops so that we are compatible with the standard i386
+ * convention.
+ */
+
+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
+{
+#if 1
+	int		mask;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	__asm__ __volatile__("ldub	[%0], %%g6\n\t"
+			     "or	%%g6, %2, %%g5\n\t"
+			     "stb	%%g5, [%0]\n\t"
+			     "and	%%g6, %2, %0\n"
+	: "=&r" (ADDR)
+	: "0" (ADDR), "r" (mask)
+	: "g5", "g6");
+	return (int) ADDR;
+#else
+	int		mask, retval;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	retval = (mask & *ADDR) != 0;
+	*ADDR |= mask;
+	return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+#if 1
+	int		mask;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	__asm__ __volatile__("ldub	[%0], %%g6\n\t"
+			     "andn	%%g6, %2, %%g5\n\t"
+			     "stb	%%g5, [%0]\n\t"
+			     "and	%%g6, %2, %0\n"
+	: "=&r" (ADDR)
+	: "0" (ADDR), "r" (mask)
+	: "g5", "g6");
+	return (int) ADDR;
+	
+#else
+	int		mask, retval;
+	unsigned char	*ADDR = (unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	retval = (mask & *ADDR) != 0;
+	*ADDR &= ~mask;
+	return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+	int			mask;
+	const unsigned char	*ADDR = (const unsigned char *) addr;
+
+	ADDR += nr >> 3;
+	mask = 1 << (nr & 0x07);
+	return ((mask & *ADDR) != 0);
+}
+
+#else
+
+/* Do things the old, unplesant way. */
+
+_INLINE_ int ext2fs_set_bit(int nr, void *addr)
+{
+	int		mask, retval;
+	unsigned long	*ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = ((mask & *ADDR) != 0);
+	*ADDR |= mask;
+	return retval;
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void *addr)
+{
+	int		mask, retval;
+	unsigned long	*ADDR = (unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	retval = ((mask & *ADDR) != 0);
+	*ADDR &= ~mask;
+	return retval;
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void *addr)
+{
+	int			mask;
+	const unsigned long	*ADDR = (const unsigned long *) addr;
+
+	ADDR += nr >> 5;
+	mask = 1 << (nr & 31);
+	return ((mask & *ADDR) != 0);
+}
+#endif
+
+#endif /* __sparc__ */
+
+#if !defined(_EXT2_HAVE_ASM_SWAB_) && defined(EXT2FS_ENABLE_SWAPFS)
+
+_INLINE_ __u16 ext2fs_swab16(__u16 val)
+{
+	return (val >> 8) | (val << 8);
+}
+
+_INLINE_ __u32 ext2fs_swab32(__u32 val)
+{
+	return ((val>>24) | ((val>>8)&0xFF00) |
+		((val<<8)&0xFF0000) | (val<<24));
+}
+
+#endif /* !_EXT2_HAVE_ASM_SWAB */
+
+#if !defined(_EXT2_HAVE_ASM_FINDBIT_)
+_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
+{
+	char	*cp = (unsigned char *) addr;
+	int 	res = 0, d0;
+
+	if (!size)
+		return 0;
+
+	while ((size > res) && (*cp == 0)) {
+		cp++;
+		res += 8;
+	}
+	d0 = ffs(*cp);
+	if (d0 == 0)
+		return size;
+	
+	return res + d0 - 1;
+}
+
+_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
+{
+	unsigned char * p;
+	int set = 0, bit = offset & 7, res = 0, d0;
+	
+	res = offset >> 3;
+	p = ((unsigned char *) addr) + res;
+	
+	if (bit) {
+		set = ffs(*p & ~((1 << bit) - 1));
+		if (set)
+			return (offset & ~7) + set - 1;
+		p++;
+		res += 8;
+	}
+	while ((size > res) && (*p == 0)) {
+		p++;
+		res += 8;
+	}
+	d0 = ffs(*p);
+	if (d0 == 0)
+		return size;
+
+	return (res + d0 - 1);
+}
+#endif	
+
+/* These two routines moved to gen_bitmap.c */
+extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+					 __u32 bitno);
+extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+					   blk_t bitno);
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+					blk_t bitno);
+
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+					blk_t bitno)
+{
+	if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
+		return 0;
+	}
+	return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+				       blk_t block)
+{
+	return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
+				       bitmap,
+					  block);
+}
+
+_INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+					 blk_t block)
+{
+	return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
+					    block);
+}
+
+_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
+				       blk_t block)
+{
+	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
+					  block);
+}
+
+_INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+				       ext2_ino_t inode)
+{
+	return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
+					  inode);
+}
+
+_INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					 ext2_ino_t inode)
+{
+	return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
+				     inode);
+}
+
+_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+				       ext2_ino_t inode)
+{
+	return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
+					  inode);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+					    blk_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+	if ((block < bitmap->start) || (block > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+				   bitmap->description);
+		return;
+	}
+#endif	
+	ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+					      blk_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+	if ((block < bitmap->start) || (block > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
+				   block, bitmap->description);
+		return;
+	}
+#endif
+	ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
+					    blk_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+	if ((block < bitmap->start) || (block > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+				   block, bitmap->description);
+		return 0;
+	}
+#endif
+	return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					    ext2_ino_t inode)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+	if ((inode < bitmap->start) || (inode > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
+				   inode, bitmap->description);
+		return;
+	}
+#endif
+	ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					      ext2_ino_t inode)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+	if ((inode < bitmap->start) || (inode > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
+				   inode, bitmap->description);
+		return;
+	}
+#endif
+	ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+					   ext2_ino_t inode)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+	if ((inode < bitmap->start) || (inode > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
+				   inode, bitmap->description);
+		return 0;
+	}
+#endif
+	return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
+{
+	return bitmap->start;
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
+{
+	return bitmap->start;
+}
+
+_INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
+{
+	return bitmap->end;
+}
+
+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
+{
+	return bitmap->end;
+}
+
+_INLINE_ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+					    blk_t block, int num)
+{
+	int	i;
+
+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+				   block, bitmap->description);
+		return 0;
+	}
+	for (i=0; i < num; i++) {
+		if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
+			return 0;
+	}
+	return 1;
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+						 blk_t block, int num)
+{
+	int	i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+				   block, bitmap->description);
+		return 0;
+	}
+#endif
+	for (i=0; i < num; i++) {
+		if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
+			return 0;
+	}
+	return 1;
+}
+
+_INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+					     blk_t block, int num)
+{
+	int	i;
+	
+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+				   bitmap->description);
+		return;
+	}
+	for (i=0; i < num; i++)
+		ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+						  blk_t block, int num)
+{
+	int	i;
+	
+#ifdef EXT2FS_DEBUG_FAST_OPS
+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+				   bitmap->description);
+		return;
+	}
+#endif	
+	for (i=0; i < num; i++)
+		ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+					       blk_t block, int num)
+{
+	int	i;
+	
+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
+				   bitmap->description);
+		return;
+	}
+	for (i=0; i < num; i++)
+		ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+						    blk_t block, int num)
+{
+	int	i;
+	
+#ifdef EXT2FS_DEBUG_FAST_OPS
+	if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+		ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
+				   bitmap->description);
+		return;
+	}
+#endif	
+	for (i=0; i < num; i++)
+		ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+#undef _INLINE_
+#endif
+

Added: ppcrcd/yaboot/include/ext2fs/ext2_err.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/ext2fs/ext2_err.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,99 @@
+/*
+ * ext2_err.h:
+ * This file is automatically generated; please do not edit it.
+ */
+
+#define EXT2_ET_BASE                             (2133571328L)
+#define EXT2_ET_MAGIC_EXT2FS_FILSYS              (2133571329L)
+#define EXT2_ET_MAGIC_BADBLOCKS_LIST             (2133571330L)
+#define EXT2_ET_MAGIC_BADBLOCKS_ITERATE          (2133571331L)
+#define EXT2_ET_MAGIC_INODE_SCAN                 (2133571332L)
+#define EXT2_ET_MAGIC_IO_CHANNEL                 (2133571333L)
+#define EXT2_ET_MAGIC_UNIX_IO_CHANNEL            (2133571334L)
+#define EXT2_ET_MAGIC_IO_MANAGER                 (2133571335L)
+#define EXT2_ET_MAGIC_BLOCK_BITMAP               (2133571336L)
+#define EXT2_ET_MAGIC_INODE_BITMAP               (2133571337L)
+#define EXT2_ET_MAGIC_GENERIC_BITMAP             (2133571338L)
+#define EXT2_ET_MAGIC_TEST_IO_CHANNEL            (2133571339L)
+#define EXT2_ET_MAGIC_DBLIST                     (2133571340L)
+#define EXT2_ET_MAGIC_ICOUNT                     (2133571341L)
+#define EXT2_ET_MAGIC_PQ_IO_CHANNEL              (2133571342L)
+#define EXT2_ET_MAGIC_EXT2_FILE                  (2133571343L)
+#define EXT2_ET_MAGIC_E2IMAGE                    (2133571344L)
+#define EXT2_ET_MAGIC_RESERVED_8                 (2133571345L)
+#define EXT2_ET_MAGIC_RESERVED_9                 (2133571346L)
+#define EXT2_ET_BAD_MAGIC                        (2133571347L)
+#define EXT2_ET_REV_TOO_HIGH                     (2133571348L)
+#define EXT2_ET_RO_FILSYS                        (2133571349L)
+#define EXT2_ET_GDESC_READ                       (2133571350L)
+#define EXT2_ET_GDESC_WRITE                      (2133571351L)
+#define EXT2_ET_GDESC_BAD_BLOCK_MAP              (2133571352L)
+#define EXT2_ET_GDESC_BAD_INODE_MAP              (2133571353L)
+#define EXT2_ET_GDESC_BAD_INODE_TABLE            (2133571354L)
+#define EXT2_ET_INODE_BITMAP_WRITE               (2133571355L)
+#define EXT2_ET_INODE_BITMAP_READ                (2133571356L)
+#define EXT2_ET_BLOCK_BITMAP_WRITE               (2133571357L)
+#define EXT2_ET_BLOCK_BITMAP_READ                (2133571358L)
+#define EXT2_ET_INODE_TABLE_WRITE                (2133571359L)
+#define EXT2_ET_INODE_TABLE_READ                 (2133571360L)
+#define EXT2_ET_NEXT_INODE_READ                  (2133571361L)
+#define EXT2_ET_UNEXPECTED_BLOCK_SIZE            (2133571362L)
+#define EXT2_ET_DIR_CORRUPTED                    (2133571363L)
+#define EXT2_ET_SHORT_READ                       (2133571364L)
+#define EXT2_ET_SHORT_WRITE                      (2133571365L)
+#define EXT2_ET_DIR_NO_SPACE                     (2133571366L)
+#define EXT2_ET_NO_INODE_BITMAP                  (2133571367L)
+#define EXT2_ET_NO_BLOCK_BITMAP                  (2133571368L)
+#define EXT2_ET_BAD_INODE_NUM                    (2133571369L)
+#define EXT2_ET_BAD_BLOCK_NUM                    (2133571370L)
+#define EXT2_ET_EXPAND_DIR_ERR                   (2133571371L)
+#define EXT2_ET_TOOSMALL                         (2133571372L)
+#define EXT2_ET_BAD_BLOCK_MARK                   (2133571373L)
+#define EXT2_ET_BAD_BLOCK_UNMARK                 (2133571374L)
+#define EXT2_ET_BAD_BLOCK_TEST                   (2133571375L)
+#define EXT2_ET_BAD_INODE_MARK                   (2133571376L)
+#define EXT2_ET_BAD_INODE_UNMARK                 (2133571377L)
+#define EXT2_ET_BAD_INODE_TEST                   (2133571378L)
+#define EXT2_ET_FUDGE_BLOCK_BITMAP_END           (2133571379L)
+#define EXT2_ET_FUDGE_INODE_BITMAP_END           (2133571380L)
+#define EXT2_ET_BAD_IND_BLOCK                    (2133571381L)
+#define EXT2_ET_BAD_DIND_BLOCK                   (2133571382L)
+#define EXT2_ET_BAD_TIND_BLOCK                   (2133571383L)
+#define EXT2_ET_NEQ_BLOCK_BITMAP                 (2133571384L)
+#define EXT2_ET_NEQ_INODE_BITMAP                 (2133571385L)
+#define EXT2_ET_BAD_DEVICE_NAME                  (2133571386L)
+#define EXT2_ET_MISSING_INODE_TABLE              (2133571387L)
+#define EXT2_ET_CORRUPT_SUPERBLOCK               (2133571388L)
+#define EXT2_ET_BAD_GENERIC_MARK                 (2133571389L)
+#define EXT2_ET_BAD_GENERIC_UNMARK               (2133571390L)
+#define EXT2_ET_BAD_GENERIC_TEST                 (2133571391L)
+#define EXT2_ET_SYMLINK_LOOP                     (2133571392L)
+#define EXT2_ET_CALLBACK_NOTHANDLED              (2133571393L)
+#define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE         (2133571394L)
+#define EXT2_ET_UNSUPP_FEATURE                   (2133571395L)
+#define EXT2_ET_RO_UNSUPP_FEATURE                (2133571396L)
+#define EXT2_ET_LLSEEK_FAILED                    (2133571397L)
+#define EXT2_ET_NO_MEMORY                        (2133571398L)
+#define EXT2_ET_INVALID_ARGUMENT                 (2133571399L)
+#define EXT2_ET_BLOCK_ALLOC_FAIL                 (2133571400L)
+#define EXT2_ET_INODE_ALLOC_FAIL                 (2133571401L)
+#define EXT2_ET_NO_DIRECTORY                     (2133571402L)
+#define EXT2_ET_TOO_MANY_REFS                    (2133571403L)
+#define EXT2_ET_FILE_NOT_FOUND                   (2133571404L)
+#define EXT2_ET_FILE_RO                          (2133571405L)
+#define EXT2_ET_DB_NOT_FOUND                     (2133571406L)
+#define EXT2_ET_DIR_EXISTS                       (2133571407L)
+#define EXT2_ET_UNIMPLEMENTED                    (2133571408L)
+#define EXT2_ET_CANCEL_REQUESTED                 (2133571409L)
+#define EXT2_ET_FILE_TOO_BIG                     (2133571410L)
+#define EXT2_ET_JOURNAL_NOT_BLOCK                (2133571411L)
+#define EXT2_ET_NO_JOURNAL_SB                    (2133571412L)
+#define EXT2_ET_JOURNAL_TOO_SMALL                (2133571413L)
+#define EXT2_ET_JOURNAL_UNSUPP_VERSION           (2133571414L)
+#define EXT2_ET_LOAD_EXT_JOURNAL                 (2133571415L)
+extern void initialize_ext2_error_table(void);
+#define ERROR_TABLE_BASE_ext2 (2133571328L)
+
+/* for compatibility with older versions... */
+#define init_ext2_err_tbl initialize_ext2_error_table
+#define ext2_err_base ERROR_TABLE_BASE_ext2

Added: ppcrcd/yaboot/include/ext2fs/ext2_io.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/ext2fs/ext2_io.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,100 @@
+/*
+ * io.h --- the I/O manager abstraction
+ * 
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#ifndef _EXT2FS_EXT2_IO_H
+#define _EXT2FS_EXT2_IO_H
+
+/*
+ * ext2_loff_t is defined here since unix_io.c needs it.
+ */
+#if defined(__GNUC__) || defined(HAS_LONG_LONG)
+typedef long long	ext2_loff_t;
+#else
+typedef long		ext2_loff_t;
+#endif
+
+/* llseek.c */
+ext2_loff_t ext2fs_llseek (int, ext2_loff_t, int);
+
+typedef struct struct_io_manager *io_manager;
+typedef struct struct_io_channel *io_channel;
+
+#define CHANNEL_FLAGS_WRITETHROUGH	0x01
+
+struct struct_io_channel {
+	errcode_t	magic;
+	io_manager	manager;
+	char		*name;
+	int		block_size;
+	errcode_t	(*read_error)(io_channel channel,
+				      unsigned long block,
+				      int count,
+				      void *data,
+				      size_t size,
+				      int actual_bytes_read,
+				      errcode_t	error);
+	errcode_t	(*write_error)(io_channel channel,
+				       unsigned long block,
+				       int count,
+				       const void *data,
+				       size_t size,
+				       int actual_bytes_written,
+				       errcode_t error);
+	int		refcount;
+	int		flags;
+	int		reserved[14];
+	void		*private_data;
+	void		*app_data;
+};
+
+struct struct_io_manager {
+	errcode_t magic;
+	const char *name;
+	errcode_t (*open)(const char *name, int flags, io_channel *channel);
+	errcode_t (*close)(io_channel channel);
+	errcode_t (*set_blksize)(io_channel channel, int blksize);
+	errcode_t (*read_blk)(io_channel channel, unsigned long block,
+			      int count, void *data);
+	errcode_t (*write_blk)(io_channel channel, unsigned long block,
+			       int count, const void *data);
+	errcode_t (*flush)(io_channel channel);
+	errcode_t (*write_byte)(io_channel channel, unsigned long offset,
+				int count, const void *data);
+	int		reserved[15];
+};
+
+#define IO_FLAG_RW	1
+
+/*
+ * Convenience functions....
+ */
+#define io_channel_close(c) 		((c)->manager->close((c)))
+#define io_channel_set_blksize(c,s)	((c)->manager->set_blksize((c),s))
+#define io_channel_read_blk(c,b,n,d)	((c)->manager->read_blk((c),b,n,d))
+#define io_channel_write_blk(c,b,n,d)	((c)->manager->write_blk((c),b,n,d))
+#define io_channel_flush(c) 		((c)->manager->flush((c)))
+#define io_channel_write_byte(c,b,n,d)	((c)->manager->write_byte((c),b,n,d))
+#define io_channel_bumpcount(c)		((c)->refcount++)
+	
+/* unix_io.c */
+extern io_manager unix_io_manager;
+
+/* test_io.c */
+extern io_manager test_io_manager, test_io_backing_manager;
+extern void (*test_io_cb_read_blk)
+	(unsigned long block, int count, errcode_t err);
+extern void (*test_io_cb_write_blk)
+	(unsigned long block, int count, errcode_t err);
+extern void (*test_io_cb_set_blksize)
+	(int blksize, errcode_t err);
+
+#endif /* _EXT2FS_EXT2_IO_H */
+	

Added: ppcrcd/yaboot/include/ext2fs/ext2fs.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/ext2fs/ext2fs.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,978 @@
+/*
+ * ext2fs.h --- ext2fs
+ * 
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#ifndef _EXT2FS_EXT2FS_H
+#define _EXT2FS_EXT2FS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Non-GNU C compilers won't necessarily understand inline
+ */
+#if (!defined(__GNUC__) && !defined(__WATCOMC__))
+#define NO_INLINE_FUNCS
+#endif
+
+/*
+ * Build in support for byte-swapping filesystems if we the feature
+ * has been configured or if we're being built on a CPU architecture
+ * with a non-native byte order.
+ */
+#if defined(ENABLE_SWAPFS) || defined(WORDS_BIGENDIAN)
+#define EXT2FS_ENABLE_SWAPFS
+#endif
+
+/*
+ * Where the master copy of the superblock is located, and how big
+ * superblocks are supposed to be.  We define SUPERBLOCK_SIZE because
+ * the size of the superblock structure is not necessarily trustworthy
+ * (some versions have the padding set up so that the superblock is
+ * 1032 bytes long).
+ */
+#define SUPERBLOCK_OFFSET	1024
+#define SUPERBLOCK_SIZE 	1024
+
+/*
+ * The last ext2fs revision level that this version of the library is
+ * able to support.
+ */
+#define EXT2_LIB_CURRENT_REV	EXT2_DYNAMIC_REV
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "stdlib.h"
+
+#if EXT2_FLAT_INCLUDES
+#include "e2_types.h"
+#else
+#include "types.h" /* use yaboot's types.h */
+#endif /* EXT2_FLAT_INCLUDES */
+
+typedef __u32		ext2_ino_t;
+typedef __u32		blk_t;
+typedef __u32		dgrp_t;
+typedef __u32		ext2_off_t;
+typedef __s64		e2_blkcnt_t;
+
+#if EXT2_FLAT_INCLUDES
+#include "com_err.h"
+#include "ext2_io.h"
+#include "ext2_err.h"
+#else
+#include "et/com_err.h"
+#include "ext2fs/ext2_io.h"
+#include "ext2fs/ext2_err.h"
+#endif
+
+/*
+ * Portability help for Microsoft Visual C++
+ */
+#ifdef _MSC_VER
+#define EXT2_QSORT_TYPE int __cdecl
+#else
+#define EXT2_QSORT_TYPE int
+#endif
+
+typedef struct struct_ext2_filsys *ext2_filsys;
+
+struct ext2fs_struct_generic_bitmap {
+	errcode_t	magic;
+	ext2_filsys 	fs;
+	__u32		start, end;
+	__u32		real_end;
+	char	*	description;
+	char	*	bitmap;
+	errcode_t	base_error_code;
+	__u32		reserved[7];
+};
+
+#define EXT2FS_MARK_ERROR 	0
+#define EXT2FS_UNMARK_ERROR 	1
+#define EXT2FS_TEST_ERROR	2
+
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
+
+#ifdef EXT2_DYNAMIC_REV
+#define EXT2_FIRST_INODE(s)	EXT2_FIRST_INO(s)
+#else
+#define EXT2_FIRST_INODE(s)	EXT2_FIRST_INO
+#define EXT2_INODE_SIZE(s)	sizeof(struct ext2_inode)
+#endif
+
+/*
+ * badblocks list definitions
+ */
+
+typedef struct ext2_struct_badblocks_list *ext2_badblocks_list;
+typedef struct ext2_struct_badblocks_iterate *ext2_badblocks_iterate;
+
+/* old */
+typedef struct ext2_struct_badblocks_list *badblocks_list;
+typedef struct ext2_struct_badblocks_iterate *badblocks_iterate;
+
+#define BADBLOCKS_FLAG_DIRTY	1
+
+/*
+ * ext2_dblist structure and abstractions (see dblist.c)
+ */
+struct ext2_db_entry {
+	ext2_ino_t	ino;
+	blk_t	blk;
+	int	blockcnt;
+};
+
+typedef struct ext2_struct_dblist *ext2_dblist;
+
+#define DBLIST_ABORT	1
+
+/*
+ * ext2_fileio definitions
+ */
+
+#define EXT2_FILE_WRITE		0x0001
+#define EXT2_FILE_CREATE	0x0002
+
+#define EXT2_FILE_MASK		0x00FF
+
+#define EXT2_FILE_BUF_DIRTY	0x4000
+#define EXT2_FILE_BUF_VALID	0x2000
+
+typedef struct ext2_file *ext2_file_t;
+
+#define EXT2_SEEK_SET	0
+#define EXT2_SEEK_CUR	1
+#define EXT2_SEEK_END	2
+
+/*
+ * Flags for the ext2_filsys structure and for ext2fs_open()
+ */
+#define EXT2_FLAG_RW			0x01
+#define EXT2_FLAG_CHANGED		0x02
+#define EXT2_FLAG_DIRTY			0x04
+#define EXT2_FLAG_VALID			0x08
+#define EXT2_FLAG_IB_DIRTY		0x10
+#define EXT2_FLAG_BB_DIRTY		0x20
+#define EXT2_FLAG_SWAP_BYTES		0x40
+#define EXT2_FLAG_SWAP_BYTES_READ	0x80
+#define EXT2_FLAG_SWAP_BYTES_WRITE	0x100
+#define EXT2_FLAG_MASTER_SB_ONLY	0x200
+#define EXT2_FLAG_FORCE			0x400
+#define EXT2_FLAG_SUPER_ONLY		0x800
+#define EXT2_FLAG_JOURNAL_DEV_OK	0x1000
+#define EXT2_FLAG_IMAGE_FILE		0x2000
+
+/*
+ * Special flag in the ext2 inode i_flag field that means that this is
+ * a new inode.  (So that ext2_write_inode() can clear extra fields.)
+ */
+#define EXT2_NEW_INODE_FL	0x80000000
+
+/*
+ * Flags for mkjournal
+ *
+ * EXT2_MKJOURNAL_V1_SUPER	Make a (deprecated) V1 journal superblock
+ */
+#define EXT2_MKJOURNAL_V1_SUPER	0x0000001
+
+struct struct_ext2_filsys {
+	errcode_t			magic;
+	io_channel			io;
+	int				flags;
+	char *				device_name;
+	struct ext2_super_block	* 	super;
+	int				blocksize;
+	int				fragsize;
+	dgrp_t				group_desc_count;
+	unsigned long			desc_blocks;
+	struct ext2_group_desc *	group_desc;
+	int				inode_blocks_per_group;
+	ext2fs_inode_bitmap		inode_map;
+	ext2fs_block_bitmap		block_map;
+	errcode_t (*get_blocks)(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
+	errcode_t (*check_directory)(ext2_filsys fs, ext2_ino_t ino);
+	errcode_t (*write_bitmaps)(ext2_filsys fs);
+	errcode_t (*read_inode)(ext2_filsys fs, ext2_ino_t ino,
+				struct ext2_inode *inode);
+	errcode_t (*write_inode)(ext2_filsys fs, ext2_ino_t ino,
+				struct ext2_inode *inode);
+	badblocks_list			badblocks;
+	ext2_dblist			dblist;
+	__u32				stride;	/* for mke2fs */
+	struct ext2_super_block *	orig_super;
+	struct ext2_image_hdr *		image_header;
+	/*
+	 * Reserved for future expansion
+	 */
+	__u32				reserved[9];
+
+	/*
+	 * Reserved for the use of the calling application.
+	 */
+	void *				priv_data;
+
+	/*
+	 * Inode cache
+	 */
+	struct ext2_inode_cache		*icache;
+};
+
+#if EXT2_FLAT_INCLUDES
+#include "e2_bitops.h"
+#else
+#include "ext2fs/bitops.h"
+#endif
+
+/*
+ * Return flags for the block iterator functions
+ */
+#define BLOCK_CHANGED	1
+#define BLOCK_ABORT	2
+#define BLOCK_ERROR	4
+
+/*
+ * Block interate flags
+ *
+ * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
+ * function should be called on blocks where the block number is zero.
+ * This is used by ext2fs_expand_dir() to be able to add a new block
+ * to an inode.  It can also be used for programs that want to be able
+ * to deal with files that contain "holes".
+ * 
+ * BLOCK_FLAG_TRAVERSE indicates that the iterator function for the
+ * indirect, doubly indirect, etc. blocks should be called after all
+ * of the blocks containined in the indirect blocks are processed.
+ * This is useful if you are going to be deallocating blocks from an
+ * inode.
+ *
+ * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
+ * called for data blocks only.
+ *
+ * BLOCK_FLAG_NO_LARGE is for internal use only.  It informs
+ * ext2fs_block_iterate2 that large files won't be accepted.
+ */
+#define BLOCK_FLAG_APPEND	1
+#define BLOCK_FLAG_HOLE		1
+#define BLOCK_FLAG_DEPTH_TRAVERSE	2
+#define BLOCK_FLAG_DATA_ONLY	4
+
+#define BLOCK_FLAG_NO_LARGE	0x1000
+
+/*
+ * Magic "block count" return values for the block iterator function.
+ */
+#define BLOCK_COUNT_IND		(-1)
+#define BLOCK_COUNT_DIND	(-2)
+#define BLOCK_COUNT_TIND	(-3)
+#define BLOCK_COUNT_TRANSLATOR	(-4)
+
+#if 0
+/*
+ * Flags for ext2fs_move_blocks
+ */
+#define EXT2_BMOVE_GET_DBLIST	0x0001	
+#define EXT2_BMOVE_DEBUG	0x0002
+#endif
+
+/*
+ * Return flags for the directory iterator functions
+ */
+#define DIRENT_CHANGED	1
+#define DIRENT_ABORT	2
+#define DIRENT_ERROR	3
+
+/*
+ * Directory iterator flags
+ */
+
+#define DIRENT_FLAG_INCLUDE_EMPTY	1
+
+
+#define DIRENT_DOT_FILE		1
+#define DIRENT_DOT_DOT_FILE	2
+#define DIRENT_OTHER_FILE	3
+
+/*
+ * Inode scan definitions
+ */
+typedef struct ext2_struct_inode_scan *ext2_inode_scan;
+
+/*
+ * ext2fs_scan flags
+ */
+#define EXT2_SF_CHK_BADBLOCKS	0x0001
+#define EXT2_SF_BAD_INODE_BLK	0x0002
+#define EXT2_SF_BAD_EXTRA_BYTES	0x0004
+#define EXT2_SF_SKIP_MISSING_ITABLE	0x0008
+
+/*
+ * ext2fs_check_if_mounted flags
+ */
+#define EXT2_MF_MOUNTED		1
+#define EXT2_MF_ISROOT		2
+#define EXT2_MF_READONLY	4
+
+/*
+ * Ext2/linux mode flags.  We define them here so that we don't need
+ * to depend on the OS's sys/stat.h, since we may be compiling on a
+ * non-Linux system.
+ */
+#define LINUX_S_IFMT  00170000
+#define LINUX_S_IFSOCK 0140000
+#define LINUX_S_IFLNK	 0120000
+#define LINUX_S_IFREG  0100000
+#define LINUX_S_IFBLK  0060000
+#define LINUX_S_IFDIR  0040000
+#define LINUX_S_IFCHR  0020000
+#define LINUX_S_IFIFO  0010000
+#define LINUX_S_ISUID  0004000
+#define LINUX_S_ISGID  0002000
+#define LINUX_S_ISVTX  0001000
+
+#define LINUX_S_IRWXU 00700
+#define LINUX_S_IRUSR 00400
+#define LINUX_S_IWUSR 00200
+#define LINUX_S_IXUSR 00100
+
+#define LINUX_S_IRWXG 00070
+#define LINUX_S_IRGRP 00040
+#define LINUX_S_IWGRP 00020
+#define LINUX_S_IXGRP 00010
+
+#define LINUX_S_IRWXO 00007
+#define LINUX_S_IROTH 00004
+#define LINUX_S_IWOTH 00002
+#define LINUX_S_IXOTH 00001
+
+#define LINUX_S_ISLNK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
+#define LINUX_S_ISREG(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
+#define LINUX_S_ISDIR(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
+#define LINUX_S_ISCHR(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFCHR)
+#define LINUX_S_ISBLK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFBLK)
+#define LINUX_S_ISFIFO(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFIFO)
+#define LINUX_S_ISSOCK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
+
+/*
+ * ext2_icount_t abstraction
+ */
+#define EXT2_ICOUNT_OPT_INCREMENT	0x01
+
+typedef struct ext2_icount *ext2_icount_t;
+
+/*
+ * Flags for ext2fs_bmap
+ */
+#define BMAP_ALLOC	1
+
+/*
+ * Flags for imager.c functions
+ */
+#define IMAGER_FLAG_INODEMAP	1
+#define IMAGER_FLAG_SPARSEWRITE	2
+
+/*
+ * For checking structure magic numbers...
+ */
+
+#define EXT2_CHECK_MAGIC(struct, code) \
+	  if ((struct)->magic != (code)) return (code)
+
+
+/*
+ * For ext2 compression support
+ */
+#define EXT2FS_COMPRESSED_BLKADDR ((blk_t) 0xffffffff)
+#define HOLE_BLKADDR(_b) ((_b) == 0 || (_b) == EXT2FS_COMPRESSED_BLKADDR)
+
+/*
+ * Features supported by this version of the library
+ */
+#define EXT2_LIB_FEATURE_COMPAT_SUPP	(EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
+					 EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
+					 EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
+					 EXT2_FEATURE_COMPAT_EXT_ATTR)
+
+/* This #ifdef is temporary until compression is fully supported */
+#ifdef ENABLE_COMPRESSION
+#ifndef I_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL
+/* If the below warning bugs you, then have
+   `CPPFLAGS=-DI_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL' in your
+   environment at configure time. */
+ #warning "Compression support is experimental"
+#endif
+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE|\
+					 EXT2_FEATURE_INCOMPAT_COMPRESSION|\
+					 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
+					 EXT3_FEATURE_INCOMPAT_RECOVER)
+#else
+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE|\
+					 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
+					 EXT3_FEATURE_INCOMPAT_RECOVER)
+#endif
+#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
+/*
+ * function prototypes
+ */
+
+/* alloc.c */
+extern errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, int mode,
+				  ext2fs_inode_bitmap map, ext2_ino_t *ret);
+extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
+				  ext2fs_block_bitmap map, blk_t *ret);
+extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
+					blk_t finish, int num,
+					ext2fs_block_bitmap map,
+					blk_t *ret);
+extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
+				    char *block_buf, blk_t *ret);
+
+/* alloc_tables.c */
+extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
+extern errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
+					     ext2fs_block_bitmap bmap);
+
+/* badblocks.c */
+extern errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret,
+					    int size);
+extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
+					   blk_t blk);
+extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
+				    blk_t blk);
+extern errcode_t
+	ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
+					    ext2_badblocks_iterate *ret);
+extern int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter,
+					 blk_t *blk);
+extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
+extern errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
+				       ext2_badblocks_list *dest);
+extern int ext2fs_badblocks_equal(ext2_badblocks_list bb1,
+				  ext2_badblocks_list bb2);
+
+/* bb_compat */
+extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
+extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
+extern int badblocks_list_test(badblocks_list bb, blk_t blk);
+extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
+					      badblocks_iterate *ret);
+extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
+extern void badblocks_list_iterate_end(badblocks_iterate iter);
+extern void badblocks_list_free(badblocks_list bb);
+
+/* bb_inode.c */
+extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
+					ext2_badblocks_list bb_list);
+
+/* bitmaps.c */
+extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
+extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
+extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+						__u32 end,
+						__u32 real_end,
+						const char *descr,
+						ext2fs_generic_bitmap *ret);
+extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
+					      const char *descr,
+					      ext2fs_block_bitmap *ret);
+extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
+					      const char *descr,
+					      ext2fs_inode_bitmap *ret);
+extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
+					       ext2_ino_t end, ext2_ino_t *oend);
+extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
+					       blk_t end, blk_t *oend);
+extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
+extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
+extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
+
+/* block.c */
+extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
+				      ext2_ino_t	ino,
+				      int	flags,
+				      char *block_buf,
+				      int (*func)(ext2_filsys fs,
+						  blk_t	*blocknr,
+						  int	blockcnt,
+						  void	*priv_data),
+				      void *priv_data);
+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
+				ext2_ino_t	ino,
+				int	flags,
+				char *block_buf,
+				int (*func)(ext2_filsys fs,
+					    blk_t	*blocknr,
+					    e2_blkcnt_t	blockcnt,
+					    blk_t	ref_blk,
+					    int		ref_offset,
+					    void	*priv_data),
+				void *priv_data);
+
+/* bmap.c */
+extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
+			     struct ext2_inode *inode, 
+			     char *block_buf, int bmap_flags,
+			     blk_t block, blk_t *phys_blk);
+
+
+#if 0
+/* bmove.c */
+extern errcode_t ext2fs_move_blocks(ext2_filsys fs,
+				    ext2fs_block_bitmap reserve,
+				    ext2fs_block_bitmap alloc_map,
+				    int flags);
+#endif
+
+/* check_desc.c */
+extern errcode_t ext2fs_check_desc(ext2_filsys fs);
+
+/* closefs.c */
+extern errcode_t ext2fs_close(ext2_filsys fs);
+extern errcode_t ext2fs_flush(ext2_filsys fs);
+extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
+extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
+
+/* cmp_bitmaps.c */
+extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
+					     ext2fs_block_bitmap bm2);
+extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
+					     ext2fs_inode_bitmap bm2);
+
+/* dblist.c */
+
+extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
+extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
+extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino,
+				      blk_t blk, int blockcnt);
+extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
+	int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
+		    void	*priv_data),
+       void *priv_data);
+extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino,
+				      blk_t blk, int blockcnt);
+extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
+				    ext2_dblist *dest);
+extern int ext2fs_dblist_count(ext2_dblist dblist);
+
+/* dblist_dir.c */
+extern errcode_t
+	ext2fs_dblist_dir_iterate(ext2_dblist dblist,
+				  int	flags,
+				  char	*block_buf,
+				  int (*func)(ext2_ino_t	dir,
+					      int		entry,
+					      struct ext2_dir_entry *dirent,
+					      int	offset,
+					      int	blocksize,
+					      char	*buf,
+					      void	*priv_data),
+				  void *priv_data);
+
+/* dirblock.c */
+extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
+				       void *buf);
+extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
+					void *buf);
+
+/* dir_iterate.c */
+extern errcode_t ext2fs_dir_iterate(ext2_filsys fs, 
+			      ext2_ino_t dir,
+			      int flags,
+			      char *block_buf,
+			      int (*func)(struct ext2_dir_entry *dirent,
+					  int	offset,
+					  int	blocksize,
+					  char	*buf,
+					  void	*priv_data),
+			      void *priv_data);
+
+/* dupfs.c */
+extern errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest);
+
+/* expanddir.c */
+extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir);
+
+/* ext_attr.c */
+void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from);
+extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
+extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *buf); 
+/* fileio.c */
+extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
+				  int flags, ext2_file_t *ret);
+extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file);
+extern errcode_t ext2fs_file_close(ext2_file_t file);
+extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
+				  unsigned int wanted, unsigned int *got);
+extern errcode_t ext2fs_file_write(ext2_file_t file, void *buf,
+				   unsigned int nbytes, unsigned int *written);
+extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
+				   int whence, ext2_off_t *ret_pos);
+extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
+extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
+
+/* finddev.c */
+#if 0 /* broken in yaboot build env */
+extern char *ext2fs_find_block_device(dev_t device);
+#endif
+
+/* flushb.c */
+extern errcode_t ext2fs_sync_device(int fd, int flushb);
+
+/* freefs.c */
+extern void ext2fs_free(ext2_filsys fs);
+extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
+extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_free_dblist(ext2_dblist dblist);
+extern void ext2fs_badblocks_list_free(badblocks_list bb);
+
+/* getsize.c */
+extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
+					blk_t *retblocks);
+
+/* imager.c */
+extern errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags);
+extern errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, int flags);
+extern errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, int flags);
+extern errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, int flags);
+extern errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags);
+extern errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags);
+
+/* initialize.c */
+extern errcode_t ext2fs_initialize(const char *name, int flags,
+				   struct ext2_super_block *param,
+				   io_manager manager, ext2_filsys *ret_fs);
+
+/* inode.c */
+extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
+extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
+				  ext2_inode_scan *ret_scan);
+extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
+extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
+			       struct ext2_inode *inode);
+extern errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
+						   int	group);
+extern void ext2fs_set_inode_callback
+	(ext2_inode_scan scan,
+	 errcode_t (*done_group)(ext2_filsys fs,
+				 ext2_inode_scan scan,
+				 dgrp_t group,
+				 void * priv_data),
+	 void *done_group_data);
+extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
+				   int clear_flags);
+extern errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
+			    struct ext2_inode * inode);
+extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
+			    struct ext2_inode * inode);
+extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
+extern errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino);
+
+/* icount.c */
+extern void ext2fs_free_icount(ext2_icount_t icount);
+extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, int size,
+				       ext2_icount_t hint, ext2_icount_t *ret);
+extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, int size,
+				      ext2_icount_t *ret);
+extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino,
+				     __u16 *ret);
+extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
+					 __u16 *ret);
+extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
+					 __u16 *ret);
+extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
+				     __u16 count);
+extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
+errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
+
+/* ismounted.c */
+extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
+extern errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
+					  char *mtpt, int mtlen);
+
+/* namei.c */
+extern errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
+			 int namelen, char *buf, ext2_ino_t *inode);
+extern errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
+			const char *name, ext2_ino_t *inode);
+errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
+			      const char *name, ext2_ino_t *inode);
+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
+			ext2_ino_t inode, ext2_ino_t *res_inode);
+
+/* native.c */
+int ext2fs_native_flag(void);
+
+/* newdir.c */
+extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
+				ext2_ino_t parent_ino, char **block);
+
+/* mkdir.c */
+extern errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
+			      const char *name);
+
+/* mkjournal.c */
+extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
+						  __u32 size, int flags,
+						  char  **ret_jsb);
+extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
+					   ext2_filsys journal_dev);
+extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size,
+					  int flags);
+
+/* openfs.c */
+extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
+			     int block_size, io_manager manager,
+			     ext2_filsys *ret_fs);
+
+/* get_pathname.c */
+extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
+			       char **name);
+
+/* link.c */
+errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
+		      ext2_ino_t ino, int flags);
+errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
+			ext2_ino_t ino, int flags);
+
+/* read_bb.c */
+extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
+				      ext2_badblocks_list *bb_list);
+
+/* read_bb_file.c */
+extern errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f, 
+				      ext2_badblocks_list *bb_list,
+				      void *private,
+				      void (*invalid)(ext2_filsys fs,
+						      blk_t blk,
+						      char *badstr,
+						      void *private));
+extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f, 
+				     ext2_badblocks_list *bb_list,
+				     void (*invalid)(ext2_filsys fs,
+						     blk_t blk));
+
+/* rs_bitmap.c */
+extern errcode_t ext2fs_resize_generic_bitmap(__u32 new_end,
+					      __u32 new_real_end,
+					      ext2fs_generic_bitmap bmap);
+extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
+					    ext2fs_inode_bitmap bmap);
+extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
+					    ext2fs_block_bitmap bmap);
+extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
+				    ext2fs_generic_bitmap *dest);
+
+/* swapfs.c */
+extern void ext2fs_swap_super(struct ext2_super_block * super);
+extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
+extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
+			      struct ext2_inode *f, int hostorder);
+
+/* valid_blk.c */
+extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
+
+/* version.c */
+extern int ext2fs_parse_version_string(const char *ver_string);
+extern int ext2fs_get_library_version(const char **ver_string,
+				      const char **date_string);
+
+/* write_bb_file.c */
+extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
+				      unsigned int flags,
+				      FILE *f);
+
+
+/* inline functions */
+extern errcode_t ext2fs_get_mem(unsigned long size, void **ptr);
+extern errcode_t ext2fs_free_mem(void **ptr);
+extern errcode_t ext2fs_resize_mem(unsigned long old_size,
+				   unsigned long size, void **ptr);
+extern void ext2fs_mark_super_dirty(ext2_filsys fs);
+extern void ext2fs_mark_changed(ext2_filsys fs);
+extern int ext2fs_test_changed(ext2_filsys fs);
+extern void ext2fs_mark_valid(ext2_filsys fs);
+extern void ext2fs_unmark_valid(ext2_filsys fs);
+extern int ext2fs_test_valid(ext2_filsys fs);
+extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
+extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
+extern int ext2fs_test_ib_dirty(ext2_filsys fs);
+extern int ext2fs_test_bb_dirty(ext2_filsys fs);
+extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
+extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
+
+/*
+ * The actual inlined functions definitions themselves...
+ *
+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
+ * functions at all!
+ */
+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
+#ifdef INCLUDE_INLINE_FUNCS
+#define _INLINE_ extern
+#else
+#ifdef __GNUC__
+#define _INLINE_ extern __inline__
+#else				/* For Watcom C */
+#define _INLINE_ extern inline
+#endif
+#endif
+
+#ifndef EXT2_CUSTOM_MEMORY_ROUTINES
+/*
+ *  Allocate memory
+ */
+_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void **ptr)
+{
+	*ptr = malloc(size);
+	if (!*ptr)
+		return EXT2_ET_NO_MEMORY;
+	return 0;
+}
+
+/*
+ * Free memory
+ */
+_INLINE_ errcode_t ext2fs_free_mem(void **ptr)
+{
+	free(*ptr);
+	*ptr = 0;
+	return 0;
+}
+	
+/*
+ *  Resize memory
+ */
+_INLINE_ errcode_t ext2fs_resize_mem(unsigned long old_size,
+				     unsigned long size, void **ptr)
+{
+	void *p;
+
+	p = realloc(*ptr, size);
+	if (!p)
+		return EXT2_ET_NO_MEMORY;
+	*ptr = p;
+	return 0;
+}
+#endif	/* Custom memory routines */
+
+/*
+ * Mark a filesystem superblock as dirty
+ */
+_INLINE_ void ext2fs_mark_super_dirty(ext2_filsys fs)
+{
+	fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Mark a filesystem as changed
+ */
+_INLINE_ void ext2fs_mark_changed(ext2_filsys fs)
+{
+	fs->flags |= EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Check to see if a filesystem has changed
+ */
+_INLINE_ int ext2fs_test_changed(ext2_filsys fs)
+{
+	return (fs->flags & EXT2_FLAG_CHANGED);
+}
+
+/*
+ * Mark a filesystem as valid
+ */
+_INLINE_ void ext2fs_mark_valid(ext2_filsys fs)
+{
+	fs->flags |= EXT2_FLAG_VALID;
+}
+
+/*
+ * Mark a filesystem as NOT valid
+ */
+_INLINE_ void ext2fs_unmark_valid(ext2_filsys fs)
+{
+	fs->flags &= ~EXT2_FLAG_VALID;
+}
+
+/*
+ * Check to see if a filesystem is valid
+ */
+_INLINE_ int ext2fs_test_valid(ext2_filsys fs)
+{
+	return (fs->flags & EXT2_FLAG_VALID);
+}
+
+/*
+ * Mark the inode bitmap as dirty
+ */
+_INLINE_ void ext2fs_mark_ib_dirty(ext2_filsys fs)
+{
+	fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Mark the block bitmap as dirty
+ */
+_INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
+{
+	fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Check to see if a filesystem's inode bitmap is dirty
+ */
+_INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
+{
+	return (fs->flags & EXT2_FLAG_IB_DIRTY);
+}
+
+/*
+ * Check to see if a filesystem's block bitmap is dirty
+ */
+_INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
+{
+	return (fs->flags & EXT2_FLAG_BB_DIRTY);
+}
+
+/*
+ * Return the group # of a block
+ */
+_INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
+{
+	return (blk - fs->super->s_first_data_block) /
+		fs->super->s_blocks_per_group;
+}
+
+/*
+ * Return the group # of an inode number
+ */
+_INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
+{
+	return (ino - 1) / fs->super->s_inodes_per_group;
+}
+#undef _INLINE_
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EXT2FS_EXT2FS_H */

Added: ppcrcd/yaboot/include/fdisk-part.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/fdisk-part.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,42 @@
+/*
+ *  fdisk-part.h - Structure of fdisk partition table
+ *
+ *  Copyright (C) 2000 Peter Bergner
+ *                2000 David Engebretsen
+ *
+ *  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.
+ */
+
+#define ACTIVE_FLAG     0x80
+
+#define EXTENDED        0x05
+#define WIN98_EXTENDED  0x0f
+#define LINUX_PARTITION 0x81
+#define LINUX_SWAP      0x82
+#define LINUX_NATIVE    0x83
+#define LINUX_EXTENDED  0x85
+
+struct fdisk_partition {
+	unsigned char boot_ind;         /* 0x80 - active */
+	unsigned char head;             /* starting head */
+	unsigned char sector;           /* starting sector */
+	unsigned char cyl;              /* starting cylinder */
+	unsigned char sys_ind;          /* What partition type */
+	unsigned char end_head;         /* end head */
+	unsigned char end_sector;       /* end sector */
+	unsigned char end_cyl;          /* end cylinder */
+	unsigned char start4[4];        /* starting sector counting from 0 */
+	unsigned char size4[4];         /* nr of sectors in partition */
+};

Added: ppcrcd/yaboot/include/file.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/file.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,74 @@
+/*
+ *  file.h - Filesystem related interfaces
+ *
+ *  Copyright (C) 2001 Ethan Benson
+ *
+ *  parse_device_path()
+ *
+ *  Copyright (C) 2001 Colin Walters
+ *
+ *  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.
+ */
+
+#ifndef FILE_H
+#define FILE_H
+
+#include "types.h"
+#include "stddef.h"
+#include "prom.h"
+
+struct boot_file_t;
+#include "fs.h"
+
+#define FILE_MAX_PATH		1024
+
+struct boot_fspec_t {
+	char*	dev;		/* OF device path */
+	int	part;		/* Partition number or -1 */
+	char*	file;		/* File path */
+};
+
+struct boot_file_t {
+
+	/* File access methods */
+        const struct fs_t *fs;
+
+	/* Filesystem private (to be broken once we have a
+	 * better malloc'ator)
+	 */
+
+	int		device_kind;
+	ihandle		of_device;
+	ino_t		inode;
+	__u64           pos;
+	unsigned char*	buffer;
+	__u64   	len;
+//	unsigned int	dev_blk_size;
+//	unsigned int	part_start;
+//	unsigned int	part_count;
+};
+
+extern int
+open_file(const struct boot_fspec_t*	spec,
+	  struct boot_file_t*		file);
+
+extern int
+parse_device_path(char *imagepath, char *defdevice, int defpart,
+		  char *deffile, struct boot_fspec_t *result);
+
+
+#endif

Added: ppcrcd/yaboot/include/fs.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/fs.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,55 @@
+/*
+ *  fs.h - Filesystem common definitions
+ *
+ *  Copyright (C) 2001 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.
+ */
+
+#ifndef FS_H
+#define FS_H
+
+#include "partition.h"
+#include "file.h"
+
+int fserrorno;
+
+struct fs_t {
+	const char* name;
+
+	int (*open)(	struct boot_file_t*	file,
+			const char*		dev_name,
+			struct partition_t*	part,
+			const char*		file_name);
+			
+	int (*read)(	struct boot_file_t*	file,
+			unsigned int		size,
+			void*			buffer);
+				
+	int (*seek)(	struct boot_file_t*	file,
+			unsigned int		newpos);
+					
+	int (*close)(	struct boot_file_t*	file);
+};
+
+extern const struct fs_t *fs_of;
+extern const struct fs_t *fs_of_netboot;
+
+const struct fs_t *fs_open(struct boot_file_t *file, const char *dev_name,
+			  struct partition_t *part, const char *file_name);
+
+#endif

Added: ppcrcd/yaboot/include/linux/elf.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/linux/elf.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,607 @@
+#ifndef _LINUX_ELF_H
+#define _LINUX_ELF_H
+
+#include <types.h>
+#include <asm/elf.h>
+
+/* 32-bit ELF base types. */
+typedef __u32	Elf32_Addr;
+typedef __u16	Elf32_Half;
+typedef __u32	Elf32_Off;
+typedef __s32	Elf32_Sword;
+typedef __u32	Elf32_Word;
+
+/* 64-bit ELF base types. */
+typedef __u64	Elf64_Addr;
+typedef __u16	Elf64_Half;
+typedef __s16	Elf64_SHalf;
+typedef __u64	Elf64_Off;
+typedef __s64	Elf64_Sword;
+typedef __u64	Elf64_Word;
+
+/* These constants are for the segment types stored in the image headers */
+#define PT_NULL    0
+#define PT_LOAD    1
+#define PT_DYNAMIC 2
+#define PT_INTERP  3
+#define PT_NOTE    4
+#define PT_SHLIB   5
+#define PT_PHDR    6
+#define PT_LOPROC  0x70000000
+#define PT_HIPROC  0x7fffffff
+#define PT_MIPS_REGINFO		0x70000000
+
+/* Flags in the e_flags field of the header */
+#define EF_MIPS_NOREORDER 0x00000001
+#define EF_MIPS_PIC       0x00000002
+#define EF_MIPS_CPIC      0x00000004
+#define EF_MIPS_ARCH      0xf0000000
+
+/* These constants define the different elf file types */
+#define ET_NONE   0
+#define ET_REL    1
+#define ET_EXEC   2
+#define ET_DYN    3
+#define ET_CORE   4
+#define ET_LOPROC 0xff00
+#define ET_HIPROC 0xffff
+
+/* These constants define the various ELF target machines */
+#define EM_NONE  0
+#define EM_M32   1
+#define EM_SPARC 2
+#define EM_386   3
+#define EM_68K   4
+#define EM_88K   5
+#define EM_486   6   /* Perhaps disused */
+#define EM_860   7
+
+#define EM_MIPS		8	/* MIPS R3000 (officially, big-endian only) */
+
+#define EM_MIPS_RS4_BE 10	/* MIPS R4000 big-endian */
+
+#define EM_PARISC      15	/* HPPA */
+
+#define EM_SPARC32PLUS 18	/* Sun's "v8plus" */
+
+#define EM_PPC	       20	/* PowerPC */
+#define EM_PPC64       21	/* PowerPC 64-bit */
+
+#define EM_SPARCV9     43	/* SPARC v9 64-bit */
+
+/*
+ * This is an interim value that we will use until the committee comes
+ * up with a final number.
+ */
+#define EM_ALPHA	0x9026
+
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH 	15
+#define DT_SYMBOLIC	16
+#define DT_REL	        17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define DT_LOPROC	0x70000000
+#define DT_HIPROC	0x7fffffff
+#define DT_MIPS_RLD_VERSION	0x70000001
+#define DT_MIPS_TIME_STAMP	0x70000002
+#define DT_MIPS_ICHECKSUM	0x70000003
+#define DT_MIPS_IVERSION	0x70000004
+#define DT_MIPS_FLAGS		0x70000005
+  #define RHF_NONE		  0
+  #define RHF_HARDWAY		  1
+  #define RHF_NOTPOT		  2
+#define DT_MIPS_BASE_ADDRESS	0x70000006
+#define DT_MIPS_CONFLICT	0x70000008
+#define DT_MIPS_LIBLIST		0x70000009
+#define DT_MIPS_LOCAL_GOTNO	0x7000000a
+#define DT_MIPS_CONFLICTNO	0x7000000b
+#define DT_MIPS_LIBLISTNO	0x70000010
+#define DT_MIPS_SYMTABNO	0x70000011
+#define DT_MIPS_UNREFEXTNO	0x70000012
+#define DT_MIPS_GOTSYM		0x70000013
+#define DT_MIPS_HIPAGENO	0x70000014
+#define DT_MIPS_RLD_MAP		0x70000016
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL  0
+#define STB_GLOBAL 1
+#define STB_WEAK   2
+
+#define STT_NOTYPE  0
+#define STT_OBJECT  1
+#define STT_FUNC    2
+#define STT_SECTION 3
+#define STT_FILE    4
+
+#define ELF32_ST_BIND(x) ((x) >> 4)
+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
+
+/* Symbolic values for the entries in the auxiliary table
+   put on the initial stack */
+#define AT_NULL   0	/* end of vector */
+#define AT_IGNORE 1	/* entry should be ignored */
+#define AT_EXECFD 2	/* file descriptor of program */
+#define AT_PHDR   3	/* program headers for program */
+#define AT_PHENT  4	/* size of program header entry */
+#define AT_PHNUM  5	/* number of program headers */
+#define AT_PAGESZ 6	/* system page size */
+#define AT_BASE   7	/* base address of interpreter */
+#define AT_FLAGS  8	/* flags */
+#define AT_ENTRY  9	/* entry point of program */
+#define AT_NOTELF 10	/* program is not ELF */
+#define AT_UID    11	/* real uid */
+#define AT_EUID   12	/* effective uid */
+#define AT_GID    13	/* real gid */
+#define AT_EGID   14	/* effective gid */
+#define AT_PLATFORM 15  /* string identifying CPU for optimizations */
+#define AT_HWCAP  16    /* arch dependent hints at CPU capabilities */
+
+typedef struct dynamic{
+  Elf32_Sword d_tag;
+  union{
+    Elf32_Sword	d_val;
+    Elf32_Addr	d_ptr;
+  } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+  Elf64_Word d_tag;		/* entry tag value */
+  union {
+    Elf64_Word d_val;
+    Elf64_Word d_ptr;
+  } d_un;
+} Elf64_Dyn;
+
+/* The following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define R_386_NONE	0
+#define R_386_32	1
+#define R_386_PC32	2
+#define R_386_GOT32	3
+#define R_386_PLT32	4
+#define R_386_COPY	5
+#define R_386_GLOB_DAT	6
+#define R_386_JMP_SLOT	7
+#define R_386_RELATIVE	8
+#define R_386_GOTOFF	9
+#define R_386_GOTPC	10
+#define R_386_NUM	11
+
+#define R_MIPS_NONE		0
+#define R_MIPS_16		1
+#define R_MIPS_32		2
+#define R_MIPS_REL32		3
+#define R_MIPS_26		4
+#define R_MIPS_HI16		5
+#define R_MIPS_LO16		6
+#define R_MIPS_GPREL16		7
+#define R_MIPS_LITERAL		8
+#define R_MIPS_GOT16		9
+#define R_MIPS_PC16		10
+#define R_MIPS_CALL16		11
+#define R_MIPS_GPREL32		12
+/* The remaining relocs are defined on Irix, although they are not
+   in the MIPS ELF ABI.  */
+#define R_MIPS_UNUSED1		13
+#define R_MIPS_UNUSED2		14
+#define R_MIPS_UNUSED3		15
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+/*
+ * The following two relocation types are specified in the the MIPS ABI
+ * conformance guide version 1.2 but not yet in the psABI.
+ */
+#define R_MIPS_GOTHI16		22
+#define R_MIPS_GOTLO16		23
+#define R_MIPS_SUB		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+/*
+ * The following two relocation types are specified in the the MIPS ABI
+ * conformance guide version 1.2 but not yet in the psABI.
+ */
+#define R_MIPS_CALLHI16		30
+#define R_MIPS_CALLLO16		31
+/*
+ * This range is reserved for vendor specific relocations.
+ */
+#define R_MIPS_LOVENDOR		100
+#define R_MIPS_HIVENDOR		127
+
+
+/*
+ * Sparc ELF relocation types
+ */
+#define	R_SPARC_NONE		0
+#define	R_SPARC_8		1
+#define	R_SPARC_16		2
+#define	R_SPARC_32		3
+#define	R_SPARC_DISP8		4
+#define	R_SPARC_DISP16		5
+#define	R_SPARC_DISP32		6
+#define	R_SPARC_WDISP30		7
+#define	R_SPARC_WDISP22		8
+#define	R_SPARC_HI22		9
+#define	R_SPARC_22		10
+#define	R_SPARC_13		11
+#define	R_SPARC_LO10		12
+#define	R_SPARC_GOT10		13
+#define	R_SPARC_GOT13		14
+#define	R_SPARC_GOT22		15
+#define	R_SPARC_PC10		16
+#define	R_SPARC_PC22		17
+#define	R_SPARC_WPLT30		18
+#define	R_SPARC_COPY		19
+#define	R_SPARC_GLOB_DAT	20
+#define	R_SPARC_JMP_SLOT	21
+#define	R_SPARC_RELATIVE	22
+#define	R_SPARC_UA32		23
+#define R_SPARC_PLT32		24
+#define R_SPARC_HIPLT22		25
+#define R_SPARC_LOPLT10		26
+#define R_SPARC_PCPLT32		27
+#define R_SPARC_PCPLT22		28
+#define R_SPARC_PCPLT10		29
+#define R_SPARC_10		30
+#define R_SPARC_11		31
+#define R_SPARC_WDISP16		40
+#define R_SPARC_WDISP19		41
+#define R_SPARC_7		43
+#define R_SPARC_5		44
+#define R_SPARC_6		45
+
+/* Bits present in AT_HWCAP, primarily for Sparc32.  */
+
+#define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
+#define HWCAP_SPARC_STBAR       2
+#define HWCAP_SPARC_SWAP        4
+#define HWCAP_SPARC_MULDIV      8
+#define HWCAP_SPARC_V9		16
+
+
+/*
+ * 68k ELF relocation types
+ */
+#define R_68K_NONE	0
+#define R_68K_32	1
+#define R_68K_16	2
+#define R_68K_8		3
+#define R_68K_PC32	4
+#define R_68K_PC16	5
+#define R_68K_PC8	6
+#define R_68K_GOT32	7
+#define R_68K_GOT16	8
+#define R_68K_GOT8	9
+#define R_68K_GOT32O	10
+#define R_68K_GOT16O	11
+#define R_68K_GOT8O	12
+#define R_68K_PLT32	13
+#define R_68K_PLT16	14
+#define R_68K_PLT8	15
+#define R_68K_PLT32O	16
+#define R_68K_PLT16O	17
+#define R_68K_PLT8O	18
+#define R_68K_COPY	19
+#define R_68K_GLOB_DAT	20
+#define R_68K_JMP_SLOT	21
+#define R_68K_RELATIVE	22
+
+/*
+ * Alpha ELF relocation types
+ */
+#define R_ALPHA_NONE            0       /* No reloc */
+#define R_ALPHA_REFLONG         1       /* Direct 32 bit */
+#define R_ALPHA_REFQUAD         2       /* Direct 64 bit */
+#define R_ALPHA_GPREL32         3       /* GP relative 32 bit */
+#define R_ALPHA_LITERAL         4       /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE          5       /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP          6       /* Add displacement to GP */
+#define R_ALPHA_BRADDR          7       /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT            8       /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16          9       /* PC relative 16 bit */
+#define R_ALPHA_SREL32          10      /* PC relative 32 bit */
+#define R_ALPHA_SREL64          11      /* PC relative 64 bit */
+#define R_ALPHA_OP_PUSH         12      /* OP stack push */
+#define R_ALPHA_OP_STORE        13      /* OP stack pop and store */
+#define R_ALPHA_OP_PSUB         14      /* OP stack subtract */
+#define R_ALPHA_OP_PRSHIFT      15      /* OP stack right shift */
+#define R_ALPHA_GPVALUE         16
+#define R_ALPHA_GPRELHIGH       17
+#define R_ALPHA_GPRELLOW        18
+#define R_ALPHA_IMMED_GP_16     19
+#define R_ALPHA_IMMED_GP_HI32   20
+#define R_ALPHA_IMMED_SCN_HI32  21
+#define R_ALPHA_IMMED_BR_HI32   22
+#define R_ALPHA_IMMED_LO32      23
+#define R_ALPHA_COPY            24      /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT        25      /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT        26      /* Create PLT entry */
+#define R_ALPHA_RELATIVE        27      /* Adjust by program base */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT		1	/* All addresses are below 2GB */
+
+
+typedef struct elf32_rel {
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+} Elf32_Rel;
+
+typedef struct elf64_rel {
+  Elf64_Addr r_offset;	/* Location at which to apply the action */
+  Elf64_Word r_info;	/* index and type of relocation */
+} Elf64_Rel;
+
+typedef struct elf32_rela{
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+  Elf32_Sword	r_addend;
+} Elf32_Rela;
+
+typedef struct elf64_rela {
+  Elf64_Addr r_offset;	/* Location at which to apply the action */
+  Elf64_Word r_info;	/* index and type of relocation */
+  Elf64_Word r_addend;	/* Constant addend used to compute value */
+} Elf64_Rela;
+
+typedef struct elf32_sym{
+  Elf32_Word	st_name;
+  Elf32_Addr	st_value;
+  Elf32_Word	st_size;
+  unsigned char	st_info;
+  unsigned char	st_other;
+  Elf32_Half	st_shndx;
+} Elf32_Sym;
+
+typedef struct elf64_sym {
+  Elf32_Word st_name;		/* Symbol name, index in string tbl (yes, Elf32) */
+  unsigned char	st_info;	/* Type and binding attributes */
+  unsigned char	st_other;	/* No defined meaning, 0 */
+  Elf64_Half st_shndx;		/* Associated section index */
+  Elf64_Addr st_value;		/* Value of the symbol */
+  Elf64_Word st_size;		/* Associated symbol size */
+} Elf64_Sym;
+
+
+#define EI_NIDENT	16
+
+/* Minimum amount of the header we need to determine whether
+ * we have an executable PPC32/PPC64 Elf file or not.
+ */
+typedef struct elf_ident_t {
+  unsigned char e_ident[EI_NIDENT];
+  __u16	        e_type;
+  __u16	        e_machine;
+} Elf_Ident;
+
+typedef struct elf32_hdr{
+  unsigned char	e_ident[EI_NIDENT];
+  Elf32_Half	e_type;
+  Elf32_Half	e_machine;
+  Elf32_Word	e_version;
+  Elf32_Addr	e_entry;  /* Entry point */
+  Elf32_Off	e_phoff;
+  Elf32_Off	e_shoff;
+  Elf32_Word	e_flags;
+  Elf32_Half	e_ehsize;
+  Elf32_Half	e_phentsize;
+  Elf32_Half	e_phnum;
+  Elf32_Half	e_shentsize;
+  Elf32_Half	e_shnum;
+  Elf32_Half	e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct elf64_hdr {
+  unsigned char	e_ident[16];		/* ELF "magic number" */
+  Elf64_SHalf e_type;
+  Elf64_Half e_machine;
+  __s32 e_version;
+  Elf64_Addr e_entry;		/* Entry point virtual address */
+  Elf64_Off e_phoff;		/* Program header table file offset */
+  Elf64_Off e_shoff;		/* Section header table file offset */
+  __s32 e_flags;
+  Elf64_SHalf e_ehsize;
+  Elf64_SHalf e_phentsize;
+  Elf64_SHalf e_phnum;
+  Elf64_SHalf e_shentsize;
+  Elf64_SHalf e_shnum;
+  Elf64_SHalf e_shstrndx;
+} Elf64_Ehdr;
+
+/* These constants define the permissions on sections in the program
+   header, p_flags. */
+#define PF_R		0x4
+#define PF_W		0x2
+#define PF_X		0x1
+
+typedef struct elf32_phdr{
+  Elf32_Word	p_type;
+  Elf32_Off	p_offset;
+  Elf32_Addr	p_vaddr;
+  Elf32_Addr	p_paddr;
+  Elf32_Word	p_filesz;
+  Elf32_Word	p_memsz;
+  Elf32_Word	p_flags;
+  Elf32_Word	p_align;
+} Elf32_Phdr;
+
+typedef struct elf64_phdr {
+  __s32 p_type;
+  __s32 p_flags;
+  Elf64_Off p_offset;		/* Segment file offset */
+  Elf64_Addr p_vaddr;		/* Segment virtual address */
+  Elf64_Addr p_paddr;		/* Segment physical address */
+  Elf64_Word p_filesz;		/* Segment size in file */
+  Elf64_Word p_memsz;		/* Segment size in memory */
+  Elf64_Word p_align;		/* Segment alignment, file & memory */
+} Elf64_Phdr;
+
+/* sh_type */
+#define SHT_NULL	0
+#define SHT_PROGBITS	1
+#define SHT_SYMTAB	2
+#define SHT_STRTAB	3
+#define SHT_RELA	4
+#define SHT_HASH	5
+#define SHT_DYNAMIC	6
+#define SHT_NOTE	7
+#define SHT_NOBITS	8
+#define SHT_REL		9
+#define SHT_SHLIB	10
+#define SHT_DYNSYM	11
+#define SHT_NUM		12
+#define SHT_LOPROC	0x70000000
+#define SHT_HIPROC	0x7fffffff
+#define SHT_LOUSER	0x80000000
+#define SHT_HIUSER	0xffffffff
+#define SHT_MIPS_LIST		0x70000000
+#define SHT_MIPS_CONFLICT	0x70000002
+#define SHT_MIPS_GPTAB		0x70000003
+#define SHT_MIPS_UCODE		0x70000004
+
+/* sh_flags */
+#define SHF_WRITE	0x1
+#define SHF_ALLOC	0x2
+#define SHF_EXECINSTR	0x4
+#define SHF_MASKPROC	0xf0000000
+#define SHF_MIPS_GPREL	0x10000000
+
+/* special section indexes */
+#define SHN_UNDEF	0
+#define SHN_LORESERVE	0xff00
+#define SHN_LOPROC	0xff00
+#define SHN_HIPROC	0xff1f
+#define SHN_ABS		0xfff1
+#define SHN_COMMON	0xfff2
+#define SHN_HIRESERVE	0xffff
+#define SHN_MIPS_ACCOMON	0xff00
+ 
+typedef struct {
+  Elf32_Word	sh_name;
+  Elf32_Word	sh_type;
+  Elf32_Word	sh_flags;
+  Elf32_Addr	sh_addr;
+  Elf32_Off	sh_offset;
+  Elf32_Word	sh_size;
+  Elf32_Word	sh_link;
+  Elf32_Word	sh_info;
+  Elf32_Word	sh_addralign;
+  Elf32_Word	sh_entsize;
+} Elf32_Shdr;
+
+typedef struct elf64_shdr {
+  Elf32_Word sh_name;		/* Section name, index in string tbl (yes Elf32) */
+  Elf32_Word sh_type;		/* Type of section (yes Elf32) */
+  Elf64_Word sh_flags;		/* Miscellaneous section attributes */
+  Elf64_Addr sh_addr;		/* Section virtual addr at execution */
+  Elf64_Off sh_offset;		/* Section file offset */
+  Elf64_Word sh_size;		/* Size of section in bytes */
+  Elf32_Word sh_link;		/* Index of another section (yes Elf32) */
+  Elf32_Word sh_info;		/* Additional section information (yes Elf32) */
+  Elf64_Word sh_addralign;	/* Section alignment */
+  Elf64_Word sh_entsize;	/* Entry size if section holds table */
+} Elf64_Shdr;
+
+#define	EI_MAG0		0		/* e_ident[] indexes */
+#define	EI_MAG1		1
+#define	EI_MAG2		2
+#define	EI_MAG3		3
+#define	EI_CLASS	4
+#define	EI_DATA		5
+#define	EI_VERSION	6
+#define	EI_PAD		7
+
+#define	ELFMAG0		0x7f		/* EI_MAG */
+#define	ELFMAG1		'E'
+#define	ELFMAG2		'L'
+#define	ELFMAG3		'F'
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define	ELFCLASSNONE	0		/* EI_CLASS */
+#define	ELFCLASS32	1
+#define	ELFCLASS64	2
+#define	ELFCLASSNUM	3
+
+#define ELFDATANONE	0		/* e_ident[EI_DATA] */
+#define ELFDATA2LSB	1
+#define ELFDATA2MSB	2
+
+#define EV_NONE		0		/* e_version, EI_VERSION */
+#define EV_CURRENT	1
+#define EV_NUM		2
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS	1
+#define NT_PRFPREG	2
+#define NT_PRPSINFO	3
+#define NT_TASKSTRUCT	4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf32_note {
+  Elf32_Word	n_namesz;	/* Name size */
+  Elf32_Word	n_descsz;	/* Content size */
+  Elf32_Word	n_type;		/* Content type */
+} Elf32_Nhdr;
+
+/* Note header in a PT_NOTE section */
+/*
+ * For now we use the 32 bit version of the structure until we figure
+ * out whether we need anything better.  Note - on the Alpha, "unsigned int"
+ * is only 32 bits.
+ */
+typedef struct elf64_note {
+  Elf32_Word n_namesz;	/* Name size */
+  Elf32_Word n_descsz;	/* Content size */
+  Elf32_Word n_type;	/* Content type */
+} Elf64_Nhdr;
+
+#if ELF_CLASS == ELFCLASS32
+
+extern Elf32_Dyn _DYNAMIC [];
+#define elfhdr		elf32_hdr
+#define elf_phdr	elf32_phdr
+#define elf_note	elf32_note
+
+#else
+
+extern Elf64_Dyn _DYNAMIC [];
+#define elfhdr		elf64_hdr
+#define elf_phdr	elf64_phdr
+#define elf_note	elf64_note
+
+#endif
+
+
+#endif /* _LINUX_ELF_H */

Added: ppcrcd/yaboot/include/linux/ext2_fs.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/linux/ext2_fs.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,624 @@
+/*
+ *  linux/include/linux/ext2_fs.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card at masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT2_FS_H
+#define _LINUX_EXT2_FS_H
+
+#include "types.h"
+
+/*
+ * The second extended filesystem constants/structures
+ */
+
+/*
+ * Define EXT2FS_DEBUG to produce debug messages
+ */
+#undef EXT2FS_DEBUG
+
+/*
+ * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
+ */
+#define EXT2_PREALLOCATE
+#define EXT2_DEFAULT_PREALLOC_BLOCKS	8
+
+/*
+ * The second extended file system version
+ */
+#define EXT2FS_DATE		"95/08/09"
+#define EXT2FS_VERSION		"0.5b"
+
+/*
+ * Debug code
+ */
+#ifdef EXT2FS_DEBUG
+#	define ext2_debug(f, a...)	{ \
+					printk ("EXT2-fs DEBUG (%s, %d): %s:", \
+						__FILE__, __LINE__, __FUNCTION__); \
+				  	printk (f, ## a); \
+					}
+#else
+#	define ext2_debug(f, a...)	/**/
+#endif
+
+/*
+ * Special inodes numbers
+ */
+#define	EXT2_BAD_INO		 1	/* Bad blocks inode */
+#define EXT2_ROOT_INO		 2	/* Root inode */
+#define EXT2_ACL_IDX_INO	 3	/* ACL inode */
+#define EXT2_ACL_DATA_INO	 4	/* ACL inode */
+#define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
+#define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
+
+/* First non-reserved inode for old ext2 filesystems */
+#define EXT2_GOOD_OLD_FIRST_INO	11
+
+/*
+ * The second extended file system magic number
+ */
+#define EXT2_SUPER_MAGIC	0xEF53
+
+/*
+ * Maximal count of links to a file
+ */
+#define EXT2_LINK_MAX		32000
+
+/*
+ * Macro-instructions used to manage several block sizes
+ */
+#define EXT2_MIN_BLOCK_SIZE		1024
+#define	EXT2_MAX_BLOCK_SIZE		4096
+#define EXT2_MIN_BLOCK_LOG_SIZE		  10
+#ifdef __KERNEL__
+# define EXT2_BLOCK_SIZE(s)		((s)->s_blocksize)
+#else
+# define EXT2_BLOCK_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#endif
+#define EXT2_ACLE_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
+#define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+#ifdef __KERNEL__
+# define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
+#else
+# define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
+#endif
+#ifdef __KERNEL__
+#define	EXT2_ADDR_PER_BLOCK_BITS(s)	((s)->u.ext2_sb.s_addr_per_block_bits)
+#define EXT2_INODE_SIZE(s)		((s)->u.ext2_sb.s_inode_size)
+#define EXT2_FIRST_INO(s)		((s)->u.ext2_sb.s_first_ino)
+#else
+#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+				 EXT2_GOOD_OLD_INODE_SIZE : \
+				 (s)->s_inode_size)
+#define EXT2_FIRST_INO(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+				 EXT2_GOOD_OLD_FIRST_INO : \
+				 (s)->s_first_ino)
+#endif
+
+/*
+ * Macro-instructions used to manage fragments
+ */
+#define EXT2_MIN_FRAG_SIZE		1024
+#define	EXT2_MAX_FRAG_SIZE		4096
+#define EXT2_MIN_FRAG_LOG_SIZE		  10
+#ifdef __KERNEL__
+# define EXT2_FRAG_SIZE(s)		((s)->u.ext2_sb.s_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s)	((s)->u.ext2_sb.s_frags_per_block)
+#else
+# define EXT2_FRAG_SIZE(s)		(EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
+#endif
+
+/*
+ * ACL structures
+ */
+struct ext2_acl_header	/* Header of Access Control Lists */
+{
+	__u32	aclh_size;
+	__u32	aclh_file_count;
+	__u32	aclh_acle_count;
+	__u32	aclh_first_acle;
+};
+
+struct ext2_acl_entry	/* Access Control List Entry */
+{
+	__u32	acle_size;
+	__u16	acle_perms;	/* Access permissions */
+	__u16	acle_type;	/* Type of entry */
+	__u16	acle_tag;	/* User or group identity */
+	__u16	acle_pad1;
+	__u32	acle_next;	/* Pointer on next entry for the */
+					/* same inode or on next free entry */
+};
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext2_group_desc
+{
+	__u32	bg_block_bitmap;		/* Blocks bitmap block */
+	__u32	bg_inode_bitmap;		/* Inodes bitmap block */
+	__u32	bg_inode_table;		/* Inodes table block */
+	__u16	bg_free_blocks_count;	/* Free blocks count */
+	__u16	bg_free_inodes_count;	/* Free inodes count */
+	__u16	bg_used_dirs_count;	/* Directories count */
+	__u16	bg_pad;
+	__u32	bg_reserved[3];
+};
+
+/*
+ * Macro-instructions used to manage group descriptors
+ */
+#ifdef __KERNEL__
+# define EXT2_BLOCKS_PER_GROUP(s)	((s)->u.ext2_sb.s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s)		((s)->u.ext2_sb.s_desc_per_block)
+# define EXT2_INODES_PER_GROUP(s)	((s)->u.ext2_sb.s_inodes_per_group)
+# define EXT2_DESC_PER_BLOCK_BITS(s)	((s)->u.ext2_sb.s_desc_per_block_bits)
+#else
+# define EXT2_BLOCKS_PER_GROUP(s)	((s)->s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+# define EXT2_INODES_PER_GROUP(s)	((s)->s_inodes_per_group)
+#endif
+
+/*
+ * Constants relative to the data blocks
+ */
+#define	EXT2_NDIR_BLOCKS		12
+#define	EXT2_IND_BLOCK			EXT2_NDIR_BLOCKS
+#define	EXT2_DIND_BLOCK			(EXT2_IND_BLOCK + 1)
+#define	EXT2_TIND_BLOCK			(EXT2_DIND_BLOCK + 1)
+#define	EXT2_N_BLOCKS			(EXT2_TIND_BLOCK + 1)
+
+/*
+ * Inode flags
+ */
+#define	EXT2_SECRM_FL			0x00000001 /* Secure deletion */
+#define	EXT2_UNRM_FL			0x00000002 /* Undelete */
+#define	EXT2_COMPR_FL			0x00000004 /* Compress file */
+#define EXT2_SYNC_FL			0x00000008 /* Synchronous updates */
+#define EXT2_IMMUTABLE_FL		0x00000010 /* Immutable file */
+#define EXT2_APPEND_FL			0x00000020 /* writes to file may only append */
+#define EXT2_NODUMP_FL			0x00000040 /* do not dump file */
+#define EXT2_NOATIME_FL			0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define EXT2_DIRTY_FL			0x00000100
+#define EXT2_COMPRBLK_FL		0x00000200 /* One or more compressed clusters */
+#define EXT2_NOCOMP_FL			0x00000400 /* Don't compress */
+#define EXT2_ECOMPR_FL			0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */	
+#define EXT2_BTREE_FL			0x00001000 /* btree format dir */
+#define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
+
+#define EXT2_FL_USER_VISIBLE		0x00001FFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE		0x000000FF /* User modifiable flags */
+
+/*
+ * ioctl commands
+ */
+#define	EXT2_IOC_GETFLAGS		_IOR('f', 1, long)
+#define	EXT2_IOC_SETFLAGS		_IOW('f', 2, long)
+#define	EXT2_IOC_GETVERSION		_IOR('v', 1, long)
+#define	EXT2_IOC_SETVERSION		_IOW('v', 2, long)
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext2_inode {
+	__u16	i_mode;		/* File mode */
+	__u16	i_uid;		/* Owner Uid */
+	__u32	i_size;		/* Size in bytes */
+	__u32	i_atime;	/* Access time */
+	__u32	i_ctime;	/* Creation time */
+	__u32	i_mtime;	/* Modification time */
+	__u32	i_dtime;	/* Deletion Time */
+	__u16	i_gid;		/* Group Id */
+	__u16	i_links_count;	/* Links count */
+	__u32	i_blocks;	/* Blocks count */
+	__u32	i_flags;	/* File flags */
+	union {
+		struct {
+			__u32  l_i_reserved1;
+		} linux1;
+		struct {
+			__u32  h_i_translator;
+		} hurd1;
+		struct {
+			__u32  m_i_reserved1;
+		} masix1;
+	} osd1;				/* OS dependent 1 */
+	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+	__u32	i_version;	/* File version (for NFS) */
+	__u32	i_file_acl;	/* File ACL */
+	__u32	i_dir_acl;	/* Directory ACL */
+	__u32	i_faddr;	/* Fragment address */
+	union {
+		struct {
+			__u8	l_i_frag;	/* Fragment number */
+			__u8	l_i_fsize;	/* Fragment size */
+			__u16	i_pad1;
+			__u32	l_i_reserved2[2];
+		} linux2;
+		struct {
+			__u8	h_i_frag;	/* Fragment number */
+			__u8	h_i_fsize;	/* Fragment size */
+			__u16	h_i_mode_high;
+			__u16	h_i_uid_high;
+			__u16	h_i_gid_high;
+			__u32	h_i_author;
+		} hurd2;
+		struct {
+			__u8	m_i_frag;	/* Fragment number */
+			__u8	m_i_fsize;	/* Fragment size */
+			__u16	m_pad1;
+			__u32	m_i_reserved2[2];
+		} masix2;
+	} osd2;				/* OS dependent 2 */
+};
+
+#define i_size_high	i_dir_acl
+
+#if defined(__KERNEL__) || defined(__linux__)
+#define i_reserved1	osd1.linux1.l_i_reserved1
+#define i_frag		osd2.linux2.l_i_frag
+#define i_fsize		osd2.linux2.l_i_fsize
+#define i_reserved2	osd2.linux2.l_i_reserved2
+#endif
+
+#ifdef	__hurd__
+#define i_translator	osd1.hurd1.h_i_translator
+#define i_frag		osd2.hurd2.h_i_frag;
+#define i_fsize		osd2.hurd2.h_i_fsize;
+#define i_uid_high	osd2.hurd2.h_i_uid_high
+#define i_gid_high	osd2.hurd2.h_i_gid_high
+#define i_author	osd2.hurd2.h_i_author
+#endif
+
+#ifdef	__masix__
+#define i_reserved1	osd1.masix1.m_i_reserved1
+#define i_frag		osd2.masix2.m_i_frag
+#define i_fsize		osd2.masix2.m_i_fsize
+#define i_reserved2	osd2.masix2.m_i_reserved2
+#endif
+
+/*
+ * File system states
+ */
+#define	EXT2_VALID_FS			0x0001	/* Unmounted cleanly */
+#define	EXT2_ERROR_FS			0x0002	/* Errors detected */
+
+/*
+ * Mount flags
+ */
+#define EXT2_MOUNT_CHECK_NORMAL		0x0001	/* Do some more checks */
+#define EXT2_MOUNT_CHECK_STRICT		0x0002	/* Do again more checks */
+#define EXT2_MOUNT_CHECK		(EXT2_MOUNT_CHECK_NORMAL | \
+					 EXT2_MOUNT_CHECK_STRICT)
+#define EXT2_MOUNT_GRPID		0x0004	/* Create files with directory's group */
+#define EXT2_MOUNT_DEBUG		0x0008	/* Some debugging messages */
+#define EXT2_MOUNT_ERRORS_CONT		0x0010	/* Continue on errors */
+#define EXT2_MOUNT_ERRORS_RO		0x0020	/* Remount fs ro on errors */
+#define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
+#define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
+
+#define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
+#define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
+#define test_opt(sb, opt)		((sb)->u.ext2_sb.s_mount_opt & \
+					 EXT2_MOUNT_##opt)
+/*
+ * Maximal mount counts between two filesystem checks
+ */
+#define EXT2_DFL_MAX_MNT_COUNT		20	/* Allow 20 mounts */
+#define EXT2_DFL_CHECKINTERVAL		0	/* Don't use interval check */
+
+/*
+ * Behaviour when detecting errors
+ */
+#define EXT2_ERRORS_CONTINUE		1	/* Continue execution */
+#define EXT2_ERRORS_RO			2	/* Remount fs read-only */
+#define EXT2_ERRORS_PANIC		3	/* Panic */
+#define EXT2_ERRORS_DEFAULT		EXT2_ERRORS_CONTINUE
+
+/*
+ * Structure of the super block
+ */
+struct ext2_super_block {
+	__u32	s_inodes_count;		/* Inodes count */
+	__u32	s_blocks_count;		/* Blocks count */
+	__u32	s_r_blocks_count;	/* Reserved blocks count */
+	__u32	s_free_blocks_count;	/* Free blocks count */
+	__u32	s_free_inodes_count;	/* Free inodes count */
+	__u32	s_first_data_block;	/* First Data Block */
+	__u32	s_log_block_size;	/* Block size */
+	__s32	s_log_frag_size;	/* Fragment size */
+	__u32	s_blocks_per_group;	/* # Blocks per group */
+	__u32	s_frags_per_group;	/* # Fragments per group */
+	__u32	s_inodes_per_group;	/* # Inodes per group */
+	__u32	s_mtime;		/* Mount time */
+	__u32	s_wtime;		/* Write time */
+	__u16	s_mnt_count;		/* Mount count */
+	__s16	s_max_mnt_count;	/* Maximal mount count */
+	__u16	s_magic;		/* Magic signature */
+	__u16	s_state;		/* File system state */
+	__u16	s_errors;		/* Behaviour when detecting errors */
+	__u16	s_minor_rev_level; 	/* minor revision level */
+	__u32	s_lastcheck;		/* time of last check */
+	__u32	s_checkinterval;	/* max. time between checks */
+	__u32	s_creator_os;		/* OS */
+	__u32	s_rev_level;		/* Revision level */
+	__u16	s_def_resuid;		/* Default uid for reserved blocks */
+	__u16	s_def_resgid;		/* Default gid for reserved blocks */
+	/*
+	 * These fields are for EXT2_DYNAMIC_REV superblocks only.
+	 *
+	 * Note: the difference between the compatible feature set and
+	 * the incompatible feature set is that if there is a bit set
+	 * in the incompatible feature set that the kernel doesn't
+	 * know about, it should refuse to mount the filesystem.
+	 * 
+	 * e2fsck's requirements are more strict; if it doesn't know
+	 * about a feature in either the compatible or incompatible
+	 * feature set, it must abort and not try to meddle with
+	 * things it doesn't understand...
+	 */
+	__u32	s_first_ino; 		/* First non-reserved inode */
+	__u16   s_inode_size; 		/* size of inode structure */
+	__u16	s_block_group_nr; 	/* block group # of this superblock */
+	__u32	s_feature_compat; 	/* compatible feature set */
+	__u32	s_feature_incompat; 	/* incompatible feature set */
+	__u32	s_feature_ro_compat; 	/* readonly-compatible feature set */
+	__u8	s_uuid[16];		/* 128-bit uuid for volume */
+	char	s_volume_name[16]; 	/* volume name */
+	char	s_last_mounted[64]; 	/* directory where last mounted */
+	__u32	s_algorithm_usage_bitmap; /* For compression */
+	/*
+	 * Performance hints.  Directory preallocation should only
+	 * happen if the EXT2_COMPAT_PREALLOC flag is on.
+	 */
+	__u8	s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
+	__u8	s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
+	__u16	s_padding1;
+	__u32	s_reserved[204];	/* Padding to the end of the block */
+};
+
+#ifdef __KERNEL__
+#define EXT2_SB(sb)	(&((sb)->u.ext2_sb))
+#else
+/* Assume that user mode programs are passing in an ext2fs superblock, not
+ * a kernel struct super_block.  This will allow us to call the feature-test
+ * macros from user land. */
+#define EXT2_SB(sb)	(sb)
+#endif
+
+/*
+ * Codes for operating systems
+ */
+#define EXT2_OS_LINUX		0
+#define EXT2_OS_HURD		1
+#define EXT2_OS_MASIX		2
+#define EXT2_OS_FREEBSD		3
+#define EXT2_OS_LITES		4
+
+/*
+ * Revision levels
+ */
+#define EXT2_GOOD_OLD_REV	0	/* The good old (original) format */
+#define EXT2_DYNAMIC_REV	1 	/* V2 format w/ dynamic inode sizes */
+
+#define EXT2_CURRENT_REV	EXT2_GOOD_OLD_REV
+#define EXT2_MAX_SUPP_REV	EXT2_DYNAMIC_REV
+
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+
+/*
+ * Feature set definitions
+ */
+
+#define EXT2_HAS_COMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_compat & (mask) )
+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)			\
+	( EXT2_SB(sb)->s_feature_incompat & (mask) )
+
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC	0x0001
+
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR	0x0004
+
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION	0x0001
+#define EXT2_FEATURE_INCOMPAT_FILETYPE		0x0002
+
+#define EXT2_FEATURE_COMPAT_SUPP	0
+#define EXT2_FEATURE_INCOMPAT_SUPP	EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+					 EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+
+/*
+ * Default values for user and/or group using reserved blocks
+ */
+#define	EXT2_DEF_RESUID		0
+#define	EXT2_DEF_RESGID		0
+
+/*
+ * Structure of a directory entry
+ */
+#define EXT2_NAME_LEN 255
+
+struct ext2_dir_entry {
+	__u32	inode;			/* Inode number */
+	__u16	rec_len;		/* Directory entry length */
+	__u16	name_len;		/* Name length */
+	char	name[EXT2_NAME_LEN];	/* File name */
+};
+
+/*
+ * The new version of the directory entry.  Since EXT2 structures are
+ * stored in intel byte order, and the name_len field could never be
+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
+ * file_type field.
+ */
+struct ext2_dir_entry_2 {
+	__u32	inode;			/* Inode number */
+	__u16	rec_len;		/* Directory entry length */
+	__u8	name_len;		/* Name length */
+	__u8	file_type;
+	char	name[EXT2_NAME_LEN];	/* File name */
+};
+
+/*
+ * Ext2 directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+#define EXT2_FT_UNKNOWN		0
+#define EXT2_FT_REG_FILE	1
+#define EXT2_FT_DIR		2
+#define EXT2_FT_CHRDEV		3
+#define EXT2_FT_BLKDEV 		4
+#define EXT2_FT_FIFO		5
+#define EXT2_FT_SOCK		6
+#define EXT2_FT_SYMLINK		7
+
+#define EXT2_FT_MAX		8
+
+/*
+ * EXT2_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define EXT2_DIR_PAD		 	4
+#define EXT2_DIR_ROUND 			(EXT2_DIR_PAD - 1)
+#define EXT2_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT2_DIR_ROUND) & \
+					 ~EXT2_DIR_ROUND)
+
+#ifdef __KERNEL__
+
+/* Filesize hard limits for 64-bit file offsets */
+extern long long ext2_max_sizes[];
+
+/*
+ * Function prototypes
+ */
+
+/*
+ * Ok, these declarations are also in <linux/kernel.h> but none of the
+ * ext2 source programs needs to include it so they are duplicated here.
+ */
+# define NORET_TYPE    /**/
+# define ATTRIB_NORET  __attribute__((noreturn))
+# define NORET_AND     noreturn,
+
+/* acl.c */
+extern int ext2_permission (struct inode *, int);
+
+/* balloc.c */
+extern int ext2_group_sparse(int group);
+extern int ext2_new_block (const struct inode *, unsigned long,
+			   __u32 *, __u32 *, int *);
+extern void ext2_free_blocks (const struct inode *, unsigned long,
+			      unsigned long);
+extern unsigned long ext2_count_free_blocks (struct super_block *);
+extern void ext2_check_blocks_bitmap (struct super_block *);
+extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
+						    unsigned int block_group,
+						    struct buffer_head ** bh);
+
+/* bitmap.c */
+extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
+
+/* dir.c */
+extern int ext2_check_dir_entry (const char *, struct inode *,
+				 struct ext2_dir_entry_2 *, struct buffer_head *,
+				 unsigned long);
+
+/* file.c */
+extern int ext2_read (struct inode *, struct file *, char *, int);
+extern int ext2_write (struct inode *, struct file *, char *, int);
+
+/* fsync.c */
+extern int ext2_sync_file (struct file *, struct dentry *);
+
+/* ialloc.c */
+extern struct inode * ext2_new_inode (const struct inode *, int, int *);
+extern void ext2_free_inode (struct inode *);
+extern unsigned long ext2_count_free_inodes (struct super_block *);
+extern void ext2_check_inodes_bitmap (struct super_block *);
+
+/* inode.c */
+extern int ext2_bmap (struct inode *, int);
+
+extern struct buffer_head * ext2_getblk (struct inode *, long, int, int *);
+extern struct buffer_head * ext2_bread (struct inode *, int, int, int *);
+
+extern int ext2_getcluster (struct inode * inode, long block);
+extern void ext2_read_inode (struct inode *);
+extern void ext2_write_inode (struct inode *);
+extern void ext2_put_inode (struct inode *);
+extern void ext2_delete_inode (struct inode *);
+extern int ext2_sync_inode (struct inode *);
+extern int ext2_notify_change(struct dentry *, struct iattr *);
+extern void ext2_discard_prealloc (struct inode *);
+
+/* ioctl.c */
+extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
+		       unsigned long);
+
+/* namei.c */
+extern void ext2_release (struct inode *, struct file *);
+extern struct dentry *ext2_lookup (struct inode *, struct dentry *);
+extern int ext2_create (struct inode *,struct dentry *,int);
+extern int ext2_mkdir (struct inode *,struct dentry *,int);
+extern int ext2_rmdir (struct inode *,struct dentry *);
+extern int ext2_unlink (struct inode *,struct dentry *);
+extern int ext2_symlink (struct inode *,struct dentry *,const char *);
+extern int ext2_link (struct dentry *, struct inode *, struct dentry *);
+extern int ext2_mknod (struct inode *, struct dentry *, int, int);
+extern int ext2_rename (struct inode *, struct dentry *,
+			struct inode *, struct dentry *);
+
+/* super.c */
+extern void ext2_error (struct super_block *, const char *, const char *, ...)
+	__attribute__ ((format (printf, 3, 4)));
+extern NORET_TYPE void ext2_panic (struct super_block *, const char *,
+				   const char *, ...)
+	__attribute__ ((NORET_AND format (printf, 3, 4)));
+extern void ext2_warning (struct super_block *, const char *, const char *, ...)
+	__attribute__ ((format (printf, 3, 4)));
+extern void ext2_put_super (struct super_block *);
+extern void ext2_write_super (struct super_block *);
+extern int ext2_remount (struct super_block *, int *, char *);
+extern struct super_block * ext2_read_super (struct super_block *,void *,int);
+extern int init_ext2_fs(void);
+extern int ext2_statfs (struct super_block *, struct statfs *, int);
+
+/* truncate.c */
+extern void ext2_truncate (struct inode *);
+
+/*
+ * Inodes and files operations
+ */
+
+/* dir.c */
+extern struct inode_operations ext2_dir_inode_operations;
+
+/* file.c */
+extern struct inode_operations ext2_file_inode_operations;
+
+/* symlink.c */
+extern struct inode_operations ext2_symlink_inode_operations;
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _LINUX_EXT2_FS_H */

Added: ppcrcd/yaboot/include/linux/iso_fs.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/linux/iso_fs.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,177 @@
+
+#ifndef _ISOFS_FS_H
+#define _ISOFS_FS_H
+
+#include <linux/types.h>
+/*
+ * The isofs filesystem constants/structures
+ */
+
+/* This part borrowed from the bsd386 isofs */
+#define ISODCL(from, to) (to - from + 1)
+
+struct iso_volume_descriptor {
+	char type[ISODCL(1,1)]; /* 711 */
+	char id[ISODCL(2,6)];
+	char version[ISODCL(7,7)];
+	char data[ISODCL(8,2048)];
+};
+
+/* volume descriptor types */
+#define ISO_VD_PRIMARY 1
+#define ISO_VD_SUPPLEMENTARY 2
+#define ISO_VD_END 255
+
+#define ISO_STANDARD_ID "CD001"
+
+struct iso_primary_descriptor {
+	char type			[ISODCL (  1,   1)]; /* 711 */
+	char id				[ISODCL (  2,   6)];
+	char version			[ISODCL (  7,   7)]; /* 711 */
+	char unused1			[ISODCL (  8,   8)];
+	char system_id			[ISODCL (  9,  40)]; /* achars */
+	char volume_id			[ISODCL ( 41,  72)]; /* dchars */
+	char unused2			[ISODCL ( 73,  80)];
+	char volume_space_size		[ISODCL ( 81,  88)]; /* 733 */
+	char unused3			[ISODCL ( 89, 120)];
+	char volume_set_size		[ISODCL (121, 124)]; /* 723 */
+	char volume_sequence_number	[ISODCL (125, 128)]; /* 723 */
+	char logical_block_size		[ISODCL (129, 132)]; /* 723 */
+	char path_table_size		[ISODCL (133, 140)]; /* 733 */
+	char type_l_path_table		[ISODCL (141, 144)]; /* 731 */
+	char opt_type_l_path_table	[ISODCL (145, 148)]; /* 731 */
+	char type_m_path_table		[ISODCL (149, 152)]; /* 732 */
+	char opt_type_m_path_table	[ISODCL (153, 156)]; /* 732 */
+	char root_directory_record	[ISODCL (157, 190)]; /* 9.1 */
+	char volume_set_id		[ISODCL (191, 318)]; /* dchars */
+	char publisher_id		[ISODCL (319, 446)]; /* achars */
+	char preparer_id		[ISODCL (447, 574)]; /* achars */
+	char application_id		[ISODCL (575, 702)]; /* achars */
+	char copyright_file_id		[ISODCL (703, 739)]; /* 7.5 dchars */
+	char abstract_file_id		[ISODCL (740, 776)]; /* 7.5 dchars */
+	char bibliographic_file_id	[ISODCL (777, 813)]; /* 7.5 dchars */
+	char creation_date		[ISODCL (814, 830)]; /* 8.4.26.1 */
+	char modification_date		[ISODCL (831, 847)]; /* 8.4.26.1 */
+	char expiration_date		[ISODCL (848, 864)]; /* 8.4.26.1 */
+	char effective_date		[ISODCL (865, 881)]; /* 8.4.26.1 */
+	char file_structure_version	[ISODCL (882, 882)]; /* 711 */
+	char unused4			[ISODCL (883, 883)];
+	char application_data		[ISODCL (884, 1395)];
+	char unused5			[ISODCL (1396, 2048)];
+};
+
+/* Almost the same as the primary descriptor but two fields are specified */
+struct iso_supplementary_descriptor {
+	char type			[ISODCL (  1,   1)]; /* 711 */
+	char id				[ISODCL (  2,   6)];
+	char version			[ISODCL (  7,   7)]; /* 711 */
+	char flags			[ISODCL (  8,   8)]; /* 853 */
+	char system_id			[ISODCL (  9,  40)]; /* achars */
+	char volume_id			[ISODCL ( 41,  72)]; /* dchars */
+	char unused2			[ISODCL ( 73,  80)];
+	char volume_space_size		[ISODCL ( 81,  88)]; /* 733 */
+	char escape			[ISODCL ( 89, 120)]; /* 856 */
+	char volume_set_size		[ISODCL (121, 124)]; /* 723 */
+	char volume_sequence_number	[ISODCL (125, 128)]; /* 723 */
+	char logical_block_size		[ISODCL (129, 132)]; /* 723 */
+	char path_table_size		[ISODCL (133, 140)]; /* 733 */
+	char type_l_path_table		[ISODCL (141, 144)]; /* 731 */
+	char opt_type_l_path_table	[ISODCL (145, 148)]; /* 731 */
+	char type_m_path_table		[ISODCL (149, 152)]; /* 732 */
+	char opt_type_m_path_table	[ISODCL (153, 156)]; /* 732 */
+	char root_directory_record	[ISODCL (157, 190)]; /* 9.1 */
+	char volume_set_id		[ISODCL (191, 318)]; /* dchars */
+	char publisher_id		[ISODCL (319, 446)]; /* achars */
+	char preparer_id		[ISODCL (447, 574)]; /* achars */
+	char application_id		[ISODCL (575, 702)]; /* achars */
+	char copyright_file_id		[ISODCL (703, 739)]; /* 7.5 dchars */
+	char abstract_file_id		[ISODCL (740, 776)]; /* 7.5 dchars */
+	char bibliographic_file_id	[ISODCL (777, 813)]; /* 7.5 dchars */
+	char creation_date		[ISODCL (814, 830)]; /* 8.4.26.1 */
+	char modification_date		[ISODCL (831, 847)]; /* 8.4.26.1 */
+	char expiration_date		[ISODCL (848, 864)]; /* 8.4.26.1 */
+	char effective_date		[ISODCL (865, 881)]; /* 8.4.26.1 */
+	char file_structure_version	[ISODCL (882, 882)]; /* 711 */
+	char unused4			[ISODCL (883, 883)];
+	char application_data		[ISODCL (884, 1395)];
+	char unused5			[ISODCL (1396, 2048)];
+};
+
+
+#define HS_STANDARD_ID "CDROM"
+
+struct  hs_volume_descriptor {
+	char foo			[ISODCL (  1,   8)]; /* 733 */
+	char type			[ISODCL (  9,   9)]; /* 711 */
+	char id				[ISODCL ( 10,  14)];
+	char version			[ISODCL ( 15,  15)]; /* 711 */
+	char data[ISODCL(16,2048)];
+};
+
+
+struct hs_primary_descriptor {
+	char foo			[ISODCL (  1,   8)]; /* 733 */
+	char type			[ISODCL (  9,   9)]; /* 711 */
+	char id				[ISODCL ( 10,  14)];
+	char version			[ISODCL ( 15,  15)]; /* 711 */
+	char unused1			[ISODCL ( 16,  16)]; /* 711 */
+	char system_id			[ISODCL ( 17,  48)]; /* achars */
+	char volume_id			[ISODCL ( 49,  80)]; /* dchars */
+	char unused2			[ISODCL ( 81,  88)]; /* 733 */
+	char volume_space_size		[ISODCL ( 89,  96)]; /* 733 */
+	char unused3			[ISODCL ( 97, 128)]; /* 733 */
+	char volume_set_size		[ISODCL (129, 132)]; /* 723 */
+	char volume_sequence_number	[ISODCL (133, 136)]; /* 723 */
+	char logical_block_size		[ISODCL (137, 140)]; /* 723 */
+	char path_table_size		[ISODCL (141, 148)]; /* 733 */
+	char type_l_path_table		[ISODCL (149, 152)]; /* 731 */
+	char unused4			[ISODCL (153, 180)]; /* 733 */
+	char root_directory_record	[ISODCL (181, 214)]; /* 9.1 */
+};
+
+/* We use this to help us look up the parent inode numbers. */
+
+struct iso_path_table{
+	unsigned char  name_len[2];	/* 721 */
+	char extent[4];		/* 731 */
+	char  parent[2];	/* 721 */
+	char name[0];
+};
+
+/* high sierra is identical to iso, except that the date is only 6 bytes, and
+   there is an extra reserved byte after the flags */
+
+struct iso_directory_record {
+	char length			[ISODCL (1, 1)]; /* 711 */
+	char ext_attr_length		[ISODCL (2, 2)]; /* 711 */
+	char extent			[ISODCL (3, 10)]; /* 733 */
+	char size			[ISODCL (11, 18)]; /* 733 */
+	char date			[ISODCL (19, 25)]; /* 7 by 711 */
+	char flags			[ISODCL (26, 26)];
+	char file_unit_size		[ISODCL (27, 27)]; /* 711 */
+	char interleave			[ISODCL (28, 28)]; /* 711 */
+	char volume_sequence_number	[ISODCL (29, 32)]; /* 723 */
+	unsigned char name_len		[ISODCL (33, 33)]; /* 711 */
+	char name			[0];
+};
+
+#define ISOFS_BLOCK_BITS 11
+#define ISOFS_BLOCK_SIZE 2048
+
+#define ISOFS_BUFFER_SIZE(INODE) ((INODE)->i_sb->s_blocksize)
+#define ISOFS_BUFFER_BITS(INODE) ((INODE)->i_sb->s_blocksize_bits)
+#define ISOFS_ZONE_BITS(INODE)   ((INODE)->i_sb->u.isofs_sb.s_log_zone_size)
+
+#define ISOFS_SUPER_MAGIC 0x9660
+
+extern int isonum_711(char *);
+extern int isonum_712(char *);
+extern int isonum_721(char *);
+extern int isonum_722(char *);
+extern int isonum_723(char *);
+extern int isonum_731(char *);
+extern int isonum_732(char *);
+extern int isonum_733(char *);
+
+
+#endif

Added: ppcrcd/yaboot/include/linux/stat.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/linux/stat.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,45 @@
+#ifndef _LINUX_STAT_H
+#define _LINUX_STAT_H
+
+#define S_IFMT  00170000
+#define S_IFSOCK 0140000
+#define S_IFLNK	 0120000
+#define S_IFREG  0100000
+#define S_IFBLK  0060000
+#define S_IFDIR  0040000
+#define S_IFCHR  0020000
+#define S_IFIFO  0010000
+#define S_ISUID  0004000
+#define S_ISGID  0002000
+#define S_ISVTX  0001000
+
+#define S_ISLNK(m)	(((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m)	(((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m)	(((m) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m)	(((m) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m)	(((m) & S_IFMT) == S_IFBLK)
+#define S_ISFIFO(m)	(((m) & S_IFMT) == S_IFIFO)
+#define S_ISSOCK(m)	(((m) & S_IFMT) == S_IFSOCK)
+
+#define S_IRWXU 00700
+#define S_IRUSR 00400
+#define S_IWUSR 00200
+#define S_IXUSR 00100
+
+#define S_IRWXG 00070
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+
+#define S_IRWXO 00007
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+
+#define S_IRWXUGO	(S_IRWXU|S_IRWXG|S_IRWXO)
+#define S_IALLUGO	(S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
+#define S_IRUGO		(S_IRUSR|S_IRGRP|S_IROTH)
+#define S_IWUGO		(S_IWUSR|S_IWGRP|S_IWOTH)
+#define S_IXUGO		(S_IXUSR|S_IXGRP|S_IXOTH)
+
+#endif

Added: ppcrcd/yaboot/include/linux/types.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/linux/types.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1 @@
+#include "../types.h"
\ No newline at end of file

Added: ppcrcd/yaboot/include/mac-part.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/mac-part.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,58 @@
+/*
+ *  mac-part.h - Structure of Apple partition tables
+ *
+ *  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.
+ */
+
+#define MAC_PARTITION_MAGIC	0x504d
+
+/* type field value for A/UX or other Unix partitions */
+#define APPLE_AUX_TYPE	"Apple_UNIX_SVR2"
+
+struct mac_partition {
+    __u16	signature;	/* expected to be MAC_PARTITION_MAGIC */
+    __u16	res1;
+    __u32	map_count;	/* # blocks in partition map */
+    __u32	start_block;	/* absolute starting block # of partition */
+    __u32	block_count;	/* number of blocks in partition */
+    char	name[32];	/* partition name */
+    char	type[32];	/* string type description */
+    __u32	data_start;	/* rel block # of first data block */
+    __u32	data_count;	/* number of data blocks */
+    __u32	status;		/* partition status */
+    __u32	boot_start;	/* logical start block no. of bootstrap */
+    __u32	boot_size;	/* no. of bytes in bootstrap */
+    __u32	boot_load;	/* bootstrap load address in memory */
+    __u32	boot_load2;	/* reserved for extension of boot_load */
+    __u32	boot_entry;	/* entry point address for bootstrap */
+    __u32	boot_entry2;	/* reserved for extension of boot_entry */
+    __u32	boot_cksum;
+    char	processor[16];	/* name of processor that boot is for */
+};
+
+/* Bit in status field */
+#define STATUS_BOOTABLE	8	/* partition is bootable */
+
+#define MAC_DRIVER_MAGIC	0x4552
+
+/* Driver descriptor structure, in block 0 */
+struct mac_driver_desc {
+    __u16	signature;	/* expected to be MAC_DRIVER_MAGIC */
+    __u16	block_size;
+    __u32	block_count;
+    /* ... more stuff */
+};

Added: ppcrcd/yaboot/include/md5.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/md5.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,30 @@
+/* md5.h - an implementation of the MD5 algorithm and MD5 crypt */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000  Free Software Foundation, Inc.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* If CHECK is true, check a password for correctness. Returns 0
+   if password was correct, and a value != 0 for error, similarly
+   to strcmp.
+   If CHECK is false, crypt KEY and save the result in CRYPTED.
+   CRYPTED must have a salt.  */
+extern int md5_password (const char *key, char *crypted, int check);
+
+/* For convenience.  */
+#define check_md5_password(key,crypted)	md5_password((key), (crypted), 1)
+#define make_md5_password(key,crypted)	md5_password((key), (crypted), 0)

Added: ppcrcd/yaboot/include/partition.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/partition.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,49 @@
+/*
+ *  partition.h - partition table support
+ *
+ *  Copyright (C) 2001 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.
+ */
+
+#ifndef PARTITION_H
+#define PARTITION_H
+
+struct partition_t;
+
+#include "types.h"
+#include "stddef.h"
+#include "prom.h"
+
+#define MAX_PARTITIONS	32
+#define MAX_PART_NAME	32
+
+struct partition_t {
+	struct partition_t*	next;
+	int			part_number;
+	char			part_type[MAX_PART_NAME];
+        char                    part_name[MAX_PART_NAME];
+	unsigned long  		part_start; /* In blocks */
+	unsigned long  		part_size; /* In blocks */
+	unsigned short		blocksize;
+};
+
+extern struct partition_t*	partitions_lookup(const char *device);
+extern char                     *get_part_type(char *device, int partition);
+extern void			partitions_free(struct partition_t* list);
+
+#endif

Added: ppcrcd/yaboot/include/prom.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/prom.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,116 @@
+/*
+ *  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 "stdarg.h"
+
+typedef void *prom_handle;
+typedef void *ihandle;
+typedef void *phandle;
+
+#define PROM_INVALID_HANDLE	((prom_handle)-1UL)
+
+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 (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_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);
+
+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, ...);
+
+#endif

Added: ppcrcd/yaboot/include/reiserfs/reiserfs.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/reiserfs/reiserfs.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,405 @@
+#ifndef _REISERFS_H_
+#define _REISERFS_H_
+#include "byteorder.h"
+#include "types.h"
+
+/* ReiserFS Super Block */
+/* include/linux/reiserfs_fs_sb.h */
+#define REISERFS_MAX_SUPPORTED_VERSION  2
+#define REISERFS_SUPER_MAGIC_STRING     "ReIsErFs"
+#define REISER2FS_SUPER_MAGIC_STRING    "ReIsEr2Fs"
+#define REISERFS_MAX_TREE_HEIGHT        7
+
+struct reiserfs_super_block
+{
+    __u32 s_block_count;
+    __u32 s_free_blocks;            /* free blocks count */
+    __u32 s_root_block;             /* root block number */
+    __u32 s_journal_block;          /* journal block number */
+    __u32 s_journal_dev;            /* journal device number */
+    __u32 s_orig_journal_size;      /* size of the journal */
+    __u32 s_journal_trans_max;      /* max number of blocks in
+                                       a transaction.  */
+    __u32 s_journal_block_count;    /* total size of the journal.
+                                       can change over time  */
+    __u32 s_journal_max_batch;      /* max number of blocks to
+                                       batch into a trans */
+    __u32 s_journal_max_commit_age; /* in seconds, how old can an
+                                       async commit be */
+    __u32 s_journal_max_trans_age;  /* in seconds, how old can a
+                                       transaction be */
+    __u16 s_blocksize;              /* block size */
+    __u16 s_oid_maxsize;            /* max size of object id array, */
+    __u16 s_oid_cursize;            /* current size of obj id array */
+    __u16 s_state;                  /* valid or error */
+    char s_magic[12];               /* reiserfs magic string indicates
+                                       that file system is reiserfs */
+    __u32 s_hash_function_code;	    /* indicate, what hash function is
+                                       being use to sort names in a
+                                       directory */
+    __u16 s_tree_height;            /* height of disk tree */
+    __u16 s_bmap_nr;                /* amount of bitmap blocks needed
+                                       to address each block of file
+                                       system */
+    __u16 s_version;
+    __u16 s_marked_in_use;
+    __u16 s_inode_generation;
+    char s_unused[124];             /* zero filled by mkreiserfs */
+    char padding_to_quad[ 2 ];      /* aligned to __u32 */
+} __attribute__ ((__packed__));
+#define SB_SIZE         (sizeof (struct reiserfs_super_block) )
+
+/* ReiserFS Journal */
+/* include/linux/reiserfs_fs.h */
+/* must be correct to keep the desc and commit structs at 4k */
+#define JOURNAL_TRANS_HALF 1018
+
+/* first block written in a commit */
+struct reiserfs_journal_desc {
+    __u32 j_trans_id;                      /* id of commit */
+    __u32 j_len;                           /* length of commit. len +1 is the
+                                            commit block */
+    __u32 j_mount_id;                      /* mount id of this trans*/
+    __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for each block */
+  char j_magic[12];
+};
+
+/* last block written in a commit */
+struct reiserfs_journal_commit {
+    __u32 j_trans_id;                      /* must match j_trans_id from the
+                                              desc block */
+    __u32 j_len;                           /* ditto */
+    __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for each block */
+    char j_digest[16];                     /* md5 sum of all the blocks
+                                              involved, including desc and
+                                              commit. not used, kill it */
+};
+
+/*
+** This header block gets written whenever a transaction is considered
+** fully flushed, and is more recent than the last fully flushed
+** transaction.  fully flushed means all the log blocks and all the real
+** blocks are on disk, and this transaction does not need to be replayed.
+*/
+struct reiserfs_journal_header {
+    __u32 j_last_flush_trans_id;    /* id of last fully flushed transaction */
+    __u32 j_first_unflushed_offset; /* offset in the log of where to start
+                                       replay after a crash */
+    __u32 j_mount_id;
+};
+
+/* Magic to find journal descriptors */
+#define JOURNAL_DESC_MAGIC "ReIsErLB"
+
+/* ReiserFS Tree structures/accessors */
+/* Item version determines which offset_v# struct to use */
+#define ITEM_VERSION_1 0
+#define ITEM_VERSION_2 1
+#define IH_KEY_OFFSET(ih) ((INFO->version < 2 \
+                           || ih_version(ih) == ITEM_VERSION_1) \
+                           ? le32_to_cpu ((ih)->ih_key.u.k_offset_v1.k_offset) \
+                           : offset_v2_k_offset(&(ih)->ih_key.u.k_offset_v2))
+ 
+#define IH_KEY_ISTYPE(ih, type) ((INFO->version < 2 \
+                || ih_version(ih) == ITEM_VERSION_1) \
+                ? le32_to_cpu((ih)->ih_key.u.k_offset_v1.k_uniqueness) == V1_##type \
+                : offset_v2_k_type(&(ih)->ih_key.u.k_offset_v2) == V2_##type)
+
+//
+// directories use this key as well as old files
+//
+struct offset_v1 {
+    __u32 k_offset;
+    __u32 k_uniqueness;
+} __attribute__ ((__packed__));
+
+struct offset_v2 {
+#ifdef __LITTLE_ENDIAN
+    /* little endian version */
+    __u64 k_offset:60;
+    __u64 k_type: 4;
+#else
+    /* big endian version */
+    __u64 k_type: 4;
+    __u64 k_offset:60;
+#endif
+} __attribute__ ((__packed__));
+
+#ifndef __LITTLE_ENDIAN
+inline __u16 offset_v2_k_type( struct offset_v2 *v2 );
+inline loff_t offset_v2_k_offset( struct offset_v2 *v2 );
+#else
+# define offset_v2_k_type(v2)           ((v2)->k_type)
+# define offset_v2_k_offset(v2)         ((v2)->k_offset)
+#endif
+
+/* Key of an item determines its location in the S+tree, and
+   is composed of 4 components */
+struct key {
+    __u32 k_dir_id;    /* packing locality: by default parent
+			  directory object id */
+    __u32 k_objectid;  /* object identifier */
+    union {
+	struct offset_v1 k_offset_v1;
+	struct offset_v2 k_offset_v2;
+    } __attribute__ ((__packed__)) u;
+} __attribute__ ((__packed__));
+#define KEY_SIZE        (sizeof (struct key))
+
+//
+// there are 5 item types currently
+//
+#define TYPE_STAT_DATA 0
+#define TYPE_INDIRECT 1
+#define TYPE_DIRECT 2
+#define TYPE_DIRENTRY 3
+#define TYPE_ANY 15 // FIXME: comment is required
+ 
+//
+// in old version uniqueness field shows key type
+//
+#define V1_SD_UNIQUENESS 0
+#define V1_INDIRECT_UNIQUENESS 0xfffffffe
+#define V1_DIRECT_UNIQUENESS 0xffffffff
+#define V1_DIRENTRY_UNIQUENESS 500
+#define V1_ANY_UNIQUENESS 555 // FIXME: comment is required
+inline int uniqueness2type (__u32 uniqueness);
+
+struct item_head
+{
+  struct key ih_key; 	              /* Everything in the tree is found by
+                                         searching for its key.*/
+
+  union {
+    __u16 ih_free_space_reserved;     /* The free space in the last unformatted
+                                         node of an indirect item if this is an
+                                         indirect item.  This equals 0xFFFF
+                                         iff this is a direct item or stat
+                                         data item. Note that the key, not
+                                         this field, is used to determine
+                                         the item type, and thus which field
+                                         this union contains. */
+    __u16 ih_entry_count;             /* Iff this is a directory item, this
+                                         field equals the number of directory
+				         entries in the directory item. */
+  } __attribute__ ((__packed__)) u;
+  __u16 ih_item_len;                  /* total size of the item body */
+  __u16 ih_item_location;             /* Offset to the item within the block */
+  __u16 ih_version;	              /* ITEM_VERSION_[01] of key type */
+} __attribute__ ((__packed__));
+#define IH_SIZE (sizeof(struct item_head))
+
+#define ih_version(ih)               le16_to_cpu((ih)->ih_version)
+#define ih_entry_count(ih)           le16_to_cpu((ih)->u.ih_entry_count)
+#define ih_location(ih)              le16_to_cpu((ih)->ih_item_location)
+#define ih_item_len(ih)              le16_to_cpu((ih)->ih_item_len)
+
+/* Header of a disk block.  More precisely, header of a formatted leaf
+   or internal node, and not the header of an unformatted node. */
+struct block_head {       
+    __u16 blk_level;                  /* Level of a block in the tree */
+    __u16 blk_nr_item;                /* Number of keys/items in a block */
+    __u16 blk_free_space;             /* Block free space in bytes */
+    __u16 blk_reserved;
+    struct key blk_right_delim_key;   /* kept only for compatibility */
+};
+#define BLKH_SIZE                     (sizeof(struct block_head))
+
+#define blkh_level(p_blkh)            (le16_to_cpu((p_blkh)->blk_level))
+#define blkh_nr_item(p_blkh)          (le16_to_cpu((p_blkh)->blk_nr_item))
+
+#define BLKH_LEVEL_FREE 0 /* Freed from the tree */
+#define BLKH_LEVEL_LEAF 1 /* Leaf node level*/
+
+struct disk_child {
+    __u32       dc_block_number;   /* Disk child's block number */
+    __u16       dc_size;           /* Disk child's used space */
+    __u16       dc_reserved;
+};
+
+#define DC_SIZE (sizeof(struct disk_child))
+#define dc_block_number(dc_p)	(le32_to_cpu((dc_p)->dc_block_number))
+#define dc_size(dc_p)		(le16_to_cpu((dc_p)->dc_size))
+
+/* Stat data */
+struct stat_data_v1
+{
+    __u16 sd_mode;              /* file type, permissions */
+    __u16 sd_nlink;             /* number of hard links */
+    __u16 sd_uid;               /* owner */
+    __u16 sd_gid;               /* group */
+    __u32 sd_size;	        /* file size */
+    __u32 sd_atime;	        /* time of last access */
+    __u32 sd_mtime;	        /* time file was last modified  */
+    __u32 sd_ctime;	        /* time inode (stat data) was last changed
+                                   (except changes to sd_atime and sd_mtime) */
+    union {
+	__u32 sd_rdev;
+	__u32 sd_blocks;	/* number of blocks file uses */
+    } __attribute__ ((__packed__)) u;
+    __u32 sd_first_direct_byte; /* 0 = no direct item, 1 = symlink */
+} __attribute__ ((__packed__));
+#define SD_V1_SIZE              (sizeof(struct stat_data_v1))
+
+#define stat_data_v1(ih)        (ih_version (ih) == ITEM_VERSION_1)
+#define sd_v1_size(sdp)         (le32_to_cpu((sdp)->sd_size))
+
+/* Stat Data on disk (reiserfs version of UFS disk inode minus the
+   address blocks) */
+struct stat_data {
+    __u16 sd_mode;     /* file type, permissions */
+    __u16 sd_reserved;
+    __u32 sd_nlink;    /* number of hard links */
+    __u64 sd_size;     /* file size */
+    __u32 sd_uid;      /* owner */
+    __u32 sd_gid;      /* group */
+    __u32 sd_atime;    /* time of last access */
+    __u32 sd_mtime;    /* time file was last modified  */
+    __u32 sd_ctime;    /* time inode (stat data) was last changed
+                          (except changes to sd_atime and sd_mtime) */
+    __u32 sd_blocks;
+    __u32 sd_rdev;
+} __attribute__ ((__packed__));
+#define SD_V2_SIZE              (sizeof(struct stat_data))
+#define stat_data_v2(ih)        (ih_version (ih) == ITEM_VERSION_2)
+#define sd_v2_size(sdp)         (le64_to_cpu((sdp)->sd_size))
+
+/* valid for any stat data */
+#define sd_size(ih,sdp)         ((ih_version(ih) == ITEM_VERSION_2) ? \
+                                  sd_v2_size((struct stat_data *)sdp) : \
+                                  sd_v1_size((struct stat_data_v1 *)sdp))
+#define sd_mode(sdp)            (le16_to_cpu((sdp)->sd_mode))
+
+struct reiserfs_de_head
+{
+    __u32 deh_offset;    /* third component of the directory entry key */
+    __u32 deh_dir_id;    /* objectid of the parent directory of the object,
+                            that is referenced by directory entry */
+    __u32 deh_objectid;  /* objectid of the object, that is referenced by
+                            directory entry */
+    __u16 deh_location;  /* offset of name in the whole item */
+    __u16 deh_state;	 /* whether 1) entry contains stat data (for future),                               and 2) whether entry is hidden (unlinked) */
+} __attribute__ ((__packed__));
+#define DEH_SIZE                  sizeof(struct reiserfs_de_head)
+
+#define deh_offset(p_deh)         (le32_to_cpu((p_deh)->deh_offset))
+#define deh_dir_id(p_deh)         (le32_to_cpu((p_deh)->deh_dir_id))
+#define deh_objectid(p_deh)       (le32_to_cpu((p_deh)->deh_objectid))
+#define deh_location(p_deh)       (le16_to_cpu((p_deh)->deh_location))
+#define deh_state(p_deh)          (le16_to_cpu((p_deh)->deh_state))
+
+/* empty directory contains two entries "." and ".." and their headers */
+#define EMPTY_DIR_SIZE \
+(DEH_SIZE * 2 + ROUND_UP (strlen (".")) + ROUND_UP (strlen ("..")))
+
+/* old format directories have this size when empty */
+#define EMPTY_DIR_SIZE_V1 (DEH_SIZE * 2 + 3)
+
+#define DEH_Statdata 0			/* not used now */
+#define DEH_Visible 2
+
+/* 64 bit systems need to aligned explicitly -jdm */
+#if BITS_PER_LONG == 64
+# define ADDR_UNALIGNED_BITS  (5)
+#endif
+
+#define test_bit(x,y) ext2fs_test_bit(x,y)
+
+#ifdef ADDR_UNALIGNED_BITS
+# define aligned_address(addr)           ((void *)((long)(addr) & ~((1UL << ADDR_UNALIGNED_BITS) - 1)))
+# define unaligned_offset(addr)          (((int)((long)(addr) & ((1 << ADDR_UNALIGNED_BITS) - 1))) << 3)
+# define set_bit_unaligned(nr, addr)     set_bit((nr) + unaligned_offset(addr), aligned_address(addr))
+# define clear_bit_unaligned(nr, addr)   clear_bit((nr) + unaligned_offset(addr), aligned_address(addr))
+# define test_bit_unaligned(nr, addr)    test_bit((nr) + unaligned_offset(addr), aligned_address(addr))
+#else
+# define set_bit_unaligned(nr, addr)     set_bit(nr, addr)
+# define clear_bit_unaligned(nr, addr)   clear_bit(nr, addr)
+# define test_bit_unaligned(nr, addr)    test_bit(nr, addr)
+#endif
+
+#define SD_OFFSET  0
+#define SD_UNIQUENESS 0
+#define DOT_OFFSET 1
+#define DOT_DOT_OFFSET 2
+#define DIRENTRY_UNIQUENESS 500
+ 
+#define V1_TYPE_STAT_DATA 0x0
+#define V1_TYPE_DIRECT 0xffffffff
+#define V1_TYPE_INDIRECT 0xfffffffe
+#define V1_TYPE_DIRECTORY_MAX 0xfffffffd
+#define V2_TYPE_STAT_DATA 0
+#define V2_TYPE_INDIRECT 1
+#define V2_TYPE_DIRECT 2
+#define V2_TYPE_DIRENTRY 3
+
+ 
+#define REISERFS_ROOT_OBJECTID 2
+#define REISERFS_ROOT_PARENT_OBJECTID 1
+#define REISERFS_SUPERBLOCK_BLOCK 16
+/* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */
+#define REISERFS_OLD_SUPERBLOCK_BLOCK 2
+#define REISERFS_OLD_BLOCKSIZE 4096
+ 
+#define S_ISREG(mode) (((mode) & 0170000) == 0100000)
+#define S_ISDIR(mode) (((mode) & 0170000) == 0040000)
+#define S_ISLNK(mode) (((mode) & 0170000) == 0120000)
+#define PATH_MAX       1024     /* include/linux/limits.h */
+#define MAX_LINK_COUNT    5     /* number of symbolic links to follow */
+
+/* Cache stuff, adapted from GRUB source */
+#define FSYSREISER_CACHE_SIZE        (REISERFS_MAX_TREE_HEIGHT*REISERFS_OLD_BLOCKSIZE)
+#define SECTOR_SIZE                  512
+#define FSYSREISER_MIN_BLOCKSIZE     SECTOR_SIZE
+#define FSYSREISER_MAX_BLOCKSIZE     FSYSREISER_CACHE_SIZE / 3
+
+
+struct reiserfs_state
+{
+    /* Context */
+    struct key fileinfo;
+    struct boot_file_t *file;
+    struct item_head *current_ih;
+    char *current_item;
+    __u64 partition_offset;
+
+    /* Commonly used values, cpu order */
+    __u32 journal_block;       /* Start of journal */
+    __u32 journal_block_count; /* The size of the journal */
+    __u32 journal_first_desc;  /* The first valid descriptor block in journal
+                                 (relative to journal_block) */
+    
+   __u16 version;              /* The ReiserFS version. */
+   __u16 tree_depth;           /* The current depth of the reiser tree. */
+   __u8  blocksize_shift;      /* 1 << blocksize_shift == blocksize. */
+   __u16 blocksize;            /* The reiserfs block size (power of 2) */
+
+    /* Cache */
+    __u16 cached_slots;
+    __u16 journal_transactions;
+    __u32 blocks[REISERFS_MAX_TREE_HEIGHT];
+    __u32 next_key_nr[REISERFS_MAX_TREE_HEIGHT];
+};
+
+#define ROOT     ((char *)FSYS_BUF)
+#define CACHE(i) (ROOT + ((i) * INFO->blocksize))
+#define LEAF     CACHE (BLKH_LEVEL_LEAF)
+
+#define BLOCKHEAD(cache) ((struct block_head *) cache)
+#define ITEMHEAD         ((struct item_head *) ((int) LEAF + BLKH_SIZE))
+#define KEY(cache)       ((struct key *) ((int) cache + BLKH_SIZE))
+#define DC(cache)        ((struct disk_child *) \
+                                ((int) cache + BLKH_SIZE + KEY_SIZE * nr_item))
+
+/*
+ * The journal cache.  For each transaction it contains the number of
+ * blocks followed by the real block numbers of this transaction.
+ *
+ * If the block numbers of some transaction won't fit in this space,
+ * this list is stopped with a 0xffffffff marker and the remaining
+ * uncommitted transactions aren't cached.
+ */
+#define JOURNAL_START    ((__u32 *) (FSYS_BUF + FSYSREISER_CACHE_SIZE))
+#define JOURNAL_END      ((__u32 *) (FSYS_BUF + sizeof(FSYS_BUF)))
+
+
+#endif /* _REISERFS_H_ */

Added: ppcrcd/yaboot/include/setjm2.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/setjm2.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,101 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/*
+ *	ISO C Standard: 4.6 NON-LOCAL JUMPS	<setjmp.h>
+ */
+
+#ifndef	_SETJMP_H
+#define	_SETJMP_H	1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+#include <bits/setjmp.h>		/* Get `__jmp_buf'.  */
+#include <bits/sigset.h>		/* Get `__sigset_t'.  */
+
+/* Calling environment, plus possibly a saved signal mask.  */
+typedef struct __jmp_buf_tag	/* C++ doesn't like tagless structs.  */
+  {
+    /* NOTE: The machine-dependent definitions of `__sigsetjmp'
+       assume that a `jmp_buf' begins with a `__jmp_buf'.
+       Do not move this member or add others before it.  */
+    __jmp_buf __jmpbuf;		/* Calling environment.  */
+    int __mask_was_saved;	/* Saved the signal mask?  */
+    __sigset_t __saved_mask;	/* Saved signal mask.  */
+  } jmp_buf[1];
+
+
+/* Store the calling environment in ENV, also saving the
+   signal mask if SAVEMASK is nonzero.  Return 0.
+   This is the internal name for `sigsetjmp'.  */
+extern int __sigsetjmp __P ((jmp_buf __env, int __savemask));
+
+#ifndef	__FAVOR_BSD
+/* Set ENV to the current position and return 0, not saving the signal mask.
+   This is just like `sigsetjmp (ENV, 0)'.
+   The ISO C standard says `setjmp' is a macro.  */
+# define setjmp(env)	__sigsetjmp ((env), 0)
+#else
+/* We are in 4.3 BSD-compatibility mode in which `setjmp'
+   saves the signal mask like `sigsetjmp (ENV, 1)'.  */
+# define setjmp(env)	__sigsetjmp ((env), 1)
+#endif /* Favor BSD.  */
+
+#if defined __USE_BSD || defined __USE_XOPEN
+/* Set ENV to the current position and return 0, not saving the signal mask.
+   This is the 4.3 BSD name for ISO `setjmp'.  */
+# define _setjmp(env)	__sigsetjmp ((env), 0)
+#endif
+
+
+/* Jump to the environment saved in ENV, making the
+   `setjmp' call there return VAL, or 1 if VAL is 0.  */
+extern void longjmp __P ((jmp_buf __env, int __val))
+     __attribute__ ((__noreturn__));
+#if defined __USE_BSD || defined __USE_XOPEN
+/* Same.  Usually `_longjmp' is used with `_setjmp', which does not save
+   the signal mask.  But it is how ENV was saved that determines whether
+   `longjmp' restores the mask; `_longjmp' is just an alias.  */
+extern void _longjmp __P ((jmp_buf __env, int __val))
+     __attribute__ ((__noreturn__));
+#endif
+
+
+#ifdef	__USE_POSIX
+/* Use the same type for `jmp_buf' and `sigjmp_buf'.
+   The `__mask_was_saved' flag determines whether
+   or not `longjmp' will restore the signal mask.  */
+typedef jmp_buf sigjmp_buf;
+
+/* Store the calling environment in ENV, also saving the
+   signal mask if SAVEMASK is nonzero.  Return 0.  */
+# define sigsetjmp(env, savemask)	__sigsetjmp ((env), (savemask))
+
+/* Jump to the environment saved in ENV, making the
+   sigsetjmp call there return VAL, or 1 if VAL is 0.
+   Restore the signal mask if that sigsetjmp call saved it.
+   This is just an alias `longjmp'.  */
+extern void siglongjmp __P ((sigjmp_buf __env, int __val))
+     __attribute__ ((__noreturn__));
+#endif /* Use POSIX.  */
+
+__END_DECLS
+
+#endif /* setjmp.h  */

Added: ppcrcd/yaboot/include/setjmp.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/setjmp.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,39 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Define the machine-dependent type `jmp_buf'.  PowerPC version.  */
+
+#ifndef	_SETJMP_H
+#define	_SETJMP_H	1
+
+typedef long int __jmp_buf[58];
+
+typedef struct __jmp_buf_tag
+{
+    __jmp_buf __jmpbuf;
+    int __mask_was_saved;
+    int __saved_mask;
+} jmp_buf[1];
+
+
+extern int __sigsetjmp (jmp_buf __env, int __savemask);
+#define setjmp(env)	__sigsetjmp ((env), 0)
+
+extern void longjmp (jmp_buf __env, int __val);
+
+#endif
\ No newline at end of file

Added: ppcrcd/yaboot/include/stdlib.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/stdlib.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,24 @@
+/*
+ * include/stdlib.h
+ *
+ */
+#ifndef __STDLIB_H
+#define __STDLIB_H
+
+#include "stdarg.h"
+
+extern void malloc_init(void *bottom, unsigned long size);
+extern void malloc_dispose(void);
+
+extern void *malloc(unsigned int size);
+extern void *realloc(void *ptr, unsigned int size);
+extern void free (void *m);
+extern void mark (void **ptr);
+extern void release (void *ptr);
+
+extern int sprintf(char * buf, const char *fmt, ...);
+extern int vsprintf(char *buf, const char *fmt, va_list args);
+extern long simple_strtol(const char *cp,char **endp,unsigned int base);
+#define strtol(x,y,z) simple_strtol(x,y,z)
+
+#endif

Added: ppcrcd/yaboot/include/string.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/string.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,35 @@
+#ifndef _LINUX_STRING_H_
+#define _LINUX_STRING_H_
+
+#include "types.h"
+#include "stddef.h"
+
+extern char * ___strtok;
+extern char * strcpy(char *,const char *);
+extern char * strncpy(char *,const char *, size_t);
+extern char * strcat(char *, const char *);
+extern char * strncat(char *, const char *, size_t);
+extern char * strchr(const char *,int);
+extern char * strrchr(const char *,int);
+extern char * strpbrk(const char *,const char *);
+extern char * strtok(char *,const char *);
+extern char * strstr(const char *,const char *);
+extern size_t strlen(const char *);
+extern size_t strspn(const char *,const char *);
+extern int strcmp(const char *,const char *);
+extern int strncmp(const char *,const char *,size_t);
+extern int strnicmp(const char *, const char *, size_t);
+extern char *strdup(char const *str);
+
+extern void * memset(void *,int,size_t);
+extern void * memcpy(void *,const void *,size_t);
+extern void * memmove(void *,const void *,size_t);
+extern void * memscan(void *,int,size_t);
+extern int memcmp(const void *,const void *,size_t);
+
+static inline size_t strnlen(const char *s,size_t max)
+{
+	size_t sz = strlen(s);
+	return sz > max ? max : sz;
+}
+#endif /* _LINUX_STRING_H_ */

Added: ppcrcd/yaboot/include/swab.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/swab.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,25 @@
+#ifndef _REISERFS_SWAB_H_
+#define _REISERFS_SWAB_H_
+/* Stolen from linux/include/linux/byteorder/swab.h */
+#define swab16(x) \
+	((__u16)( \
+		(((__u16)(x) & (__u16)0x00ffU) << 8) | \
+		(((__u16)(x) & (__u16)0xff00U) >> 8) ))
+#define swab32(x) \
+	((__u32)( \
+		(((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
+		(((__u32)(x) & (__u32)0x0000ff00UL) <<  8) | \
+		(((__u32)(x) & (__u32)0x00ff0000UL) >>  8) | \
+		(((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
+#define swab64(x) \
+	((__u64)( \
+		(__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \
+		(__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \
+		(__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \
+		(__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) <<  8) | \
+	        (__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >>  8) | \
+		(__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
+		(__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
+		(__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
+
+#endif /* _REISERFS_SWAB_H_ */

Added: ppcrcd/yaboot/include/types.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/types.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,60 @@
+#ifndef __TYPES_H
+#define __TYPES_H
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* bsd */
+typedef unsigned char		u_char;
+typedef unsigned short		u_short;
+typedef unsigned int		u_int;
+typedef unsigned long		u_long;
+
+/* sysv */
+typedef unsigned char		unchar;
+typedef unsigned short		ushort;
+typedef unsigned int		uint;
+typedef unsigned long		ulong;
+
+typedef		__u8		u_int8_t;
+typedef		__s8		int8_t;
+typedef		__u16		u_int16_t;
+typedef		__s16		int16_t;
+typedef		__u32		u_int32_t;
+typedef		__s32		int32_t;
+
+typedef		__u8		uint8_t;
+typedef		__u16		uint16_t;
+typedef		__u32		uint32_t;
+
+typedef		__u64		uint64_t;
+typedef		__u64		u_int64_t;
+typedef		__s64		int64_t;
+
+typedef unsigned int ino_t;
+typedef __u64 loff_t;
+
+#endif

Added: ppcrcd/yaboot/include/xfs/xfs.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/xfs/xfs.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,545 @@
+/*
+ * xfs.h - an extraction from xfsprogs-1.3.5/include/xfs* into one file
+ *
+ * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * 
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#ifndef _BITS_TYPES_H
+typedef signed char	__int8_t;
+typedef unsigned char	__uint8_t;
+typedef short		__int16_t;
+typedef unsigned short	__uint16_t;
+typedef int		__int32_t;
+typedef unsigned int	__uint32_t;
+typedef long long	__int64_t;
+typedef unsigned long long __uint64_t;
+#endif
+
+typedef __uint64_t	xfs_ino_t;
+typedef	__uint32_t	xfs_agino_t;
+typedef __int64_t	xfs_daddr_t;
+typedef __int64_t	xfs_off_t;
+typedef __uint8_t	uuid_t[16];
+
+
+/* those are from xfs_types.h */
+
+typedef __uint32_t	xfs_agblock_t;	/* blockno in alloc. group */
+typedef	__uint32_t	xfs_extlen_t;	/* extent length in blocks */
+typedef	__uint32_t	xfs_agnumber_t;	/* allocation group number */
+typedef __int32_t	xfs_extnum_t;	/* # of extents in a file */
+typedef __int16_t	xfs_aextnum_t;	/* # extents in an attribute fork */
+typedef	__int64_t	xfs_fsize_t;	/* bytes in a file */
+
+typedef	__uint32_t	xfs_dablk_t;	/* dir/attr block number (in file) */
+typedef	__uint32_t	xfs_dahash_t;	/* dir/attr hash value */
+
+/*
+ * Disk based types:
+ */
+typedef __uint64_t	xfs_dfsbno_t;	/* blockno in filesystem (agno|agbno) */
+typedef __uint64_t	xfs_drfsbno_t;	/* blockno in filesystem (raw) */
+typedef	__uint64_t	xfs_drtbno_t;	/* extent (block) in realtime area */
+typedef	__uint64_t	xfs_dfiloff_t;	/* block number in a file */
+
+typedef	__uint64_t	xfs_fsblock_t;	/* blockno in filesystem (agno|agbno) */
+typedef	__uint64_t	xfs_fileoff_t;	/* block number in a file */
+typedef	__uint64_t	xfs_filblks_t;	/* number of blocks in a file */
+
+
+/* those are from xfs_sb.h */
+
+#define	XFS_SB_MAGIC		0x58465342	/* 'XFSB'*/
+#define	XFS_SB_VERSION_4	4		/* 6.2+ - bitmask version */
+#define	XFS_SB_VERSION_NUMBITS	0x000f
+
+typedef struct xfs_sb
+{
+	__uint32_t	sb_magicnum;	/* magic number == XFS_SB_MAGIC */
+	__uint32_t	sb_blocksize;	/* logical block size, bytes */
+	xfs_drfsbno_t	sb_dblocks;	/* number of data blocks */
+	xfs_drfsbno_t	sb_rblocks;	/* number of realtime blocks */
+	xfs_drtbno_t	sb_rextents;	/* number of realtime extents */
+	uuid_t		sb_uuid;	/* file system unique id */
+	xfs_dfsbno_t	sb_logstart;	/* starting block of log if internal */
+	xfs_ino_t	sb_rootino;	/* root inode number */
+	xfs_ino_t	sb_rbmino;	/* bitmap inode for realtime extents */
+	xfs_ino_t	sb_rsumino;	/* summary inode for rt bitmap */
+	xfs_agblock_t	sb_rextsize;	/* realtime extent size, blocks */
+	xfs_agblock_t	sb_agblocks;	/* size of an allocation group */
+	xfs_agnumber_t	sb_agcount;	/* number of allocation groups */
+	xfs_extlen_t	sb_rbmblocks;	/* number of rt bitmap blocks */
+	xfs_extlen_t	sb_logblocks;	/* number of log blocks */
+	__uint16_t	sb_versionnum;	/* header version == XFS_SB_VERSION */
+	__uint16_t	sb_sectsize;	/* volume sector size, bytes */
+	__uint16_t	sb_inodesize;	/* inode size, bytes */
+	__uint16_t	sb_inopblock;	/* inodes per block */
+	char		sb_fname[12];	/* file system name */
+	__uint8_t	sb_blocklog;	/* log2 of sb_blocksize */
+	__uint8_t	sb_sectlog;	/* log2 of sb_sectsize */
+	__uint8_t	sb_inodelog;	/* log2 of sb_inodesize */
+	__uint8_t	sb_inopblog;	/* log2 of sb_inopblock */
+	__uint8_t	sb_agblklog;	/* log2 of sb_agblocks (rounded up) */
+	__uint8_t	sb_rextslog;	/* log2 of sb_rextents */
+	__uint8_t	sb_inprogress;	/* mkfs is in progress, don't mount */
+	__uint8_t	sb_imax_pct;	/* max % of fs for inode space */
+					/* statistics */
+	/*
+	 * These fields must remain contiguous.  If you really
+	 * want to change their layout, make sure you fix the
+	 * code in xfs_trans_apply_sb_deltas().
+	 */
+	__uint64_t	sb_icount;	/* allocated inodes */
+	__uint64_t	sb_ifree;	/* free inodes */
+	__uint64_t	sb_fdblocks;	/* free data blocks */
+	__uint64_t	sb_frextents;	/* free realtime extents */
+	/*
+	 * End contiguous fields.
+	 */
+	xfs_ino_t	sb_uquotino;	/* user quota inode */
+	xfs_ino_t	sb_gquotino;	/* group quota inode */
+	__uint16_t	sb_qflags;	/* quota flags */
+	__uint8_t	sb_flags;	/* misc. flags */
+	__uint8_t	sb_shared_vn;	/* shared version number */
+	xfs_extlen_t	sb_inoalignmt;	/* inode chunk alignment, fsblocks */
+	__uint32_t	sb_unit;	/* stripe or raid unit */
+	__uint32_t	sb_width;	/* stripe or raid width */	
+	__uint8_t	sb_dirblklog;	/* log2 of dir block size (fsbs) */
+        __uint8_t       sb_dummy[7];    /* padding */
+} xfs_sb_t;
+
+
+/* those are from xfs_btree.h */
+
+/*
+ * Long form header: bmap btrees.
+ */
+typedef struct xfs_btree_lblock
+{
+	__uint32_t	bb_magic;	/* magic number for block type */
+	__uint16_t	bb_level;	/* 0 is a leaf */
+	__uint16_t	bb_numrecs;	/* current # of data records */
+	xfs_dfsbno_t	bb_leftsib;	/* left sibling block or NULLDFSBNO */
+	xfs_dfsbno_t	bb_rightsib;	/* right sibling block or NULLDFSBNO */
+} xfs_btree_lblock_t;
+
+/*
+ * Combined header and structure, used by common code.
+ */
+typedef struct xfs_btree_hdr
+{
+	__uint32_t	bb_magic;	/* magic number for block type */
+	__uint16_t	bb_level;	/* 0 is a leaf */
+	__uint16_t	bb_numrecs;	/* current # of data records */
+} xfs_btree_hdr_t;
+
+typedef struct xfs_btree_block
+{
+	xfs_btree_hdr_t	bb_h;		/* header */
+	union		{
+		struct	{
+			xfs_agblock_t	bb_leftsib;
+			xfs_agblock_t	bb_rightsib;
+		}	s;		/* short form pointers */
+		struct	{
+			xfs_dfsbno_t	bb_leftsib;
+			xfs_dfsbno_t	bb_rightsib;
+		}	l;		/* long form pointers */
+	}		bb_u;		/* rest */
+} xfs_btree_block_t;
+
+/* those are from xfs_bmap_btree.h */
+
+/*
+ * Bmap root header, on-disk form only.
+ */
+typedef struct xfs_bmdr_block
+{
+	__uint16_t	bb_level;	/* 0 is a leaf */
+	__uint16_t	bb_numrecs;	/* current # of data records */
+} xfs_bmdr_block_t;
+
+/*
+ * Bmap btree record and extent descriptor.
+ * For 32-bit kernels,
+ *  l0:31 is an extent flag (value 1 indicates non-normal).
+ *  l0:0-30 and l1:9-31 are startoff.
+ *  l1:0-8, l2:0-31, and l3:21-31 are startblock.
+ *  l3:0-20 are blockcount.
+ * For 64-bit kernels,
+ *  l0:63 is an extent flag (value 1 indicates non-normal).
+ *  l0:9-62 are startoff.
+ *  l0:0-8 and l1:21-63 are startblock.
+ *  l1:0-20 are blockcount.
+ */
+
+#define	BMBT_USE_64	1
+
+typedef struct xfs_bmbt_rec_32
+{
+	__uint32_t		l0, l1, l2, l3;
+} xfs_bmbt_rec_32_t;
+typedef struct xfs_bmbt_rec_64
+{
+	__uint64_t		l0, l1;
+} xfs_bmbt_rec_64_t;
+
+#if BMBT_USE_64
+typedef	__uint64_t	xfs_bmbt_rec_base_t;	/* use this for casts */
+typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
+#else	/* !BMBT_USE_64 */
+typedef	__uint32_t	xfs_bmbt_rec_base_t;	/* use this for casts */
+typedef xfs_bmbt_rec_32_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
+#endif	/* BMBT_USE_64 */
+
+/*
+ * Key structure for non-leaf levels of the tree.
+ */
+typedef struct xfs_bmbt_key
+{
+	xfs_dfiloff_t	br_startoff;	/* starting file offset */
+} xfs_bmbt_key_t, xfs_bmdr_key_t;
+
+typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;	/* btree pointer type */
+					/* btree block header type */
+typedef	struct xfs_btree_lblock xfs_bmbt_block_t;
+
+
+/* those are from xfs_dir2.h */
+/*
+ * Directory version 2.
+ * There are 4 possible formats:
+ *	shortform
+ *	single block - data with embedded leaf at the end
+ *	multiple data blocks, single leaf+freeindex block
+ *	data blocks, node&leaf blocks (btree), freeindex blocks
+ *
+ *	The shortform format is in xfs_dir2_sf.h.
+ *	The single block format is in xfs_dir2_block.h.
+ *	The data block format is in xfs_dir2_data.h.
+ *	The leaf and freeindex block formats are in xfs_dir2_leaf.h.
+ *	Node blocks are the same as the other version, in xfs_da_btree.h.
+ */
+
+/*
+ * Byte offset in data block and shortform entry.
+ */
+typedef	__uint16_t	xfs_dir2_data_off_t;
+
+/*
+ * Byte offset in a directory.
+ */
+typedef	xfs_off_t		xfs_dir2_off_t;
+
+/* those are from xfs_da_btree.h */
+/*========================================================================
+ * Directory Structure when greater than XFS_LBSIZE(mp) bytes.
+ *========================================================================*/
+
+/*
+ * This structure is common to both leaf nodes and non-leaf nodes in the Btree.
+ *
+ * Is is used to manage a doubly linked list of all blocks at the same
+ * level in the Btree, and to identify which type of block this is.
+ */
+#define	XFS_DIR2_LEAF1_MAGIC	0xd2f1	/* magic number: v2 dirlf single blks */
+#define	XFS_DIR2_LEAFN_MAGIC	0xd2ff	/* magic number: v2 dirlf multi blks */
+
+typedef struct xfs_da_blkinfo {
+	xfs_dablk_t forw;			/* previous block in list */
+	xfs_dablk_t back;			/* following block in list */
+	__uint16_t magic;			/* validity check on block */
+	__uint16_t pad;				/* unused */
+} xfs_da_blkinfo_t;
+
+/*
+ * This is the structure of the root and intermediate nodes in the Btree.
+ * The leaf nodes are defined above.
+ *
+ * Entries are not packed.
+ *
+ * Since we have duplicate keys, use a binary search but always follow
+ * all match in the block, not just the first match found.
+ */
+
+typedef struct xfs_da_intnode {
+	struct xfs_da_node_hdr {	/* constant-structure header block */
+		xfs_da_blkinfo_t info;	/* block type, links, etc. */
+		__uint16_t count;	/* count of active entries */
+		__uint16_t level;	/* level above leaves (leaf == 0) */
+	} hdr;
+	struct xfs_da_node_entry {
+		xfs_dahash_t hashval;	/* hash value for this descendant */
+		xfs_dablk_t before;	/* Btree block before this key */
+	} btree[1];			/* variable sized array of keys */
+} xfs_da_intnode_t;
+
+
+/* those are from xfs_dir2_data.h */
+/*
+ * Directory format 2, data block structures.
+ */
+
+/*
+ * Constants.
+ */
+#define	XFS_DIR2_DATA_FREE_TAG	0xffff
+#define	XFS_DIR2_DATA_FD_COUNT	3
+
+/*
+ * Structures.
+ */
+
+/*
+ * Describe a free area in the data block.
+ * The freespace will be formatted as a xfs_dir2_data_unused_t.
+ */
+typedef struct xfs_dir2_data_free {
+	xfs_dir2_data_off_t	offset;		/* start of freespace */
+	xfs_dir2_data_off_t	length;		/* length of freespace */
+} xfs_dir2_data_free_t;
+
+/*
+ * Header for the data blocks.
+ * Always at the beginning of a directory-sized block.
+ * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
+ */
+typedef struct xfs_dir2_data_hdr {
+	__uint32_t		magic;		/* XFS_DIR2_DATA_MAGIC */
+						/* or XFS_DIR2_BLOCK_MAGIC */
+	xfs_dir2_data_free_t	bestfree[XFS_DIR2_DATA_FD_COUNT];
+} xfs_dir2_data_hdr_t;
+
+/*
+ * Active entry in a data block.  Aligned to 8 bytes.
+ * Tag appears as the last 2 bytes.
+ */
+typedef struct xfs_dir2_data_entry {
+	xfs_ino_t		inumber;	/* inode number */
+	__uint8_t		namelen;	/* name length */
+	__uint8_t		name[1];	/* name bytes, no null */
+						/* variable offset */
+	xfs_dir2_data_off_t	tag;		/* starting offset of us */
+} xfs_dir2_data_entry_t;
+
+/*
+ * Unused entry in a data block.  Aligned to 8 bytes.
+ * Tag appears as the last 2 bytes.
+ */
+typedef struct xfs_dir2_data_unused {
+	__uint16_t		freetag;	/* XFS_DIR2_DATA_FREE_TAG */
+	xfs_dir2_data_off_t	length;		/* total free length */
+						/* variable offset */
+	xfs_dir2_data_off_t	tag;		/* starting offset of us */
+} xfs_dir2_data_unused_t;
+
+typedef union {
+	xfs_dir2_data_entry_t	entry;
+	xfs_dir2_data_unused_t	unused;
+} xfs_dir2_data_union_t;
+
+
+/* those are from xfs_dir2_leaf.h */
+/*
+ * Directory version 2, leaf block structures.
+ */
+
+/*
+ * Leaf block header.
+ */
+typedef struct xfs_dir2_leaf_hdr {
+	xfs_da_blkinfo_t	info;		/* header for da routines */
+	__uint16_t		count;		/* count of entries */
+	__uint16_t		stale;		/* count of stale entries */
+} xfs_dir2_leaf_hdr_t;
+
+
+/* those are from xfs_dir2_block.h */
+/*
+ * xfs_dir2_block.h
+ * Directory version 2, single block format structures
+ */
+
+/*
+ * The single block format is as follows:
+ * xfs_dir2_data_hdr_t structure
+ * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures
+ * xfs_dir2_leaf_entry_t structures
+ * xfs_dir2_block_tail_t structure
+ */
+
+#define	XFS_DIR2_BLOCK_MAGIC	0x58443242	/* XD2B: for one block dirs */
+
+typedef struct xfs_dir2_block_tail {
+	__uint32_t	count;			/* count of leaf entries */
+	__uint32_t	stale;			/* count of stale lf entries */
+} xfs_dir2_block_tail_t;
+
+
+/* those are from xfs_dir2_sf.h */
+
+/*
+ * Directory layout when stored internal to an inode.
+ *
+ * Small directories are packed as tightly as possible so as to
+ * fit into the literal area of the inode.
+ */
+
+/*
+ * Inode number stored as 8 8-bit values.
+ */
+typedef	struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
+
+/*
+ * Inode number stored as 4 8-bit values.
+ * Works a lot of the time, when all the inode numbers in a directory
+ * fit in 32 bits.
+ */
+typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
+
+typedef union {
+	xfs_dir2_ino8_t	i8;
+	xfs_dir2_ino4_t	i4;
+} xfs_dir2_inou_t;
+
+/*
+ * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
+ * Only need 16 bits, this is the byte offset into the single block form.
+ */
+typedef struct { __uint8_t i[2]; } xfs_dir2_sf_off_t;
+
+/*
+ * The parent directory has a dedicated field, and the self-pointer must
+ * be calculated on the fly.
+ *
+ * Entries are packed toward the top as tightly as possible.  The header
+ * and the elements must be bcopy()'d out into a work area to get correct
+ * alignment for the inode number fields.
+ */
+typedef struct xfs_dir2_sf_hdr {
+	__uint8_t		count;		/* count of entries */
+	__uint8_t		i8count;	/* count of 8-byte inode #s */
+	xfs_dir2_inou_t		parent;		/* parent dir inode number */
+} xfs_dir2_sf_hdr_t;
+
+typedef struct xfs_dir2_sf_entry {
+	__uint8_t		namelen;	/* actual name length */
+	xfs_dir2_sf_off_t	offset;		/* saved offset */
+	__uint8_t		name[1];	/* name, variable size */
+	xfs_dir2_inou_t		inumber;	/* inode number, var. offset */
+} xfs_dir2_sf_entry_t;
+
+typedef struct xfs_dir2_sf {
+	xfs_dir2_sf_hdr_t	hdr;		/* shortform header */
+	xfs_dir2_sf_entry_t	list[1];	/* shortform entries */
+} xfs_dir2_sf_t;
+
+/* those are from xfs_dinode.h */
+
+#define	XFS_DINODE_VERSION_1	1
+#define	XFS_DINODE_VERSION_2	2
+#define	XFS_DINODE_MAGIC	0x494e	/* 'IN' */
+
+/*
+ * Disk inode structure.
+ * This is just the header; the inode is expanded to fill a variable size
+ * with the last field expanding.  It is split into the core and "other"
+ * because we only need the core part in the in-core inode.
+ */
+typedef struct xfs_timestamp {
+	__int32_t	t_sec;		/* timestamp seconds */
+	__int32_t	t_nsec;		/* timestamp nanoseconds */
+} xfs_timestamp_t;
+
+/*
+ * Note: Coordinate changes to this structure with the XFS_DI_* #defines
+ * below and the offsets table in xfs_ialloc_log_di().
+ */
+typedef struct xfs_dinode_core
+{
+	__uint16_t	di_magic;	/* inode magic # = XFS_DINODE_MAGIC */
+	__uint16_t	di_mode;	/* mode and type of file */
+	__int8_t	di_version;	/* inode version */
+	__int8_t	di_format;	/* format of di_c data */
+	__uint16_t	di_onlink;	/* old number of links to file */
+	__uint32_t	di_uid;		/* owner's user id */
+	__uint32_t	di_gid;		/* owner's group id */
+	__uint32_t	di_nlink;	/* number of links to file */
+	__uint16_t	di_projid;	/* owner's project id */
+	__uint8_t	di_pad[10];	/* unused, zeroed space */
+	xfs_timestamp_t	di_atime;	/* time last accessed */
+	xfs_timestamp_t	di_mtime;	/* time last modified */
+	xfs_timestamp_t	di_ctime;	/* time created/inode modified */
+	xfs_fsize_t	di_size;	/* number of bytes in file */
+	xfs_drfsbno_t	di_nblocks;	/* # of direct & btree blocks used */
+	xfs_extlen_t	di_extsize;	/* basic/minimum extent size for file */
+	xfs_extnum_t	di_nextents;	/* number of extents in data fork */
+	xfs_aextnum_t	di_anextents;	/* number of extents in attribute fork*/
+	__uint8_t	di_forkoff;	/* attr fork offs, <<3 for 64b align */
+	__int8_t	di_aformat;	/* format of attr fork's data */
+	__uint32_t	di_dmevmask;	/* DMIG event mask */
+	__uint16_t	di_dmstate;	/* DMIG state info */
+	__uint16_t	di_flags;	/* random flags, XFS_DIFLAG_... */
+	__uint32_t	di_gen;		/* generation number */
+} xfs_dinode_core_t;
+
+typedef struct xfs_dinode
+{
+	xfs_dinode_core_t	di_core;
+	xfs_agino_t		di_next_unlinked;/* agi unlinked list ptr */
+	union {
+		xfs_bmdr_block_t di_bmbt;	/* btree root block */
+		xfs_bmbt_rec_32_t di_bmx[1];	/* extent list */
+		xfs_dir2_sf_t	di_dir2sf;	/* shortform directory v2 */
+		char		di_c[1];	/* local contents */
+	} di_u;
+} xfs_dinode_t;
+
+/*
+ * Values for di_format
+ */
+typedef enum xfs_dinode_fmt
+{
+	XFS_DINODE_FMT_DEV,		/* CHR, BLK: di_dev */
+	XFS_DINODE_FMT_LOCAL,		/* DIR, REG: di_c */
+					/* LNK: di_symlink */
+	XFS_DINODE_FMT_EXTENTS,		/* DIR, REG, LNK: di_bmx */
+	XFS_DINODE_FMT_BTREE,		/* DIR, REG, LNK: di_bmbt */
+	XFS_DINODE_FMT_UUID 		/* MNT: di_uuid */
+} xfs_dinode_fmt_t;
+
+/*
+ * File types (mode field)
+ */
+#define	IFMT		0170000		/* type of file */
+#define	IFDIR		0040000		/* directory */
+#define	IFREG		0100000		/* regular */
+#define	IFLNK		0120000		/* symbolic link */

Added: ppcrcd/yaboot/include/yaboot.h
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/include/yaboot.h	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,62 @@
+/*
+ *  Yaboot - secondary boot loader for Linux on PowerPC. 
+ *
+ *  Copyright (C) 2001 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.
+ */
+
+#ifndef __YABOOT_H__
+#define __YABOOT_H__
+
+#include "file.h"
+
+struct boot_param_t {
+	struct boot_fspec_t	kernel;
+	struct boot_fspec_t	rd;
+	struct boot_fspec_t	sysmap;
+
+	char*	args;
+};
+
+extern int useconf;
+extern char bootdevice[];
+extern char *bootpath;
+extern int bootpartition;
+
+#endif

Added: ppcrcd/yaboot/iso_util.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/iso_util.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,92 @@
+/*
+ *  linux/fs/isofs/util.c
+ *
+ *  The special functions in the file are numbered according to the section
+ *  of the iso 9660 standard in which they are described.  isonum_733 will
+ *  convert numbers according to section 7.3.3, etc.
+ *
+ *  isofs special functions.  This file was lifted in its entirety from
+ *  the 386BSD iso9660 filesystem, by Pace Willisson <pace at blitz.com>.
+ */
+
+int
+isonum_711 (char * p)
+{
+     return (*p & 0xff);
+}
+
+int
+isonum_712 (char * p)
+{
+     int val;
+	
+     val = *p;
+     if (val & 0x80)
+	  val |= 0xffffff00;
+     return (val);
+}
+
+int
+isonum_721 (char * p)
+{
+     return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
+}
+
+int
+isonum_722 (char * p)
+{
+     return (((p[0] & 0xff) << 8) | (p[1] & 0xff));
+}
+
+int
+isonum_723 (char * p)
+{
+#if 0
+     if (p[0] != p[3] || p[1] != p[2]) {
+	  fprintf (stderr, "invalid format 7.2.3 number\n");
+	  exit (1);
+     }
+#endif
+     return (isonum_721 (p));
+}
+
+int
+isonum_731 (char * p)
+{
+     return ((p[0] & 0xff)
+	     | ((p[1] & 0xff) << 8)
+	     | ((p[2] & 0xff) << 16)
+	     | ((p[3] & 0xff) << 24));
+}
+
+int
+isonum_732 (char * p)
+{
+     return (((p[0] & 0xff) << 24)
+	     | ((p[1] & 0xff) << 16)
+	     | ((p[2] & 0xff) << 8)
+	     | (p[3] & 0xff));
+}
+
+int
+isonum_733 (char * p)
+{
+#if 0
+     int i;
+
+     for (i = 0; i < 4; i++) {
+	  if (p[i] != p[7-i]) {
+	       fprintf (stderr, "bad format 7.3.3 number\n");
+	       exit (1);
+	  }
+     }
+#endif
+     return (isonum_731 (p));
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 8
+ * End:
+ */

Added: ppcrcd/yaboot/lib/ctype.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/lib/ctype.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,46 @@
+#include "string.h"
+#include "ctype.h"
+
+unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,		/* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,			/* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P,			/* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D,			/* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P,			/* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,	/* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U,			/* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U,			/* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P,			/* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,	/* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L,			/* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L,			/* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C,			/* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
+
+
+int strcasecmp(const char *s1, const char *s2)
+{
+    int c1, c2;
+
+    for (;;) {
+	c1 = *s1++;
+	if ('A' <= c1 && c1 <= 'Z')
+	    c1 += 'a' - 'A';
+	c2 = *s2++;
+	if ('A' <= c2 && c2 <= 'Z')
+	    c2 += 'a' - 'A';
+	if (c1 != c2 || c1 == 0)
+	    return c1 - c2;
+    }
+}
+

Added: ppcrcd/yaboot/lib/malloc.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/lib/malloc.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,111 @@
+/*  malloc.c - Dumb memory allocation routines
+ *  
+ *  Copyright (C) 1997 Paul Mackerras
+ *                1996 Maurizio Plaza
+ *                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 "types.h"
+#include "stddef.h"
+
+/* Imported functions */
+extern void prom_printf (char *fmt, ...);
+
+static char *malloc_ptr = 0;
+static char *malloc_top = 0;
+static char *last_alloc = 0;
+
+void malloc_init(void *bottom, unsigned long size)
+{
+	malloc_ptr = bottom;
+	malloc_top = bottom + size;
+}
+
+void malloc_dispose(void)
+{
+	malloc_ptr = 0;
+	last_alloc = 0;
+}
+
+void *malloc (unsigned int size)
+{
+    char *caddr;
+
+    if (!malloc_ptr)
+    	return NULL;
+    if ((malloc_ptr + size + sizeof(int)) > malloc_top) {
+	prom_printf("malloc failed\n");
+    	return NULL;
+    }
+    *(int *)malloc_ptr = size;
+    caddr = malloc_ptr + sizeof(int);
+    malloc_ptr += size + sizeof(int);
+    last_alloc = caddr;
+    malloc_ptr = (char *) ((((unsigned int) malloc_ptr) + 3) & (~3));
+    return caddr;
+}
+
+void *realloc(void *ptr, unsigned int size)
+{
+    char *caddr, *oaddr = ptr;
+
+    if (!malloc_ptr)
+    	return NULL;
+    if (oaddr == last_alloc) {
+	if (oaddr + size > malloc_top) {
+		prom_printf("realloc failed\n");
+		return NULL;
+	}
+	*(int *)(oaddr - sizeof(int)) = size;
+	malloc_ptr = oaddr + size;
+	return oaddr;
+    }
+    caddr = malloc(size);
+    if (caddr != 0 && oaddr != 0)
+	memcpy(caddr, oaddr, *(int *)(oaddr - sizeof(int)));
+    return caddr;
+}
+
+void free (void *m)
+{
+    if (!malloc_ptr)
+    	return;
+    if (m == last_alloc)
+	malloc_ptr = (char *) last_alloc - sizeof(int);
+}
+
+void mark (void **ptr)
+{
+    if (!malloc_ptr)
+    	return;
+    *ptr = (void *) malloc_ptr;
+}
+
+void release (void *ptr)
+{
+    if (!malloc_ptr)
+    	return;
+    malloc_ptr = (char *) ptr;
+}
+
+char *strdup(char const *str)
+{
+    char *p = malloc(strlen(str) + 1);
+    if (p)
+	 strcpy(p, str);
+    return p;
+}

Added: ppcrcd/yaboot/lib/nosys.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/lib/nosys.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,5 @@
+/* we got no time */
+long time()
+{
+    return 0;
+}

Added: ppcrcd/yaboot/lib/string.S
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/lib/string.S	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,255 @@
+/*
+ *  string.S - String handling functions for PowerPC.
+ *
+ *  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 "asm/processor.h"
+#include "asm/ppc_asm.tmpl"
+
+	.globl	strcpy
+strcpy:
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r5)
+	bne	1b
+	blr
+
+	.globl	strncpy
+strncpy:
+	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r6)
+	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
+	blr
+
+	.globl	strcat
+strcat:
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r5)
+	cmpwi	0,r0,0
+	bne	1b
+	addi	r5,r5,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r5)
+	bne	1b
+	blr
+
+	.globl	strcmp
+strcmp:
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r3,1(r5)
+	cmpwi	1,r3,0
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	beqlr	1
+	beq	1b
+	blr
+
+	.globl	strncmp
+strncmp:
+	cmpwi	0,r5,0
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+	beqlr
+	mtctr	r5
+1:	lbzu	r3,1(r6)
+	cmpwi	1,r3,0
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	beqlr	1
+	bdnzt	2,1b		/* dec ctr, branch if ctr != 0 && cr0.eq */
+	blr
+
+	.globl	strlen
+strlen:
+	addi	r4,r3,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	bne	1b
+	subf	r3,r3,r4
+	blr
+
+	.globl	strchr
+strchr:
+	addi	r3,r3,-1
+1:	lbzu	r0,1(r3)
+	cmpw	0,r0,r4
+	cmpwi	1,r0,0
+	beqlr
+	bne	1,1b
+	li	r3,0
+	blr
+
+	.globl	strrchr
+strrchr:
+	addi	r5,r3,-1
+	li	r3,0
+1:	lbzu	r0,1(r5)
+	cmpwi	0,r0,0
+	cmpw	1,r0,r4
+	beqlr
+	bne	1,1b
+	mr	r3,r5
+	b	1b
+
+	.globl	memset
+memset:
+	rlwimi	r4,r4,8,16,23
+	rlwimi	r4,r4,16,0,15
+	addi	r6,r3,-4
+	cmplwi	0,r5,4
+	blt	7f
+	stwu	r4,4(r6)
+	beqlr
+	andi.	r0,r6,3
+	add	r5,r0,r5
+	subf	r6,r0,r6
+	rlwinm	r0,r5,32-2,2,31
+	mtctr	r0
+	bdz	6f
+1:	stwu	r4,4(r6)
+	bdnz	1b
+6:	andi.	r5,r5,3
+7:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r6,3
+8:	stbu	r4,1(r6)
+	bdnz	8b
+	blr
+
+	.globl	bcopy
+bcopy:
+	mr	r6,r3
+	mr	r3,r4
+	mr	r4,r6
+	b	memcpy
+
+	.globl __bzero
+__bzero:
+        mr r5, r4
+        li r4, 0
+        b memset
+
+	.globl	memmove
+memmove:
+	cmplw	0,r3,r4
+	bgt	backwards_memcpy
+	/* fall through */
+
+	.globl	memcpy
+memcpy:
+	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+	addi	r6,r3,-4
+	addi	r4,r4,-4
+	beq	2f			/* if less than 8 bytes to do */
+	andi.	r0,r6,3			/* get dest word aligned */
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,4(r4)
+	lwzu	r8,8(r4)
+	stw	r7,4(r6)
+	stwu	r8,8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,4(r4)
+	addi	r5,r5,-4
+	stwu	r0,4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r4,r4,3
+	addi	r6,r6,3
+4:	lbzu	r0,1(r4)
+	stbu	r0,1(r6)
+	bdnz	4b
+	blr
+5:	subfic	r0,r0,4
+	mtctr	r0
+6:	lbz	r7,4(r4)
+	addi	r4,r4,1
+	stb	r7,4(r6)
+	addi	r6,r6,1
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+
+	.globl	backwards_memcpy
+backwards_memcpy:
+	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+	add	r6,r3,r5
+	add	r4,r4,r5
+	beq	2f
+	andi.	r0,r6,3
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,-4(r4)
+	lwzu	r8,-8(r4)
+	stw	r7,-4(r6)
+	stwu	r8,-8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,-4(r4)
+	subi	r5,r5,4
+	stwu	r0,-4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+4:	lbzu	r0,-1(r4)
+	stbu	r0,-1(r6)
+	bdnz	4b
+	blr
+5:	mtctr	r0
+6:	lbzu	r7,-1(r4)
+	stbu	r7,-1(r6)
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+
+	.globl	memcmp
+memcmp:
+	cmpwi	0,r5,0
+	blelr
+	mtctr	r5
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r3,1(r6)
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	bdnzt	2,1b
+	blr

Added: ppcrcd/yaboot/lib/strstr.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/lib/strstr.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,119 @@
+/* Return the offset of one string within another.
+   Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/*
+ * My personal strstr() implementation that beats most other algorithms.
+ * Until someone tells me otherwise, I assume that this is the
+ * fastest implementation of strstr() in C.
+ * I deliberately chose not to comment it.  You should have at least
+ * as much fun trying to understand it, as I had to write it :-).
+ *
+ * Stephen R. van den Berg, berg at pool.informatik.rwth-aachen.de	*/
+
+#include <string.h>
+
+typedef unsigned chartype;
+
+#undef strstr
+
+char *
+strstr (phaystack, pneedle)
+     const char *phaystack;
+     const char *pneedle;
+{
+  register const unsigned char *haystack, *needle;
+  register chartype b, c;
+
+  haystack = (const unsigned char *) phaystack;
+  needle = (const unsigned char *) pneedle;
+
+  b = *needle;
+  if (b != '\0')
+    {
+      haystack--;				/* possible ANSI violation */
+      do
+	{
+	  c = *++haystack;
+	  if (c == '\0')
+	    goto ret0;
+	}
+      while (c != b);
+
+      c = *++needle;
+      if (c == '\0')
+	goto foundneedle;
+      ++needle;
+      goto jin;
+
+      for (;;)
+        {
+          register chartype a;
+	  register const unsigned char *rhaystack, *rneedle;
+
+	  do
+	    {
+	      a = *++haystack;
+	      if (a == '\0')
+		goto ret0;
+	      if (a == b)
+		break;
+	      a = *++haystack;
+	      if (a == '\0')
+		goto ret0;
+shloop:	    }
+          while (a != b);
+
+jin:	  a = *++haystack;
+	  if (a == '\0')
+	    goto ret0;
+
+	  if (a != c)
+	    goto shloop;
+
+	  rhaystack = haystack-- + 1;
+	  rneedle = needle;
+	  a = *rneedle;
+
+	  if (*rhaystack == a)
+	    do
+	      {
+		if (a == '\0')
+		  goto foundneedle;
+		++rhaystack;
+		a = *++needle;
+		if (*rhaystack != a)
+		  break;
+		if (a == '\0')
+		  goto foundneedle;
+		++rhaystack;
+		a = *++needle;
+	      }
+	    while (*rhaystack == a);
+
+	  needle = rneedle;		/* took the register-poor approach */
+
+	  if (a == '\0')
+	    break;
+        }
+    }
+foundneedle:
+  return (char*) haystack;
+ret0:
+  return 0;
+}

Added: ppcrcd/yaboot/lib/strtol.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/lib/strtol.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,140 @@
+/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+   Cambridge, MA 02139, USA.  */
+
+/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
+   If BASE is 0 the base is determined by the presence of a leading
+   zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
+   If BASE is < 2 or > 36, it is reset to 10.
+   If ENDPTR is not NULL, a pointer to the character after the last
+   one converted is stored in *ENDPTR.  */
+
+#include "ctype.h"
+
+int strtol (nptr, endptr, base)
+const char *nptr;
+char **endptr;
+int base;
+{
+    int negative;
+    register unsigned int cutoff;
+    register unsigned int cutlim;
+    register unsigned int i;
+    register const char *s;
+    register unsigned char c;
+    const char *save, *end;
+    int overflow;
+
+    if (base < 0 || base == 1 || base > 36)
+	base = 10;
+
+    save = s = nptr;
+
+    /* Skip white space.  */
+    while (((unsigned char) *s) <= 32 && *s)
+	++s;
+    if (*s == '\0')
+	goto noconv;
+
+    /* Check for a sign.  */
+    if (*s == '-') {
+	negative = 1;
+	++s;
+    } else if (*s == '+') {
+	negative = 0;
+	++s;
+    } else
+	negative = 0;
+
+    if ((base == 16 && s[0] == '0' && (s[1] == 'X')) || (s[1] == 'x'))
+	s += 2;
+
+    /* If BASE is zero, figure it out ourselves.  */
+    if (base == 0) {
+	if (*s == '0') {
+	    if (s[1] == 'X' || s[1] == 'x') {
+		s += 2;
+		base = 16;
+	    } else
+		base = 8;
+	} else
+	    base = 10;
+    }
+
+    /* Save the pointer so we can check later if anything happened.  */
+    save = s;
+
+    end = 0;
+
+    cutoff = 0x7FFFFFFF / (unsigned int) base;
+    cutlim = 0x7FFFFFFF % (unsigned int) base;
+
+    overflow = 0;
+    i = 0;
+    for (c = *s; c != '\0'; c = *++s) {
+	if (s == end)
+	    break;
+	if (c >= '0' && c <= '9')
+	    c -= '0';
+	else if (c >= 'A' && c <= 'Z')
+	    c = c - 'A' + 10;
+	else if (c >= 'a' && c <= 'z')
+	    c = c - 'a' + 10;
+	else
+	    break;
+	if (c >= base)
+	    break;
+	/* Check for overflow.  */
+	if (i > cutoff || (i == cutoff && c > cutlim))
+	    overflow = 1;
+	else {
+	    i *= (unsigned int) base;
+	    i += c;
+	}
+    }
+
+    /* Check if anything actually happened.  */
+    if (s == save)
+	goto noconv;
+
+    /* Store in ENDPTR the address of one character
+       past the last character we converted.  */
+    if (endptr)
+	*endptr = (char *) s;
+
+    if (overflow)
+	return negative ? (int) 0x80000000 : (int) 0x7FFFFFFF;
+
+    /* Return the result of the appropriate sign.  */
+    return (negative ? -i : i);
+
+  noconv:
+    /* We must handle a special case here: the base is 0 or 16 and the
+       first two characters and '0' and 'x', but the rest are no
+       hexadecimal digits.  This is no error case.  We return 0 and
+       ENDPTR points to the `x`.  */
+    if (endptr) {
+	if (save - nptr >= 2 && tolower (save[-1]) == 'x' && save[-2] == '0')
+	    *endptr = (char *) &save[-1];
+	else
+	    /*  There was no number to convert.  */
+	    *endptr = (char *) nptr;
+    }
+
+    return 0L;
+}

Added: ppcrcd/yaboot/lib/vsprintf.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/lib/vsprintf.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,396 @@
+/*
+ *  linux/lib/vsprintf.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
+/*
+ * Wirzenius wrote this portably, Torvalds fucked it up :-)
+ */
+
+#include <stdarg.h>
+#include <types.h>
+#include <string.h>
+#include <ctype.h>
+
+
+/**
+ * simple_strtoul - convert a string to an unsigned long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+{
+	unsigned long result = 0,value;
+
+	if (!base) {
+		base = 10;
+		if (*cp == '0') {
+			base = 8;
+			cp++;
+			if ((*cp == 'x') && isxdigit(cp[1])) {
+				cp++;
+				base = 16;
+			}
+		}
+	}
+	while (isxdigit(*cp) &&
+	       (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+	return result;
+}
+
+/**
+ * simple_strtol - convert a string to a signed long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long simple_strtol(const char *cp,char **endp,unsigned int base)
+{
+	if(*cp=='-')
+		return -simple_strtoul(cp+1,endp,base);
+	return simple_strtoul(cp,endp,base);
+}
+
+/**
+ * simple_strtoull - convert a string to an unsigned long long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
+{
+	unsigned long long result = 0,value;
+
+	if (!base) {
+		base = 10;
+		if (*cp == '0') {
+			base = 8;
+			cp++;
+			if ((*cp == 'x') && isxdigit(cp[1])) {
+				cp++;
+				base = 16;
+			}
+		}
+	}
+	while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+	    ? toupper(*cp) : *cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+	return result;
+}
+
+/**
+ * simple_strtoll - convert a string to a signed long long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long long simple_strtoll(const char *cp,char **endp,unsigned int base)
+{
+	if(*cp=='-')
+		return -simple_strtoull(cp+1,endp,base);
+	return simple_strtoull(cp,endp,base);
+}
+
+static int skip_atoi(const char **s)
+{
+	int i=0;
+
+	while (isdigit(**s))
+		i = i*10 + *((*s)++) - '0';
+	return i;
+}
+
+#define ZEROPAD	1		/* pad with zero */
+#define SIGN	2		/* unsigned/signed long */
+#define PLUS	4		/* show plus */
+#define SPACE	8		/* space if plus */
+#define LEFT	16		/* left justified */
+#define SPECIAL	32		/* 0x */
+#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
+
+static char * number(char * str, long long num, int base, int size, int precision, int type)
+{
+	char c,sign,tmp[66];
+	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+	int i;
+
+	if (type & LARGE)
+		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	if (type & LEFT)
+		type &= ~ZEROPAD;
+	if (base < 2 || base > 36)
+		return 0;
+	c = (type & ZEROPAD) ? '0' : ' ';
+	sign = 0;
+	if (type & SIGN) {
+		if (num < 0) {
+			sign = '-';
+			num = -num;
+			size--;
+		} else if (type & PLUS) {
+			sign = '+';
+			size--;
+		} else if (type & SPACE) {
+			sign = ' ';
+			size--;
+		}
+	}
+	if (type & SPECIAL) {
+		if (base == 16)
+			size -= 2;
+		else if (base == 8)
+			size--;
+	}
+	i = 0;
+	if (num == 0)
+		tmp[i++]='0';
+	else while (num != 0)
+        {
+                int t = ((long long) num) % (unsigned int) base;
+		tmp[i++] = digits[t];
+                num = ((long long) num) / (unsigned int) base;
+        }
+	if (i > precision)
+		precision = i;
+	size -= precision;
+	if (!(type&(ZEROPAD+LEFT)))
+		while(size-->0)
+			*str++ = ' ';
+	if (sign)
+		*str++ = sign;
+	if (type & SPECIAL) {
+		if (base==8)
+			*str++ = '0';
+		else if (base==16) {
+			*str++ = '0';
+			*str++ = digits[33];
+		}
+	}
+	if (!(type & LEFT))
+		while (size-- > 0)
+			*str++ = c;
+	while (i < precision--)
+		*str++ = '0';
+	while (i-- > 0)
+		*str++ = tmp[i];
+	while (size-- > 0)
+		*str++ = ' ';
+	return str;
+}
+
+/**
+ * vsprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * Call this function if you are already dealing with a va_list.
+ * You probably want sprintf instead.
+ */
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+	int len;
+	unsigned long long num;
+	int i, base;
+	char * str;
+	const char *s;
+
+	int flags;		/* flags to number() */
+
+	int field_width;	/* width of output field */
+	int precision;		/* min. # of digits for integers; max
+				   number of chars for from string */
+	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
+	                        /* 'z' support added 23/7/1999 S.H.    */
+				/* 'z' changed to 'Z' --davidm 1/25/99 */
+
+
+	for (str=buf ; *fmt ; ++fmt) {
+		if (*fmt != '%') {
+			*str++ = *fmt;
+			continue;
+		}
+			
+		/* process flags */
+		flags = 0;
+		repeat:
+			++fmt;		/* this also skips first '%' */
+			switch (*fmt) {
+				case '-': flags |= LEFT; goto repeat;
+				case '+': flags |= PLUS; goto repeat;
+				case ' ': flags |= SPACE; goto repeat;
+				case '#': flags |= SPECIAL; goto repeat;
+				case '0': flags |= ZEROPAD; goto repeat;
+				}
+		
+		/* get field width */
+		field_width = -1;
+		if (isdigit(*fmt))
+			field_width = skip_atoi(&fmt);
+		else if (*fmt == '*') {
+			++fmt;
+			/* it's the next argument */
+			field_width = va_arg(args, int);
+			if (field_width < 0) {
+				field_width = -field_width;
+				flags |= LEFT;
+			}
+		}
+
+		/* get the precision */
+		precision = -1;
+		if (*fmt == '.') {
+			++fmt;	
+			if (isdigit(*fmt))
+				precision = skip_atoi(&fmt);
+			else if (*fmt == '*') {
+				++fmt;
+				/* it's the next argument */
+				precision = va_arg(args, int);
+			}
+			if (precision < 0)
+				precision = 0;
+		}
+
+		/* get the conversion qualifier */
+		qualifier = -1;
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+			qualifier = *fmt;
+			++fmt;
+		}
+
+		/* default base */
+		base = 10;
+
+		switch (*fmt) {
+		case 'c':
+			if (!(flags & LEFT))
+				while (--field_width > 0)
+					*str++ = ' ';
+			*str++ = (unsigned char) va_arg(args, int);
+			while (--field_width > 0)
+				*str++ = ' ';
+			continue;
+
+		case 's':
+			s = va_arg(args, char *);
+			if (!s)
+				s = "<NULL>";
+
+			len = strnlen(s, precision);
+
+			if (!(flags & LEFT))
+				while (len < field_width--)
+					*str++ = ' ';
+			for (i = 0; i < len; ++i)
+				*str++ = *s++;
+			while (len < field_width--)
+				*str++ = ' ';
+			continue;
+
+		case 'p':
+			if (field_width == -1) {
+				field_width = 2*sizeof(void *);
+				flags |= ZEROPAD;
+			}
+			str = number(str,
+				(unsigned long) va_arg(args, void *), 16,
+				field_width, precision, flags);
+			continue;
+
+
+		case 'n':
+			if (qualifier == 'l') {
+				long * ip = va_arg(args, long *);
+				*ip = (str - buf);
+			} else if (qualifier == 'Z') {
+				size_t * ip = va_arg(args, size_t *);
+				*ip = (str - buf);
+			} else {
+				int * ip = va_arg(args, int *);
+				*ip = (str - buf);
+			}
+			continue;
+
+		case '%':
+			*str++ = '%';
+			continue;
+
+		/* integer number formats - set up the flags and "break" */
+		case 'o':
+			base = 8;
+			break;
+
+		case 'X':
+			flags |= LARGE;
+		case 'x':
+			base = 16;
+			break;
+
+		case 'd':
+		case 'i':
+			flags |= SIGN;
+		case 'u':
+			break;
+
+		default:
+			*str++ = '%';
+			if (*fmt)
+				*str++ = *fmt;
+			else
+				--fmt;
+			continue;
+		}
+		if (qualifier == 'L') {
+			num = va_arg(args, unsigned long long);
+                        if( flags & SIGN)
+                                num = (signed long long) num;
+                } else if (qualifier == 'l') {
+			num = va_arg(args, unsigned long);
+			if (flags & SIGN)
+				num = (signed long) num;
+		} else if (qualifier == 'Z') {
+			num = va_arg(args, size_t);
+		} else if (qualifier == 'h') {
+			num = (unsigned short) va_arg(args, int);
+			if (flags & SIGN)
+				num = (signed short) num;
+		} else {
+			num = va_arg(args, unsigned int);
+			if (flags & SIGN)
+				num = (signed int) num;
+		}
+		str = number(str, num, base, field_width, precision, flags);
+	}
+	*str = '\0';
+	return str-buf;
+}
+
+/**
+ * sprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ */
+int sprintf(char * buf, const char *fmt, ...)
+{
+	va_list args;
+	int i;
+
+	va_start(args, fmt);
+	i=vsprintf(buf,fmt,args);
+	va_end(args);
+	return i;
+}

Added: ppcrcd/yaboot/md5.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/md5.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,383 @@
+/*
+ *  md5.c - an implementation of the MD5 algorithm and MD5 crypt
+ *
+ *  Copyright (C) 2001, 2002 Ethan Benson
+ * 
+ *  Adapted from GRUB
+ * 
+ *  Copyright (C) 2000  Free Software Foundation, Inc.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* See RFC 1321 for a description of the MD5 algorithm. */
+
+#include "string.h"
+#include "md5.h"
+
+#ifdef TEST
+# include <stdio.h>
+# define USE_MD5_PASSWORDS
+# define USE_MD5
+#endif
+
+#ifdef USE_MD5_PASSWORDS
+# define USE_MD5
+#endif
+
+#ifdef USE_MD5
+#define cpu_to_le32(x) le32_to_cpu((x))
+unsigned long le32_to_cpu(unsigned long x)
+{
+        return (((x & 0x000000ffU) << 24) |
+                ((x & 0x0000ff00U) <<  8) |
+                ((x & 0x00ff0000U) >>  8) |
+                ((x & 0xff000000U) >> 24));
+}
+
+typedef unsigned int UINT4;
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x >> (32 - (n)))))
+
+static UINT4 initstate[4] =
+{
+  0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 
+};
+
+static char s1[4] = {  7, 12, 17, 22 };
+static char s2[4] = {  5,  9, 14, 20 };
+static char s3[4] = {  4, 11, 16, 23 };
+static char s4[4] = {  6, 10, 15, 21 };
+
+static UINT4 T[64] =
+{
+  0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+  0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+  0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+  0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+  0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+  0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+  0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+  0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+  0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+  0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+  0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+  0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+  0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+  0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+  0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+  0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+};
+
+static const char *b64t =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static UINT4 state[4];
+static unsigned int length;
+static unsigned char buffer[64];
+
+static void
+md5_transform (const unsigned char block[64])
+{
+  int i, j;
+  UINT4 a,b,c,d,tmp;
+  const UINT4 *x = (UINT4 *) block;
+
+  a = state[0];
+  b = state[1];
+  c = state[2];
+  d = state[3];
+
+  /* Round 1 */
+  for (i = 0; i < 16; i++)
+    {
+      tmp = a + F (b, c, d) + le32_to_cpu (x[i]) + T[i];
+      tmp = ROTATE_LEFT (tmp, s1[i & 3]);
+      tmp += b;
+      a = d; d = c; c = b; b = tmp;
+    }
+  /* Round 2 */
+  for (i = 0, j = 1; i < 16; i++, j += 5)
+    {
+      tmp = a + G (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+16];
+      tmp = ROTATE_LEFT (tmp, s2[i & 3]);
+      tmp += b;
+      a = d; d = c; c = b; b = tmp;
+    }
+  /* Round 3 */
+  for (i = 0, j = 5; i < 16; i++, j += 3)
+    {
+      tmp = a + H (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+32];
+      tmp = ROTATE_LEFT (tmp, s3[i & 3]);
+      tmp += b;
+      a = d; d = c; c = b; b = tmp;
+    }
+  /* Round 4 */
+  for (i = 0, j = 0; i < 16; i++, j += 7)
+    {
+      tmp = a + I (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+48];
+      tmp = ROTATE_LEFT (tmp, s4[i & 3]);
+      tmp += b;
+      a = d; d = c; c = b; b = tmp;
+    }
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+}
+
+static void
+md5_init(void)
+{
+  memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+  length = 0;
+}
+
+static void
+md5_update (const char *input, int inputlen)
+{
+  int buflen = length & 63;
+  length += inputlen;
+  if (buflen + inputlen < 64) 
+    {
+      memcpy (buffer + buflen, input, inputlen);
+      buflen += inputlen;
+      return;
+    }
+  
+  memcpy (buffer + buflen, input, 64 - buflen);
+  md5_transform (buffer);
+  input += 64 - buflen;
+  inputlen -= 64 - buflen;
+  while (inputlen >= 64)
+    {
+      md5_transform (input);
+      input += 64;
+      inputlen -= 64;
+    }
+  memcpy (buffer, input, inputlen);
+  buflen = inputlen;
+}
+
+static unsigned char *
+md5_final()
+{
+  int i, buflen = length & 63;
+
+  buffer[buflen++] = 0x80;
+  memset (buffer+buflen, 0, 64 - buflen);
+  if (buflen > 56)
+    {
+      md5_transform (buffer);
+      memset (buffer, 0, 64);
+      buflen = 0;
+    }
+  
+  *(UINT4 *) (buffer + 56) = cpu_to_le32 (8 * length);
+  *(UINT4 *) (buffer + 60) = 0;
+  md5_transform (buffer);
+
+  for (i = 0; i < 4; i++)
+    state[i] = cpu_to_le32 (state[i]);
+  return (unsigned char *) state;
+}
+
+#ifdef USE_MD5_PASSWORDS
+/* If CHECK is true, check a password for correctness. Returns 0
+   if password was correct, and a value != 0 for error, similarly
+   to strcmp.
+   If CHECK is false, crypt KEY and save the result in CRYPTED.
+   CRYPTED must have a salt.  */
+int
+md5_password (const char *key, char *crypted, int check)
+{
+  int keylen = strlen (key);
+  char *salt = crypted + 3; /* skip $1$ header */
+  char *p; 
+  int saltlen;
+  int i, n;
+  unsigned char alt_result[16];
+  unsigned char *digest;
+
+  if (check)
+    saltlen = strstr (salt, "$") - salt;
+  else
+    {
+      char *end = strstr (salt, "$");
+      if (end && end - salt < 8)
+	saltlen = end - salt;
+      else
+	saltlen = 8;
+
+      salt[saltlen] = '$';
+    }
+  
+  md5_init ();
+  md5_update (key, keylen);
+  md5_update (salt, saltlen);
+  md5_update (key, keylen);
+  digest = md5_final ();
+  memcpy (alt_result, digest, 16);
+  
+  memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+  length = 0;
+  md5_update (key, keylen);
+  md5_update (crypted, 3 + saltlen); /* include the $1$ header */
+  for (i = keylen; i > 16; i -= 16)
+    md5_update (alt_result, 16);
+  md5_update (alt_result, i);
+
+  for (i = keylen; i > 0; i >>= 1)
+    md5_update (key + ((i & 1) ? keylen : 0), 1);
+  digest = md5_final ();
+
+  for (i = 0; i < 1000; i++)
+    {
+      memcpy (alt_result, digest, 16);
+
+      memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+      length = 0;
+      if ((i & 1) != 0)
+	md5_update (key, keylen);
+      else
+	md5_update (alt_result, 16);
+      
+      if (i % 3 != 0)
+	md5_update (salt, saltlen);
+
+      if (i % 7 != 0)
+	md5_update (key, keylen);
+
+      if ((i & 1) != 0)
+	md5_update (alt_result, 16);
+      else
+	md5_update (key, keylen);
+      digest = md5_final ();
+    }
+
+  p = salt + saltlen + 1;
+  for (i = 0; i < 5; i++)
+    {
+      unsigned int w = 
+	digest[i == 4 ? 5 : 12+i] | (digest[6+i] << 8) | (digest[i] << 16);
+      for (n = 4; n-- > 0;)
+	{
+	  if (check)
+	    {
+	      if (*p++ != b64t[w & 0x3f])
+		return 1;
+	    }
+	  else
+	    {
+	      *p++ = b64t[w & 0x3f];
+	    }
+	  
+	  w >>= 6;
+	}
+    }
+  {
+    unsigned int w = digest[11];
+    for (n = 2; n-- > 0;)
+      {
+	if (check)
+	  {
+	    if (*p++ != b64t[w & 0x3f])
+	      return 1;
+	  }
+	else
+	  {
+	    *p++ = b64t[w & 0x3f];
+	  }
+	
+	w >>= 6;
+      }
+  }
+
+  if (! check)
+    *p = '\0';
+  
+  return *p;
+}
+#endif
+
+#ifdef TEST
+static char *
+md5 (const char *input) 
+{
+  memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+  length = 0;
+  md5_update (input, strlen (input));
+  return md5_final ();
+}
+
+static void
+test (char *buffer, char *expected) 
+{
+  char result[16 * 3 +1];
+  unsigned char* digest = md5 (buffer);
+  int i;
+
+  for (i=0; i < 16; i++)
+    sprintf (result+2*i, "%02x", digest[i]);
+
+  if (strcmp (result, expected))
+    printf ("MD5(%s) failed: %s\n", buffer, result);
+  else
+    printf ("MD5(%s) OK\n", buffer);
+}
+
+int
+main (void)
+{
+  test ("", "d41d8cd98f00b204e9800998ecf8427e");
+  test ("a", "0cc175b9c0f1b6a831c399e269772661");
+  test ("abc", "900150983cd24fb0d6963f7d28e17f72");
+  test ("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
+  test ("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+	"d174ab98d277d9f5a5611c2c9f419d9f");
+  test ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+	"57edf4a22be3c955ac49da2e2107b67a");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz3456",
+	"6831fa90115bb9a54fbcd4f9fee0b5c4");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz345",
+	"bc40505cc94a43b7ff3e2ac027325233");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567",
+	"fa94b73a6f072a0239b52acacfbcf9fa");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz345678901234",
+	"bd201eae17f29568927414fa326f1267");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567890123",
+	"80063db1e6b70a2e91eac903f0e46b85");
+
+  if (check_md5_password ("Hello world!",
+			  "$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1"))
+    printf ("Password differs\n");
+  else
+    printf ("Password OK\n");
+  return 0;
+}
+#endif
+
+#endif

Added: ppcrcd/yaboot/partition.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/partition.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,335 @@
+/*
+ *  partition.c - partition table support
+ *
+ *  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.
+ */
+
+/*
+ *  Todo: Add disklabel (or let OF do it ?). Eventually think about
+ *        fixing CDROM handling by directly using the ATAPI layer.
+ */
+
+#include "ctype.h"
+#include "types.h"
+#include "stddef.h"
+#include "stdlib.h"
+#include "mac-part.h"
+#include "fdisk-part.h"
+#include "partition.h"
+#include "prom.h"
+#include "string.h"
+#include "linux/iso_fs.h"
+#include "debug.h"
+#include "errors.h"
+
+/* We currently don't check the partition type, some users
+ * are putting crap there and still expect it to work...
+ */
+#undef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+
+#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+static const char *valid_mac_partition_types[] = {
+     "apple_unix_svr2",
+     "linux",
+     "apple_hfs",
+     "apple_boot",
+     "apple_bootstrap",
+     NULL
+};
+#endif
+    
+
+/* Local functions */
+static unsigned long swab32(unsigned long value);
+
+#define MAX_BLOCK_SIZE	2048
+static unsigned char block_buffer[MAX_BLOCK_SIZE];
+
+static void
+add_new_partition(struct partition_t**	list, int part_number, const char *part_type,
+		  const char *part_name, unsigned long part_start, unsigned long part_size,
+		  unsigned short part_blocksize)
+{
+     struct partition_t*	part;
+     part = (struct partition_t*)malloc(sizeof(struct partition_t));
+	
+     part->part_number = part_number;
+     strncpy(part->part_type, part_type, MAX_PART_NAME);
+     strncpy(part->part_name, part_name, MAX_PART_NAME);
+     part->part_start = part_start;
+     part->part_size = part_size;
+     part->blocksize = part_blocksize;
+
+     /* Tack this entry onto the list */
+     part->next = *list;
+     *list = part;
+}
+
+/* Note, we rely on partitions being dev-block-size aligned,
+ * I have to check if it's true. If it's not, then things will get
+ * a bit more complicated
+ */
+static void
+partition_mac_lookup( const char *dev_name, prom_handle disk,
+                      unsigned int prom_blksize, struct partition_t** list )
+{
+     int block, map_size;
+
+     /* block_buffer contains block 0 from the partitions_lookup() stage */
+     struct mac_partition* part = (struct mac_partition *)block_buffer;
+     unsigned short ptable_block_size =
+	  ((struct mac_driver_desc *)block_buffer)->block_size;
+	
+     map_size = 1;
+     for (block=1; block < map_size + 1; block++)
+     {
+#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+	  int valid = 0;
+	  const char *ptype;
+#endif
+	  if (prom_readblocks(disk, block, 1, block_buffer) != 1) {
+	       prom_printf("Can't read partition %d\n", block);
+	       break;
+	  }
+	  if (part->signature != MAC_PARTITION_MAGIC) {
+#if 0
+	       prom_printf("Wrong partition %d signature\n", block);
+#endif
+	       break;
+	  }
+	  if (block == 1)
+	       map_size = part->map_count;
+		
+#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+	  /* We don't bother looking at swap partitions of any type, 
+	   * and the rest are the ones we know about */
+	  for (ptype = valid_mac_partition_types; ptype; ptype++)
+	       if (!strcmp (part->type, ptype))
+	       {
+		    valid = 1;
+		    break;
+	       }
+#if DEBUG
+	  if (!valid)
+	       prom_printf( "MAC: Unsupported partition #%d; type=%s\n",
+			    block, part->type );
+#endif
+#endif
+
+
+#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+	  if (valid)
+#endif
+	       /* We use the partition block size from the partition table.
+		* The filesystem implmentations are responsible for mapping
+		* to their own fs blocksize */
+	       add_new_partition(
+		    list, /* partition list */
+		    block, /* partition number */
+		    part->type, /* type */
+		    part->name, /* name */
+		    part->start_block + part->data_start, /* start */
+		    part->data_count, /* size */
+		    ptable_block_size );
+     }
+}
+
+/* 
+ * Same function as partition_mac_lookup(), except for fdisk
+ * partitioned disks.
+ */
+static void
+partition_fdisk_lookup( const char *dev_name, prom_handle disk,
+                        unsigned int prom_blksize, struct partition_t** list )
+{
+     int partition;
+
+     /* fdisk partition tables start at offset 0x1be
+      * from byte 0 of the boot drive.
+      */
+     struct fdisk_partition* part = 
+	  (struct fdisk_partition *) (block_buffer + 0x1be);
+
+     for (partition=1; partition <= 4 ;partition++, part++) {
+	  if (part->sys_ind == LINUX_NATIVE) {
+	       add_new_partition(  list,
+				   partition,
+				   "Linux", /* type */
+				   '\0', /* name */
+				   swab32(*(unsigned int *)(part->start4)),
+				   swab32(*(unsigned int *)(part->size4)),
+				   512 /*blksize*/ );
+	  }
+     }
+}
+
+/* I don't know if it's possible to handle multisession and other multitrack
+ * stuffs with the current OF disklabel package. This can still be implemented
+ * with direct calls to atapi stuffs.
+ * Currently, we enter this code for any device of block size 0x2048 who lacks
+ * a MacOS partition map signature.
+ */
+static int
+identify_iso_fs(ihandle device, unsigned int *iso_root_block)
+{
+     int block;
+
+     for (block = 16; block < 100; block++) {
+	  struct iso_volume_descriptor  * vdp;
+
+	  if (prom_readblocks(device, block, 1, block_buffer) != 1) {
+	       prom_printf("Can't read volume desc block %d\n", block);
+	       break;
+	  }
+ 		
+	  vdp = (struct iso_volume_descriptor *)block_buffer;
+	    
+	  /* Due to the overlapping physical location of the descriptors, 
+	   * ISO CDs can match hdp->id==HS_STANDARD_ID as well. To ensure 
+	   * proper identification in this case, we first check for ISO.
+	   */
+	  if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
+	       *iso_root_block = block;
+	       return 1;
+	  }
+     }
+	
+     return 0;
+}
+
+struct partition_t*
+partitions_lookup(const char *device)
+{
+     ihandle	disk;
+     struct mac_driver_desc *desc = (struct mac_driver_desc *)block_buffer;
+     struct partition_t* list = NULL;
+     unsigned int prom_blksize, iso_root_block;
+	
+     strncpy(block_buffer, device, 2040);
+     strcat(block_buffer, ":0");
+	
+     /* Open device */
+     disk = prom_open(block_buffer);
+     if (disk == NULL) {
+	  prom_printf("Can't open device <%s>\n", block_buffer);
+	  goto bail;
+     }
+     prom_blksize = prom_getblksize(disk);
+     DEBUG_F("block size of device is %d\n", prom_blksize);
+
+     if (prom_blksize <= 1)
+	  prom_blksize = 512;
+     if (prom_blksize > MAX_BLOCK_SIZE) {
+	  prom_printf("block_size %d not supported !\n", prom_blksize);
+	  goto bail;
+     }
+	
+     /* Read boot blocs */
+     if (prom_readblocks(disk, 0, 1, block_buffer) != 1) {
+	  prom_printf("Can't read boot blocks\n");
+	  goto bail;
+     }	
+     if (desc->signature == MAC_DRIVER_MAGIC) {
+	  /* pdisk partition format */
+	  partition_mac_lookup(device, disk, prom_blksize, &list);
+     } else if ((block_buffer[510] == 0x55) && (block_buffer[511] == 0xaa)) {
+	  /* fdisk partition format */
+	  partition_fdisk_lookup(device, disk, prom_blksize, &list);
+     } else if (prom_blksize == 2048 && identify_iso_fs(disk, &iso_root_block)) {
+	  add_new_partition(&list,
+			    0,
+			    '\0',
+			    '\0',
+			    iso_root_block,
+			    0,
+			    prom_blksize);
+	  prom_printf("ISO9660 disk\n");
+     } else {
+	  prom_printf("No supported partition table detected\n");
+	  goto bail;
+     }
+
+bail:
+     prom_close(disk);
+	
+     return list;
+}
+
+char *
+get_part_type(char *device, int partition)
+{
+     struct partition_t*	parts;
+     struct partition_t*	p;
+     struct partition_t*	found;
+     char *type = NULL;
+
+     if (prom_get_devtype(device) != FILE_DEVICE_BLOCK)
+	  return NULL;
+
+     parts = partitions_lookup(device);
+     found = NULL;
+
+     if (!parts)
+	  return '\0';
+
+     for (p = parts; p && !found; p=p->next) {
+	  DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx, type: %s, name: %s\n",
+		  p->part_number, p->part_start, p->part_size, p->part_type, p->part_name);
+	  if ((partition >= 0) && (partition == p->part_number)) {
+	       type = strdup(p->part_type);
+	       break;
+	  }	  
+     }
+     if (parts)
+	  partitions_free(parts);
+     return type;
+}
+
+/* Freed in reverse order of allocation to help malloc'ator */
+void
+partitions_free(struct partition_t* list)
+{
+     struct partition_t*	next;
+	
+     while(list) {
+	  next = list->next;
+	  free(list);
+	  list = next;
+     }
+}
+unsigned long
+swab32(unsigned long value)
+{
+     __u32 result;
+
+     __asm__("rlwimi %0,%1,24,16,23\n\t"
+	     "rlwimi %0,%1,8,8,15\n\t"
+	     "rlwimi %0,%1,24,0,7"
+	     : "=r" (result)
+	     : "r" (value), "0" (value >> 24));
+     return result;
+}
+
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/prom.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/prom.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,639 @@
+/*
+ *  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"
+
+#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<nret; i++) {
+	       void** rp = va_arg(list, void**);
+	       *rp = prom_args.args[i+nargs];
+	  }
+     } else
+	  result = 0;
+     va_end(list);
+     return result;
+}
+
+static void *
+call_method_1 (char *method, prom_handle h, int nargs, ...)
+{
+     va_list list;
+     int i;
+     struct prom_args prom_args;
+  
+     prom_args.service = "call-method";
+     prom_args.nargs = nargs+2;
+     prom_args.nret = 2;
+     prom_args.args[0] = method;
+     prom_args.args[1] = h;
+     va_start (list, nargs);
+     for (i = 0; i < nargs; ++i)
+	  prom_args.args[2+i] = va_arg(list, void *);
+     va_end(list);
+     prom_args.args[2+nargs] = 0;
+     prom_args.args[2+nargs+1] = 0;
+  
+     prom (&prom_args);
+
+     if (prom_args.args[2+nargs] != 0)
+     {
+	  prom_printf ("method '%s' failed %p\n", method, prom_args.args[2+nargs]);
+	  return 0;
+     }
+     return prom_args.args[2+nargs+1];
+}
+
+
+prom_handle
+prom_finddevice (char *name)
+{
+     return call_prom ("finddevice", 1, 1, name);
+}
+
+prom_handle
+prom_findpackage(char *path)
+{
+     return call_prom ("find-package", 1, 1, path);
+}
+
+int
+prom_getprop (prom_handle pack, char *name, void *mem, int len)
+{
+     return (int)call_prom ("getprop", 4, 1, pack, name, mem, len);
+}
+
+int
+prom_get_chosen (char *name, void *mem, int len)
+{
+     return prom_getprop (prom_chosen, name, mem, len);
+}
+
+int
+prom_get_options (char *name, void *mem, int len)
+{
+     if (prom_options == (void *)-1)
+	  return -1;
+     return prom_getprop (prom_options, name, mem, len);
+}
+
+int
+prom_get_devtype (char *device)
+{
+     phandle    dev;
+     int        result;
+     char       tmp[64];
+
+     /* Find OF device phandle */
+     dev = prom_finddevice(device);
+     if (dev == PROM_INVALID_HANDLE) {
+	  return FILE_ERR_BADDEV;
+     }
+
+     /* Check the kind of device */
+     result = prom_getprop(dev, "device_type", tmp, 63);
+     if (result == -1) {
+	  prom_printf("can't get <device_type> 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);
+}
+
+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);
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */

Added: ppcrcd/yaboot/setjmp.S
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/setjmp.S	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,56 @@
+	.globl	__sigsetjmp
+__sigsetjmp:
+	mflr	0
+	stw	1,0(3)
+	stw	2,4(3)
+	stw	0,8(3)
+	stw	14,12(3)
+	stw	15,16(3)
+	stw	16,20(3)
+	stw	17,24(3)
+	stw	18,28(3)
+	stw	19,32(3)
+	stw	20,36(3)
+	stw	21,40(3)
+	stw	22,44(3)
+	stw	23,48(3)
+	stw	24,52(3)
+	stw	25,56(3)
+	stw	26,60(3)
+	stw	27,64(3)
+	stw	28,68(3)
+	stw	29,72(3)
+	stw	30,76(3)
+	stw	31,80(3)
+	li	3,0
+	blr
+
+	.globl	longjmp
+longjmp:
+	cmpwi	0,4,0
+	bne	1f
+	li	4,1
+1:	lwz	1,0(3)
+	lwz	2,4(3)
+	lwz	0,8(3)
+	lwz	14,12(3)
+	lwz	15,16(3)
+	lwz	16,20(3)
+	lwz	17,24(3)
+	lwz	18,28(3)
+	lwz	19,32(3)
+	lwz	20,36(3)
+	lwz	21,40(3)
+	lwz	22,44(3)
+	lwz	23,48(3)
+	lwz	24,52(3)
+	lwz	25,56(3)
+	lwz	26,60(3)
+	lwz	27,64(3)
+	lwz	28,68(3)
+	lwz	29,72(3)
+	lwz	30,76(3)
+	lwz	31,80(3)
+	mtlr	0
+	mr	3,4
+	blr

Added: ppcrcd/yaboot/yaboot.c
==============================================================================
--- (empty file)
+++ ppcrcd/yaboot/yaboot.c	Wed Jun 15 22:40:03 2005
@@ -0,0 +1,1538 @@
+/*
+ *  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[1024];
+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<return> 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(char *device, char* path, int partition)
+{
+     char *conf_file = NULL, *p;
+     struct boot_file_t file;
+     int sz, opened = 0, result = 0;
+     char conf_path[512];
+     struct boot_fspec_t fspec;
+
+     /* Allocate a buffer for the config file */
+     conf_file = malloc(CONFIG_FILE_MAX);
+     if (!conf_file) {
+	  prom_printf("Can't alloc config file buffer\n");
+	  goto bail;
+     }
+
+     /* Build the path to the file */
+     if (_machine == _MACH_chrp)
+	  strcpy(conf_path, "/etc/");
+     else if (path && *path)
+	  strcpy(conf_path, path);
+     else
+	  conf_path[0] = 0;
+     strcat(conf_path, CONFIG_FILE_NAME);
+
+     /* Open it */
+     fspec.dev = device;
+     fspec.file = conf_path;
+     fspec.part = partition;
+     result = open_file(&fspec, &file);
+     if (result != FILE_ERR_OK) {
+	  prom_printf("%s:%d,", fspec.dev, fspec.part);
+	  prom_perror(result, fspec.file);
+	  prom_printf("Can't open config file\n");
+	  goto bail;
+     }
+     opened = 1;
+
+     /* Read it */
+     sz = file.fs->read(&file, CONFIG_FILE_MAX, conf_file);
+     if (sz <= 0) {
+	  prom_printf("Error, can't read config file\n");
+	  goto bail;
+     }
+     prom_printf("Config file read, %d bytes\n", sz);
+
+     /* Close the file */
+     if (opened)
+	  file.fs->close(&file);
+     opened = 0;
+
+     /* Call the parsing code in cfg.c */
+     if (cfg_parse(conf_path, conf_file, sz) < 0) {
+	  prom_printf ("Syntax error or read error config\n");
+	  goto bail;
+     }
+
+     DEBUG_F("Config file successfully parsed, %d bytes\n", sz);
+
+     /* Now, we do the initialisations stored in the config file */
+     p = cfg_get_strg(0, "init-code");
+     if (p)
+	  prom_interpret(p);
+
+     password = cfg_get_strg(0, "password");
+	
+#ifdef CONFIG_COLOR_TEXT
+     p = cfg_get_strg(0, "fgcolor");
+     if (p) {
+	  DEBUG_F("fgcolor=%s\n", p);
+	  fgcolor = check_color_text_ui(p);
+	  if (fgcolor == -1) {
+	       prom_printf("Invalid fgcolor: \"%s\".\n", p);
+	  }
+     }
+     p = cfg_get_strg(0, "bgcolor");
+     if (p) {
+	  DEBUG_F("bgcolor=%s\n", p);
+	  bgcolor = check_color_text_ui(p);
+	  if (bgcolor == -1)
+	       prom_printf("Invalid bgcolor: \"%s\".\n", p);
+     }
+     if (bgcolor >= 0) {
+	  char temp[64];
+	  sprintf(temp, "%x to background-color", bgcolor); 
+	  prom_interpret(temp); 
+#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 (result != 1 && conf_file)
+	  free(conf_file);
+    	
+     return result;
+}
+
+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 *p, *q, *endp;
+     int c, n;
+     char *imagename = 0, *label;
+     int timeout = -1;
+     int beg = 0, end;
+     int singlekey = 0;
+     int restricted = 0;
+     static int first = 1;
+     static char bootargs[1024];
+     static char imagepath[1024];
+     static char initrdpath[1024];
+     static char sysmappath[1024];
+
+     pause_after = 0;
+     memset(params, 0, sizeof(*params));
+     params->args = "";
+     params->kernel.part = -1;
+     params->rd.part = -1;
+     params->sysmap.part = -1;
+     defpart = boot.part;
+    
+     cmdinit();
+
+     if (first) {
+	  first = 0;
+	  prom_get_chosen("bootargs", bootargs, sizeof(bootargs));
+	  imagename = bootargs;
+	  word_split(&imagename, &params->args);
+	  timeout = DEFAULT_TIMEOUT;
+	  if (imagename) {
+	       prom_printf("Default supplied on the command line: %s ", imagename);
+	       if (params->args)
+		    prom_printf("%s", params->args);
+	       prom_printf("\n");
+	  }
+	  if (useconf && (q = cfg_get_strg(0, "timeout")) != 0 && *q != 0)
+	       timeout = simple_strtol(q, NULL, 0);
+     }
+
+     prom_printf("boot: ");
+     c = -1;
+     if (timeout != -1) {
+	  beg = prom_getms();
+	  if (timeout > 0) {
+	       end = beg + 100 * timeout;
+	       do {
+		    c = prom_nbgetchar();
+	       } while (c == -1 && prom_getms() <= end);
+	  }
+	  if (c == -1)
+	       c = '\n';
+	  else if (c != '\n' && c != '\t' && c != '\r' && c != '\b' ) {
+	       cbuff[0] = c;
+	       cbuff[1] = 0;
+	  }
+     }
+
+     if (c != -1 && c != '\n' && c != '\r') {
+	  if (c == '\t') {
+	       maintabfunc ();
+	  }  else if (c >= ' ') {
+	       cbuff[0] = c;
+	       cbuff[1] = 0;
+	       if ((cfg_get_flag (cbuff, "single-key")) && useconf) {
+		    imagename = cbuff;
+		    singlekey = 1;
+		    prom_printf("%s\n", cbuff);
+	       }
+	  }
+     }
+
+     if (c == '\n' || c == '\r') {
+	  if (!imagename)
+	       imagename = cfg_get_default();
+	  if (imagename)
+	       prom_printf("%s", imagename);
+	  if (params->args)
+	       prom_printf(" %s", params->args);
+	  prom_printf("\n");
+     } else if (!singlekey) {
+	  cmdedit(maintabfunc, 0);
+	  prom_printf("\n");
+	  strcpy(given_bootargs, cbuff);
+	  given_bootargs_by_user = 1;
+	  imagename = cbuff;
+	  word_split(&imagename, &params->args);
+     }
+
+     /* chrp gets this wrong, force it -- Cort */
+     if ( useconf && (!imagename || imagename[0] == 0 ))
+	  imagename = cfg_get_default();
+
+     label = 0;
+     defdevice = boot.dev;
+
+     if (useconf) {
+	  defdevice = cfg_get_strg(0, "device");
+	  p = cfg_get_strg(0, "partition");
+	  if (p) {
+	       n = simple_strtol(p, &endp, 10);
+	       if (endp != p && *endp == 0)
+		    defpart = n;
+	  }
+	  p = cfg_get_strg(0, "pause-message");
+	  if (p)
+	       pause_message = p;
+	  if (cfg_get_flag(0, "restricted"))
+	       restricted = 1;
+	  p = cfg_get_strg(imagename, "image");
+	  if (p && *p) {
+	       label = imagename;
+	       imagename = p;
+	       defdevice = cfg_get_strg(label, "device");
+	       if(!defdevice) defdevice=boot.dev;
+	       p = cfg_get_strg(label, "partition");
+	       if (p) {
+		    n = simple_strtol(p, &endp, 10);
+		    if (endp != p && *endp == 0)
+			 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 <return> to boot it.\n\n"
+	       "To boot any other label simply type its name and press <return>.\n\n"
+	       "To boot a kernel image which is not defined in the yaboot configuration \n"
+	       "file, enter the kernel image name as [[device:][partno],]/path, where \n"
+	       "\"device:\" is the OpenFirmware device path to the disk the image \n"
+	       "resides on, and \"partno\" is the partition number the image resides on.\n"
+	       "Note that the comma (,) is only required if you specify an OpenFirmware\n"
+	       "device, if you only specify a filename you should not start it with a \",\"\n\n"
+	       "If you omit \"device:\" and \"partno\" yaboot will use the values of \n"
+	       "\"device=\" and \"partition=\" in yaboot.conf, right now those are set to: \n"
+	       "device=%s\n"
+	       "partition=%d\n\n", defdevice, defpart);
+	  return 0;
+     }
+
+     if (!strcmp (imagename, "halt")) {
+	  if (password)
+	       check_password ("Restricted command.");
+	  prom_pause();
+	  return 0;
+     }
+     if (!strcmp (imagename, "bye")) {
+	  if (password) {
+	       check_password ("Restricted command.");
+	       return 1;
+	  }
+	  return 1; 
+     }
+
+     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", &params->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", &params->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", &params->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(&params))
+	       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(&params.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(&params.sysmap, &file);
+	       if (result != FILE_ERR_OK) {
+		    prom_printf("%s:%d,", params.sysmap.dev, params.sysmap.part);
+		    prom_perror(result, params.sysmap.file);
+	       }
+	       else {
+		    sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0);
+		    if (sysmap_base == (void *)-1) {
+			 prom_printf("Claim failed for sysmap memory\n");
+			 sysmap_base = 0;
+		    } else {
+			 sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base);
+			 if (sysmap_size == 0)
+			      sysmap_base = 0;
+			 else
+			      ((char *)sysmap_base)[sysmap_size++] = 0;
+		    }
+		    file.fs->close(&file);
+		    memset(&file, 0, sizeof(file));
+	       }
+	       if (sysmap_base) {
+		    prom_printf("System.map loaded at %p, size: %lu Kbytes\n",
+				sysmap_base, sysmap_size >> 10);
+		    loadinfo.memsize += _ALIGN(0x100000, 0x1000);
+	       } else {
+		    prom_printf("System.map load failed !\n");
+		    prom_pause();
+	       }
+	  }
+
+	  /* If ramdisk, load it (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(&params.rd, &file);
+	       if (result != FILE_ERR_OK) {
+		    prom_printf("%s:%d,", params.rd.dev, params.rd.part);
+		    prom_perror(result, params.rd.file);
+	       }
+	       else {
+#define INITRD_CHUNKSIZE 0x400000
+		    initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0);
+		    if (initrd_base == (void *)-1) {
+			 prom_printf("Claim failed for initrd memory\n");
+			 initrd_base = 0;
+		    } else {
+			 initrd_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_base);
+			 if (initrd_size == 0)
+			      initrd_base = 0;
+			 initrd_read = initrd_size;
+			 initrd_more = initrd_base;
+			 while (initrd_read == INITRD_CHUNKSIZE ) { /* need to read more? */
+			      initrd_want = (void *)((unsigned long)initrd_more+INITRD_CHUNKSIZE);
+			      initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0);
+			      if (initrd_more != initrd_want) {
+				   prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more);
+				   break;
+			      }
+			      initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
+			      DEBUG_F("  block at %p rc=%lu\n",initrd_more,initrd_read);
+			      initrd_size += initrd_read;
+			 }
+		    }
+		    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	addr, loadaddr;
+
+     /* Read the rest of the Elf header... */
+     if ((*(file->fs->read))(file, size, &e->e_version) < size) {
+	  prom_printf("\nCan't read Elf32 image header\n");
+	  return 0;
+     }
+
+     DEBUG_F("Elf32 header:\n");
+     DEBUG_F(" e.e_type      = %d\n", (int)e->e_type);
+     DEBUG_F(" e.e_machine   = %d\n", (int)e->e_machine);
+     DEBUG_F(" e.e_version   = %d\n", (int)e->e_version);
+     DEBUG_F(" e.e_entry     = 0x%08x\n", (int)e->e_entry);
+     DEBUG_F(" e.e_phoff     = 0x%08x\n", (int)e->e_phoff);
+     DEBUG_F(" e.e_shoff     = 0x%08x\n", (int)e->e_shoff);
+     DEBUG_F(" e.e_flags     = %d\n", (int)e->e_flags);
+     DEBUG_F(" e.e_ehsize    = 0x%08x\n", (int)e->e_ehsize);
+     DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
+     DEBUG_F(" e.e_phnum     = %d\n", (int)e->e_phnum);
+
+     loadinfo->entry = e->e_entry;
+
+     if (e->e_phnum > MAX_HEADERS) {
+	  prom_printf ("Can only load kernels with one program header\n");
+	  return 0;
+     }
+
+     ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum);
+     if (!ph) {
+	  prom_printf ("Malloc error\n");
+	  return 0;
+     }
+
+     /* Now, we read the section header */
+     if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
+	  prom_printf ("seek error\n");
+	  return 0;
+     }
+     if ((*(file->fs->read))(file, sizeof(Elf32_Phdr) * e->e_phnum, ph) !=
+	 sizeof(Elf32_Phdr) * e->e_phnum) {
+	  prom_printf ("read error\n");
+	  return 0;
+     }
+
+     /* Scan through the program header
+      * HACK:  We must return the _memory size of the kernel image, not the
+      *        file size (because we have to leave room before other boot
+      *	  infos. This code works as a side effect of the fact that
+      *	  we have one section and vaddr == p_paddr
+      */
+     loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
+     p = ph;
+     for (i = 0; i < e->e_phnum; ++i, ++p) {
+	  if (p->p_type != PT_LOAD || p->p_offset == 0)
+	       continue;
+	  if (loadinfo->memsize == 0) {
+	       loadinfo->offset = p->p_offset;
+	       loadinfo->memsize = p->p_memsz;
+	       loadinfo->filesize = p->p_filesz;
+	       loadinfo->load_loc = p->p_vaddr;
+	  } else {
+	       loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
+	       loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
+	  }
+     }
+
+     if (loadinfo->memsize == 0) {
+	  prom_printf("Can't find a loadable segment !\n");
+	  return 0;
+     }
+
+     /* leave some room (1Mb) for boot infos */
+     loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
+     /* Claim OF memory */
+     DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
+
+     /* 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 = e->e_entry;
+     }
+
+     /* On some systems, loadaddr may already be claimed, so try some
+      * other nearby addresses before giving up.
+      */
+     for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
+	  loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
+	  if (loadinfo->base != (void *)-1) break;
+     }
+     if (loadinfo->base == (void *)-1) {
+	  prom_printf("Claim error, can't allocate kernel memory\n");
+	  return 0;
+     }	
+
+     DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
+	     loadinfo->base, loadinfo->memsize);
+     DEBUG_F("    wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
+	     loadaddr, loadinfo->memsize);
+
+     /* Load the program segments... */
+     p = ph;
+     for (i = 0; i < e->e_phnum; ++i, ++p) {
+	  unsigned long offset;
+	  if (p->p_type != PT_LOAD || p->p_offset == 0)
+	       continue;
+
+	  /* Now, we skip to the image itself */
+	  if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
+	       prom_printf ("Seek error\n");
+	       prom_release(loadinfo->base, loadinfo->memsize);
+	       return 0;
+	  }
+	  offset = p->p_vaddr - loadinfo->load_loc;
+	  if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
+	       prom_printf ("Read failed\n");
+	       prom_release(loadinfo->base, loadinfo->memsize);
+	       return 0;
+	  }
+     }
+
+     free(ph);
+    
+     /* Return success at loading the Elf32 kernel */
+     return 1;
+}
+
+static int
+load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
+{
+     int			i;
+     Elf64_Ehdr		*e = &(loadinfo->elf.elf64hdr);
+     Elf64_Phdr		*p, *ph;
+     int			size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident);
+     unsigned long	addr, loadaddr;
+
+     /* Read the rest of the Elf header... */
+     if ((*(file->fs->read))(file, size, &e->e_version) < size) {
+	  prom_printf("\nCan't read Elf64 image header\n");
+	  return 0;
+     }
+
+     DEBUG_F("Elf64 header:\n");
+     DEBUG_F(" e.e_type      = %d\n", (int)e->e_type);
+     DEBUG_F(" e.e_machine   = %d\n", (int)e->e_machine);
+     DEBUG_F(" e.e_version   = %d\n", (int)e->e_version);
+     DEBUG_F(" e.e_entry     = 0x%016lx\n", (long)e->e_entry);
+     DEBUG_F(" e.e_phoff     = 0x%016lx\n", (long)e->e_phoff);
+     DEBUG_F(" e.e_shoff     = 0x%016lx\n", (long)e->e_shoff);
+     DEBUG_F(" e.e_flags     = %d\n", (int)e->e_flags);
+     DEBUG_F(" e.e_ehsize    = 0x%08x\n", (int)e->e_ehsize);
+     DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
+     DEBUG_F(" e.e_phnum     = %d\n", (int)e->e_phnum);
+
+     loadinfo->entry = e->e_entry;
+
+     if (e->e_phnum > MAX_HEADERS) {
+	  prom_printf ("Can only load kernels with one program header\n");
+	  return 0;
+     }
+
+     ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum);
+     if (!ph) {
+	  prom_printf ("Malloc error\n");
+	  return 0;
+     }
+
+     /* Now, we read the section header */
+     if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
+	  prom_printf ("Seek error\n");
+	  return 0;
+     }
+     if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) !=
+	 sizeof(Elf64_Phdr) * e->e_phnum) {
+	  prom_printf ("Read error\n");
+	  return 0;
+     }
+
+     /* Scan through the program header
+      * HACK:  We must return the _memory size of the kernel image, not the
+      *        file size (because we have to leave room before other boot
+      *	  infos. This code works as a side effect of the fact that
+      *	  we have one section and vaddr == p_paddr
+      */
+     loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
+     p = ph;
+     for (i = 0; i < e->e_phnum; ++i, ++p) {
+	  if (p->p_type != PT_LOAD || p->p_offset == 0)
+	       continue;
+	  if (loadinfo->memsize == 0) {
+	       loadinfo->offset = p->p_offset;
+	       loadinfo->memsize = p->p_memsz;
+	       loadinfo->filesize = p->p_filesz;
+	       loadinfo->load_loc = p->p_vaddr;
+	  } else {
+	       loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
+	       loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
+	  }
+     }
+
+     if (loadinfo->memsize == 0) {
+	  prom_printf("Can't find a loadable segment !\n");
+	  return 0;
+     }
+
+     /* leave some room (1Mb) for boot infos */
+     loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
+     /* Claim OF memory */
+     DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
+
+     /* 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;
+     }
+
+     /* On some systems, loadaddr may already be claimed, so try some
+      * other nearby addresses before giving up.
+      */
+     for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
+	  loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
+	  if (loadinfo->base != (void *)-1) break;
+     }
+     if (loadinfo->base == (void *)-1) {
+	  prom_printf("Claim error, can't allocate kernel memory\n");
+	  return 0;
+     }	
+
+     DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
+	     loadinfo->base, loadinfo->memsize);
+     DEBUG_F("    wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
+	     loadaddr, loadinfo->memsize);
+
+     /* Load the program segments... */
+     p = ph;
+     for (i = 0; i < e->e_phnum; ++i, ++p) {
+	  unsigned long offset;
+	  if (p->p_type != PT_LOAD || p->p_offset == 0)
+	       continue;
+
+	  /* Now, we skip to the image itself */
+	  if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
+	       prom_printf ("Seek error\n");
+	       prom_release(loadinfo->base, loadinfo->memsize);
+	       return 0;
+	  }
+	  offset = p->p_vaddr - loadinfo->load_loc;
+	  if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
+	       prom_printf ("Read failed\n");
+	       prom_release(loadinfo->base, loadinfo->memsize);
+	       return 0;
+	  }
+     }
+
+     free(ph);
+    
+     /* Return success at loading the Elf64 kernel */
+     return 1;
+}
+
+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;
+
+     if (_machine == _MACH_Pmac)
+	  setup_display();
+	
+     prom_get_chosen("bootpath", bootdevice, sizeof(bootdevice));
+     DEBUG_F("/chosen/bootpath = %s\n", bootdevice);
+     if (bootdevice[0] == 0) {
+	  prom_get_options("boot-device", bootdevice, sizeof(bootdevice));
+	  DEBUG_F("boot-device = %s\n", bootdevice);
+     }
+     if (bootdevice[0] == 0) {
+	  prom_printf("Couldn't determine boot device\n");
+	  return -1;
+     }
+
+     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 (strlen(boot.file)) {
+	  if (!strncmp(boot.file, "\\\\", 2))
+	       boot.file = "\\\\";
+	  else {
+	       char *p, *last;
+	       p = last = boot.file;
+	       while(*p) {
+		    if (*p == '\\')
+			 last = p;
+		    p++;
+	       }
+	       if (p)
+		    *(last) = 0;
+	       else
+		    boot.file = "";
+	       if (strlen(boot.file))
+		    strcat(boot.file, "\\");
+	  }
+     }
+     DEBUG_F("After pmac path kludgeup: dev=%s, part=%d, file=%s\n",
+	     boot.dev, boot.part, boot.file);
+
+     useconf = load_config_file(boot.dev, boot.file, boot.part);
+
+     prom_printf("Welcome to yaboot version " VERSION "\n");
+     prom_printf("Enter \"help\" to get some basic usage information\n");
+
+     /* I am fed up with lusers using the wrong partition type and
+	mailing me *when* it breaks */
+
+     if (_machine == _MACH_Pmac) {
+	  char *entry = cfg_get_strg(0, "ptypewarning");
+	  int warn = 1;
+	  if (entry)
+	       warn = strcmp(entry,
+			     "I_know_the_partition_type_is_wrong_and_will_NOT_send_mail_when_booting_breaks");
+	  if (warn) {
+	       ptype = get_part_type(boot.dev, boot.part);
+	       if ((ptype != NULL) && (strcmp(ptype, "Apple_Bootstrap")))
+		    prom_printf("\nWARNING: Bootstrap partition type is wrong: \"%s\"\n"
+				"         type should be: \"Apple_Bootstrap\"\n\n", ptype);
+	  }
+     }
+
+     yaboot_text_ui();
+	
+     prom_printf("Bye.\n");
+     return 0;
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "k&r"
+ * c-basic-offset: 5
+ * End:
+ */



More information about the pld-cvs-commit mailing list