diff -u -N -r tmp/arcboot/arclib/Makefile arcboot-onion/arclib/Makefile --- tmp/arcboot/arclib/Makefile 2004-11-29 10:52:21.000000000 +0000 +++ arcboot-onion/arclib/Makefile 2004-11-25 15:50:25.000000000 +0000 @@ -1,7 +1,7 @@ # # Copyright 1999 Silicon Graphics, Inc. # -CFLAGS = -O2 -Werror -Wall -mno-abicalls -G 0 -fno-pic +CFLAGS = -O2 -march=mips3 -Werror -Wall -mno-abicalls -G 0 -fno-pic OBJECTS = arc.o stdio.o stdlib.o string.o diff -u -N -r tmp/arcboot/arclib/stdio.c arcboot-onion/arclib/stdio.c --- tmp/arcboot/arclib/stdio.c 2004-11-29 10:39:38.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 -N -r tmp/arcboot/arclib/stdlib.c arcboot-onion/arclib/stdlib.c --- tmp/arcboot/arclib/stdlib.c 2004-11-29 10:39:38.000000000 +0000 +++ arcboot-onion/arclib/stdlib.c 2004-12-03 16:18:10.000000000 +0000 @@ -116,3 +116,14 @@ node->size = size - (size % sizeof(Node)); free((void *) (node + 1)); } + +int atoi(char *str) +{ + int i,k=1,num=0; + + for (i=strlen(str);i>0;i--) { + num+=(str[i-1]-48)*k; + k=k*10; + } + return num; +} diff -u -N -r tmp/arcboot/arclib/stdlib.h arcboot-onion/arclib/stdlib.h --- tmp/arcboot/arclib/stdlib.h 2004-11-29 10:39:38.000000000 +0000 +++ arcboot-onion/arclib/stdlib.h 2004-12-03 16:17:56.000000000 +0000 @@ -12,5 +12,6 @@ extern void *realloc(void *ptr, size_t size); extern void arclib_malloc_add(ULONG start, ULONG size); +extern int atoi(char *str); #endif /* _STDLIB_H_ */ diff -u -N -r tmp/arcboot/common/subarch.h arcboot-onion/common/subarch.h --- tmp/arcboot/common/subarch.h 2004-11-29 10:52:21.000000000 +0000 +++ arcboot-onion/common/subarch.h 2004-11-21 18:33:15.000000000 +0000 @@ -34,7 +34,7 @@ }, { /* IP32 */ .base = 0x80004000, - .reserved = 0x1400000, + .reserved = 0x1400000, }, }; diff -u -N -r tmp/arcboot/common/version.h arcboot-onion/common/version.h --- tmp/arcboot/common/version.h 2004-11-29 10:52:21.000000000 +0000 +++ arcboot-onion/common/version.h 2004-12-03 15:04:30.000000000 +0000 @@ -1 +1 @@ -#define __ARCSBOOT_VERSION__ "0.3.8.4" +#define __ARCSBOOT_VERSION__ "0.3.9.0" diff -u -N -r tmp/arcboot/e2fslib/et/com_err.texinfo arcboot-onion/e2fslib/et/com_err.texinfo --- tmp/arcboot/e2fslib/et/com_err.texinfo 2004-11-29 10:39:38.000000000 +0000 +++ arcboot-onion/e2fslib/et/com_err.texinfo 2002-02-03 22:53:44.000000000 +0000 @@ -1,7 +1,7 @@ \input texinfo @c -*-texinfo-*- -@c $Header: /home/cvs/arcboot/e2fslib/et/com_err.texinfo,v 1.1 2004/11/29 10:39:38 ladis Exp $ -@c $Source: /home/cvs/arcboot/e2fslib/et/com_err.texinfo,v $ +@c $Header: /cvs/debian/arcboot/e2fslib/et/com_err.texinfo,v 1.1 2002/02/03 22:53:44 agx Exp $ +@c $Source: /cvs/debian/arcboot/e2fslib/et/com_err.texinfo,v $ @c $Locker: $ @c Note that although this source file is in texinfo format (more diff -u -N -r tmp/arcboot/e2fslib/et/Makefile arcboot-onion/e2fslib/et/Makefile --- tmp/arcboot/e2fslib/et/Makefile 2004-11-29 10:39:38.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 -N -r tmp/arcboot/e2fslib/fileio.c arcboot-onion/e2fslib/fileio.c --- tmp/arcboot/e2fslib/fileio.c 2004-11-29 10:39:38.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 -N -r tmp/arcboot/e2fslib/Makefile arcboot-onion/e2fslib/Makefile --- tmp/arcboot/e2fslib/Makefile 2004-11-29 10:39:38.000000000 +0000 +++ arcboot-onion/e2fslib/Makefile 2004-11-25 15:51:06.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 -march=mips3 -G 0 -fno-pic -mno-abicalls CPPFLAGS = ALL_CFLAGS = $(CPPFLAGS) $(DEFS) $(USE_WFLAGS) $(CFLAGS) $(XTRA_CFLAGS) \ -I. $(LINUX_INCLUDE) diff -u -N -r tmp/arcboot/e2fslib/MCONFIG arcboot-onion/e2fslib/MCONFIG --- tmp/arcboot/e2fslib/MCONFIG 2004-11-29 10:39:38.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 -N -r tmp/arcboot/e2fslib/util/Makefile arcboot-onion/e2fslib/util/Makefile --- tmp/arcboot/e2fslib/util/Makefile 2004-11-29 10:39:38.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 -N -r tmp/arcboot/ext2load/arcboot.h arcboot-onion/ext2load/arcboot.h --- tmp/arcboot/ext2load/arcboot.h 2004-11-29 12:39:31.000000000 +0000 +++ arcboot-onion/ext2load/arcboot.h 2004-12-03 15:29:51.000000000 +0000 @@ -7,6 +7,15 @@ #include +#define ANSI_CLEAR "\033[2J" +#define GOTO_COL "\033[%dG" +#define RED "\033[01;31m" +#define GREEN "\033[01;32m" +#define BLUE "\033[01;34m" +#define YELLOW "\033[01;33m" +#define WHITE "\033[01;39m" +#define NORMAL "\033[00m" + /* loader.c */ extern CHAR *OSLoadPartition; extern CHAR *OSLoadFilename; @@ -14,13 +23,12 @@ typedef enum { False = 0, True } Boolean; -Boolean OpenFile(const char *partition, const char *filename, ext2_file_t* file); void Fatal(const CHAR * message, ...); +Boolean Non_Fatal(const CHAR * message, ...); /* conffile.c */ CHAR** ReadConfFile(char **partition, const char *filename, char* config); /* ext2io.c */ -extern int arc_do_progress; void print_ext2fs_error(long status); #endif /* _ARCBOOT_H */ diff -u -N -r tmp/arcboot/ext2load/conffile.c arcboot-onion/ext2load/conffile.c --- tmp/arcboot/ext2load/conffile.c 2004-11-29 10:39:38.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 -N -r tmp/arcboot/ext2load/conffile.h arcboot-onion/ext2load/conffile.h --- tmp/arcboot/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 -N -r tmp/arcboot/ext2load/ext2.c arcboot-onion/ext2load/ext2.c --- tmp/arcboot/ext2load/ext2.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/ext2.c 2004-12-03 12:53:02.000000000 +0000 @@ -0,0 +1,183 @@ +/* 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 "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 */ +static 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); + 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(unsigned 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; +} + +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 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, + .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 -N -r tmp/arcboot/ext2load/ext2io.c arcboot-onion/ext2load/ext2io.c --- tmp/arcboot/ext2load/ext2io.c 2004-11-29 12:39:31.000000000 +0000 +++ arcboot-onion/ext2load/ext2io.c 2004-12-02 19:39:50.000000000 +0000 @@ -157,11 +157,11 @@ int hitrate_w = (hits * 1000) / (hits + misses) / 10; int hitrate_f = (hits * 1000) / (hits + misses) % 10; +#ifdef DEBUG_CACHE priv->total_read += count; printf("\r%lx (cache: %u.%u%%)", priv->total_read, hitrate_w, hitrate_f); -#ifdef DEBUG if ((hits + misses) % 100 == 0) printf("hits: %u misses %u\n\r", hits, misses); #endif @@ -599,7 +599,7 @@ priv = (struct arc_private_data *) channel->private_data; EXT2_CHECK_MAGIC(priv, EXT2_ET_BAD_MAGIC); -#ifdef DEBUG +#ifdef DEBUG_CACGE printf("req %lu id %lu count %u\n\r", block, priv->fileID, count); #endif @@ -610,7 +610,7 @@ while (count > 0) { if ((cache = find_cached_block(channel, priv, block)) == NULL) break; -#ifdef DEBUG +#ifdef DEBUG_CACHE printf("Cache hit on block %lu\n\r", block); #endif memcpy(cbuf, cache->buf, channel->block_size); @@ -629,13 +629,13 @@ * for reads we expect are not part of a sequential set. */ while (count > 0) { -#ifdef DEBUG +#ifdef DEBUG_CACHE printf("Cache miss on block %lu (readahead %u)\n\r", block, CACHE_SG_MAX); #endif if ((cb_alloc = alloc_sg_blocks(channel, priv, block, CACHE_SG_MAX)) == 0) { -#ifdef DEBUG +#ifdef DEBUG_CACHE printf("%s\n\r", "Cache error: can't alloc any blocks"); #endif /* Cache is broken, so do the raw read. */ @@ -646,7 +646,7 @@ } if ((status = fill_sg_blocks(channel, priv, cb_alloc)) != 0) { -#ifdef DEBUG +#ifdef DEBUG_CACHE printf("Cache error (status %lu at block %lu(%u)\n\r", (unsigned long) status, block, count); #endif diff -u -N -r tmp/arcboot/ext2load/file.c arcboot-onion/ext2load/file.c --- tmp/arcboot/ext2load/file.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/file.c 2004-12-03 15:34:22.000000000 +0000 @@ -0,0 +1,292 @@ +/* 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; + +/* 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; + +#define LINES_PER_PAGE 25 + +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 ) { + 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>LINES_PER_PAGE) { + 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) { + 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); + printf("Failed to open file %s\n\r", filename); + return False; + } + + return True; +} + +int file_read (char *buffer, unsigned int size) { + if (cur_ops==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(unsigned 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(); + 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); + size=file_size(); + buffer=malloc(550); + while (file_read(buffer, 512)) { + puts(buffer); + memset(buffer, 0, 513); + } + + free(buffer); + file_close(); +} diff -u -N -r tmp/arcboot/ext2load/file.h arcboot-onion/ext2load/file.h --- tmp/arcboot/ext2load/file.h 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/file.h 2004-12-03 13:00:20.000000000 +0000 @@ -0,0 +1,49 @@ +/* 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 */ + +int file_open(char *filename); +int file_lseek(unsigned 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 *); + 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) (unsigned int position); + void (*print_error) (int); + void (*close) (void); + int inode; +}; diff -u -N -r tmp/arcboot/ext2load/isofs.c arcboot-onion/ext2load/isofs.c --- tmp/arcboot/ext2load/isofs.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/isofs.c 2004-12-03 13:00:59.000000000 +0000 @@ -0,0 +1,526 @@ +/* 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 "file.h" +#include "rock.h" +#include "ext2_fs.h" +#include "ext2fs.h" + +/* Reuse and abuse */ +typedef ext2_filsys isofs_filsys; + +struct isofs_inode { + unsigned int extent; + unsigned int size; +}; + +extern void rotate(void); + +static struct isofs_inode inode, root_inode; +static int link_count = 0; + +struct isofs_file { + isofs_filsys fs; + ext2_off_t pos; + struct isofs_inode inode; + char *buf; +}; + +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]; +}; + +static struct isofs_file *file; + +unsigned int bs; + +static int block_no; + +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; + + ret = open_namei (fs, filename, &inode, &root_inode); + iso_fs_ops.inode = (ret) ? 0 : 1; + + 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; + + if (((struct struct_io_manager *)(arc_io_manager))->open (device, 0, &fs->io)) + return 1; + + io_channel_set_blksize (fs->io, 2048); + fs->blocksize = 2048; + + if (isofs_read_super(fs->io)) + return 1; + + 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; + + 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; + + file = malloc (sizeof(struct isofs_file) ); + memset (file, 0, sizeof(struct isofs_file) ); + + ret = open_namei (fs, filename, &inode, &root_inode); + iso_fs_ops.inode = (ret) ? 0 : 1; + + file->fs=fs; + file->pos=0; + file->inode=inode; + + file->buf=malloc(2048); + if (!file->buf) ret=1; + memset (file->buf, 0, 2048); + + return ret; +} + +static void isofs_close(void) +{ + free (fs->io); + free (fs); +} + +static int close_file_isofs(void) +{ + free (file->buf); + free (file); + return 0; +} + +static int seek_file_isofs(unsigned int position) +{ + file->pos = position; + block_no = file->pos / file->fs->blocksize; + return 0; +} + +static int read_file_isofs(char *buffer, unsigned int size) +{ + unsigned int b, start, left, c = 0, count = 0; + isofs_filsys fs; + int retval; + + fs=file->fs; + while ((file->pos < file->inode.size) && (size > 0)) { + + b = file->pos / file->fs->blocksize; + block_no=b+file->inode.extent; + + retval = io_channel_read_blk (fs->io, block_no, 1, file->buf); + if (retval) return retval; + + start = file->pos % fs->blocksize; + c = fs->blocksize - start; + + if (c > size) + c=size; + + left = file->inode.size - file->pos; + if (c > left) + c=left; + + memcpy(buffer, file->buf + start, c); + file->pos += c; + buffer += c; + count += c; + size -= c; + + rotate(); + } + return 0; +} + +static void print_error_isofs (int error_val) { + printf("Unknown isofs error\n\r"); +} + +struct fs_ops iso_fs_ops = { + .name "ISO-9660 CDROM", + .open = open_isofs, + .ls = ls_isofs, + .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 -N -r tmp/arcboot/ext2load/loader.c arcboot-onion/ext2load/loader.c --- tmp/arcboot/ext2load/loader.c 2004-11-29 12:39:31.000000000 +0000 +++ arcboot-onion/ext2load/loader.c 2004-12-03 17:11:27.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,19 +19,36 @@ #include #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)rdisk(0)partition(8)" +#define ARC_DISK "pci(0)scsi(0)rdisk(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]; @@ -38,7 +56,55 @@ 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 *prompt, int edit_mode) +{ + char ch=0; + int i=0; + char *t; + + + printf("%s%s%s",GREEN, prompt, NORMAL); + if (!edit_mode) + 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; + +#ifdef DEBUG_INTERACTIVE + printf("Command is: %s\n\r", cmd); + printf("Param is: %s\n\r", cmd_param); +#endif +} + +void Wait(const char *prompt) { int ch; @@ -47,9 +113,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, ...) { @@ -66,6 +146,23 @@ 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); + } + +#ifdef DEBUG + Wait("\n\r--- Press to continue ---"); +#endif + return False; +} + void InitMalloc(void) { @@ -91,7 +188,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 @@ -146,10 +243,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); @@ -158,6 +257,7 @@ } } } + /* * in case the user typed "boot a b c" the argv looks like: * scsi(0)..(8)/arcboot a b c OSLoadPartition=.. SystemPartition=.. @@ -181,7 +281,7 @@ } -void LoadProgramSegments(ext2_file_t file, Elf_Ehdr * header) +Boolean LoadProgramSegments(Elf_Ehdr * header) { int idx; Boolean loaded = False; @@ -196,33 +296,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) { @@ -236,26 +337,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"); } - arc_do_progress = 1; - status = ext2fs_file_read(file, - (void *) (KSEG0ADDR( + status = file_read( (void *) (KSEG0ADDR( segment->p_vaddr)), - segment->p_filesz, NULL); - printf("\n\n\r"); /* Clear progress */ - arc_do_progress = 0; + 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", @@ -267,6 +368,9 @@ } loaded = True; +#ifdef DEBUG + Wait("\n\r--- Waiting... ---"); +#endif } segment = @@ -286,22 +390,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"); } - arc_do_progress = 1; - status = ext2fs_file_read(file, - (void *) (KSEG0ADDR( + status = file_read( (void *) (KSEG0ADDR( segment->p_vaddr)), - segment->p_filesz, NULL); - arc_do_progress = 0; + 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; @@ -324,114 +424,197 @@ } } - 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"); + return Non_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"); + return Non_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"); + return Non_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"); + return Non_Fatal("Not a big-endian file\n\r"); if (header.e_ident[EI_VERSION] != EV_CURRENT) - Fatal("Wrong ELF version\n\r"); + return Non_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"); + return Non_Fatal("Not an executable file\n\r"); if (header.header32.e_machine != EM_MIPS) - Fatal("Unsupported machine type\n\r"); + return Non_Fatal("Unsupported machine type\n\r"); if (header.header32.e_version != EV_CURRENT) - Fatal("Wrong ELF version\n\r"); + return Non_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"); + return Non_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"); + return Non_Fatal("Wrong ELF version\n\r"); entry = header.header64.e_entry; } - LoadProgramSegments(file, &header); + set_rotate(1); + if (LoadProgramSegments(&header)==False) { + set_rotate(0); + if (interactive==1) return entry; + return Non_Fatal("Program segment load failed!\n\r"); + } + set_rotate(0); return entry; } +Elf64_Addr LoadKernel(const char *partition, const char *filename) +{ + if(!open_file( partition, filename )) + Fatal("Can't load kernel!\n\r"); + return LoadKernelFile(); +} -Boolean OpenFile(const char *partition, const char *filename, ext2_file_t* file) +int LoadInitrd(const char *partition, const char *filename ) { - extern io_manager arc_io_manager; - ext2_filsys fs; - ext2_ino_t file_inode; - errcode_t status; + int status; + void *ramdisk; - initialize_ext2_error_table(); + if(!open_file( partition, filename )) { + printf("Can't load initrd, skipping for now!\n\r"); + return False; + } - status = ext2fs_open(partition, 0, 0, 0, arc_io_manager, &fs); - if (status != 0) { - print_ext2fs_error(status); + rd_size = file_size(); + if (rd_size==0) { + printf("Got initrd size of 0?"); return False; } - status = ext2fs_namei_follow - (fs, EXT2_ROOT_INO, EXT2_ROOT_INO, filename, &file_inode); - if (status != 0) { - print_ext2fs_error(status); + 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_open(fs, file_inode, 0, file); + 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; } -Elf64_Addr LoadKernel(const char *partition, const char *filename) +void Help(void) { - ext2_file_t file; - - if(!OpenFile( partition, filename, &file )) - Fatal("Can't load kernel!\n\r"); - return LoadKernelFile(file); + 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- %s\n\r", ARC_CDROM); + printf("setdisk - Set filesystem to DISK:\n\r- %s\n\r", ARC_DISK); + printf("setdefault - Set filesystem to defaul\n\r"); + printf("sysid - Display Systme ID\n\r"); + printf("info - Show current variables\n\r"); + printf("clear - Clear screen\n\r"); + printf("cmdline - Kernel command line\n\r"); + printf("cmdedit l - Edit kernel command line #l\n\r"); + printf("loadkernel fn - Load kernel 'fn'\n\r"); + printf("loadinitrd fn - Load initrd 'fn'\n\r"); +/* printf("loadconfig fn - Load config file 'fn'\n\r"); */ +} + +void doSetPartition(char *newpart) { + if (newpart==NULL) return; + close_fs(); + if (OSLoadPartition) free(OSLoadPartition); + open_fs(newpart); + OSLoadPartition=strdup(newpart); + printf("OSLoadPartition set to: %s\n\r", OSLoadPartition); +} + +void doLoadConfig(char *file) { + printf("Custom configuration file loading is not yet implemented\n\r"); +#if 0 + if( !(params = ReadConfFile(&OSLoadPartition, file, OSLoadFilename))) { + } else { + } +#endif } void printCmdLine(int argc, CHAR *argv[]) { - int i; + int i; + + for(i = 0; i < argc; i++ ) + printf("%u: %s\n\r", i, argv[i]); +} + +void editCmdLine(char *num) +{ + int t, new=0, old=0; + + t=atoi(num); + + if (t>=nargc) { + nargc++; + t=nargc-1; + nargv[t]=malloc(256); + memset(nargv[t], 0, 256); + printf("Adding new line: %d\n\r", t); + } else { + printf("Editing line: %d\n\r", t); + old=strlen(nargv[t]); + } + printf("\n\r"); - for(i = 0; i < argc; i++ ) - printf("%u: %s\n\r", i, argv[i]); + strcpy(cmd, nargv[t]); + read_cmd("> ", 1); + new=strlen(cmd); + if (new>old) { + if (nargv[t]) free(nargv[t]); + nargv[t]=malloc(new); + } + strcpy(nargv[t], cmd); } void _start64(LONG argc, CHAR * argv[], CHAR * envp[], @@ -447,88 +630,202 @@ "\t.set pop"); } -void _start(LONG argc, CHAR *argv[], CHAR *envp[]) +Boolean doLoadKernel(char *filename) { + printf("Loading %s from %s\n\r",(params) ? params[0] : filename, OSLoadPartition); + + kernel_entry64 = LoadKernel(OSLoadPartition, filename); + 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; - Elf32_Addr kernel_entry32; - Elf64_Addr kernel_entry64; + printf("Interactive mode started. Use help for help.\n\r"); + do { + read_cmd(PROMPT, 0); + + 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(cmd_param); + else if (strncmp(cmd,"loadinitrd", 10)==0) + doLoadInitrd(cmd_param); + else if (strncmp(cmd,"loadconfig", 10)==0) + doLoadConfig(cmd_param); + 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,"cmdedit", 7)==0) + editCmdLine(cmd_param); + 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); + else if (strncmp(cmd,"clear", 5)==0) + printf(ANSI_CLEAR); + else printf("Unknown command\n\r"); + + } while (q==0); + + 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 + +#if DEBUG_CONFIG 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 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"); + + if (interactive==1) { + goInteractive(envp); } + if (doLoadKernel(OSLoadFilename)==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 -N -r tmp/arcboot/ext2load/Makefile arcboot-onion/ext2load/Makefile --- tmp/arcboot/ext2load/Makefile 2004-11-29 10:52:21.000000000 +0000 +++ arcboot-onion/ext2load/Makefile 2004-12-03 15:01:34.000000000 +0000 @@ -3,7 +3,13 @@ # 2001-04 Guido Guenther # -SUBARCH ?= IP22 +SUBARCH ?= IP32 + +# Comment out if you don't need them +USE_ISOFS=-DUSE_ISOFS + +# This does not work (yet) so don't use it +#USE_ROMFS=-DUSE_ROMSFS COMMONDIR = ../common @@ -13,22 +19,48 @@ ARCLIBDIR = ../arclib ARCLIB = $(ARCLIBDIR)/libarc.a -OBJECTS = loader.o ext2io.o conffile.o +OBJECTS = loader.o ext2io.o conffile.o ext2.o file.o stringops2.o + +ifneq ($(USE_ISOFS),) +OBJECTS+=isofs.o +endif + +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 \ - -DSUBARCH=${SUBARCH} +CFLAGS = -O2 -march=mips3 -I $(COMMONDIR) -I$(ARCLIBDIR) -I$(E2FSLIBDIR) \ + -Wall -mno-abicalls -G 0 -fno-pic -fno-builtin-printf \ + -DSUBARCH=${SUBARCH} $(USE_ISOFS) $(USE_ROMFS) -# uncomment for debugging +# 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 + +# uncomment for config file debug +#CFLAGS+=-DDEBUG_INTERACTIVE + LD = ld LDFLAGS = -N -T ld.script all: $(TARGETS) +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 $@ $(OBJECTS) $(LIBS) diff -u -N -r tmp/arcboot/ext2load/rock.h arcboot-onion/ext2load/rock.h --- tmp/arcboot/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 /* Parent link */ +#define RR_RE 64 /* Relocation directory */ +#define RR_TF 128 /* Timestamps */ diff -u -N -r tmp/arcboot/ext2load/romfs.c arcboot-onion/ext2load/romfs.c --- tmp/arcboot/ext2load/romfs.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/romfs.c 2004-12-03 13:02:46.000000000 +0000 @@ -0,0 +1,413 @@ +/* Linux ROMFS Interface for arcboot filesystem access routines + Based on same for SILO + + Copyright (C) 1998 Jakub Jelinek + 1997 Janos Farkas + 2001 Ben Collins + 2004 Kaj-Michael Lang + + 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 "file.h" +#include +#include "romfs_fs.h" + +/* Reuse and abuse */ +typedef ext2_filsys romfs_filsys; + +static ino_t inode = 0; +static int link_count = 0; + +unsigned int bs; +ext2_ino_t root, cwd; + +static int block_no; + +#define SUPROMFS (struct romfs_super_block *)(fs->io->private_data) +#define BLOCK_SIZE_BITS 9 /* 512 */ +#define BLOCK_SIZE (1<>=2; + while (size>0) { + sum += *ptr++; + size--; + } + return sum; +} + +static struct romfs_super_block *romfs_read_super(romfs_filsys fs) +{ + struct romfs_super_block *rsb; + + /* The 2048 comes from the space needed to make room for the first + * stage loader. The image has to be created with "-A 2048,/.." + */ + rsb = (struct romfs_super_block *) malloc (2048+ROMBSIZE); + if (!rsb) return NULL; + + if (io_channel_read_blk (fs->io, 0, 1, (char *)rsb)) + return NULL; + + if (strncmp((char *)rsb, "-rom1fs-", 8) || rsb->size < ROMFH_SIZE) + return NULL; + + if (romfs_checksum(rsb, min(rsb->size,512))) { + printf("ROMFS: Bad initial checksum.\n"); + return NULL; + } + + rsb->checksum = strlen(rsb->name); + if (rsb->checksum > ROMFS_MAXFN) rsb->checksum = ROMFS_MAXFN; + rsb->checksum += (ROMFH_SIZE + 1 + ROMFH_PAD); + rsb->checksum &= ROMFH_MASK; + rsb->word0 = -1; + rsb->word1 = -1; + rsb->name[0] = 0; + return rsb; +} + +static int romfs_copyfrom(romfs_filsys fs, void *dest, unsigned long offset, unsigned long count) +{ + struct romfs_super_block *rsb = SUPROMFS; + unsigned long res; + char buffer[ROMBSIZE]; + int maxsize; + + if ((offset>>ROMBSBITS)<= rsb->size+ROMBSIZE || count > rsb->size || + offset+count>rsb->size+ROMBSIZE) + return -1; + + maxsize = min(count, (ROMBSIZE - (offset & ROMBMASK))); + res = maxsize; + + if (io_channel_read_blk (fs->io, offset>>ROMBSBITS, 1, buffer)) + return -1; + + memcpy(dest, buffer + (offset & ROMBMASK), maxsize); + + while (res < count) { + offset += maxsize; + + if (io_channel_read_blk (fs->io, offset>>ROMBSBITS, 1, buffer)) + return -1; + + dest += maxsize; + maxsize = min(count-res, ROMBSIZE); + + memcpy(dest, buffer, maxsize); + + res += maxsize; + } + return 0; +} + +static int romfs_read_inode (romfs_filsys fs, ino_t inode, struct romfs_inode *ui) +{ + struct romfs_inode romfsip; + struct romfs_super_block *rsb = SUPROMFS; + + if (inode < rsb->checksum || inode >= rsb->size) + return -1; + + if (romfs_copyfrom (fs, &romfsip, inode, ROMFH_SIZE)) + return -1; + + *ui = romfsip; + return 0; +} + +static mode_t romfs_modemap[] = +{ + 0, LINUX_S_IFDIR+0555, LINUX_S_IFREG+0444, LINUX_S_IFLNK+0777, + LINUX_S_IFBLK+0600, LINUX_S_IFCHR+0600, LINUX_S_IFSOCK+0644, + LINUX_S_IFIFO+0644 +}; + +static int romfs_lookup (romfs_filsys fs, struct romfs_inode *dirui, + const char *name, int len, ino_t *result) +{ + char buffer [8192]; + struct romfs_inode ui; + ino_t dir = dirui->spec & ROMFH_MASK; + struct romfs_super_block *rsb = SUPROMFS; + + while (dir && dir < rsb->size) { + if (romfs_read_inode (fs, dir, &ui)) + return -1; + + if (romfs_copyfrom (fs, buffer, dir + ROMFH_SIZE, ROMFS_MAXFN)) + return -1; + + if (result == NULL) { + /* We aren't returning an inode, so we must be iterating */ + char symlink[1024] = {0}; + unsigned int mode = romfs_modemap[ui.next & ROMFH_TYPE]; + + /* Check for symlinks */ + if ((ui.next & ROMFH_TYPE) == ROMFH_SYM) { + int offset = dir + ROMFH_SIZE + ((strlen(buffer) + ROMFH_SIZE) & ROMFH_MASK); + if (romfs_copyfrom (fs, symlink, offset, ROMFS_MAXFN)) + return -1; + } + + if (buffer[0] == '.' && (!buffer[1] || (buffer[1] == '.' && !buffer[2]))) + mode = LINUX_S_IFDIR+0555; + + print_dir_list(0, ui.size, mode, + 0, 0, buffer, symlink[0] ? symlink : NULL); + + } else if ((!len && buffer[0] == '.' && !buffer[1]) || + (strlen(buffer) == len && !memcmp(buffer, name, len))) { + if ((ui.next & ROMFH_TYPE) == ROMFH_HRD) + dir = ui.spec; + *result = dir; + return 0; + } + dir = ui.next & ROMFH_MASK; + } + if (result == NULL) + return 0; + + return -1; +} + +static int open_namei(romfs_filsys, const char *, ino_t *, ino_t); + +static int romfs_follow_link(romfs_filsys fs, ino_t dir, ino_t inode, + struct romfs_inode *ui, ino_t *res_inode) +{ + int error; + char buffer[1024]; + + if ((ui->next & ROMFH_TYPE) != ROMFH_SYM) { + *res_inode = inode; + return 0; + } + if (link_count > 5) { + printf ("ROMFS: Symlink loop.\n"); + return -1; /* Loop */ + } + if (romfs_copyfrom (fs, buffer, inode + ROMFH_SIZE, ROMFS_MAXFN)) + return -1; + error = inode + ROMFH_SIZE + ((strlen(buffer) + ROMFH_SIZE) & ROMFH_MASK); + if (romfs_copyfrom (fs, buffer, error, ROMFS_MAXFN)) + return -1; + link_count++; + error = open_namei (fs, buffer, res_inode, dir); + link_count--; + return error; +} + +static int dir_namei(romfs_filsys fs, const char *pathname, int *namelen, + const char **name, ino_t base, ino_t *res_inode) +{ + char c; + const char *thisname; + int len; + struct romfs_inode ub; + ino_t inode; + + if ((c = *pathname) == '/') { + base = root; + pathname++; + } + + if (romfs_read_inode (fs, base, &ub)) return -1; + while (1) { + thisname = pathname; + for(len=0;(c = *(pathname++))&&(c != '/');len++); + if (!c) break; + if (romfs_lookup (fs, &ub, thisname, len, &inode)) return -1; + if (romfs_read_inode (fs, inode, &ub)) return -1; + if (romfs_follow_link (fs, base, inode, &ub, &base)) return -1; + if (base != inode && romfs_read_inode (fs, base, &ub)) return -1; + } + *name = thisname; + *namelen = len; + *res_inode = base; + return 0; +} + +static int open_namei(romfs_filsys fs, const char *pathname, + ino_t *res_inode, ino_t base) +{ + const char *basename; + int namelen; + ino_t dir, inode; + struct romfs_inode ub; + + if (dir_namei(fs, pathname, &namelen, &basename, base, &dir)) return -1; + if (!namelen) { /* special case: '/usr/' etc */ + *res_inode=dir; + return 0; + } + if (romfs_read_inode (fs, dir, &ub)) return -1; + if (romfs_lookup (fs, &ub, basename, namelen, &inode)) return -1; + if (romfs_read_inode (fs, inode, &ub)) return -1; + if (romfs_follow_link (fs, dir, inode, &ub, &inode)) return -1; + *res_inode = inode; + return 0; +} + +struct fs_ops rom_fs_ops; + +static int namei_follow_romfs (const char *filename) +{ + int ret; + + link_count = 0; + + ret = open_namei (fs, filename, &inode, root); + rom_fs_ops.inode = (ret) ? 0 : 1; + + return ret; +} + +static void romfs_close(void) +{ + free (fs->io); + free (fs); +} + +#if 0 +static int romfs_block_iterate(void) +{ + struct romfs_inode ub; + int i; + blk_t nr; + int size; + char buffer[ROMFS_MAXFN]; + + if (romfs_read_inode (fs, inode, &ub)) return 0; + if (romfs_copyfrom (fs, buffer, inode + ROMFH_SIZE, ROMFS_MAXFN)) return 0; + nr = inode + ROMFH_SIZE + ((strlen(buffer) + ROMFH_SIZE) & ROMFH_MASK); + if (nr & ROMBMASK) { + printf("ROMFS: File not aligned on a %dB boundary.\n", ROMBSIZE); + return 0; + } + size = (ub.size + ROMBMASK) / ROMBSIZE; + nr /= ROMBSIZE; + for (i = 0; i < size; i++, nr++) { + switch (dump_block_romfs (&nr, i)) { + case BLOCK_ABORT: + case BLOCK_ERROR: + return 0; + } + } + return dump_finish_romfs(); +} +#endif + +static int open_romfs (const char *device) +{ + extern io_manager arc_io_manager; + + fs = (romfs_filsys) malloc (sizeof (struct struct_ext2_filsys)); + if (!fs) + return 0; + + if (((struct struct_io_manager *)(arc_io_manager))->open (device, 0, &fs->io)) + return 0; + + io_channel_set_blksize (fs->io, ROMBSIZE); + + fs->io->private_data = romfs_read_super(fs); + if (!fs->io->private_data) + return 0; + + root = ((struct romfs_super_block *)(fs->io->private_data))->checksum; + inode = 1; + + return 1; +} + +static int ino_size_romfs (void) +{ + struct romfs_inode ri; + + if (romfs_read_inode (fs, inode, &ri)) + return 0; + + if ((ri.next & ROMFH_TYPE) != ROMFH_REG) + return 0; + + return ri.size; +} + +static unsigned file_size_romfs(void) { + return 0; +} + +static int open_file_romfs(char *filename) { + return 0; +} + +static int read_file_romfs() { + return 0; +} + +static int close_file_romfs() { + return 0; +} + +static int seek_file_romfs(int position) { + return 0; +} + +static int ls_romfs (void) +{ + struct romfs_inode ub; + link_count = 0; + + if (romfs_read_inode (fs, inode, &ub)) return -1; + + if (romfs_lookup (fs, &ub, NULL, 0, NULL)) + return -1; + + return 0; +} + +static void print_error_romfs (int error_val) { + printf("Unknown ROMFS error"); +} + +struct fs_ops rom_fs_ops = { + .name "Linux ROMFS", + .open = open_romfs, + .ls = ls_romfs, + .file_size = file_size_romfs, + .open_file = open_file_romfs, + .close_file = close_file_romfs, + .read_file = read_file_romfs, + .seek_file = seek_file_romfs, + .print_error = print_error_romfs, + .close = romfs_close, + .inode = 0, +}; diff -u -N -r tmp/arcboot/ext2load/romfs_fs.h arcboot-onion/ext2load/romfs_fs.h --- tmp/arcboot/ext2load/romfs_fs.h 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/romfs_fs.h 2004-11-23 21:38:30.000000000 +0000 @@ -0,0 +1,61 @@ +#ifndef __LINUX_ROMFS_FS_H +#define __LINUX_ROMFS_FS_H + +/* The basic structures of the romfs filesystem */ + +#define ROMBSIZE BLOCK_SIZE +#define ROMBSBITS BLOCK_SIZE_BITS +#define ROMBMASK (ROMBSIZE-1) +#define ROMFS_MAGIC 0x7275 + +#define ROMFS_MAXFN 128 + +#define __mkw(h,l) (((h)&0x00ff)<< 8|((l)&0x00ff)) +#define __mkl(h,l) (((h)&0xffff)<<16|((l)&0xffff)) +#define __mk4(a,b,c,d) htonl(__mkl(__mkw(a,b),__mkw(c,d))) +#define ROMSB_WORD0 __mk4('-','r','o','m') +#define ROMSB_WORD1 __mk4('1','f','s','-') + +/* On-disk "super block" */ + +struct romfs_super_block { + __u32 word0; + __u32 word1; + __u32 size; + __u32 checksum; + char name[0]; /* volume name */ +}; + +/* On disk inode */ + +struct romfs_inode { + __u32 next; /* low 4 bits see ROMFH_ */ + __u32 spec; + __u32 size; + __u32 checksum; + char name[0]; +}; + +#define ROMFH_TYPE 7 +#define ROMFH_HRD 0 +#define ROMFH_DIR 1 +#define ROMFH_REG 2 +#define ROMFH_SYM 3 +#define ROMFH_BLK 4 +#define ROMFH_CHR 5 +#define ROMFH_SCK 6 +#define ROMFH_FIF 7 +#define ROMFH_EXEC 8 + +/* Alignment */ + +#define ROMFH_SIZE 16 +#define ROMFH_PAD (ROMFH_SIZE-1) +#define ROMFH_MASK (~ROMFH_PAD) + +#ifdef __KERNEL__ + +/* Not much now */ + +#endif /* __KERNEL__ */ +#endif diff -u -N -r tmp/arcboot/ext2load/stringops2.c arcboot-onion/ext2load/stringops2.c --- tmp/arcboot/ext2load/stringops2.c 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/ext2load/stringops2.c 2004-11-23 18:05:23.000000000 +0000 @@ -0,0 +1,98 @@ +/* Slooow, but small string operations, so that we don't have + to link libc5/glibc in. + Originally from linux/lib/string.c, which is + Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include + +#if 0 +char * strncpy(char *dest, const char *src, size_t count) +{ + char *tmp = dest; + + while (count-- && (*dest++ = *src++) != '\0') + /* nothing */; + + return tmp; +} +#endif + +char *strcat(char *dest, const char *src) +{ + char *tmp = dest; + while (*dest) dest++; + while ((*dest++ = *src++) != '\0'); + return tmp; +} + +char *strncat(char *dest, const char *src, size_t n) +{ + char *tmp = dest; + while (*dest) dest++; + while (n && (*dest++ = *src++) != '\0') n--; + if (!n) *dest = 0; + return tmp; +} + +char * strrchr(const char * s, int c) +{ + const char *p = s + strlen(s); + do { + if (*p == (char)c) + return (char *)p; + } while (--p >= s); + return 0; +} + +#if 0 +char *strdup(const char *str) +{ + extern void *malloc(int); + char *ret; + ret = malloc(strlen(str) + 1); + strcpy(ret, str); + return ret; +} +#endif + +__inline__ int tolower(int c) +{ + if (c >= 'A' && c <= 'Z') return c - 'A' + 'a'; + return c; +} + +int strcasecmp(const char *cs,const char *ct) +{ + register signed char __res; + while (1) + if ((__res = tolower(*cs) - tolower(*ct++)) != 0 || !*cs++) + break; + return __res; +} + +int strncasecmp(const char *cs,const char *ct,size_t n) +{ + register signed char __res = 0; + while (n--) + if ((__res = tolower(*cs) - tolower(*ct++)) != 0 || !*cs++) + break; + return __res; +} + +char * strstr(const char * s1,const char * s2) +{ + int l1, l2; + + l2 = strlen(s2); + if (!l2) + return (char *) s1; + l1 = strlen(s1); + while (l1 >= l2) { + l1--; + if (!memcmp(s1,s2,l2)) + return (char *) s1; + s1++; + } + return 0; +} diff -u -N -r tmp/arcboot/Makefile arcboot-onion/Makefile --- tmp/arcboot/Makefile 2004-11-29 10:52:21.000000000 +0000 +++ arcboot-onion/Makefile 2004-11-21 17:00:16.000000000 +0000 @@ -5,7 +5,7 @@ # # default subarch -SUBARCH ?= IP22 +SUBARCH ?= IP32 # these contain subarch independent files SUBARCH_INDEP_DIRS= \ diff -u -N -r tmp/arcboot/README arcboot-onion/README --- tmp/arcboot/README 2004-11-29 10:39:38.000000000 +0000 +++ arcboot-onion/README 2003-04-26 18:33:50.000000000 +0000 @@ -42,7 +42,7 @@ Acknowledgements: - arcboot is based on the arc-bootloader for SGI visual workstations written - by Ralf Bächle + by Ralf Bächle - the e2fslib dir is basically a stripped down verion of e2fsprogs 1.25 as found on http://sourceforge.net/projects/e2fsprogs and written by Theodore Tso compiled with -nopic. diff -u -N -r tmp/arcboot/tip22/kernel/parse_rd_cmd_line-2002-05-09.diff arcboot-onion/tip22/kernel/parse_rd_cmd_line-2002-05-09.diff --- tmp/arcboot/tip22/kernel/parse_rd_cmd_line-2002-05-09.diff 2004-11-29 10:39:38.000000000 +0000 +++ arcboot-onion/tip22/kernel/parse_rd_cmd_line-2002-05-09.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -Index: arch/mips/kernel/setup.c -=================================================================== -RCS file: /cvs/linux/arch/mips/kernel/setup.c,v -retrieving revision 1.96.2.12 -diff -u -u -r1.96.2.12 setup.c ---- arch/mips/kernel/setup.c 2002/02/15 21:05:48 1.96.2.12 -+++ arch/mips/kernel/setup.c 2002/05/09 17:17:59 -@@ -650,6 +650,38 @@ - } - } - -+static inline void parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_end) -+{ -+ char c = ' ', *to = command_line, *from = saved_command_line; -+ int len = 0; -+ unsigned long rd_size = 0; -+ -+ for (;;) { -+ /* -+ * "rd_start=0xNNNNNNNN" defines the memory address of an initrd -+ * "rd_size=0xNN" it's size -+ */ -+ if (c == ' ' && !memcmp(from, "rd_start=", 9)) { -+ if (to != command_line) -+ to--; -+ (*rd_start) = memparse(from + 9, &from); -+ } -+ if (c == ' ' && !memcmp(from, "rd_size=", 8)) { -+ if (to != command_line) -+ to--; -+ rd_size = memparse(from + 8, &from); -+ } -+ c = *(from++); -+ if (!c) -+ break; -+ if (CL_SIZE <= ++len) -+ break; -+ *(to++) = c; -+ } -+ *to = '\0'; -+ (*rd_end) = (*rd_start) + rd_size; -+} -+ - void __init setup_arch(char **cmdline_p) - { - void atlas_setup(void); -@@ -674,10 +706,7 @@ - - unsigned long bootmap_size; - unsigned long start_pfn, max_pfn, max_low_pfn, first_usable_pfn; --#ifdef CONFIG_BLK_DEV_INITRD -- unsigned long tmp; -- unsigned long* initrd_header; --#endif -+ unsigned long end = &_end; - - int i; - -@@ -828,22 +857,18 @@ - #define MAXMEM_PFN PFN_DOWN(MAXMEM) - - #ifdef CONFIG_BLK_DEV_INITRD -- tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; -- if (tmp < (unsigned long)&_end) -- tmp += PAGE_SIZE; -- initrd_header = (unsigned long *)tmp; -- if (initrd_header[0] == 0x494E5244) { -- initrd_start = (unsigned long)&initrd_header[2]; -- initrd_end = initrd_start + initrd_header[1]; -+ parse_rd_cmdline(&initrd_start, &initrd_end); -+ if(initrd_start && initrd_end) -+ end = initrd_end; -+ else { -+ initrd_start = initrd_end = 0; - } -- start_pfn = PFN_UP(__pa((&_end)+(initrd_end - initrd_start) + PAGE_SIZE)); --#else -+#endif /* CONFIG_BLK_DEV_INITRD */ - /* - * Partially used pages are not usable - thus - * we are rounding upwards. - */ -- start_pfn = PFN_UP(__pa(&_end)); --#endif /* CONFIG_BLK_DEV_INITRD */ -+ start_pfn = PFN_UP(__pa(end)); - - /* Find the highest page frame number we have available. */ - max_pfn = 0; diff -u -N -r tmp/arcboot/tip22/ld.kernel.script arcboot-onion/tip22/ld.kernel.script --- tmp/arcboot/tip22/ld.kernel.script 2004-11-29 10:39:38.000000000 +0000 +++ arcboot-onion/tip22/ld.kernel.script 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -OUTPUT_FORMAT("ecoff-bigmips") -OUTPUT_ARCH(mips) -SECTIONS -{ - .data : - { - __kernel_start = .; - *(.data) - __kernel_end = .; - } -} diff -u -N -r tmp/arcboot/tip22/ld.ramdisk.script arcboot-onion/tip22/ld.ramdisk.script --- tmp/arcboot/tip22/ld.ramdisk.script 2004-11-29 10:39:38.000000000 +0000 +++ arcboot-onion/tip22/ld.ramdisk.script 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -OUTPUT_FORMAT("ecoff-bigmips") -OUTPUT_ARCH(mips) -SECTIONS -{ - .data : - { - __rd_start = .; - *(.data) - __rd_end = .; - } -} diff -u -N -r tmp/arcboot/tip22/ld.script arcboot-onion/tip22/ld.script --- tmp/arcboot/tip22/ld.script 1970-01-01 00:00:00.000000000 +0000 +++ arcboot-onion/tip22/ld.script 2004-11-21 14:11:54.000000000 +0000 @@ -0,0 +1,50 @@ +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + /* XXX: place the loader after the kernel */ + . = 0x80802000; + + /* merge everything into one segment */ + .text : + { _ftext = . ; + *(.text) + *(.rodata*) + _etext = .; + PROVIDE (etext = .); + } =0 + + /* kernel and initrd will go in here */ + .data : + { + _fdata = .; + *(.data) + CONSTRUCTORS + PROVIDE (edata = .); + } + + .bss : + { + *(.bss) + *(COMMON) + . = ALIGN(4); + _end = . ; + PROVIDE (end = .); + } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + *(.stab) + *(.stabstr) + *(.pdr) + *(.note) + *(.reginfo) + *(.debug*) + *(.mdebug*) + *(.comment*) + } +} diff -u -N -r tmp/arcboot/tip22/tftpload.h arcboot-onion/tip22/tftpload.h --- tmp/arcboot/tip22/tftpload.h 2004-11-29 10:39:38.000000000 +0000 +++ arcboot-onion/tip22/tftpload.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -/* - * Copyright 2001 Guido Guenther - */ - -#ifndef _TFTPLOAD_H -#define _TFTPLOAD_H - -#include - -typedef enum { False = 0, True } Boolean; - -void Fatal(const CHAR * message, ...); - -#endif /* _TFTPLAOD_H */