diff -u -r -N arcboot-0.3.8.4/arclib/Makefile arcboot-onion/arclib/Makefile --- arcboot-0.3.8.4/arclib/Makefile 2002-02-03 22:53:42.000000000 +0000 +++ arcboot-onion/arclib/Makefile 2004-11-21 15:13:08.000000000 +0000 @@ -1,8 +1,7 @@ # # Copyright 1999 Silicon Graphics, Inc. # -CFLAGS = -O -Werror -Wall -mno-abicalls -G 0 -fno-pic -ASFLAGS= -mno-abicalls -G 0 -fno-pic +CFLAGS = -O2 -Werror -Wall -mno-abicalls -G 0 -fno-pic OBJECTS = arc.o stdio.o stdlib.o string.o @@ -12,5 +11,9 @@ rm -f $@ $(AR) -cr $@ $(OBJECTS) +install: libarc.a + install -d ${PREFIX}/${LIBDIR} + install -m 644 $< ${PREFIX}/${LIBDIR} + clean: rm -f libarc.a $(OBJECTS) diff -u -r -N arcboot-0.3.8.4/arclib/stdio.c arcboot-onion/arclib/stdio.c --- arcboot-0.3.8.4/arclib/stdio.c 2002-08-03 10:07:21.000000000 +0000 +++ arcboot-onion/arclib/stdio.c 2004-11-25 13:49:57.000000000 +0000 @@ -38,7 +38,6 @@ return status; } - int fgetc(FILE * stream) { LONG status; @@ -76,6 +75,7 @@ int count = 0; const char *str; unsigned int uint; + static char tmp[2]; if (format != NULL) { while (*format != '\0') { @@ -131,6 +131,14 @@ count += strlen(str); break; + case 'c': + tmp[0] = va_arg(ap, int); + tmp[1] = 0x0; + if (fputs(tmp, stream) == EOF) + return EOF; + count += 1; + break; + case '%': if (fputs("%", stream) == EOF) return EOF; diff -u -r -N arcboot-0.3.8.4/common/Makefile arcboot-onion/common/Makefile --- arcboot-0.3.8.4/common/Makefile 2004-09-25 20:55:26.000000000 +0000 +++ arcboot-onion/common/Makefile 2004-11-21 15:13:08.000000000 +0000 @@ -1,3 +1,5 @@ +SUBARCH ?= IP22 + CFLAGS = -Wall -O2 -I. -I../arclib -DSUBARCH=${SUBARCH} TARGETS = print_loadaddr @@ -10,5 +12,7 @@ $(TARGETS): print_loadaddr.c subarch.h $(HOSTCC) $(HOSTCFLAGS) -o $@ $< +install: + clean: rm -f $(TARGETS) *.a *.o tags diff -u -r -N arcboot-0.3.8.4/common/print_loadaddr.c arcboot-onion/common/print_loadaddr.c --- arcboot-0.3.8.4/common/print_loadaddr.c 2004-09-25 20:56:49.000000000 +0000 +++ arcboot-onion/common/print_loadaddr.c 2004-11-21 15:13:08.000000000 +0000 @@ -2,12 +2,29 @@ #include #include +#include #include "subarch.h" -int main() +int main(int argc, char *argv[]) { - printf("0x%lx\n", kernel_load[SUBARCH].base - + kernel_load[SUBARCH].reserved); - return(0); + int subarch = SUBARCH; + + if (argc == 2) { + if (!strcasecmp(argv[1], "ip22")) + subarch = IP22; + else if (!strcasecmp(argv[1], "ip32")) + subarch = IP32; + else { + fprintf(stderr, + "Unknown subarchitecture %s requested\n", + argv[1]); + return 1; + } + } + + printf("%#08x\n", kernel_load[subarch].base + + kernel_load[subarch].reserved); + + return 0; } diff -u -r -N arcboot-0.3.8.4/common/print_outputformat arcboot-onion/common/print_outputformat --- arcboot-0.3.8.4/common/print_outputformat 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/common/print_outputformat 2004-11-21 15:13:08.000000000 +0000 @@ -0,0 +1,9 @@ +#!/bin/sh + +# default to ecoff + +case $1 in + ip32 | IP32) echo "elf32-tradbigmips" ;; + ip22 | IP22) echo "ecoff-bigmips" ;; + *) echo "ecoff-bigmips" ;; +esac diff -u -r -N arcboot-0.3.8.4/common/subarch.h arcboot-onion/common/subarch.h --- arcboot-0.3.8.4/common/subarch.h 2004-09-25 20:56:17.000000000 +0000 +++ arcboot-onion/common/subarch.h 2004-11-21 18:33:15.000000000 +0000 @@ -34,7 +34,7 @@ }, { /* IP32 */ .base = 0x80004000, - .reserved = 0x800000, + .reserved = 0x1400000, }, }; diff -u -r -N arcboot-0.3.8.4/common/version.h arcboot-onion/common/version.h --- arcboot-0.3.8.4/common/version.h 2004-03-01 13:01:26.000000000 +0000 +++ arcboot-onion/common/version.h 2004-11-21 16:59:37.000000000 +0000 @@ -1 +1 @@ -#define __ARCSBOOT_VERSION__ "0.3.8" +#define __ARCSBOOT_VERSION__ "0.3.8.4-1" diff -u -r -N arcboot-0.3.8.4/debian/rules arcboot-onion/debian/rules --- arcboot-0.3.8.4/debian/rules 2004-09-25 21:47:01.000000000 +0000 +++ arcboot-onion/debian/rules 2004-11-21 15:13:08.000000000 +0000 @@ -8,7 +8,12 @@ realver := $(shell dpkg-parsechangelog | awk -F' ' '/^Version:/ {print $$2}' | awk -F- '{print $$1}') PREFIX_ARCB=${CURDIR}/debian/arcboot +BIN_ARCB=usr/sbin +LIB_ARCB=usr/lib/arcboot + PREFIX_TIP22=${CURDIR}/debian/tip22 +BIN_TIP22=usr/sbin +LIB_TIP22=usr/lib/tip22 architecture=$(dpkg --print-architecture) @@ -26,12 +31,12 @@ # update the version string echo "#define __ARCSBOOT_VERSION__ \"${realver}\"" > common/version.h # build the package - make build-subarch-indep - make clean-subarch - make SUBARCH=IP32 + $(MAKE) build-subarch-indep + $(MAKE) clean-subarch-dep + $(MAKE) SUBARCH=IP32 build-subarch-dep cp ext2load/ext2load arcboot.ip32 - make clean-subarch - make SUBARCH=IP22 + $(MAKE) clean-subarch-dep + $(MAKE) SUBARCH=IP22 build-subarch-dep cp ext2load/ext2load arcboot.ip22 touch build-stamp @@ -53,12 +58,13 @@ dh_installdirs # install arcboot into debian/arcboot - install -m 644 arcboot.ip22 ${PREFIX_ARCB}/usr/lib/arcboot/arcboot.ip22 - install -m 644 arcboot.ip32 ${PREFIX_ARCB}/usr/lib/arcboot/arcboot.ip32 - install -m 755 scripts/arcboot ${PREFIX_ARCB}/usr/sbin/arcboot + install -m 644 arcboot.ip22 ${PREFIX_ARCB}/${LIB_ARCB}/arcboot.ip22 + install -m 644 arcboot.ip32 ${PREFIX_ARCB}/${LIB_ARCB}/arcboot.ip32 + install -m 755 scripts/arcboot ${PREFIX_ARCB}/${BIN_ARCB}/arcboot # install tip22 into debian/tip22 - make PREFIX=${PREFIX_TIP22} -C tip22 install + $(MAKE) PREFIX=${PREFIX_TIP22} BINDIR=${BIN_TIP22} LIBDIR=${LIB_TIP22} -C arclib install + $(MAKE) PREFIX=${PREFIX_TIP22} BINDIR=${BIN_TIP22} LIBDIR=${LIB_TIP22} -C tip22 install # Build architecture-independent files here. binary-indep: build install diff -u -r -N arcboot-0.3.8.4/debian/tip22.manpages arcboot-onion/debian/tip22.manpages --- arcboot-0.3.8.4/debian/tip22.manpages 2002-05-09 19:50:16.000000000 +0000 +++ arcboot-onion/debian/tip22.manpages 2004-11-21 15:13:08.000000000 +0000 @@ -1 +1,2 @@ debian/tip22.8 +debian/tip32.8 diff -u -r -N arcboot-0.3.8.4/debian/tip32.8 arcboot-onion/debian/tip32.8 --- arcboot-0.3.8.4/debian/tip32.8 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/debian/tip32.8 2004-11-21 15:13:09.000000000 +0000 @@ -0,0 +1,27 @@ +.TH "TIP32" "8" "17 November 2004" "" "" +.SH NAME +tip32 \- create "piggyback" style boot images for SGI/MIPS IP32 machines +.SH SYNOPSIS + +\fB/usr/sbin/tip32\fR + +.SH "DESCRIPTION" +.PP +\fBtip32\fR is used on SGI/MIPS IP32 machines (SGI O2) to embed kernel and +initial ramdisk into one ELF image which can then be booted by the ARCS PROM. +This is usually used to create tftp boot images. +.SH "USAGE" +.PP + is the ELF kernel you want to embed into the bootimage +.P + is the (optionally gzip compressed) initial ramdisk +.P + is the resulting tftpboot image + +.SH "SEE ALSO" +.PP +arcboot(8). +.SH "AUTHORS" +Tip32 is an adaption of tip22, which is the equivalent for SGI IP22 machines. +Tip22 was written by Guido Günther and borrows heavily +from arcboot written by Ralf Bächle and Guido Günther. diff -u -r -N arcboot-0.3.8.4/e2fslib/et/Makefile arcboot-onion/e2fslib/et/Makefile --- arcboot-0.3.8.4/e2fslib/et/Makefile 2002-02-03 22:53:44.000000000 +0000 +++ arcboot-onion/e2fslib/et/Makefile 2004-11-19 11:08:07.000000000 +0000 @@ -44,7 +44,7 @@ CC = cc BUILD_CC = cc DEFS = -DENABLE_SWAPFS=1 -DPACKAGE=\"e2fsprogs\" -DVERSION=\"1.25\" -DSTDC_HEADERS=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_ARGZ_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_NL_TYPES_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_GETCWD=1 -DHAVE_MUNMAP=1 -DHAVE_PUTENV=1 -DHAVE_SETENV=1 -DHAVE_SETLOCALE=1 -DHAVE_STRCHR=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1 -DHAVE___ARGZ_COUNT=1 -DHAVE___ARGZ_STRINGIFY=1 -DHAVE___ARGZ_NEXT=1 -DHAVE_STPCPY=1 -DHAVE_STPCPY=1 -DHAVE_LC_MESSAGES=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_ERRNO_H=1 -DHAVE_MALLOC_H=1 -DHAVE_MNTENT_H=1 -DHAVE_PATHS_H=1 -DHAVE_DIRENT_H=1 -DHAVE_GETOPT_H=1 -DHAVE_SETJMP_H=1 -DHAVE_SIGNAL_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_LINUX_FD_H=1 -DHAVE_LINUX_MAJOR_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_MOUNT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_NET_IF_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_VPRINTF=1 -DHAVE_LSEEK64_PROTOTYPE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DWORDS_BIGENDIAN=1 -DHAVE_GETRUSAGE=1 -DHAVE_LLSEEK=1 -DHAVE_LSEEK64=1 -DHAVE_OPEN64=1 -DHAVE_STRCASECMP=1 -DHAVE_SRANDOM=1 -DHAVE_FCHOWN=1 -DHAVE_MALLINFO=1 -DHAVE_FDATASYNC=1 -DHAVE_STRNLEN=1 -DHAVE_EXT2_IOCTLS=1 -CFLAGS = -g -O2 +CFLAGS = -O2 CPPFLAGS = ALL_CFLAGS = $(CPPFLAGS) $(DEFS) $(USE_WFLAGS) $(CFLAGS) $(XTRA_CFLAGS) \ -I$(top_builddir)/lib -I$(top_srcdir)/lib \ diff -u -r -N arcboot-0.3.8.4/e2fslib/fileio.c arcboot-onion/e2fslib/fileio.c --- arcboot-0.3.8.4/e2fslib/fileio.c 2002-02-03 22:53:42.000000000 +0000 +++ arcboot-onion/e2fslib/fileio.c 2004-11-24 21:01:15.000000000 +0000 @@ -226,7 +226,11 @@ ptr += c; count += c; wanted -= c; + + rotate(); + } + printf("\n\r"); fail: if (got) diff -u -r -N arcboot-0.3.8.4/e2fslib/Makefile arcboot-onion/e2fslib/Makefile --- arcboot-0.3.8.4/e2fslib/Makefile 2002-02-03 22:53:42.000000000 +0000 +++ arcboot-onion/e2fslib/Makefile 2004-11-14 21:27:05.000000000 +0000 @@ -38,7 +38,7 @@ CC = cc BUILD_CC = cc DEFS = -DENABLE_SWAPFS=1 -DPACKAGE=\"e2fsprogs\" -DVERSION=\"1.25\" -DSTDC_HEADERS=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_ARGZ_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_NL_TYPES_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_GETCWD=1 -DHAVE_MUNMAP=1 -DHAVE_PUTENV=1 -DHAVE_SETENV=1 -DHAVE_SETLOCALE=1 -DHAVE_STRCHR=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1 -DHAVE___ARGZ_COUNT=1 -DHAVE___ARGZ_STRINGIFY=1 -DHAVE___ARGZ_NEXT=1 -DHAVE_STPCPY=1 -DHAVE_STPCPY=1 -DHAVE_LC_MESSAGES=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_ERRNO_H=1 -DHAVE_MALLOC_H=1 -DHAVE_MNTENT_H=1 -DHAVE_PATHS_H=1 -DHAVE_DIRENT_H=1 -DHAVE_GETOPT_H=1 -DHAVE_SETJMP_H=1 -DHAVE_SIGNAL_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_LINUX_FD_H=1 -DHAVE_LINUX_MAJOR_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_MOUNT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_NET_IF_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_VPRINTF=1 -DHAVE_LSEEK64_PROTOTYPE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DWORDS_BIGENDIAN=1 -DHAVE_GETRUSAGE=1 -DHAVE_LLSEEK=1 -DHAVE_LSEEK64=1 -DHAVE_OPEN64=1 -DHAVE_STRCASECMP=1 -DHAVE_SRANDOM=1 -DHAVE_FCHOWN=1 -DHAVE_MALLINFO=1 -DHAVE_FDATASYNC=1 -DHAVE_STRNLEN=1 -DHAVE_EXT2_IOCTLS=1 -CFLAGS = -g -O -G 0 -fno-pic -mno-abicalls +CFLAGS = -O -G 0 -fno-pic -mno-abicalls CPPFLAGS = ALL_CFLAGS = $(CPPFLAGS) $(DEFS) $(USE_WFLAGS) $(CFLAGS) $(XTRA_CFLAGS) \ -I. $(LINUX_INCLUDE) diff -u -r -N arcboot-0.3.8.4/e2fslib/MCONFIG arcboot-onion/e2fslib/MCONFIG --- arcboot-0.3.8.4/e2fslib/MCONFIG 2002-02-03 22:53:42.000000000 +0000 +++ arcboot-onion/e2fslib/MCONFIG 2004-11-19 11:08:11.000000000 +0000 @@ -30,7 +30,7 @@ CC = cc BUILD_CC = cc DEFS = -DENABLE_SWAPFS=1 -DPACKAGE=\"e2fsprogs\" -DVERSION=\"1.25\" -DSTDC_HEADERS=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_ARGZ_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_NL_TYPES_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_GETCWD=1 -DHAVE_MUNMAP=1 -DHAVE_PUTENV=1 -DHAVE_SETENV=1 -DHAVE_SETLOCALE=1 -DHAVE_STRCHR=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1 -DHAVE___ARGZ_COUNT=1 -DHAVE___ARGZ_STRINGIFY=1 -DHAVE___ARGZ_NEXT=1 -DHAVE_STPCPY=1 -DHAVE_STPCPY=1 -DHAVE_LC_MESSAGES=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_ERRNO_H=1 -DHAVE_MALLOC_H=1 -DHAVE_MNTENT_H=1 -DHAVE_PATHS_H=1 -DHAVE_DIRENT_H=1 -DHAVE_GETOPT_H=1 -DHAVE_SETJMP_H=1 -DHAVE_SIGNAL_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_LINUX_FD_H=1 -DHAVE_LINUX_MAJOR_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_MOUNT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_NET_IF_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_VPRINTF=1 -DHAVE_LSEEK64_PROTOTYPE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DWORDS_BIGENDIAN=1 -DHAVE_GETRUSAGE=1 -DHAVE_LLSEEK=1 -DHAVE_LSEEK64=1 -DHAVE_OPEN64=1 -DHAVE_STRCASECMP=1 -DHAVE_SRANDOM=1 -DHAVE_FCHOWN=1 -DHAVE_MALLINFO=1 -DHAVE_FDATASYNC=1 -DHAVE_STRNLEN=1 -DHAVE_EXT2_IOCTLS=1 -CFLAGS = -g -O2 +CFLAGS = -O2 CPPFLAGS = ALL_CFLAGS = $(CPPFLAGS) $(DEFS) $(USE_WFLAGS) $(CFLAGS) $(XTRA_CFLAGS) \ -I$(top_builddir)/lib -I$(top_srcdir)/lib \ diff -u -r -N arcboot-0.3.8.4/e2fslib/util/Makefile arcboot-onion/e2fslib/util/Makefile --- arcboot-0.3.8.4/e2fslib/util/Makefile 2002-02-03 22:53:44.000000000 +0000 +++ arcboot-onion/e2fslib/util/Makefile 2004-11-19 11:08:11.000000000 +0000 @@ -44,7 +44,7 @@ CC = cc BUILD_CC = cc DEFS = -DENABLE_SWAPFS=1 -DPACKAGE=\"e2fsprogs\" -DVERSION=\"1.25\" -DSTDC_HEADERS=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_ARGZ_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_NL_TYPES_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_GETCWD=1 -DHAVE_MUNMAP=1 -DHAVE_PUTENV=1 -DHAVE_SETENV=1 -DHAVE_SETLOCALE=1 -DHAVE_STRCHR=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1 -DHAVE___ARGZ_COUNT=1 -DHAVE___ARGZ_STRINGIFY=1 -DHAVE___ARGZ_NEXT=1 -DHAVE_STPCPY=1 -DHAVE_STPCPY=1 -DHAVE_LC_MESSAGES=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_ERRNO_H=1 -DHAVE_MALLOC_H=1 -DHAVE_MNTENT_H=1 -DHAVE_PATHS_H=1 -DHAVE_DIRENT_H=1 -DHAVE_GETOPT_H=1 -DHAVE_SETJMP_H=1 -DHAVE_SIGNAL_H=1 -DHAVE_TERMIOS_H=1 -DHAVE_LINUX_FD_H=1 -DHAVE_LINUX_MAJOR_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_MOUNT_H=1 -DHAVE_SYS_SYSMACROS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_NET_IF_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_VPRINTF=1 -DHAVE_LSEEK64_PROTOTYPE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DWORDS_BIGENDIAN=1 -DHAVE_GETRUSAGE=1 -DHAVE_LLSEEK=1 -DHAVE_LSEEK64=1 -DHAVE_OPEN64=1 -DHAVE_STRCASECMP=1 -DHAVE_SRANDOM=1 -DHAVE_FCHOWN=1 -DHAVE_MALLINFO=1 -DHAVE_FDATASYNC=1 -DHAVE_STRNLEN=1 -DHAVE_EXT2_IOCTLS=1 -CFLAGS = -g -O2 +CFLAGS = -O2 CPPFLAGS = ALL_CFLAGS = $(CPPFLAGS) $(DEFS) $(USE_WFLAGS) $(CFLAGS) $(XTRA_CFLAGS) \ -I$(top_builddir)/lib -I$(top_srcdir)/lib \ diff -u -r -N arcboot-0.3.8.4/ext2load/conffile.c arcboot-onion/ext2load/conffile.c --- arcboot-0.3.8.4/ext2load/conffile.c 2004-03-01 11:23:57.000000000 +0000 +++ arcboot-onion/ext2load/conffile.c 2004-11-25 10:29:13.000000000 +0000 @@ -17,18 +17,31 @@ #include "arcboot.h" #include -#define _PARM_LIMIT 32 +#define _PARM_LIMIT 48 +#define LABELS_MAX 10 + +#include "conffile.h" static char *carray[_PARM_LIMIT+3]; /* 0 is the name, - 1 the boofile, ... + 1 the boofile/kernel image, + 2 is any initrd and + 3 is image password X is OSLoadOptions X+1 ... _PARM_LIMIT are options given on the command line */ +static char *labels[LABELS_MAX]; + CHAR** GetConfig(char* config, char* name) { char *t, *start, *end; - int i; + int i,l=0; + + carray[CONF_IMAGE]=0; + carray[CONF_INITRD]=0; + carray[CONF_PASSWD]=0; + carray[CONF_LABEL]=0; + carray[CONF_ARGS]=0; /* Loop on lines */ while(*config != 0x0) { @@ -64,24 +77,41 @@ while(*end == ' ' || *end == '\t') *end--=0x0; + /* Configuration section label */ if (strncmp("label=",start,6) == 0) { /* If we found the right profile or want the first */ - if (carray[0]) - if (((strcmp(carray[0], name) == 0) && (strcmp(name, carray[0]) == 0))) { + if (carray[CONF_LABEL]) + if (((strcmp(carray[CONF_LABEL], name) == 0) && (strcmp(name, carray[CONF_LABEL]) == 0))) { return carray; } /* Reset image & append */ - carray[1]=carray[2]=0; - carray[0]=&start[6]; + carray[CONF_IMAGE]=0; + carray[CONF_INITRD]=0; + carray[CONF_PASSWD]=0; + carray[CONF_LABEL]=&start[6]; + labels[l]=&start[6]; + l++; + + /* Kernel image */ } else if (strncmp("image=",start,6) == 0) { - carray[1]=&start[6]; + carray[CONF_IMAGE]=&start[6]; + + /* Ramdisk image */ + } else if (strncmp("initrd=",start,7) == 0) { + carray[CONF_INITRD]=&start[7]; + + /* Boot password */ + } else if (strncmp("passwd=",start,7) == 0) { + carray[CONF_PASSWD]=&start[7]; + + /* Kernel cmd-line */ } else if (strncmp("append=",start,7) == 0) { t=&start[7]; /* Does append start with " */ if (*t == '"') { t++; /* If so - append starts +1 */ - carray[2]=t; + carray[CONF_ARGS]=t; /* Search ending quote */ while(*t != '"' && *t != 0x0) t++; @@ -89,9 +119,10 @@ if (*t == '"') *t=0x0; } else - carray[2]=&start[7]; - t=carray[2]; - i=3; + carray[CONF_ARGS]=&start[7]; + + t=carray[CONF_ARGS]; + i=CONF_ARGS+1; while(i<_PARM_LIMIT && *t != 0x0) { t++; @@ -103,23 +134,30 @@ } } } - if (carray[0]) + + /* We found what we wanted */ + if (carray[CONF_LABEL]) if ((name == NULL) || - (strcmp(carray[0], name) == 0)) { + (strcmp(carray[CONF_LABEL], name) == 0)) { return carray; } + /* Found nothing appropriate: */ + /* XXX: We should do something nicer here, like a list of labels */ return NULL; } CHAR** ReadConfFile(char** partition, const char *filename, char* label) { - ext2_file_t file; - unsigned size, num_read; + unsigned int size; errcode_t status; char *conf_file; - if(!OpenFile( *partition, filename, &file )){ +#ifdef DEBUG_CONFIG + printf("About to load configuration file\n\r"); +#endif + + if(!open_file(*partition, filename, NULL)) { /* OSLoadPartition seems to be wrong, but don't give up now */ int npart,i; char *part,*spart; @@ -139,11 +177,9 @@ npart = part[strlen(part)-2] - '0'; for(i = 0; i < npart; i++) { part[strlen(part)-2] = '0' + i; -#if DEBUG printf("Trying %s\n\r", part); -#endif /* we found it, good */ - if(OpenFile( part, filename, &file )) { + if( open_file( part, filename, NULL) == True ) { printf("Please adjust OSLoadPartition to %s\n\r", part); *partition = part; break; @@ -153,20 +189,27 @@ return False; } - size = ext2fs_file_get_size(file); + size = file_size(); +#ifdef DEBUG_CONFIG + if (size==0) { + printf("Config file of size 0?\n\r"); + } +#endif conf_file = malloc(size); if( !conf_file ) { printf("Can't read configuration file - not enough memory\n\r"); return False; } - status = ext2fs_file_read(file,(char*) conf_file, size, &num_read); + status = file_read((char*) conf_file, size ); +#ifdef DEBUG_CONFIG + printf("Loaded config, size 0x%x status: 0x%x\n\r", size, (int)status); +#endif + if( status ) { print_ext2fs_error(status); return False; } - if( size != num_read ) { - printf("Wanted: %u, got %u bytes of configuration file\n\r", size, num_read); - return False; - } + + file_close(); return GetConfig(conf_file, label); } diff -u -r -N arcboot-0.3.8.4/ext2load/conffile.h arcboot-onion/ext2load/conffile.h --- arcboot-0.3.8.4/ext2load/conffile.h 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/conffile.h 2004-11-21 15:49:33.000000000 +0000 @@ -0,0 +1,7 @@ +/* Blah */ + +#define CONF_LABEL 0 +#define CONF_IMAGE 1 +#define CONF_INITRD 2 +#define CONF_PASSWD 3 +#define CONF_ARGS 4 diff -u -r -N arcboot-0.3.8.4/ext2load/decomp.c arcboot-onion/ext2load/decomp.c --- arcboot-0.3.8.4/ext2load/decomp.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/decomp.c 2004-11-23 17:30:05.000000000 +0000 @@ -0,0 +1,129 @@ +/* Self decompression and image decompression routines + + Copyright (C) 1993 Hannu Savolainen + 1996,1998 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 "gio.h" +#include +#ifndef NULL +#define NULL (void *)0 +#endif + +/* + * gzip declarations + */ + +#define OF(args) args +#define STATIC static + +#define memzero(s, n) memset ((s), 0, (n)) + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ +static uch window[WSIZE]; /* Sliding window buffer */ + +static unsigned outcnt = 0; /* bytes in output buffer */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +#define Assert(cond,msg) +#define Trace(x) +#define Tracev(x) +#define Tracevv(x) +#define Tracec(c,x) +#define Tracecv(c,x) + +static void flush_window (void); +static void error (char *); +#define gzip_mark mark +inline void gzip_release (void **p) +{ + release (*p); +} + +static long bytes_out; +static uch *output_data, *output_limit; +static unsigned char (*get_input_fun) (void); +static void (*unget_input_fun) (void); + +jmp_buf gunzip_env; +#define get_byte() (*get_input_fun)() +#define unget_byte() (*unget_input_fun)() + +#include "inflate.c" + +static void error (char *m) +{ + printf ("\nDecompression error: %s\n", m); + longjmp (gunzip_env, 1); +} + +static void flush_window () +{ + ulg c = crc; + unsigned n; + uch *in, ch; + in = window; + if (output_data + outcnt > output_limit) + error ("uncompressed image too long - wouldn't fit into destination"); + for (n = 0; n < outcnt; n++) { + ch = *output_data++ = *in++; + c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg) outcnt; + outcnt = 0; +} + +int decompress (char *outptr, char *outptrlim, unsigned char (*get_input) (void), void (*unget_input) (void)) +{ + void *save_ptr; + static int first = 1; + + gzip_mark (&save_ptr); + if (setjmp (gunzip_env)) { + gzip_release (&save_ptr); + return -1; + } + output_data = outptr; + output_limit = outptrlim; + get_input_fun = get_input; + unget_input_fun = unget_input; + bytes_out = 0; + crc = 0xffffffffL; + if (first) { + makecrc (); + first = 0; + } + gunzip (); + gzip_release (&save_ptr); + return bytes_out; +} + +static unsigned char *gzminp; diff -u -r -N arcboot-0.3.8.4/ext2load/ext2.c arcboot-onion/ext2load/ext2.c --- arcboot-0.3.8.4/ext2load/ext2.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/ext2.c 2004-11-25 15:42:38.000000000 +0000 @@ -0,0 +1,208 @@ +/* EXT2 Interface for filesystem access routines + Based on same for SILO + + Copyright 2004 Kaj-Michael Lang + + Copyright (C) 1996 Maurizio Plaza + 1996,1997,1999 Jakub Jelinek + 2001 Ben Collins + + 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 +#include +#include +#include +#include "gio.h" +#include "file.h" +#include "arcboot.h" +#include + +static ext2_ino_t inode = 0; +static ext2_filsys fs; /* Generic filesystem */ +static ext2_ino_t root; /* root and cwd for current fs */ +extern ext2_file_t file; + +struct fs_ops ext2_fs_ops; + +static int open_ext2 (const char *device) +{ + extern io_manager arc_io_manager; + errcode_t status; + + initialize_ext2_error_table(); + + status = ext2fs_open (device, 0, 0, 0, arc_io_manager, &fs); +#ifdef DEBUG_FS + printf("Ext2 status: %d", (int)status); +#endif + if (status == EXT2_ET_BAD_MAGIC) { +#ifdef DEBUG_FS + printf("Not ext2 fs\n\r"); + print_ext2fs_error(status); +#endif + return status; + } + + if (status != 0) { + print_ext2fs_error(status); + return status; + } + + root = EXT2_ROOT_INO; + return status; +} + +static int seek_file_ext2(int position) { + return ext2fs_file_lseek(file, (ext2_off_t) position, EXT2_SEEK_SET, NULL); +} + +static unsigned int file_size_ext2() { + unsigned int size; + + size=ext2fs_file_get_size(file); + return size; +} + +static int read_file_ext2(char *buffer, unsigned int size) { + return ext2fs_file_read(file, buffer, size, NULL); +} + +static int open_file_ext2 (const char *filename) { + int ret; + errcode_t status; + + ret = ext2fs_namei_follow (fs, EXT2_ROOT_INO, EXT2_ROOT_INO, filename, &inode); + if (ret != 0) { + print_ext2fs_error(ret); + return ret; + } + ext2_fs_ops.inode = inode; + + status = ext2fs_file_open(fs, inode, 0, &file); + if (status != 0) { + print_ext2fs_error(status); + return status; + } + + return status; +} + +#if 0 +static int dump_block_ext2 (ext2_filsys fs, blk_t *blocknr, + int blockcnt, void *private) +{ + return dump_block(blocknr, blockcnt); +} + +static int dump_ext2 (void) +{ + if (ext2fs_block_iterate (fs, inode, 0, 0, dump_block_ext2, 0)) + return 0; + + return dump_finish (); +} +#endif + +static int ls_ext2_proc(struct ext2_dir_entry *dirent, int offset, + int blocksize, char *buf, void *private) +{ + struct ext2_inode ino; + int sl = 0, name_len = dirent->name_len & 0xFF; + char name[256], symlink[256]; + + strncpy(name, dirent->name, name_len); + name[name_len] = 0; + + if (ext2fs_read_inode(fs, dirent->inode, &ino)) + strcpy (name, "--- error ---"); + + if (LINUX_S_ISLNK (ino.i_mode)) { + sl = 1; +/* XXX: e2fslib is too old for this... + if (ext2fs_inode_data_blocks(fs, ino)) { +*/ + if (ino.i_blocks == 0) { + if (io_channel_read_blk(fs->io, ino.i_block[0], 1, symlink)) + ino.i_size = 0; + } else { + strncpy (symlink, (char *)&(ino.i_block[0]),ino.i_size); + } + symlink[ino.i_size] = 0; + } + + print_dir_list(ino.i_mtime, ino.i_size, ino.i_mode, ino.i_uid, + ino.i_gid, name, sl ? symlink : NULL); + + return 0; +} + +static int ls_ext2 (char *filename) +{ + int status; + + if (filename==NULL) + status = ext2fs_namei_follow (fs, EXT2_ROOT_INO, EXT2_ROOT_INO, filename, &inode); + else + status = ext2fs_namei_follow (fs, EXT2_ROOT_INO, EXT2_ROOT_INO, "/", &inode); + + if (status != 0) { + print_ext2fs_error(status); + return status; + } + + ext2_fs_ops.inode = inode; + + return ext2fs_dir_iterate (fs, inode, DIRENT_FLAG_INCLUDE_EMPTY, + 0, ls_ext2_proc, NULL); +} + +static int dump_ext2(void) { + return 0; +} + +static int close_file_ext2(void) { + return ext2fs_file_close(file); +} + +static void print_error_ext2 (int error_val) { + print_ext2fs_error(error_val); +} + +void close_ext2 (void) { + ext2fs_close(fs); +} + +struct fs_ops ext2_fs_ops = { + .name = "Linux EXT2", + .open = open_ext2, + .ls = ls_ext2, + .dump = dump_ext2, + .file_size = file_size_ext2, + .open_file = open_file_ext2, + .close_file = close_file_ext2, + .read_file = read_file_ext2, + .seek_file = seek_file_ext2, + .print_error = print_error_ext2, + .close = close_ext2, + .inode = 0, +}; + +/* These are silly stubs to satisfy libext2fs symbols */ +unsigned long time(void) +{ + return 0; +} diff -u -r -N arcboot-0.3.8.4/ext2load/file.c arcboot-onion/ext2load/file.c --- arcboot-0.3.8.4/ext2load/file.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/file.c 2004-11-25 15:41:44.000000000 +0000 @@ -0,0 +1,296 @@ +/* Filesystem interface abstraction. + + Copyright 2004 Kaj-Michael Lang + + Based on code from SILO + Copyright (C) 1996 Maurizio Plaza + 1996,1997,1999 Jakub Jelinek + 2001 Ben Collins + + 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 +#include "file.h" +#include "arcboot.h" +#include + +ext2_filsys fs = 0; +unsigned int bs; +ext2_ino_t root, cwd; +ext2_file_t file=NULL; + +/* Externally provided filesystem interfaces */ +extern struct fs_ops ext2_fs_ops; +#ifdef USE_ISOFS +extern struct fs_ops iso_fs_ops; +#endif +#ifdef USE_ROMFS +extern struct fs_ops rom_fs_ops; +#endif + +/* Array of our supported ops */ +static struct fs_ops *arcboot_fs_ops[] = { + &ext2_fs_ops, +#ifdef USE_ISOFS + &iso_fs_ops, +#endif +#ifdef USE_ROMFS + &rom_fs_ops, +#endif + NULL, +}; + +static struct fs_ops *cur_ops=NULL; +static int do_rotate = 0; +static int lines=0; + +void rotate (void) +{ + static int i = 0, slowdown = 0; + static char rot[] = "\\|/-"; + + if (!do_rotate) + return; + + if (slowdown++ % 4) + return; + + printf ("\r[%c]", rot[i % 4]); + + i++; +} + +void set_rotate(int i) { + do_rotate = i; +} + +static void ls_rwx (unsigned int bits, char *chars) +{ + chars[0] = (bits & LINUX_S_IRUSR) ? 'r' : '-'; + chars[1] = (bits & LINUX_S_IWUSR) ? 'w' : '-'; + chars[2] = (bits & LINUX_S_IXUSR) ? 'x' : '-'; +} + +static void ls_modestring (unsigned int mode, char *chars) +{ + if (LINUX_S_ISBLK (mode)) chars[0] = 'b'; + else if (LINUX_S_ISCHR (mode)) chars[0] = 'c'; + else if (LINUX_S_ISDIR (mode)) chars[0] = 'd'; + else if (LINUX_S_ISREG (mode)) chars[0] = '-'; + else if (LINUX_S_ISFIFO (mode)) chars[0] = 'p'; + else if (LINUX_S_ISLNK (mode)) chars[0] = 'l'; + else if (LINUX_S_ISSOCK (mode)) chars[0] = 's'; + ls_rwx ((mode & 0700) << 0, chars+1); + ls_rwx ((mode & 0070) << 3, chars+4); + ls_rwx ((mode & 0007) << 6, chars+7); + if (mode & LINUX_S_ISUID) { + if (chars[3] != 'x') + chars[3] = 'S'; + else + chars[3] = 's'; + } + if (mode & LINUX_S_ISGID) { + if (chars[6] != 'x') + chars[6] = 'S'; + else + chars[6] = 's'; + } + if (mode & LINUX_S_ISVTX) { + if (chars[9] != 'x') + chars[9] = 'T'; + else + chars[9] = 't'; + } +} + +void print_number (unsigned int num, int pad, char *padc) +{ + int len; + unsigned int i; + for (len = 1, i = num; i >= 10; len++) i /= 10; + if (pad > 0) { /* Pad left */ + while (len < pad) { printf ("%s",padc); len++; } + printf (" %u", num); + } else { + printf (" %u", num); + while (len < -pad) { printf ("%s", padc); len++; } + } +} + +void print_dir_list(unsigned int mtime, unsigned int size, int mode, int uid, int gid, char *name, char *symlink ) { + int i; + char modestr[11]; + char *q; + unsigned int day, hour, min, month, year; + static char *months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + static unsigned short m_yday[] = { + 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; + + if (lines>20) { + Wait("Press for more..."); + lines=0; + } + ls_modestring (mode, modestr); + modestr[10] = 0; + printf ("%s ", modestr); + print_number (uid, -8, " "); + printf (" "); + print_number (gid, -8, " "); + printf (" "); + print_number (size, 8, " "); + printf (" "); + /* Following code taken from glibc */ + day = mtime / (60 * 60 * 24); + hour = mtime % (60 * 60 * 24); + hour /= 60; + min = hour % 60; + hour /= 60; + year = 1970; +#define ISLEAP(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) +#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) + while (day < 0 || day >= (ISLEAP (year) ? 366 : 365)) { + /* Guess a corrected year, assuming 365 days per year. */ + long int yg = year + day / 365 - (day % 365 < 0); + /* Adjust DAYS and Y to match the guessed year. */ + day -= ((yg - year) * 365 + LEAPS_THRU_END_OF (yg - 1) - LEAPS_THRU_END_OF (year - 1)); + year = yg; + } + if (!ISLEAP(year) && day >= 59) day++; + for (month = 11; day < m_yday[month]; month--); + day -= m_yday[month] - 1; + printf ("%s ", months[month]); + print_number (day, 2, " "); + printf (" "); + print_number (hour, 2, "0"); + printf (":"); + print_number (min, 2, "0"); + printf (" %u %s", year, name); + if (LINUX_S_ISLNK (mode)) { + q = strchr (name, 0) + 1; + if (*q) printf (" -> %s", q); + } + printf ("\n\r"); + lines++; +} + +Boolean open_fs(char *device) { + int i; + + /* If device is null and we are open, then do nothing */ + if ( (!device) && (cur_ops)) return True; + + cur_ops=NULL; + + for (i = 0; arcboot_fs_ops[i]; i++) { +#ifdef DEBUG_FS + printf("Opening device:\n\r%s using %s\n\r", + device, arcboot_fs_ops[i]->name); +#endif + if (arcboot_fs_ops[i]->open(device) == 0) + break; + } + + if (!arcboot_fs_ops[i]) { + printf("Failed to open any filesystem!\n\r"); + return False; + } else { + cur_ops = arcboot_fs_ops[i]; +#ifdef DEBUG_FS + printf("Succesfully opened: %s using %s\n\r", device, cur_ops->name); +#endif + return True; + } +} + +void close_fs(void) { + cur_ops=NULL; +} + +Boolean open_file (char *device, char *filename, ext2_file_t *file) { + errcode_t status; + + if (open_fs(device)==False) return False; + +#ifdef DEBUG_FS + printf("Trying to open file:\n\r%s using %s\n\r", + filename, cur_ops->name); + Wait("-- Pause --"); +#endif + + status = cur_ops->open_file(filename); + if (status != 0) { + cur_ops->print_error(status); + file=NULL; + printf("Failed to open file %s\n\r", filename); + return False; + } + printf("File open %s\n\r", filename); + + return True; +} + +int file_read (char *buffer, unsigned int size) { + if (cur_ops==NULL) return -1; + if (file==NULL) return -1; + return cur_ops->read_file(buffer, size); +} + +unsigned int file_size() { + if (cur_ops==NULL) return 0; + return cur_ops->file_size(); +} + +int file_lseek(int position) { + if (cur_ops==NULL) return -1; + return cur_ops->seek_file(position); +} + +int file_close(void) { + if (cur_ops==NULL) return -1; + cur_ops->close_file(); + file=NULL; + return 0; +} + +int file_ls(char *filename) { + if (cur_ops==NULL) { + printf("No filesystem is currently open.\n\r"); + return 0; + } + lines=0; + return cur_ops->ls(filename); + printf("\n\r"); +} + +void file_cat(char *filename) { + int status; + unsigned int size; + char *buffer; + + status=open_file(NULL, filename, NULL); + size=file_size(); + buffer=malloc(512); + while (file_read(buffer, 511)) { + printf("%s", buffer); + memset(buffer, 0, 512); + } + + file_close(); + +} diff -u -r -N arcboot-0.3.8.4/ext2load/file.h arcboot-onion/ext2load/file.h --- arcboot-0.3.8.4/ext2load/file.h 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/file.h 2004-11-25 12:01:06.000000000 +0000 @@ -0,0 +1,55 @@ +/* Exported filesystem related stuff + + Copyright (C) 2001 Ben Collins + + 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 +#include +#include +#include +#include + +extern unsigned int bs; /* Block Size */ +extern ext2_filsys fs; /* Generic filesystem */ +extern ext2_ino_t root, cwd; /* root and cwd for current fs */ + +/* +extern int dump_block (blk_t *, int); +extern int dump_finish (void); +*/ + +int file_open(char *filename); +int file_lseek(int position); +int file_read(char *buffer, unsigned int size); +int file_ls(char *filename); +unsigned int file_size(); + +/* Filesystem operations provided by each module */ +struct fs_ops { + char *name; + int (*open) (const char *); + int (*ls) (char *); + int (*dump) (void); + unsigned int (*file_size) (void); + int (*open_file) (const char *); + int (*close_file) (void); + int (*read_file) (char *buffer, unsigned int size); + int (*seek_file) (int position); + void (*print_error) (int); + void (*close) (void); + int inode; +}; diff -u -r -N arcboot-0.3.8.4/ext2load/gio.h arcboot-onion/ext2load/gio.h --- arcboot-0.3.8.4/ext2load/gio.h 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/gio.h 2004-11-23 17:15:56.000000000 +0000 @@ -0,0 +1,23 @@ +#ifndef GIO_H +#define GIO_H + +#define CMD_LENG 512 + +struct gio_inode { + unsigned int inolen; + unsigned int mtime; + unsigned int size; + unsigned int mode; + unsigned int uid; + unsigned int gid; + unsigned char name[0]; +}; + +#define LOADFILE_GZIP 0x01 +#define LOADFILE_LS 0x02 +#define LOADFILE_MATCH 0x04 +#define LOADFILE_QUIET 0x08 +#define LOADFILE_NO_ROTATE 0x10 +#define LOADFILE_LS_MATCH (LOADFILE_MATCH | LOADFILE_MATCH) + +#endif diff -u -r -N arcboot-0.3.8.4/ext2load/inflate.c arcboot-onion/ext2load/inflate.c --- arcboot-0.3.8.4/ext2load/inflate.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/inflate.c 2004-11-23 17:29:14.000000000 +0000 @@ -0,0 +1,1022 @@ +/* inflate.c -- Not copyrighted 1992 by Mark Adler + version c10p1, 10 January 1993 */ + +/* + * Adapted for booting Linux by Hannu Savolainen 1993 + * based on gzip-1.0.3 + */ + +/* + Inflate deflated (PKZIP's method 8 compressed) data. The compression + method searches for as much of the current string of bytes (up to a + length of 258) in the previous 32K bytes. If it doesn't find any + matches (of at least length 3), it codes the next byte. Otherwise, it + codes the length of the matched string and its distance backwards from + the current position. There is a single Huffman code that codes both + single bytes (called "literals") and match lengths. A second Huffman + code codes the distance information, which follows a length code. Each + length or distance code actually represents a base value and a number + of "extra" (sometimes zero) bits to get to add to the base value. At + the end of each deflated block is a special end-of-block (EOB) literal/ + length code. The decoding process is basically: get a literal/length + code; if EOB then done; if a literal, emit the decoded byte; if a + length then get the distance and emit the referred-to bytes from the + sliding window of previously emitted data. + + There are (currently) three kinds of inflate blocks: stored, fixed, and + dynamic. The compressor deals with some chunk of data at a time, and + decides which method to use on a chunk-by-chunk basis. A chunk might + typically be 32K or 64K. If the chunk is uncompressible, then the + "stored" method is used. In this case, the bytes are simply stored as + is, eight bits per byte, with none of the above coding. The bytes are + preceded by a count, since there is no longer an EOB code. + + If the data is compressible, then either the fixed or dynamic methods + are used. In the dynamic method, the compressed data is preceded by + an encoding of the literal/length and distance Huffman codes that are + to be used to decode this block. The representation is itself Huffman + coded, and so is preceded by a description of that code. These code + descriptions take up a little space, and so for small blocks, there is + a predefined set of codes, called the fixed codes. The fixed method is + used if the block codes up smaller that way (usually for quite small + chunks), otherwise the dynamic method is used. In the latter case, the + codes are customized to the probabilities in the current block, and so + can code it much better than the pre-determined fixed codes. + + The Huffman codes themselves are decoded using a multi-level table + lookup, in order to maximize the speed of decoding plus the speed of + building the decoding tables. See the comments below that precede the + lbits and dbits tuning parameters. + */ + + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarly, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + +#include + +#define slide window + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). + Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 + means that v is a literal, 16 < e < 32 means that v is a pointer to + the next table, which codes e - 16 bits, and lastly e == 99 indicates + an unused code. If a code with e == 99 is looked up, this implies an + error in the data. */ +struct huft { + uch e; /* number of extra bits or operation */ + uch b; /* number of bits in this code or subcode */ + union { + ush n; /* literal, length base, or distance base */ + struct huft *t; /* pointer to next level of table */ + } v; +}; + + +/* Function prototypes */ +STATIC int huft_build OF ((unsigned *, unsigned, unsigned, ush *, ush *, + struct huft **, int *)); +STATIC int huft_free OF ((struct huft *)); +STATIC int inflate_codes OF ((struct huft *, struct huft *, int, int)); +STATIC int inflate_stored OF ((void)); +STATIC int inflate_fixed OF ((void)); +STATIC int inflate_dynamic OF ((void)); +STATIC int inflate_block OF ((int *)); +STATIC int inflate OF ((void)); + + +/* The inflate algorithm uses a sliding 32K byte window on the uncompressed + stream to find repeated byte strings. This is implemented here as a + circular buffer. The index is updated simply by incrementing and then + and'ing with 0x7fff (32K-1). */ +/* It is left to other modules to supply the 32K area. It is assumed + to be usable as if it were declared "uch slide[32768];" or as just + "uch *slide;" and then malloc'ed in the latter case. The definition + must be in unzip.h, included above. */ +/* unsigned wp; current position in slide */ +#define wp outcnt +#define flush_output(w) (wp=(w),flush_window()) + +/* Tables for deflate from PKZIP's appnote.txt. */ +static unsigned border[] = +{ /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +static ush cplens[] = +{ /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* note: see note #13 above about the 258 in this list. */ +static ush cplext[] = +{ /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ +static ush cpdist[] = +{ /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +static ush cpdext[] = +{ /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + + +/* Macros for inflate() bit peeking and grabbing. + The usage is: + + NEEDBITS(j) + x = b & mask_bits[j]; + DUMPBITS(j) + + where NEEDBITS makes sure that b has at least j bits in it, and + DUMPBITS removes the bits from b. The macros use the variable k + for the number of bits in b. Normally, b and k are register + variables for speed, and are initialized at the beginning of a + routine that uses these macros from a global bit buffer and count. + + If we assume that EOB will be the longest code, then we will never + ask for bits with NEEDBITS that are beyond the end of the stream. + So, NEEDBITS should not read any more bytes than are needed to + meet the request. Then no bytes need to be "returned" to the buffer + at the end of the last block. + + However, this assumption is not true for fixed blocks--the EOB code + is 7 bits, but the other literal/length codes can be 8 or 9 bits. + (The EOB code is shorter than other codes because fixed blocks are + generally short. So, while a block always has an EOB, many other + literal/length codes have a significantly lower probability of + showing up at all.) However, by making the first table have a + lookup of seven bits, the EOB code will be found in that first + lookup, and so will not require that too many bits be pulled from + the stream. + */ + +STATIC ulg bb; /* bit buffer */ +STATIC unsigned bk; /* bits in bit buffer */ + +STATIC ush mask_bits[] = +{ + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +#define NEXTBYTE() (uch)get_byte() +#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<>=(n);k-=(n);} + + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +STATIC int lbits = 9; /* bits in base literal/length lookup table */ +STATIC int dbits = 6; /* bits in base distance lookup table */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ +#define BMAX 16 /* maximum bit length of any code (16 for explode) */ +#define N_MAX 288 /* maximum number of codes in any set */ + + +STATIC unsigned hufts; /* track memory usage */ + + +STATIC int huft_build (b, n, s, d, e, t, m) +unsigned *b; /* code lengths in bits (all assumed <= BMAX) */ +unsigned n; /* number of codes (assumed <= N_MAX) */ +unsigned s; /* number of simple-valued codes (0..s-1) */ +ush *d; /* list of base values for non-simple codes */ +ush *e; /* list of extra bits for non-simple codes */ +struct huft **t; /* result: starting table */ +int *m; /* maximum lookup bits, returns actual */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return zero on success, one if + the given code set is incomplete (the tables are still built in this + case), two if the input is invalid (all zero length codes or an + oversubscribed set of lengths), and three if not enough memory. */ +{ + unsigned a; /* counter for codes of length k */ + unsigned c[BMAX + 1]; /* bit length count table */ + unsigned f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register unsigned i; /* counter, current code */ + register unsigned j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + register unsigned *p; /* pointer into c[], b[], or v[] */ + register struct huft *q; /* points to current table */ + struct huft r; /* table entry for structure assignment */ + struct huft *u[BMAX]; /* table stack */ + unsigned v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + unsigned x[BMAX + 1]; /* bit offsets, then code stack */ + unsigned *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + unsigned z; /* number of entries in current table */ + + /* Generate counts for each bit length */ + memzero (c, sizeof (c)); + p = b; + i = n; + do { + Tracecv (*p, (stderr, (n - i >= ' ' && n - i <= '~' ? "%c %d\n" : "0x%x %d\n"), + n - i, *p)); + c[*p]++; /* assume all entries <= BMAX */ + p++; /* Can't combine with above line (Solaris bug) */ + } while (--i); + if (c[0] == n) { /* null input--all zero length codes */ + *t = (struct huft *) NULL; + *m = 0; + return 0; + } + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((unsigned) l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((unsigned) l > i) + l = i; + *m = l; + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return 2; /* bad input: more codes than bits */ + if ((y -= c[i]) < 0) + return 2; + c[i] += y; + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; + xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + /* Make a table of values in order of bit lengths */ + p = b; + i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (struct huft *) NULL; /* just to keep compilers happy */ + q = (struct huft *) NULL; /* ditto */ + z = 0; /* ditto */ + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) { + a = c[k]; + while (a--) { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = (z = g - w) > (unsigned) l ? l : z; /* upper limit on table size */ + if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table *//* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + while (++j < z) { /* try smaller tables up to z bits */ + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ + if ((q = (struct huft *) malloc ((z + 1) * sizeof (struct huft))) == + (struct huft *) NULL) { + if (h) + huft_free (u[0]); + return 3; /* not enough memory */ + } + hufts += z + 1; /* track memory usage */ + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->v.t)) = (struct huft *) NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) { + x[h] = i; /* save pattern for backing up */ + r.b = (uch) l; /* bits to dump before this table */ + r.e = (uch) (16 + j); /* bits in this table */ + r.v.t = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h - 1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.b = (uch) (k - w); + if (p >= v + n) + r.e = 99; /* out of values--invalid code */ + else if (*p < s) { + r.e = (uch) (*p < 256 ? 16 : 15); /* 256 is end-of-block code */ + r.v.n = (ush) (*p); /* simple code is just the value */ + p++; /* one compiler does not like *p++ */ + } else { + r.e = (uch) e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) { + h--; /* don't need to update q */ + w -= l; + } + } + } + + + /* Return true (1) if we were given an incomplete table */ + return y != 0 && g != 1; +} + + + +STATIC int huft_free (t) +struct huft *t; /* table to free */ +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +{ + register struct huft *p, *q; + + + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + p = t; + while (p != (struct huft *) NULL) { + q = (--p)->v.t; + free ((char *) p); + p = q; + } + return 0; +} + + +STATIC int inflate_codes (tl, td, bl, bd) +struct huft *tl, *td; /* literal/length and distance decoder tables */ +int bl, bd; /* number of bits decoded by tl[] and td[] */ +/* inflate (decompress) the codes in a deflated (compressed) block. + Return an error code or zero if it all goes ok. */ +{ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft *t; /* pointer to table entry */ + unsigned ml, md; /* masks for bl and bd bits */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + + /* make local copies of globals */ + b = bb; /* initialize bit buffer */ + k = bk; + w = wp; /* initialize window position */ + + /* inflate the coded data */ + ml = mask_bits[bl]; /* precompute masks for speed */ + md = mask_bits[bd]; + for (;;) { /* do until end of block */ + NEEDBITS ((unsigned) bl) + if ((e = (t = tl + ((unsigned) b & ml))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS (t->b) + e -= 16; + NEEDBITS (e) + } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); + DUMPBITS (t->b) + if (e == 16) { /* then it's a literal */ + slide[w++] = (uch) t->v.n; + Tracevv ((stderr, "%c", slide[w - 1])); + if (w == WSIZE) { + flush_output (w); + w = 0; + } + } else { /* it's an EOB or a length */ + /* exit if end of block */ + if (e == 15) + break; + + /* get length of block to copy */ + NEEDBITS (e) + n = t->v.n + ((unsigned) b & mask_bits[e]); + DUMPBITS (e); + + /* decode distance of block to copy */ + NEEDBITS ((unsigned) bd) + if ((e = (t = td + ((unsigned) b & md))->e) > 16) + do { + if (e == 99) + return 1; + DUMPBITS (t->b) + e -= 16; + NEEDBITS (e) + } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); + DUMPBITS (t->b) + NEEDBITS (e) + d = w - t->v.n - ((unsigned) b & mask_bits[e]); + DUMPBITS (e) + Tracevv ((stderr, "\\[%d,%d]", w - d, n)); + + /* do the copy */ + do { + n -= (e = (e = WSIZE - ((d &= WSIZE - 1) > w ? d : w)) > n ? n : e); + if (w - d >= e) { /* (this test assumes unsigned comparison) */ + memcpy (slide + w, slide + d, e); + w += e; + d += e; + } else /* do it slow to avoid memcpy() overlap */ + do { + slide[w++] = slide[d++]; + Tracevv ((stderr, "%c", slide[w - 1])); + } while (--e); + if (w == WSIZE) { + flush_output (w); + w = 0; + } + } while (n); + } + } + + + /* restore the globals from the locals */ + wp = w; /* restore global window pointer */ + bb = b; /* restore global bit buffer */ + bk = k; + + /* done */ + return 0; +} + + + +STATIC int inflate_stored () +/* "decompress" an inflated type 0 (stored) block. */ +{ + unsigned n; /* number of bytes in block */ + unsigned w; /* current window position */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + /* make local copies of globals */ + b = bb; /* initialize bit buffer */ + k = bk; + w = wp; /* initialize window position */ + + + /* go to byte boundary */ + n = k & 7; + DUMPBITS (n); + + + /* get the length and its complement */ + NEEDBITS (16) + n = ((unsigned) b & 0xffff); + DUMPBITS (16) + NEEDBITS (16) + if (n != (unsigned) ((~b) & 0xffff)) + return 1; /* error in compressed data */ + DUMPBITS (16) + /* read and output the compressed data */ + while (n--) { + NEEDBITS (8) + slide[w++] = (uch) b; + if (w == WSIZE) { + flush_output (w); + w = 0; + } + DUMPBITS (8) + } + + + /* restore the globals from the locals */ + wp = w; /* restore global window pointer */ + bb = b; /* restore global bit buffer */ + bk = k; + + return 0; +} + + + +STATIC int inflate_fixed () +/* decompress an inflated type 1 (fixed Huffman codes) block. We should + either replace this with a custom decoder, or at least precompute the + Huffman tables. */ +{ + int i; /* temporary variable */ + struct huft *tl; /* literal/length code table */ + struct huft *td; /* distance code table */ + int bl; /* lookup bits for tl */ + int bd; /* lookup bits for td */ + unsigned l[288]; /* length list for huft_build */ + + /* set up literal table */ + for (i = 0; i < 144; i++) + l[i] = 8; + for (; i < 256; i++) + l[i] = 9; + for (; i < 280; i++) + l[i] = 7; + for (; i < 288; i++) /* make a complete, but wrong code set */ + l[i] = 8; + bl = 7; + if ((i = huft_build (l, 288, 257, cplens, cplext, &tl, &bl)) != 0) + return i; + + + /* set up distance table */ + for (i = 0; i < 30; i++) /* make an incomplete code set */ + l[i] = 5; + bd = 5; + if ((i = huft_build (l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) { + huft_free (tl); + + return i; + } + /* decompress until an end-of-block code */ + if (inflate_codes (tl, td, bl, bd)) + return 1; + + + /* free the decoding tables, return */ + huft_free (tl); + huft_free (td); + return 0; +} + + + +STATIC int inflate_dynamic () +/* decompress an inflated type 2 (dynamic Huffman codes) block. */ +{ + int i; /* temporary variables */ + unsigned j; + unsigned l; /* last length */ + unsigned m; /* mask for bit lengths table */ + unsigned n; /* number of lengths to get */ + struct huft *tl; /* literal/length code table */ + struct huft *td; /* distance code table */ + int bl; /* lookup bits for tl */ + int bd; /* lookup bits for td */ + unsigned nb; /* number of bit length codes */ + unsigned nl; /* number of literal/length codes */ + unsigned nd; /* number of distance codes */ +#ifdef PKZIP_BUG_WORKAROUND + unsigned ll[288 + 32]; /* literal/length and distance code lengths */ +#else + unsigned ll[286 + 30]; /* literal/length and distance code lengths */ +#endif + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + /* make local bit buffer */ + b = bb; + k = bk; + + + /* read in table lengths */ + NEEDBITS (5) + nl = 257 + ((unsigned) b & 0x1f); /* number of literal/length codes */ + DUMPBITS (5) + NEEDBITS (5) + nd = 1 + ((unsigned) b & 0x1f); /* number of distance codes */ + DUMPBITS (5) + NEEDBITS (4) + nb = 4 + ((unsigned) b & 0xf); /* number of bit length codes */ + DUMPBITS (4) +#ifdef PKZIP_BUG_WORKAROUND + if (nl > 288 || nd > 32) +#else + if (nl > 286 || nd > 30) +#endif + return 1; /* bad lengths */ + + /* read in bit-length-code lengths */ + for (j = 0; j < nb; j++) { + NEEDBITS (3) + ll[border[j]] = (unsigned) b & 7; + DUMPBITS (3) + } + for (; j < 19; j++) + ll[border[j]] = 0; + + /* build decoding table for trees--single level, 7 bit lookup */ + bl = 7; + if ((i = huft_build (ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) { + if (i == 1) + huft_free (tl); + return i; /* incomplete code set */ + } + /* read in literal and distance code lengths */ + n = nl + nd; + m = mask_bits[bl]; + i = l = 0; + while ((unsigned) i < n) { + NEEDBITS ((unsigned) bl) + j = (td = tl + ((unsigned) b & m))->b; + DUMPBITS (j) + j = td->v.n; + if (j < 16) /* length of code in bits (0..15) */ + ll[i++] = l = j; /* save last length in l */ + else if (j == 16) { /* repeat last length 3 to 6 times */ + NEEDBITS (2) + j = 3 + ((unsigned) b & 3); + DUMPBITS (2) + if ((unsigned) i + j > n) + return 1; + while (j--) + ll[i++] = l; + } else if (j == 17) { /* 3 to 10 zero length codes */ + NEEDBITS (3) + j = 3 + ((unsigned) b & 7); + DUMPBITS (3) + if ((unsigned) i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } else { /* j == 18: 11 to 138 zero length codes */ + NEEDBITS (7) + j = 11 + ((unsigned) b & 0x7f); + DUMPBITS (7) + if ((unsigned) i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + } + + /* free decoding table for trees */ + huft_free (tl); + + /* restore the global bit buffer */ + bb = b; + bk = k; + + /* build the decoding tables for literal/length and distance codes */ + bl = lbits; + if ((i = huft_build (ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) { + if (i == 1) + error ("incomplete literal tree"); + return i; /* incomplete code set */ + } + bd = dbits; + if ((i = huft_build (ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) { + if (i == 1) + error ("incomplete distance tree"); + huft_free (tl); + return i; /* incomplete code set */ + } + /* decompress until an end-of-block code */ + if (inflate_codes (tl, td, bl, bd)) + return 1; + + /* free the decoding tables, return */ + huft_free (tl); + huft_free (td); + + return 0; +} + + + +STATIC int inflate_block (e) +int *e; /* last block flag */ +/* decompress an inflated block */ +{ + unsigned t; /* block type */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + /* make local bit buffer */ + b = bb; + k = bk; + + + /* read in last block bit */ + NEEDBITS (1) + * e = (int) b & 1; + DUMPBITS (1) + /* read in block type */ + NEEDBITS (2) + t = (unsigned) b & 3; + DUMPBITS (2) + /* restore the global bit buffer */ + bb = b; + bk = k; + + /* inflate that block type */ + if (t == 2) + return inflate_dynamic (); + if (t == 0) + return inflate_stored (); + if (t == 1) + return inflate_fixed (); + + /* bad block type */ + return 2; +} + +STATIC int inflate () +/* decompress an inflated entry */ +{ + int e; /* last block flag */ + int r; /* result code */ + unsigned h; /* maximum struct huft's malloc'ed */ + void *ptr; + + /* initialize window, bit buffer */ + wp = 0; + bk = 0; + bb = 0; + + + /* decompress until the last block */ + h = 0; + do { + hufts = 0; + gzip_mark (&ptr); + if ((r = inflate_block (&e)) != 0) { + gzip_release (&ptr); + return r; + } + gzip_release (&ptr); + if (hufts > h) + h = hufts; + } while (!e); + + /* Undo too much lookahead. The next read will be byte aligned so we + * can discard unused bits in the last meaningful byte. + */ + while (bk >= 8) { + bk -= 8; + unget_byte (); + } + + /* flush out slide */ + flush_output (wp); + + + /* return success */ + return 0; +} + +/********************************************************************** + * + * The following are support routines for inflate.c + * + **********************************************************************/ + +static ulg crc_32_tab[256]; +static ulg crc; /* shift register contents */ +#define CRC_VALUE (crc ^ 0xffffffffL) + +/* + * Code to compute the CRC-32 table. Borrowed from + * gzip-1.0.3/makecrc.c. + */ + +static void makecrc (void) +{ +/* Not copyrighted 1990 Mark Adler */ + + unsigned long c; /* crc shift register */ + unsigned long e; /* polynomial exclusive-or pattern */ + int i; /* counter for all possible eight bit values */ + int k; /* byte being shifted into crc apparatus */ + + /* terms of polynomial defining this crc (except x^32): */ + static int p[] = + {0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26}; + + /* Make exclusive-or pattern from polynomial */ + e = 0; + for (i = 0; i < sizeof (p) / sizeof (int); i++) + e |= 1L << (31 - p[i]); + + crc_32_tab[0] = 0; + + for (i = 1; i < 256; i++) { + c = 0; + for (k = i | 256; k != 1; k >>= 1) { + c = c & 1 ? (c >> 1) ^ e : c >> 1; + if (k & 1) + c ^= e; + } + crc_32_tab[i] = c; + } +} + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +/* + * Do the uncompression! + */ +static int gunzip (void) +{ + uch flags; + unsigned char magic[2]; /* magic header */ + char method; + ulg orig_crc = 0; /* original crc */ + ulg orig_len = 0; /* original uncompressed length */ + int res; + + magic[0] = (unsigned char) get_byte (); + magic[1] = (unsigned char) get_byte (); + method = (unsigned char) get_byte (); + + if (magic[0] != 037 || + ((magic[1] != 0213) && (magic[1] != 0236))) { + error ("bad gzip magic numbers"); + } + /* We only support method #8, DEFLATED */ + if (method != 8) { + error ("internal error, invalid method"); + } + flags = (uch) get_byte (); + if ((flags & ENCRYPTED) != 0) { + error ("Input is encrypted"); + } + if ((flags & CONTINUATION) != 0) { + error ("Multi part input"); + } + if ((flags & RESERVED) != 0) { + error ("Input has invalid flags"); + } + (ulg) get_byte (); /* Get timestamp */ + (ulg) get_byte (); + (ulg) get_byte (); + (ulg) get_byte (); + + (void) get_byte (); /* Ignore extra flags for the moment */ + (void) get_byte (); /* Ignore OS type for the moment */ + + if ((flags & EXTRA_FIELD) != 0) { + unsigned len = (unsigned) get_byte (); + len |= ((unsigned) get_byte ()) << 8; + while (len--) + (void) get_byte (); + } + /* Get original file name if it was truncated */ + if ((flags & ORIG_NAME) != 0) { + /* Discard the old name */ + while (get_byte () != 0) /* null */ + ; + } + /* Discard file comment if any */ + if ((flags & COMMENT) != 0) { + while (get_byte () != 0) /* null */ + ; + } + /* Decompress */ + if ((res = inflate ())) { + switch (res) { + case 1: + error ("invalid compressed format (err=1)"); + case 2: + error ("invalid compressed format (err=2)"); + case 3: + error ("out of memory"); + default: + error ("invalid compressed format (other)"); + } + return -1; + } + /* Get the crc and original length */ + /* crc32 (see algorithm.doc) + * uncompressed input size modulo 2^32 + */ + orig_crc = (ulg) get_byte (); + orig_crc |= (ulg) get_byte () << 8; + orig_crc |= (ulg) get_byte () << 16; + orig_crc |= (ulg) get_byte () << 24; + + orig_len = (ulg) get_byte (); + orig_len |= (ulg) get_byte () << 8; + orig_len |= (ulg) get_byte () << 16; + orig_len |= (ulg) get_byte () << 24; + + /* Validate decompression */ + if (orig_crc != CRC_VALUE) { + error ("crc error"); + } + if (orig_len != bytes_out) { + error ("length error"); + } + return 0; +} diff -u -r -N arcboot-0.3.8.4/ext2load/isofs.c arcboot-onion/ext2load/isofs.c --- arcboot-0.3.8.4/ext2load/isofs.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/isofs.c 2004-11-25 14:44:23.000000000 +0000 @@ -0,0 +1,571 @@ +/* ISO9660 (CDROM) Interface for ARCBOOT filesystem access routines + + Based on ISO9660 (CDROM) Interface for SILO filesystem access routines + + Copyright (C) 1999 Jakub Jelinek + 1992,1993 Eric Youngdale + 2001 Ben Collins + + 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 +#include +#include +#include +#include +#include "gio.h" +#include "file.h" +#include "rock.h" + +/* Reuse and abuse */ +typedef ext2_filsys isofs_filsys; + +struct isofs_inode { + unsigned int extent; + unsigned int size; +}; + +static struct isofs_inode inode, root_inode; +static int link_count = 0; + +unsigned int bs; +unsigned char *filebuffer; + +static unsigned char *filelimit; +static int first_block; +static int block_no; +static int block_cnt; +static int last_blockcnt; + +struct fs_ops iso_fs_ops; + +void *alloca(size_t); +static int isofs_lookup (isofs_filsys, struct isofs_inode *, + const char *, int, struct isofs_inode *); +static int open_namei(isofs_filsys, const char *, struct isofs_inode *, + struct isofs_inode *); + +static unsigned int file_size_isofs (void) { + return inode.size; +} + +static int ls_isofs (char *filename) +{ + int ret; + + link_count = 0; + +#ifdef DEBUG_FS + printf("open_namei\n\r"); +#endif + ret = open_namei (fs, filename, &inode, &root_inode); + iso_fs_ops.inode = (ret) ? 0 : 1; +#ifdef DEBUG_FS + printf("open_namei: %x\n\r", ret); +#endif + + return isofs_lookup (fs, &inode, "", 0, NULL); +} + +static int isonum_731 (char * p) +{ + return ((p[0] & 0xff) + | ((p[1] & 0xff) << 8) + | ((p[2] & 0xff) << 16) + | ((p[3] & 0xff) << 24)); +} + +#define isonum_733(p) isonum_731(p) + +static int isofs_read_super(io_channel io) +{ + int i; + struct iso_primary_descriptor iso; + + for (i = 16; i < 100; i++) { + if (io_channel_read_blk (io, i, -2048, (char *)&iso)) + return -1; + if (!strncmp (iso.id, ISO_STANDARD_ID, sizeof (iso.id))) + break; + } + + if (i == 100) + return -1; + + root_inode.extent = isonum_733 (((struct iso_directory_record *) + (iso.root_directory_record))->extent); + root_inode.size = isonum_733 (((struct iso_directory_record *) + (iso.root_directory_record))->size); + + return 0; +} + +static int open_isofs (const char *device) +{ + extern io_manager arc_io_manager; + + fs = (isofs_filsys) malloc (sizeof (struct struct_ext2_filsys)); + if (!fs) + return 1; + +#ifdef DEBUG_FS + printf("abc\n\r"); +#endif + + if (((struct struct_io_manager *)(arc_io_manager))->open (device, 0, &fs->io)) + return 1; + +#ifdef DEBUG_FS + printf("asfbc\n\r"); +#endif + + io_channel_set_blksize (fs->io, 2048); + +#ifdef DEBUG_FS + printf("asdfabc\n\r"); +#endif + + if (isofs_read_super(fs->io)) + return 1; + +#ifdef DEBUG_FS + printf("aasdfsdbc\n\r"); +#endif + +#ifdef DEBUG_FS + ls_isofs(""); +#endif + + return 0; +} + +static int iso_date(char * p, int flag) +{ + int year, month, day, hour, minute, second, tz; + int crtime, days, i; + + year = p[0] - 70; + month = p[1]; + day = p[2]; + hour = p[3]; + minute = p[4]; + second = p[5]; + if (flag == 0) tz = p[6]; /* High sierra has no time zone */ + else tz = 0; + + if (year < 0) { + crtime = 0; + } else { + int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; + + days = year * 365; + if (year > 2) + days += (year+1) / 4; + for (i = 1; i < month; i++) + days += monlen[i-1]; + if (((year+2) % 4) == 0 && month > 2) + days++; + days += day - 1; + crtime = ((((days * 24) + hour) * 60 + minute) * 60) + + second; + + /* sign extend */ + if (tz & 0x80) + tz |= (-1 << 8); + + if (-52 <= tz && tz <= 52) + crtime -= tz * 15 * 60; + } + return crtime; +} + + +static void parse_rr (isofs_filsys fs, unsigned char *chr, unsigned char *end, + char *name, char *symlink, struct gio_inode *sino) +{ + int cont_extent = 0, cont_offset = 0, cont_size = 0; + struct rock_ridge *rr; + int cnt, sig; + int truncate = 0; + int symlink_len = 0; + int rootflag; + + *name = 0; + + while (chr < end) { + rr = (struct rock_ridge *) chr; + if (rr->len == 0) goto out; + sig = (chr[0] << 8) + chr[1]; + chr += rr->len; + + switch(sig){ + case SIG('R','R'): + if((rr->u.RR.flags[0] & + (RR_PX | RR_TF | RR_SL | RR_CL | RR_NM | RR_PX | RR_TF)) == 0) + goto out; + break; + case SIG('N','M'): + if (truncate) break; + if (rr->u.NM.flags & 6) break; + if (rr->u.NM.flags & ~1) { + printf ("Unsupported NM flag settings (%d)\n\r",rr->u.NM.flags); + break; + } + if((strlen(name) + rr->len - 5) >= 254) { + truncate = 1; + break; + } + strncat(name, rr->u.NM.name, rr->len - 5); + break; + case SIG('S','L'): + { + int slen; + struct SL_component * slp; + struct SL_component * oldslp; + slen = rr->len - 5; + slp = &rr->u.SL.link; + sino->size = symlink_len; + + while (slen > 1) { + rootflag = 0; + switch(slp->flags &~1) { + case 0: + sino->size += slp->len; + strncat (symlink, slp->text, slp->len); + break; + case 2: + sino->size += 1; + strcat (symlink, "."); + break; + case 4: + sino->size += 2; + strcat (symlink, ".."); + break; + case 8: + rootflag = 1; + sino->size += 1; + strcat (symlink, "/"); + break; + default: + printf("Symlink component flag not implemented\n\r"); + } + slen -= slp->len + 2; + oldslp = slp; + slp = (struct SL_component *) (((char *) slp) + slp->len + 2); + + if (slen < 2) { + if(((rr->u.SL.flags & 1) != 0) + && ((oldslp->flags & 1) == 0) ) sino->size += 1; + break; + } + + /* + * If this component record isn't continued, then append a '/'. + */ + if (!rootflag && (oldslp->flags & 1) == 0) { + strcat (symlink, "/"); + sino->size += 1; + } + + } + } + symlink_len = sino->size; + break; + case SIG('C','E'): + CHECK_CE; + break; + case SIG('P','X'): + sino->mode = isonum_733(rr->u.PX.mode); + sino->uid = isonum_733(rr->u.PX.uid); + sino->gid = isonum_733(rr->u.PX.gid); + break; + case SIG('T','F'): + cnt = 0; + if(rr->u.TF.flags & TF_CREATE) + cnt++; + if(rr->u.TF.flags & TF_MODIFY) + sino->mtime = iso_date(rr->u.TF.times[cnt++].time, 0); + break; + } + if (chr >= end && cont_extent) { + char *sect = alloca (2048); + if (io_channel_read_blk (fs->io, cont_extent, 1, sect)) + return; + parse_rr (fs, § [cont_offset], § [cont_offset + cont_size - 3], + name, symlink, sino); + } + } +out: + return; +} + +static int isofs_lookup (isofs_filsys fs, struct isofs_inode *dir, + const char *name, int len, struct isofs_inode *result) +{ + char buffer [2048]; + char namebuf [512]; + char symlink [512]; + int block, size, i; + struct iso_directory_record *idr; + unsigned char *rr; + struct gio_inode sino; + + size = dir->size; + block = dir->extent; + +#ifdef DEBUG_FS + printf("isofs_lookup: %x\n\r",size); + printf("isofs_lookup: %x\n\r",block); +#endif + + while (size > 0) { + if (io_channel_read_blk (fs->io, block, 1, buffer)) { + printf ("Could not read directory\n\r"); + return -1; + } + + size -= 2048; + block++; + + for (i = 0;;) { + idr = (struct iso_directory_record *) (buffer + i); + if (!idr->length[0]) + break; + + i += (unsigned char)idr->length[0]; + strncpy(namebuf, idr->name, (unsigned char)idr->name_len[0]); + namebuf[(unsigned char)idr->name_len[0]] = 0; + + rr = (unsigned char *)(idr + 1); + rr += ((unsigned char)idr->name_len[0]) - sizeof(idr->name); + + if (!(idr->name_len[0] & 1)) + rr++; + + *symlink = 0; + memset(&sino, 0, sizeof(struct gio_inode)); + parse_rr (fs, rr, &buffer[i-3], namebuf, symlink, &sino); + + if (idr->name_len[0] == 1 && !idr->name[0]) + strcpy(namebuf, "."); + else if (idr->name_len[0] == 1 && idr->name[0] == 1) + strcpy(namebuf, ".."); + + if (result == NULL) { + /* We aren't returning a result inode, so we must be + * iterating... */ + print_dir_list(sino.mtime, sino.size?:isonum_733(idr->size), + sino.mode, sino.uid, sino.gid, namebuf, + *symlink ? symlink : NULL); + } else if ((!len && namebuf[0] == '.' && !namebuf[1]) || + (strlen(namebuf) == len && !memcmp(namebuf, name, len))) { + if (*symlink) { + int error; + if (link_count > 5) { + printf ("Symlink loop, stopping.\n\r"); + return -1; /* Loop */ + } + link_count++; + error = open_namei (fs, symlink, result, dir); + link_count--; + return error; + } + result->extent = isonum_733 (idr->extent); + result->size = isonum_733 (idr->size); + return 0; + } + + if (i >= 2048 - sizeof(struct iso_directory_record) + sizeof(idr->name)) + break; + } + } + if (result == NULL) + return 0; + else + return -1; +} + +static int dir_namei(isofs_filsys fs, const char *pathname, int *namelen, + const char **name, struct isofs_inode *base, + struct isofs_inode *res_inode) +{ + char c; + const char *thisname; + int len; + struct isofs_inode inode; + + if ((c = *pathname) == '/') { + base = &root_inode; + pathname++; + } + while (1) { + thisname = pathname; + for(len=0;(c = *(pathname++))&&(c != '/');len++); + if (!c) break; + if (isofs_lookup (fs, base, thisname, len, &inode)) return -1; + base = &inode; + } + *name = thisname; + *namelen = len; + *res_inode = *base; + return 0; +} + +static int open_namei(isofs_filsys fs, const char *pathname, + struct isofs_inode *res_inode, + struct isofs_inode *base) +{ + const char *basename; + int namelen; + struct isofs_inode dir, inode; + + if (dir_namei(fs, pathname, &namelen, &basename, base, &dir)) return -1; + if (!namelen) { /* special case: '/usr/' etc */ + *res_inode=dir; + return 0; + } + if (isofs_lookup (fs, &dir, basename, namelen, &inode)) return -1; + *res_inode = inode; + return 0; +} + +static int open_file_isofs (const char *filename) +{ + int ret; + link_count = 0; + + ret = open_namei (fs, filename, &inode, &root_inode); + iso_fs_ops.inode = (ret) ? 0 : 1; + + return ret; +} + +static void isofs_close(void) +{ + free (fs->io); + free (fs); +} + +static int close_file_isofs(void) { + return 0; +} + +static int seek_file_isofs(int position) { + return 0; +} + +static int read_file_isofs(char *buffer, unsigned int size) { + return 0; +} + +static void print_error_isofs (int error_val) { + printf("Unknown isofs error\n\r"); +} + +int dump_block_isofs (blk_t * blocknr, int blockcnt) +{ + if (blockcnt < 0) + return 0; + + /* rotate(); */ + + if (*blocknr || block_no) { + if (first_block || !*blocknr || blockcnt != last_blockcnt + 1 || (block_no && *blocknr != block_no + block_cnt)) { + if (first_block) { + block_no = *blocknr; + block_cnt = 1; + if (blockcnt) { + Fatal ("File cannot have a hole at beginning\n\r"); + return BLOCK_ABORT; + } + last_blockcnt = -1; + } + if (filebuffer + (block_cnt + ((*blocknr) ? (blockcnt - last_blockcnt - 1) : 0)) * bs > filelimit) { + Fatal ("Image too large to fit in destination\n\r"); + return BLOCK_ABORT; + } + if (block_cnt > 0 && io_channel_read_blk (fs->io, block_no, block_cnt, filebuffer)) + return BLOCK_ABORT; + if (first_block) { + first_block = 0; + last_blockcnt = 0; + filebuffer += bs; + block_no = 0; + block_cnt = 0; + return 0; + } + filebuffer += block_cnt * bs; + if (*blocknr && blockcnt && blockcnt != last_blockcnt + 1) { + memset (filebuffer, 0, (blockcnt - last_blockcnt - 1) * bs); + filebuffer += (blockcnt - last_blockcnt - 1) * bs; + } + block_no = 0; + } + if (*blocknr) { + if (!block_no) { + block_no = *blocknr; + block_cnt = 1; + } else + block_cnt++; + last_blockcnt = blockcnt; + } + } + return 0; +} + +int dump_finish_isofs (void) +{ + if (block_no) { + blk_t tmp = 0; + if (dump_block_isofs (&tmp, 0)) + return 0; + } + + return 1; +} + +static int isofs_block_iterate(void) +{ + int i; + blk_t nr; + int size; + + nr = inode.extent; + size = (inode.size + 2047) / 2048; + for (i = 0; i < size; i++, nr++) { + switch (dump_block_isofs (&nr, i)) { + case BLOCK_ABORT: + case BLOCK_ERROR: + return 0; + } + } + return dump_finish_isofs(); +} + +struct fs_ops iso_fs_ops = { + .name "ISO-9660 CDROM", + .open = open_isofs, + .ls = ls_isofs, + .dump = isofs_block_iterate, + .file_size = file_size_isofs, + .open_file = open_file_isofs, + .close_file = close_file_isofs, + .read_file = read_file_isofs, + .seek_file = seek_file_isofs, + .close = isofs_close, + .print_error = print_error_isofs, + .inode = 0, +}; diff -u -r -N arcboot-0.3.8.4/ext2load/ld.script.in arcboot-onion/ext2load/ld.script.in --- arcboot-0.3.8.4/ext2load/ld.script.in 2004-09-25 21:34:39.000000000 +0000 +++ arcboot-onion/ext2load/ld.script.in 2004-11-24 22:14:54.000000000 +0000 @@ -1,3 +1,4 @@ +OUTPUT_FORMAT("@@OUTPUTFORMAT@@") OUTPUT_ARCH(mips) ENTRY(_start) SECTIONS @@ -6,22 +7,22 @@ . = @@LOADADDR@@; /* Read-only sections, merged into text segment: */ - .text : - { - _ftext = . ; + .text : { + _ftext = .; *(.text) *(.rodata*) } =0 _etext = .; PROVIDE (etext = .); - .data : - { - _fdata = . ; + . = ALIGN(16); + + .data : { + _fdata = .; *(.data) CONSTRUCTORS } - _gp = . + 0x8000; + _gp = ALIGN(16) + 0x7ff0; .lit8 : { *(.lit8) } .lit4 : { *(.lit4) } /* We want the small data sections together, so single-instruction offsets @@ -30,29 +31,43 @@ .sdata : { *(.sdata) } PROVIDE (edata = .); - .sbss : { + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } .bss : { - *(.bss) + _fbss = .; + *(.dynbss) + *(.bss .bss.*) *(COMMON) - . = ALIGN(4); + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); } + . = ALIGN(32 / 8); __bss_stop = .; - + _end = .; PROVIDE (end = .); /* Sections to be discarded */ - /DISCARD/ : - { + /DISCARD/ : { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) *(.stab) *(.stabstr) *(.pdr) *(.note) *(.reginfo) + *(.options) + *(.MIPS.options) *(.debug*) + *(.line) *(.mdebug*) *(.comment*) + *(.gptab*) + *(.note) } } diff -u -r -N arcboot-0.3.8.4/ext2load/loader.c arcboot-onion/ext2load/loader.c --- arcboot-0.3.8.4/ext2load/loader.c 2004-09-25 20:53:52.000000000 +0000 +++ arcboot-onion/ext2load/loader.c 2004-11-25 15:41:24.000000000 +0000 @@ -2,6 +2,7 @@ * Copyright 1999, 2001 Silicon Graphics, Inc. * Copyright 2001 Ralf Baechle * 2001-04 Guido Guenther + * 2004 Kaj-Michael Lang */ #include #include @@ -18,18 +19,37 @@ #include #include +#include "file.h" #include "arcboot.h" +#include "conffile.h" #include #define ANSI_CLEAR "\033[2J" -#define CONF_FILE "/etc/arcboot.conf" +#define ARC_CONF_FILE "/etc/arcboot.conf" +#define PROMPT "arcboot@ip32: # " +#define ARC_CDROM "pci(0)scsi(0)cdrom(4)" +#define ARC_DISK "pci(0)scsi(0)rdisk(0)partition(0)" CHAR *OSLoadPartition = NULL; CHAR *OSLoadFilename = NULL; CHAR *OSLoadOptions = NULL; static int is64=0; +static int interactive=0; +char *initrd_filename=NULL; +char *origOSLoadPartition; +SYSTEMID *sysid=NULL; +ULONG rd_size; +void *rd_vaddr; +static char argv_rd_start[32]; +static char argv_rd_size[32]; + +CHAR** nargv; +CHAR** params; +int nargc, nopt; +Elf32_Addr kernel_entry32; +Elf64_Addr kernel_entry64; typedef union { unsigned char e_ident[EI_NIDENT]; @@ -37,7 +57,51 @@ Elf64_Ehdr header64; } Elf_Ehdr; -static void Wait(const char *prompt) +#define CMD_LEN 255 +static char cmd[256]; +static char *cmd_param; + +static void read_cmd() +{ + char ch=0; + int i=0; + char *t; + + printf(PROMPT); + memset(cmd, 0, CMD_LEN); + i=0; + do { + ch = getchar(); + + if (ch == 0xa) break; + if (ch == 0xd) break; + + if (ch!=0x8) { + if (i0) + i--; + cmd[i]=0x0; + } + printf("\r%s%s", PROMPT, cmd); + } while ( ch!=0xd ); + printf("\n\r"); + + /* Check for command parameters */ + t=cmd; + /* Skip first word (cmd) */ + while (*t!=' ' && *t!=0x0) t++; t++; + cmd_param=t; + + printf("Command is: %s\n\r", cmd); + printf("Param is: %s\n\r", cmd_param); +} + +void Wait(const char *prompt) { int ch; @@ -46,9 +110,23 @@ do { ch = getchar(); + /* printf("Char is: 0x%x \n\r", ch); */ } while ((ch != EOF) && (((char) ch) != ' ')); } +static void printSystemId(void) +{ + int i; + + if (sysid!=NULL) { + printf("System ID:\n\rVendor Id: %s\n\r", sysid->VendorId); + + for(i=0;iProductId);i++) + printf("0x%x ", sysid->ProductId[i]); + + printf("\n\r"); + } +} void Fatal(const CHAR * message, ...) { @@ -65,6 +143,21 @@ ArcEnterInteractiveMode(); } +Boolean Non_Fatal(const CHAR * message, ...) +{ + va_list ap; + + if (message != NULL) { + printf("ERROR: "); + va_start(ap, message); + vprintf(message, ap); + va_end(ap); + } + + Wait("\n\r--- Press to continue ---"); + return False; +} + void InitMalloc(void) { @@ -90,7 +183,7 @@ ULONG start = KSEG0ADDR(current->BasePage * PAGE_SIZE); ULONG end = start + (current->PageCount * PAGE_SIZE); -#if DEBUG +#ifdef DEBUG printf("Free Memory(%u) segment found at (0x%lx,0x%lx).\n\r", current->Type, start, end); #endif @@ -145,10 +238,12 @@ equals = strchr(argv[arg], '='); if (equals != NULL) { len = equals - argv[arg]; - if (strncmp(argv[arg], "OSLoadPartition", len) == 0) - OSLoadPartition = equals + 1; + if (strncmp(argv[arg], "OSLoadPartition", len) == 0) { + OSLoadPartition = strdup(equals + 1); + origOSLoadPartition = strdup(equals + 1); + } if (strncmp(argv[arg], "OSLoadFilename", len) == 0) - OSLoadFilename = equals + 1; + OSLoadFilename = strdup(equals + 1); if (strncmp(argv[arg], "OSLoadOptions", len) == 0) { /* Copy options to local memory to avoid overwrite later */ OSLoadOptions = strdup(equals + 1); @@ -157,6 +252,7 @@ } } } + /* * in case the user typed "boot a b c" the argv looks like: * scsi(0)..(8)/arcboot a b c OSLoadPartition=.. SystemPartition=.. @@ -180,7 +276,7 @@ } -void LoadProgramSegments(ext2_file_t file, Elf_Ehdr * header) +Boolean LoadProgramSegments(Elf_Ehdr * header) { int idx; Boolean loaded = False; @@ -195,33 +291,34 @@ size = (size_t) (header->header64.e_phentsize * header->header64.e_phnum); + if (header->e_ident[EI_CLASS] == ELFCLASS32) + printf("Header says 32-bit\n\r"); + else + printf("Header says 64-bit\n\r"); + if (size <= 0) - Fatal("No program segments\n\r"); + return Non_Fatal("No program segments\n\r"); segments = malloc(size); if (segments == NULL) - Fatal("Cannot allocate memory for segment headers\n\r"); + return Non_Fatal("Cannot allocate memory for segment headers\n\r"); else - printf("Allocated 0x%x bytes for segments\n\r",size); + printf("Allocated 0x%x bytes for segments\n\r", size); if (header->e_ident[EI_CLASS] == ELFCLASS32) { - status = ext2fs_file_lseek(file, - (ext2_off_t) header->header32.e_phoff, - EXT2_SEEK_SET, NULL); + status = file_lseek((ext2_off_t) header->header32.e_phoff); } else { - status = ext2fs_file_lseek(file, - (ext2_off_t) header->header64.e_phoff, - EXT2_SEEK_SET, NULL); + status = file_lseek((ext2_off_t) header->header64.e_phoff); } if (status != 0) { print_ext2fs_error(status); - Fatal("Cannot seek to program segment headers\n\r"); + return Non_Fatal("Cannot seek to program segment headers\n\r"); } - status = ext2fs_file_read(file, segments, size, NULL); + status = file_read(segments, size); if (status != 0) { print_ext2fs_error(status); - Fatal("Cannot read program segment headers\n\r"); + return Non_Fatal("Cannot read program segment headers\n\r"); } if(header->e_ident[EI_CLASS] == ELFCLASS32) { @@ -235,23 +332,26 @@ segment->p_offset, segment->p_filesz); status = - ext2fs_file_lseek(file, segment->p_offset, - EXT2_SEEK_SET, NULL); + file_lseek(segment->p_offset); if (status != 0) { print_ext2fs_error(status); Fatal("Cannot seek to program segment\n\r"); } - status = ext2fs_file_read(file, - (void *) (KSEG0ADDR( + status = file_read( (void *) (KSEG0ADDR( segment->p_vaddr)), - segment->p_filesz, NULL); + segment->p_filesz); if (status != 0) { print_ext2fs_error(status); - Fatal("Cannot read program segment\n\r"); + return Non_Fatal("Cannot read program segment\n\r"); } size = segment->p_memsz - segment->p_filesz; + +#ifdef DEBUG + Wait("\n\r--- Waiting... ---"); +#endif + if (size > 0) { printf ("Zeroing memory at 0x%x, size = 0x%x\n\r", @@ -263,6 +363,9 @@ } loaded = True; +#ifdef DEBUG + Wait("\n\r--- Waiting... ---"); +#endif } segment = @@ -282,20 +385,18 @@ (long)(segment->p_filesz>>32),(long)(segment->p_filesz&0xffffffff)); status = - ext2fs_file_lseek(file, segment->p_offset, - EXT2_SEEK_SET, NULL); + file_lseek( segment->p_offset ); if (status != 0) { print_ext2fs_error(status); - Fatal("Cannot seek to program segment\n\r"); + return Non_Fatal("Cannot seek to program segment\n\r"); } - status = ext2fs_file_read(file, - (void *) (KSEG0ADDR( + status = file_read( (void *) (KSEG0ADDR( segment->p_vaddr)), - segment->p_filesz, NULL); + segment->p_filesz); if (status != 0) { print_ext2fs_error(status); - Fatal("Cannot read program segment\n\r"); + return Non_Fatal("Cannot read program segment\n\r"); } size = segment->p_memsz - segment->p_filesz; @@ -318,21 +419,21 @@ } } - if (!loaded) - Fatal("No loadable program segments found\n\r"); + if (!loaded) { + return Non_Fatal("No loadable program segments found\n\r"); + } free(segments); + return True; } - -Elf64_Addr LoadKernelFile(ext2_file_t file) +Elf64_Addr LoadKernelFile() { Elf_Ehdr header; - Elf64_Addr entry; + Elf64_Addr entry=NULL; errcode_t status; - status = - ext2fs_file_read(file, (void *) &header, sizeof(header), NULL); + status = file_read((void *) &header, sizeof(header)); if (status != 0) { print_ext2fs_error(status); Fatal("Can't read file header\n\r"); @@ -375,12 +476,18 @@ entry = header.header64.e_entry; } - LoadProgramSegments(file, &header); + set_rotate(1); + if (LoadProgramSegments(&header)==False) { + set_rotate(0); + if (interactive==1) return entry; + Fatal("Not in interactive mode! Unable to continue\n\r"); + } + set_rotate(0); return entry; } - +#if 0 Boolean OpenFile(const char *partition, const char *filename, ext2_file_t* file) { extern io_manager arc_io_manager; @@ -390,7 +497,7 @@ initialize_ext2_error_table(); - status = ext2fs_open(partition, 0, 0, 0, arc_io_manager, &fs); + status = open(partition, 0, 0, 0, arc_io_manager, &fs); if (status != 0) { print_ext2fs_error(status); return False; @@ -410,118 +517,299 @@ } return True; } +#endif Elf64_Addr LoadKernel(const char *partition, const char *filename) { - ext2_file_t file; - - if(!OpenFile( partition, filename, &file )) + if(!open_file( partition, filename )) Fatal("Can't load kernel!\n\r"); - return LoadKernelFile(file); + return LoadKernelFile(); +} + +int LoadInitrd(const char *partition, const char *filename ) +{ + int status; + void *ramdisk; + + if(!open_file( partition, filename )) { + printf("Can't load initrd, skipping for now!\n\r"); + return False; + } + + rd_size = file_size(); + if (rd_size==0) { + printf("Got initrd size of 0?"); + return False; + } + + ramdisk = malloc(rd_size+PAGE_SIZE); /* Let's be on the safe side */ + if (ramdisk == NULL) { + printf("Unable to allocate memory for ramdisk image!\n\r"); + return False; + } else + printf("Allocated 0x%lx bytes for ramdisk\n\r", rd_size); + + /* XXX: should I do something like this ? Seems to work without :) */ + /* rd_vaddr = (char*)(((ramdisk + PAGE_SIZE) / PAGE_SIZE ) * PAGE_SIZE);*/ + + printf ("Loading ramdisk %s at 0x%p, size = 0x%lx\n\r", + filename, ramdisk, rd_size); + + set_rotate(1); + status = file_read(ramdisk, rd_size); + set_rotate(0); + if (status != 0) { + print_ext2fs_error(status); + printf("Cannot read ramdisk image\n\r"); + return False; + } else { + rd_vaddr=ramdisk; + } + return True; +} + +void Help(void) +{ + printf("\n\r-- Help:\n\rCommands:\n\r"); + printf("help - Show help\n\r"); + printf("quit,arc - Back to ARCS\n\r"); + printf("init - Re-init ARCS\n\r"); + printf("boot - Boot loaded kernel\n\r"); + printf("cat fn - Display file 'fn'\n\r"); + printf("setpart part - Set new filesystem partition\n\r"); + printf("setcdrom - Set filesystem to CDROM\n\r"); + printf("setdisk - Set filesystem to CDROM\n\r"); + printf("setdefault - Set filesystem to defaul\n\r"); + printf("sysid - Display Systme ID\n\r"); + printf("info - Show current variables\n\r"); + printf("cmdline - Kernel command line\n\r"); + printf("loadkernel fn - Load kernel 'fn'\n\r"); + printf("loadinitrd fn - Load initrd 'fn'\n\r"); +} + +void doSetPartition(char *newpart) { + if (newpart==NULL) return; + close_fs(); + if (OSLoadPartition) free(OSLoadPartition); + open_fs(newpart); + OSLoadPartition=strdup(newpart); +} + +void doLoadConfig() { } void printCmdLine(int argc, CHAR *argv[]) { - int i; + int i; - for(i = 0; i < argc; i++ ) - printf("%u: %s\n\r", i, argv[i]); + for(i = 0; i < argc; i++ ) + printf("%u: %s\n\r", i, argv[i]); } void _start64(LONG argc, CHAR * argv[], CHAR * envp[], unsigned long long *addr) { - asm volatile (".set mips4\n" + asm volatile (".set push\n" + "\t.set mips3\n" "\t.set noreorder\n" - "\tld $2, 0($7)\n" - "\tj $2\n" - "\tnop\n" - "\t.set noreorder\n" - "\t.set mips0"); + "\t.set noat\n" + "\tld $1, 0($7)\n" + "\tjr $1\n" + "\t nop\n" + "\t.set pop"); } -void _start(LONG argc, CHAR *argv[], CHAR *envp[]) +Boolean doLoadKernel() { + printf("Loading %s from %s\n\r",(params) ? params[0] : OSLoadFilename, OSLoadPartition); + + kernel_entry64 = LoadKernel(OSLoadPartition, OSLoadFilename); + kernel_entry32 = (Elf32_Addr) kernel_entry64; + + if (!kernel_entry64) return Non_Fatal("Kernel load failed!"); + + printf("Kernel entry: 0x%lx %lx\n\r", + (long)(kernel_entry64>>32), (long)(kernel_entry64&0xffffffff)); + + return True; +} + +void doLoadInitrd(char *filename) { + if (filename != NULL) { + if (LoadInitrd(OSLoadPartition, filename)) { + sprintf(argv_rd_start, "rd_start=0x%p", rd_vaddr); + sprintf(argv_rd_size, "rd_size=0x%lx", rd_size); + nargv[nargc]=argv_rd_start; + nargc++; + nargv[nargc]=argv_rd_size; + nargc++; + } + } +} + +void doStartKernel(CHAR *envp[]) { +#if DEBUG + Wait("\n\r--- Debug: press to boot kernel ---"); +#endif + + if( kernel_entry64 ) { + if(is64==0) { + printf("Starting ELF32 kernel\n\r"); + ArcFlushAllCaches(); + ((void (*)(int argc, CHAR * argv[], CHAR * envp[])) + kernel_entry32)(nargc ,nargv, envp); + } else { + printf("Starting ELF64 kernel\n\r"); + ArcFlushAllCaches(); + _start64(nargc, nargv, envp, &kernel_entry64); + } + } else { + Non_Fatal("Invalid kernel entry NULL\n\r"); + } +} + +void printInfo(void) { + printf("OSLoadPartition: %s\n\r", OSLoadPartition); + printf("OSLoadFilename: %s\n\r", OSLoadFilename); + printf("OSLoadOptions: %s\n\r", OSLoadOptions); +} + +void goInteractive(CHAR *envp[]) { - CHAR** nargv; - CHAR** params; - int nargc, nopt; + int q=0; + + printf("Interactive mode started. Use help for help.\n\r"); + do { + read_cmd(); + + if (strncmp(cmd,"ls",2)==0) + file_ls(cmd_param); + else if (strncmp(cmd,"quit",4)==0) + q=1; + else if (strncmp(cmd,"arc",3)==0) + q=1; + else if (strncmp(cmd,"init",4)==0) + ArcRestart(); + else if (strncmp(cmd,"loadkernel", 10)==0) + doLoadKernel(); + else if (strncmp(cmd,"loadinitrd", 10)==0) + doLoadInitrd(cmd_param); + else if (strncmp(cmd,"loadconfig", 10)==0) + doLoadConfig(); + else if (strncmp(cmd,"setpart", 7)==0) + doSetPartition(cmd_param); + else if (strncmp(cmd,"setcdrom", 7)==0) + doSetPartition(ARC_CDROM); + else if (strncmp(cmd,"setdisk", 7)==0) + doSetPartition(ARC_DISK); + else if (strncmp(cmd,"setdefault", 7)==0) + doSetPartition(origOSLoadPartition); + else if (strncmp(cmd,"help", 4)==0) + Help(); + else if (strncmp(cmd,"boot", 4)==0) + doStartKernel(envp); + else if (strncmp(cmd,"cmdline", 7)==0) + printCmdLine(nargc, nargv); + else if (strncmp(cmd,"info", 4)==0) + printInfo(); + else if (strncmp(cmd,"sysid", 7)==0) + printSystemId(); + else if (strncmp(cmd,"cat", 3)==0) + file_cat(cmd_param); + + } while (q==0); - Elf32_Addr kernel_entry32; - Elf64_Addr kernel_entry64; + Wait("\n\r--- Press to enter ARC interactive mode ---"); + ArcEnterInteractiveMode(); +} +void _start(LONG argc, CHAR *argv[], CHAR *envp[]) +{ /* Print identification */ printf(ANSI_CLEAR "\n\rarcsboot: ARCS Linux ext2fs loader " __ARCSBOOT_VERSION__ "\n\n\r"); InitMalloc(); + sysid = ArcGetSystemId(); nopt = ProcessArguments(argc, argv); #if DEBUG - printf("Command line: \n\r"); + printf("Command line (%d): \n\r", nopt); printCmdLine(argc, argv); #endif - if (nopt) { /* the user typed s.th. on the commandline */ - OSLoadFilename = argv[1]; + + /* Check for interactive mode */ + if (strncmp(argv[1],"-i",2)==0) { + interactive=1; + } else { + if (nopt) { /* the user typed s.th. on the commandline */ + OSLoadFilename = argv[1]; + } + } + + if (OSLoadPartition == NULL) { + Non_Fatal("Invalid load parition\n\r"); + interactive=1; + } + if (OSLoadFilename == NULL) { + Non_Fatal("Invalid load filename\n\r"); + interactive=1; } - if (OSLoadPartition == NULL) - Fatal("Invalid load parition\n\r"); - if (OSLoadFilename == NULL) - Fatal("Invalid load filename\n\r"); #if DEBUG printf("OSLoadPartition: %s\n\r", OSLoadPartition); printf("OSLoadFilename: %s\n\r", OSLoadFilename); #endif + /* * XXX: let's play stupid for now: assume /etc/arcboot.conf * is on OSLoadPartition */ - if( !(params = ReadConfFile(&OSLoadPartition, CONF_FILE, OSLoadFilename))) { - printf("Couldn't find label: %s in %s.\n\r", OSLoadFilename, CONF_FILE); + if( !(params = ReadConfFile(&OSLoadPartition, ARC_CONF_FILE, OSLoadFilename))) { + printf("Couldn't find label: %s in %s.\n\r", OSLoadFilename, ARC_CONF_FILE); printf("Will try to boot %s%s.\n\r", OSLoadPartition, OSLoadFilename); nargc = argc; nargv = argv; } else { int i; - OSLoadFilename = params[1]; - nargv = ¶ms[1]; /* nargv[0] is the labels name */ + OSLoadFilename = params[CONF_IMAGE]; + nargv = ¶ms[CONF_ARGS]; /* nargv[0] is the labels name */ for( nargc=0; nargv[nargc]; nargc++); /* count nargv argumnts */ if(OSLoadOptions != NULL) { /* append OSLoadOptions if present */ nargv[nargc] = OSLoadOptions; nargc++; } + + if (params[CONF_INITRD]!=0) + initrd_filename=params[CONF_INITRD]; + /* append command line arguments */ for(i = 2; i <= nopt; i++) { nargv[nargc] = argv[i]; nargc++; } } - printf("Loading %s from %s\n\r",(params) ? params[0] : OSLoadFilename, OSLoadPartition); - kernel_entry64 = LoadKernel(OSLoadPartition, OSLoadFilename); - kernel_entry32 = (Elf32_Addr) kernel_entry64; + #if DEBUG printf("Command line after config file: \n\r"); printCmdLine(nargc, nargv); - printf("Kernel entry: 0x%lx %lx\n\r", - (long)(kernel_entry64>>32),(long)(kernel_entry64&0xffffffff)); Wait("\n\r--- Debug: press to boot kernel ---"); #endif - if( kernel_entry64 ) { - if(is64==0){ - printf("Starting 32-bit kernel\n\r"); - ArcFlushAllCaches(); - ((void (*)(int argc, CHAR * argv[], CHAR * envp[])) - kernel_entry32)(nargc ,nargv, envp); - } else { - printf("Starting 64-bit kernel\n\r"); - ArcFlushAllCaches(); - _start64(nargc ,nargv, envp, &kernel_entry64); - } - } else { - printf("Invalid kernel entry NULL\n\r"); + + if (interactive==1) { + goInteractive(envp); } + if (doLoadKernel()==False) goInteractive(envp); + doLoadInitrd(initrd_filename); + +#if DEBUG_INITRD + printf("Command line after initrd: \n\r"); + printCmdLine(nargc, nargv); +#endif + + doStartKernel(envp); + /* Not likely to get back here in a functional state, but what the heck */ Wait("\n\r--- Press to restart ---"); ArcRestart(); diff -u -r -N arcboot-0.3.8.4/ext2load/loader_ok.c arcboot-onion/ext2load/loader_ok.c --- arcboot-0.3.8.4/ext2load/loader_ok.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/loader_ok.c 2004-11-23 18:12:27.000000000 +0000 @@ -0,0 +1,635 @@ +/* + * Copyright 1999, 2001 Silicon Graphics, Inc. + * Copyright 2001 Ralf Baechle + * 2001-04 Guido Guenther + */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include "arcboot.h" +#include "conffile.h" + +#include + +#define ANSI_CLEAR "\033[2J" +#define ARC_CONF_FILE "/etc/arcboot.conf" +#define PROMPT ":> " + +CHAR *OSLoadPartition = NULL; +CHAR *OSLoadFilename = NULL; +CHAR *OSLoadOptions = NULL; +static int is64=0; +static int interactive=0; +char *cmd_buffer; +char *initrd_filename=NULL; +SYSTEMID *sysid=NULL; +ULONG rd_size; +void *rd_vaddr; +static char argv_rd_start[32]; +static char argv_rd_size[32]; + +typedef union { + unsigned char e_ident[EI_NIDENT]; + Elf32_Ehdr header32; + Elf64_Ehdr header64; +} Elf_Ehdr; + +static void Wait(const char *prompt) +{ + int ch; + + if (prompt != NULL) + puts(prompt); + + do { + ch = getchar(); + } while ((ch != EOF) && (((char) ch) != ' ')); +} + +static void printSystemId(void) +{ + int i; + + sysid=ArcGetSystemId(); + if (sysid!=NULL) { + printf("System ID:\n\rVendor Id: %s\n\r", sysid->VendorId); + for(i=0;iProductId);i++) + printf("0x%x\n\r", sysid->ProductId[i]); + } +} + +void Fatal(const CHAR * message, ...) +{ + va_list ap; + + if (message != NULL) { + printf("FATAL ERROR: "); + va_start(ap, message); + vprintf(message, ap); + va_end(ap); + } + + Wait("\n\r--- Press to enter ARC interactive mode ---"); + ArcEnterInteractiveMode(); +} + + +void InitMalloc(void) +{ + MEMORYDESCRIPTOR *current = NULL; + ULONG stack = (ULONG) ¤t; +#ifdef DEBUG + printf("stack starts at: 0x%lx\n\r", stack); +#endif + + current = ArcGetMemoryDescriptor(current); + if(! current ) { + Fatal("Can't find any valid memory descriptors!\n\r"); + } + while (current != NULL) { + /* + * The spec says we should have an adjacent FreeContiguous + * memory area that includes our stack. It would be much + * easier to just look for that and give it to malloc, but + * the Indy only shows FreeMemory areas, no FreeContiguous. + * Oh well. + */ + if (current->Type == FreeMemory) { + ULONG start = KSEG0ADDR(current->BasePage * PAGE_SIZE); + ULONG end = + start + (current->PageCount * PAGE_SIZE); +#ifdef DEBUG + printf("Free Memory(%u) segment found at (0x%lx,0x%lx).\n\r", + current->Type, start, end); +#endif + + /* Leave some space for our stack */ + if ((stack >= start) && (stack < end)) + end = + (stack - + (STACK_PAGES * + PAGE_SIZE)) & ~(PAGE_SIZE - 1); + /* Don't use memory from reserved region */ + if ((start >= kernel_load[SUBARCH].base ) + && (start < (kernel_load[SUBARCH].base + + kernel_load[SUBARCH].reserved ))) + start = kernel_load[SUBARCH].base + + kernel_load[SUBARCH].reserved; + if ((end > kernel_load[SUBARCH].base) + && (end <= (kernel_load[SUBARCH].base + + kernel_load[SUBARCH].reserved ))) + end = kernel_load[SUBARCH].base; + if (end > start) { +#ifdef DEBUG + printf("Adding %lu bytes at 0x%lx to the list of available memory\n\r", + end-start, start); +#endif + arclib_malloc_add(start, end - start); + } + } + current = ArcGetMemoryDescriptor(current); + } +} + +int isEnvVar(const char* arg) +{ + int i; + + for (i = 0; i < NENTS(env_vars); i++) { + if(strncmp( env_vars[i], arg, strlen(env_vars[i]) ) == 0) + return 1; + } + return 0; +} + +int ProcessArguments(LONG argc, CHAR * argv[]) +{ + LONG arg; + CHAR *equals; + size_t len; + + /* save some things we need later */ + for (arg = 1; arg < argc; arg++) { + equals = strchr(argv[arg], '='); + if (equals != NULL) { + len = equals - argv[arg]; + if (strncmp(argv[arg], "OSLoadPartition", len) == 0) + OSLoadPartition = equals + 1; + if (strncmp(argv[arg], "OSLoadFilename", len) == 0) + OSLoadFilename = equals + 1; + if (strncmp(argv[arg], "OSLoadOptions", len) == 0) { + /* Copy options to local memory to avoid overwrite later */ + OSLoadOptions = strdup(equals + 1); + if (OSLoadOptions == NULL) + Fatal ("Cannot allocate memory for options string\n\r"); + } + } + } + /* + * in case the user typed "boot a b c" the argv looks like: + * scsi(0)..(8)/arcboot a b c OSLoadPartition=.. SystemPartition=.. + * argv: `0 `-1`-2`-3`-4 `-5 + * we're interested in a,b,c so scan the command line and check for + * each argument if it is an environment variable. We're using a fixed + * list instead of ArcGetEnvironmentVariable since e.g. the prom sets + * "OSLoadOptions=auto" on reboot but + * EnvironmentVariable("OSLoadOptions") == NULL + */ + for( arg = 1; arg < argc; arg++ ) { + if( isEnvVar(argv[arg])) { + return (arg-1); +#ifdef DEBUG + } else { + printf("%s is not an envVar\n\r", argv[arg]); +#endif + } + } + return 0; +} + + +void LoadProgramSegments(ext2_file_t file, Elf_Ehdr * header) +{ + int idx; + Boolean loaded = False; + void *segments; + size_t size; + errcode_t status; + + if (header->e_ident[EI_CLASS] == ELFCLASS32) + size = (size_t) (header->header32.e_phentsize * + header->header32.e_phnum); + else + size = (size_t) (header->header64.e_phentsize * + header->header64.e_phnum); + + if (header->e_ident[EI_CLASS] == ELFCLASS32) + printf("Header says 32-bit\n\r"); + else + printf("Header says 64-bit\n\r"); + + if (size <= 0) + Fatal("No program segments\n\r"); + + segments = malloc(size); + if (segments == NULL) + Fatal("Cannot allocate memory for segment headers\n\r"); + else + printf("Allocated 0x%x bytes for segments\n\r", size); + + if (header->e_ident[EI_CLASS] == ELFCLASS32) { + status = ext2fs_file_lseek(file, + (ext2_off_t) header->header32.e_phoff, + EXT2_SEEK_SET, NULL); + } else { + status = ext2fs_file_lseek(file, + (ext2_off_t) header->header64.e_phoff, + EXT2_SEEK_SET, NULL); + } + if (status != 0) { + print_ext2fs_error(status); + Fatal("Cannot seek to program segment headers\n\r"); + } + + status = ext2fs_file_read(file, segments, size, NULL); + if (status != 0) { + print_ext2fs_error(status); + Fatal("Cannot read program segment headers\n\r"); + } + + if(header->e_ident[EI_CLASS] == ELFCLASS32) { + Elf32_Phdr* segment=(Elf32_Phdr*)segments; + printf("Loading 32-bit executable\n\r"); + for (idx = 0; idx < header->header32.e_phnum; idx++) { + if (segment->p_type == PT_LOAD) { + printf + ("Loading program segment %u at 0x%x, offset=0x%x, size = 0x%x\n\r", + idx + 1, KSEG0ADDR(segment->p_vaddr), + segment->p_offset, segment->p_filesz); + + status = + ext2fs_file_lseek(file, segment->p_offset, + EXT2_SEEK_SET, NULL); + if (status != 0) { + print_ext2fs_error(status); + Fatal("Cannot seek to program segment\n\r"); + } + + status = ext2fs_file_read(file, + (void *) (KSEG0ADDR( + segment->p_vaddr)), + segment->p_filesz, NULL); + if (status != 0) { + print_ext2fs_error(status); + Fatal("Cannot read program segment\n\r"); + } + + size = segment->p_memsz - segment->p_filesz; + +#ifdef DEBUG + Wait("\n\r--- Waiting... ---"); +#endif + + if (size > 0) { + printf + ("Zeroing memory at 0x%x, size = 0x%x\n\r", + (KSEG0ADDR(segment->p_vaddr + + segment->p_filesz)), size); + memset((void *) + (KSEG0ADDR(segment-> + p_vaddr + segment->p_filesz)), 0, size); + } + + loaded = True; +#ifdef DEBUG + Wait("\n\r--- Waiting... ---"); +#endif + } + + segment = + (Elf32_Phdr *) (((char *) segment) + + header->header32.e_phentsize); + } + } else { + Elf64_Phdr* segment=(Elf64_Phdr*)segments; + is64=1; + printf("Loading 64-bit executable\n\r"); + for (idx = 0; idx < header->header64.e_phnum; idx++) { + if (segment->p_type == PT_LOAD) { + printf + ("Loading program segment %u at 0x%x, offset=0x%lx %lx, size = 0x%lx %lx\n\r", + idx + 1, KSEG0ADDR(segment->p_vaddr), + (long)(segment->p_offset>>32),(long)(segment->p_offset&0xffffffff), + (long)(segment->p_filesz>>32),(long)(segment->p_filesz&0xffffffff)); + + status = + ext2fs_file_lseek(file, segment->p_offset, + EXT2_SEEK_SET, NULL); + if (status != 0) { + print_ext2fs_error(status); + Fatal("Cannot seek to program segment\n\r"); + } + + status = ext2fs_file_read(file, + (void *) (KSEG0ADDR( + segment->p_vaddr)), + segment->p_filesz, NULL); + if (status != 0) { + print_ext2fs_error(status); + Fatal("Cannot read program segment\n\r"); + } + + size = segment->p_memsz - segment->p_filesz; + if (size > 0) { + printf + ("Zeroing memory at 0x%x, size = 0x%x\n\r", + (KSEG0ADDR(segment->p_vaddr + + segment->p_filesz)), size); + memset((void *) + (KSEG0ADDR(segment-> + p_vaddr + segment->p_filesz)), 0, size); + } + + loaded = True; + } + + segment = + (Elf64_Phdr *) (((char *) segment) + + header->header64.e_phentsize); + } + } + + if (!loaded) + Fatal("No loadable program segments found\n\r"); + + free(segments); +} + +Elf64_Addr LoadKernelFile(ext2_file_t file) +{ + Elf_Ehdr header; + Elf64_Addr entry; + errcode_t status; + + status = + ext2fs_file_read(file, (void *) &header, sizeof(header), NULL); + if (status != 0) { + print_ext2fs_error(status); + Fatal("Can't read file header\n\r"); + } + + if (memcmp(&(header.e_ident[EI_MAG0]), ELFMAG, SELFMAG) != 0) + Fatal("Not an ELF file\n\r"); + + if (header.e_ident[EI_CLASS] != ELFCLASS32 && + header.e_ident[EI_CLASS] != ELFCLASS64) + Fatal("Not a 32-bit or 64-bit file\n\r"); + + if (header.e_ident[EI_DATA] != ELFDATA2MSB) + Fatal("Not a big-endian file\n\r"); + + if (header.e_ident[EI_VERSION] != EV_CURRENT) + Fatal("Wrong ELF version\n\r"); + + if (header.e_ident[EI_CLASS]==ELFCLASS32) { + if (header.header32.e_type != ET_EXEC) + Fatal("Not an executable file\n\r"); + + if (header.header32.e_machine != EM_MIPS) + Fatal("Unsupported machine type\n\r"); + + if (header.header32.e_version != EV_CURRENT) + Fatal("Wrong ELF version\n\r"); + + entry = (Elf64_Addr) header.header32.e_entry; + } else { + if (header.header64.e_type != ET_EXEC) + Fatal("Not an executable file\n\r"); + + if (header.header64.e_machine != EM_MIPS) + Fatal("Unsupported machine type\n\r"); + + if (header.header64.e_version != EV_CURRENT) + Fatal("Wrong ELF version\n\r"); + + entry = header.header64.e_entry; + } + + LoadProgramSegments(file, &header); + + return entry; +} + + +Boolean OpenFile(const char *partition, const char *filename, ext2_file_t* file) +{ + extern io_manager arc_io_manager; + ext2_filsys fs; + ext2_ino_t file_inode; + errcode_t status; + + initialize_ext2_error_table(); + + status = ext2fs_open(partition, 0, 0, 0, arc_io_manager, &fs); + if (status != 0) { + print_ext2fs_error(status); + return False; + } + + status = ext2fs_namei_follow + (fs, EXT2_ROOT_INO, EXT2_ROOT_INO, filename, &file_inode); + if (status != 0) { + print_ext2fs_error(status); + return False; + } + + status = ext2fs_file_open(fs, file_inode, 0, file); + if (status != 0) { + print_ext2fs_error(status); + return False; + } + return True; +} + +Elf64_Addr LoadKernel(const char *partition, const char *filename) +{ + ext2_file_t file; + + if(!OpenFile( partition, filename, &file )) + Fatal("Can't load kernel!\n\r"); + return LoadKernelFile(file); +} + +int LoadInitrd(const char *partition, const char *filename ) +{ + ext2_file_t file; + int status; + void *ramdisk; + + if(!OpenFile( partition, filename, &file )) { + printf("Can't load initrd, skipping for now!\n\r"); + return; + } + + rd_size = ext2fs_file_get_size(file); + + ramdisk = malloc(rd_size+PAGE_SIZE); /* Let's be on the safe side */ + if (ramdisk == NULL) { + printf("Unable to allocate memory for ramdisk image!\n\r"); + return False; + } else + printf("Allocated 0x%lx bytes for ramdisk\n\r", rd_size); + + /* XXX: should I do something like this ? Seems to work without :) */ + /* rd_vaddr = (char*)(((ramdisk + PAGE_SIZE) / PAGE_SIZE ) * PAGE_SIZE);*/ + + printf ("Loading ramdisk %s at 0x%p, size = 0x%lx\n\r", + filename, ramdisk, rd_size); + + status = ext2fs_file_read(file, ramdisk, rd_size, NULL); + if (status != 0) { + print_ext2fs_error(status); + printf("Cannot read ramdisk image\n\r"); + return False; + } else { + rd_vaddr=ramdisk; + } + return True; +} + +void goInteractive() +{ + printf("-- Sorry, interactive mode not yet implemented\n\r"); +} + +void printCmdLine(int argc, CHAR *argv[]) +{ + int i; + + for(i = 0; i < argc; i++ ) + if (argv[i]!=0) + printf("%u: %s\n\r", i, argv[i]); +} + +void _start64(LONG argc, CHAR * argv[], CHAR * envp[], + unsigned long long *addr) +{ + asm volatile (".set push\n" + "\t.set mips3\n" + "\t.set noreorder\n" + "\t.set noat\n" + "\tld $1, 0($7)\n" + "\tjr $1\n" + "\t nop\n" + "\t.set pop"); +} + +void _start(LONG argc, CHAR *argv[], CHAR *envp[]) +{ + CHAR** nargv; + CHAR** params; + int nargc, nopt; + + Elf32_Addr kernel_entry32; + Elf64_Addr kernel_entry64; + + /* Print identification */ + printf(ANSI_CLEAR "\n\rarcsboot: ARCS Linux ext2fs loader " + __ARCSBOOT_VERSION__ "\n\n\r"); + + InitMalloc(); + +#if DEBUG + printSystemId(); +#endif + + nopt = ProcessArguments(argc, argv); + +#if DEBUG + printf("Command line: \n\r"); + printCmdLine(argc, argv); +#endif + if (nopt) { /* the user typed s.th. on the commandline */ + OSLoadFilename = argv[1]; + } + + if (OSLoadPartition == NULL) + Fatal("Invalid load parition\n\r"); + if (OSLoadFilename == NULL) + Fatal("Invalid load filename\n\r"); + +#if DEBUG + printf("OSLoadPartition: %s\n\r", OSLoadPartition); + printf("OSLoadFilename: %s\n\r", OSLoadFilename); +#endif + /* + * XXX: let's play stupid for now: assume /etc/arcboot.conf + * is on OSLoadPartition + */ + if( !(params = ReadConfFile(&OSLoadPartition, ARC_CONF_FILE, OSLoadFilename))) { + printf("Couldn't find label: %s in %s.\n\r", OSLoadFilename, ARC_CONF_FILE); + printf("Will try to boot %s%s.\n\r", OSLoadPartition, OSLoadFilename); + nargc = argc; + nargv = argv; + } else { + int i; + OSLoadFilename = params[CONF_IMAGE]; + nargv = ¶ms[CONF_IMAGE]; /* nargv[0] is the labels name */ + for( nargc=0; nargv[nargc]; nargc++); /* count nargv argumnts */ + if(OSLoadOptions != NULL) { /* append OSLoadOptions if present */ + nargv[nargc] = OSLoadOptions; + nargc++; + } + + if (params[CONF_INITRD]) + initrd_filename=params[CONF_INITRD]; + + /* append command line arguments */ + for(i = CONF_ARGS; i <= nopt; i++) { + nargv[nargc] = argv[i]; + nargc++; + } + } + +#if DEBUG + printf("Command line after config file: \n\r"); + printCmdLine(nargc, nargv); + Wait("\n\r--- Debug: press to boot kernel ---"); +#endif + + printf("Loading %s from %s\n\r",(params) ? params[0] : OSLoadFilename, OSLoadPartition); + + kernel_entry64 = LoadKernel(OSLoadPartition, OSLoadFilename); + kernel_entry32 = (Elf32_Addr) kernel_entry64; + + printf("Kernel entry: 0x%lx %lx\n\r", + (long)(kernel_entry64>>32), (long)(kernel_entry64&0xffffffff)); + + if (initrd_filename != NULL) { + if (LoadInitrd(OSLoadPartition, initrd_filename)==True) { + sprintf(argv_rd_start, "rd_start=0x%p", rd_vaddr); + sprintf(argv_rd_size, "rd_size=0x%lx", rd_size); + nargv[nargc]=argv_rd_start; + nargc++; + nargv[nargc]=argv_rd_size; + nargc++; + } + } + +#if DEBUG_INITRD + printf("Command line after initrd: \n\r"); + printCmdLine(nargc, nargv); + Wait("\n\r--- Debug: press to boot kernel ---"); +#endif + + if( kernel_entry64 ) { + if(is64==0) { + printf("Starting ELF32 kernel\n\r"); + ArcFlushAllCaches(); + ((void (*)(int argc, CHAR * argv[], CHAR * envp[])) + kernel_entry32)(nargc ,nargv, envp); + } else { + printf("Starting ELF64 kernel\n\r"); + ArcFlushAllCaches(); + _start64(nargc, nargv, envp, &kernel_entry64); + } + } else { + printf("Invalid kernel entry NULL\n\r"); + } + + /* Not likely to get back here in a functional state, but what the heck */ + Wait("\n\r--- Press to restart ---"); + ArcRestart(); +} diff -u -r -N arcboot-0.3.8.4/ext2load/Makefile arcboot-onion/ext2load/Makefile --- arcboot-0.3.8.4/ext2load/Makefile 2004-09-25 16:20:39.000000000 +0000 +++ arcboot-onion/ext2load/Makefile 2004-11-25 14:01:08.000000000 +0000 @@ -2,42 +2,72 @@ # Copyright 1999 Silicon Graphics, Inc. # 2001-04 Guido Guenther # -EXT2_OBJS = loader.o ext2io.o conffile.o -LARC_OBJS = larc.o -OBJECTS = $(EXT2_OBJS) $(LARC_OBJS) -E2FSLIBDIR=../e2fslib +SUBARCH ?= IP32 -ARCLIBDIR = ../arclib -ARCLIB = $(ARCLIBDIR)/libarc.a +# Comment out if you don't need them +USE_ISOFS=-DUSE_ISOFS +#USE_ROMFS=-DUSE_ROMSFS COMMONDIR = ../common -EXT2LIB = ../e2fslib/libext2fs.a +E2FSLIBDIR = ../e2fslib +EXT2LIB = $(E2FSLIBDIR)/libext2fs.a -CFLAGS = -O -I $(COMMONDIR) -I$(ARCLIBDIR) -I$(E2FSLIBDIR) \ - -Wall -mno-abicalls -G 0 -fno-pic \ - -DSUBARCH=${SUBARCH} +ARCLIBDIR = ../arclib +ARCLIB = $(ARCLIBDIR)/libarc.a -ASFLAGS= -mno-abicalls -G 0 -fno-pic +OBJECTS = loader.o ext2io.o conffile.o ext2.o file.o stringops2.o -# uncomment for debugging -#CFLAGS+=-DDEBUG +ifneq ($(USE_ISOFS),) +OBJECTS+=isofs.o +endif -LD = ld -LDFLAGS = -N --oformat ecoff-bigmips -T ld.script +ifneq ($(USE_ROMFS),) +OBJECTS+=romfs.o +endif +LIBS = $(EXT2LIB) $(ARCLIB) TARGETS = ext2load +CFLAGS = -O2 -I $(COMMONDIR) -I$(ARCLIBDIR) -I$(E2FSLIBDIR) \ + -Wall -mno-abicalls -G 0 -fno-pic -fno-builtin-printf \ + -DSUBARCH=${SUBARCH} $(USE_ISOFS) $(USE_ROMFS) + +# uncomment for generic debugging +CFLAGS+=-DDEBUG + +# uncomment for initrd debugging +CFLAGS+=-DDEBUG_INITRD + +# uncomment for fs debug +CFLAGS+=-DDEBUG_FS + +# uncomment for config file debug +CFLAGS+=-DDEBUG_CONFIG + +LD = ld +LDFLAGS = -N -T ld.script + all: $(TARGETS) -ext2load: $(EXT2_OBJS) $(ARCLIB) ld.script ../common/subarch.h +loader.o: file.h arcboot.h +ext2.o: file.h +romfs.o: file.h +isofs.o: file.h + +ext2load: $(OBJECTS) $(LIBS) ld.script ../common/subarch.h rm -f $@ - $(LD) $(LDFLAGS) -o $@ $(EXT2_OBJS) $(EXT2LIB) $(ARCLIB) + $(LD) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS) + +ld.script: ld.script.in + $(MAKE) -C ../common SUBARCH=$(SUBARCH) print_loadaddr + LOADADDR=$$(../common/print_loadaddr $(SUBARCH)); \ + OUTPUTFORMAT=$$(../common/print_outputformat $(SUBARCH)); \ + sed -e "s/@@LOADADDR@@/$$LOADADDR/" \ + -e "s/@@OUTPUTFORMAT@@/$$OUTPUTFORMAT/" <$< >$@ -ld.script: ld.script.in ../common/print_loadaddr - LOADADDR=$$(../common/print_loadaddr); \ - sed -e "s/@@LOADADDR@@/$$LOADADDR/" <$< >$@ +install: clean: rm -f $(TARGETS) *.a *.o tags ld.script diff -u -r -N arcboot-0.3.8.4/ext2load/rock.h arcboot-onion/ext2load/rock.h --- arcboot-0.3.8.4/ext2load/rock.h 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/rock.h 2004-11-23 11:10:53.000000000 +0000 @@ -0,0 +1,119 @@ +/* These structs are used by the system-use-sharing protocol, in which the + Rock Ridge extensions are embedded. It is quite possible that other + extensions are present on the disk, and this is fine as long as they + all use SUSP */ + +#define SIG(A,B) ((A << 8) | B) + +#define CHECK_CE \ + {cont_extent = isonum_733(rr->u.CE.extent); \ + cont_offset = isonum_733(rr->u.CE.offset); \ + cont_size = isonum_733(rr->u.CE.size);} + + +struct SU_SP{ + unsigned char magic[2]; + unsigned char skip; +}; + +struct SU_CE{ + char extent[8]; + char offset[8]; + char size[8]; +}; + +struct SU_ER{ + unsigned char len_id; + unsigned char len_des; + unsigned char len_src; + unsigned char ext_ver; + char data[0]; +}; + +struct RR_RR{ + char flags[1]; +}; + +struct RR_PX{ + char mode[8]; + char n_links[8]; + char uid[8]; + char gid[8]; +}; + +struct RR_PN{ + char dev_high[8]; + char dev_low[8]; +}; + + +struct SL_component{ + unsigned char flags; + unsigned char len; + char text[0]; +}; + +struct RR_SL{ + unsigned char flags; + struct SL_component link; +}; + +struct RR_NM{ + unsigned char flags; + char name[0]; +}; + +struct RR_CL{ + char location[8]; +}; + +struct RR_PL{ + char location[8]; +}; + +struct stamp{ + char time[7]; +}; + +struct RR_TF{ + char flags; + struct stamp times[0]; /* Variable number of these beasts */ +}; + +/* These are the bits and their meanings for flags in the TF structure. */ +#define TF_CREATE 1 +#define TF_MODIFY 2 +#define TF_ACCESS 4 +#define TF_ATTRIBUTES 8 +#define TF_BACKUP 16 +#define TF_EXPIRATION 32 +#define TF_EFFECTIVE 64 +#define TF_LONG_FORM 128 + +struct rock_ridge{ + char signature[2]; + unsigned char len; + unsigned char version; + union{ + struct SU_SP SP; + struct SU_CE CE; + struct SU_ER ER; + struct RR_RR RR; + struct RR_PX PX; + struct RR_PN PN; + struct RR_SL SL; + struct RR_NM NM; + struct RR_CL CL; + struct RR_PL PL; + struct RR_TF TF; + } u; +}; + +#define RR_PX 1 /* POSIX attributes */ +#define RR_PN 2 /* POSIX devices */ +#define RR_SL 4 /* Symbolic link */ +#define RR_NM 8 /* Alternate Name */ +#define RR_CL 16 /* Child link */ +#define RR_PL 32 /*