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, ¶ms->args);
+ timeout = DEFAULT_TIMEOUT;
+ if (imagename) {
+ prom_printf("Default supplied on the command line: %s ", imagename);
+ if (params->args)
+ prom_printf("%s", params->args);
+ prom_printf("\n");
+ }
+ if (useconf && (q = cfg_get_strg(0, "timeout")) != 0 && *q != 0)
+ timeout = simple_strtol(q, NULL, 0);
+ }
+
+ prom_printf("boot: ");
+ c = -1;
+ if (timeout != -1) {
+ beg = prom_getms();
+ if (timeout > 0) {
+ end = beg + 100 * timeout;
+ do {
+ c = prom_nbgetchar();
+ } while (c == -1 && prom_getms() <= end);
+ }
+ if (c == -1)
+ c = '\n';
+ else if (c != '\n' && c != '\t' && c != '\r' && c != '\b' ) {
+ cbuff[0] = c;
+ cbuff[1] = 0;
+ }
+ }
+
+ if (c != -1 && c != '\n' && c != '\r') {
+ if (c == '\t') {
+ maintabfunc ();
+ } else if (c >= ' ') {
+ cbuff[0] = c;
+ cbuff[1] = 0;
+ if ((cfg_get_flag (cbuff, "single-key")) && useconf) {
+ imagename = cbuff;
+ singlekey = 1;
+ prom_printf("%s\n", cbuff);
+ }
+ }
+ }
+
+ if (c == '\n' || c == '\r') {
+ if (!imagename)
+ imagename = cfg_get_default();
+ if (imagename)
+ prom_printf("%s", imagename);
+ if (params->args)
+ prom_printf(" %s", params->args);
+ prom_printf("\n");
+ } else if (!singlekey) {
+ cmdedit(maintabfunc, 0);
+ prom_printf("\n");
+ strcpy(given_bootargs, cbuff);
+ given_bootargs_by_user = 1;
+ imagename = cbuff;
+ word_split(&imagename, ¶ms->args);
+ }
+
+ /* chrp gets this wrong, force it -- Cort */
+ if ( useconf && (!imagename || imagename[0] == 0 ))
+ imagename = cfg_get_default();
+
+ label = 0;
+ defdevice = boot.dev;
+
+ if (useconf) {
+ defdevice = cfg_get_strg(0, "device");
+ p = cfg_get_strg(0, "partition");
+ if (p) {
+ n = simple_strtol(p, &endp, 10);
+ if (endp != p && *endp == 0)
+ defpart = n;
+ }
+ p = cfg_get_strg(0, "pause-message");
+ if (p)
+ pause_message = p;
+ if (cfg_get_flag(0, "restricted"))
+ restricted = 1;
+ p = cfg_get_strg(imagename, "image");
+ if (p && *p) {
+ label = imagename;
+ imagename = p;
+ defdevice = cfg_get_strg(label, "device");
+ if(!defdevice) defdevice=boot.dev;
+ p = cfg_get_strg(label, "partition");
+ if (p) {
+ n = simple_strtol(p, &endp, 10);
+ if (endp != p && *endp == 0)
+ 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", ¶ms->kernel)) {
+ prom_printf("%s: Unable to parse\n", imagepath);
+ return 0;
+ }
+ DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev,
+ params->kernel.part, params->kernel.file);
+
+ if (useconf) {
+ p = cfg_get_strg(label, "initrd");
+ if (p && *p) {
+ DEBUG_F("Parsing initrd path <%s>\n", p);
+ strncpy(initrdpath, p, 1024);
+ if (!parse_device_path(initrdpath, defdevice, defpart,
+ "/root.bin", ¶ms->rd)) {
+ prom_printf("%s: Unable to parse\n", imagepath);
+ return 0;
+ }
+ }
+ p = cfg_get_strg(label, "sysmap");
+ if (p && *p) {
+ DEBUG_F("Parsing sysmap path <%s>\n", p);
+ strncpy(sysmappath, p, 1024);
+ if (!parse_device_path(sysmappath, defdevice, defpart,
+ "/boot/System.map", ¶ms->sysmap)) {
+ prom_printf("%s: Unable to parse\n", imagepath);
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+/* This is derived from quik core. To be changed to first parse the headers
+ * doing lazy-loading, and then claim the memory before loading the kernel
+ * to it
+ * We also need to add initrd support to this whole mecanism
+ */
+void
+yaboot_text_ui(void)
+{
+#define MAX_HEADERS 32
+
+ struct boot_file_t file;
+ int result;
+ static struct boot_param_t params;
+ void *initrd_base;
+ unsigned long initrd_size;
+ void *sysmap_base;
+ unsigned long sysmap_size;
+ kernel_entry_t kernel_entry;
+ struct bi_record* birec;
+ char* loc=NULL;
+ loadinfo_t loadinfo;
+ void *initrd_more,*initrd_want;
+ unsigned long initrd_read;
+
+ loadinfo.load_loc = 0;
+
+ for (;;) {
+ initrd_size = 0;
+ initrd_base = 0;
+ sysmap_base = 0;
+ sysmap_size = 0;
+
+ if (get_params(¶ms))
+ return;
+ if (!params.kernel.file)
+ continue;
+
+ prom_printf("Please wait, loading kernel...\n");
+
+ memset(&file, 0, sizeof(file));
+
+ if (strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.kernel.file[0] != '/'
+ && params.kernel.file[0] != '\\') {
+ loc=(char*)malloc(strlen(params.kernel.file)+3);
+ if (!loc) {
+ prom_printf ("malloc error\n");
+ goto next;
+ }
+ strcpy(loc,boot.file);
+ strcat(loc,params.kernel.file);
+ free(params.kernel.file);
+ params.kernel.file=loc;
+ }
+ result = open_file(¶ms.kernel, &file);
+ if (result != FILE_ERR_OK) {
+ prom_printf("%s:%d,", params.kernel.dev, params.kernel.part);
+ prom_perror(result, params.kernel.file);
+ goto next;
+ }
+
+ /* Read the Elf e_ident, e_type and e_machine fields to
+ * determine Elf file type
+ */
+ if (file.fs->read(&file, sizeof(Elf_Ident), &loadinfo.elf) < sizeof(Elf_Ident)) {
+ prom_printf("\nCan't read Elf e_ident/e_type/e_machine info\n");
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ goto next;
+ }
+
+ if (is_elf32(&loadinfo)) {
+ if (!load_elf32(&file, &loadinfo)) {
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ goto next;
+ }
+ prom_printf(" Elf32 kernel loaded...\n");
+ } else if (is_elf64(&loadinfo)) {
+ if (!load_elf64(&file, &loadinfo)) {
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ goto next;
+ }
+ prom_printf(" Elf64 kernel loaded...\n");
+ } else {
+ prom_printf ("%s: Not a valid ELF image\n", params.kernel.file);
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ goto next;
+ }
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+
+ /* If sysmap, load it (only if booting a vmlinux).
+ */
+ if (flat_vmlinux && params.sysmap.file) {
+ prom_printf("Loading System.map ...\n");
+ if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.sysmap.file[0] != '/'
+ && params.sysmap.file[0] != '\\') {
+ if (loc) free(loc);
+ loc=(char*)malloc(strlen(params.sysmap.file)+3);
+ if (!loc) {
+ prom_printf ("malloc error\n");
+ goto next;
+ }
+ strcpy(loc,boot.file);
+ strcat(loc,params.sysmap.file);
+ free(params.sysmap.file);
+ params.sysmap.file=loc;
+ }
+
+ result = open_file(¶ms.sysmap, &file);
+ if (result != FILE_ERR_OK) {
+ prom_printf("%s:%d,", params.sysmap.dev, params.sysmap.part);
+ prom_perror(result, params.sysmap.file);
+ }
+ else {
+ sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0);
+ if (sysmap_base == (void *)-1) {
+ prom_printf("Claim failed for sysmap memory\n");
+ sysmap_base = 0;
+ } else {
+ sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base);
+ if (sysmap_size == 0)
+ sysmap_base = 0;
+ else
+ ((char *)sysmap_base)[sysmap_size++] = 0;
+ }
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ }
+ if (sysmap_base) {
+ prom_printf("System.map loaded at %p, size: %lu Kbytes\n",
+ sysmap_base, sysmap_size >> 10);
+ loadinfo.memsize += _ALIGN(0x100000, 0x1000);
+ } else {
+ prom_printf("System.map load failed !\n");
+ prom_pause();
+ }
+ }
+
+ /* If ramdisk, load it (only if booting a vmlinux). For now, we
+ * can't tell the size it will be so we claim an arbitrary amount
+ * of 4Mb.
+ */
+ if (flat_vmlinux && params.rd.file) {
+ if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.rd.file[0] != '/'
+ && params.kernel.file[0] != '\\')
+ {
+ if (loc) free(loc);
+ loc=(char*)malloc(strlen(params.rd.file)+3);
+ if (!loc) {
+ prom_printf ("Malloc error\n");
+ goto next;
+ }
+ strcpy(loc,boot.file);
+ strcat(loc,params.rd.file);
+ free(params.rd.file);
+ params.rd.file=loc;
+ }
+ prom_printf("Loading ramdisk...\n");
+ result = open_file(¶ms.rd, &file);
+ if (result != FILE_ERR_OK) {
+ prom_printf("%s:%d,", params.rd.dev, params.rd.part);
+ prom_perror(result, params.rd.file);
+ }
+ else {
+#define INITRD_CHUNKSIZE 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