diff -x stage2_size.h -x start -x grub-image -x grub-install -x grub-md5-crypt -x mbchk -x stamp-h -x stamp-h1 -x config.* -x building* -x *_stage1_5 -x *.exec -x *.[ao] -x .deps -x Makefile -Nur grub-0.91-original/stage2/disk_io.c grub-0.91/stage2/disk_io.c
--- grub-0.91-original/stage2/disk_io.c	Sun Feb 24 12:03:36 2002
+++ grub-0.91/stage2/disk_io.c	Sun Feb 24 12:03:24 2002
@@ -68,6 +68,9 @@
 # ifdef FSYS_XFS
   {"xfs", xfs_mount, xfs_read, xfs_dir, 0, 0},
 # endif
+# ifdef FSYS_ROMFS
+  {"romfs", romfs_mount, romfs_read, romfs_dir, 0, 0},
+# endif
   /* XX FFS should come last as it's superblock is commonly crossing tracks
      on floppies from track 1 to 2, while others only use 1.  */
 # ifdef FSYS_FFS
diff -x stage2_size.h -x start -x grub-image -x grub-install -x grub-md5-crypt -x mbchk -x stamp-h -x stamp-h1 -x config.* -x building* -x *_stage1_5 -x *.exec -x *.[ao] -x .deps -x Makefile -Nur grub-0.91-original/stage2/filesys.h grub-0.91/stage2/filesys.h
--- grub-0.91-original/stage2/filesys.h	Sun Feb 24 12:03:32 2002
+++ grub-0.91/stage2/filesys.h	Sun Feb 24 12:03:22 2002
@@ -105,11 +105,20 @@
 #define FSYS_TFTP_NUM 0
 #endif
 
+#ifdef FSYS_ROMFS
+#define FSYS_ROMFS_NUM 1
+int romfs_mount (void);
+int romfs_read (char *buf, int len);
+int romfs_dir (char *dirname);
+#else
+#define FSYS_ROMFS_NUM 0
+#endif
+
 #ifndef NUM_FSYS
 #define NUM_FSYS	\
   (FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM	\
    + FSYS_REISERFS_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM + FSYS_XFS_NUM	\
-   + FSYS_TFTP_NUM)
+   + FSYS_TFTP_NUM + FSYS_ROMFS_NUM)
 #endif
 
 /* defines for the block filesystem info area */
diff -x stage2_size.h -x start -x grub-image -x grub-install -x grub-md5-crypt -x mbchk -x stamp-h -x stamp-h1 -x config.* -x building* -x *_stage1_5 -x *.exec -x *.[ao] -x .deps -x Makefile -Nur grub-0.91-original/stage2/fsys_romfs.c grub-0.91/stage2/fsys_romfs.c
--- grub-0.91-original/stage2/fsys_romfs.c	Thu Jan  1 02:00:00 1970
+++ grub-0.91/stage2/fsys_romfs.c	Thu Feb 28 13:31:47 2002
@@ -0,0 +1,264 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999, 2001  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef FSYS_ROMFS
+
+#include "shared.h"
+#include "filesys.h"
+
+/* include/asm-i386/types.h */
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#include "romfs_fs.h"
+
+/* linux/limits.h */
+#define NAME_MAX         255	/* # chars in a file name */
+
+/* linux/posix_type.h */
+typedef long linux_off_t;
+
+/* "local" defs, not stolen from a header file */
+#define MAX_LINK_COUNT 5
+
+/* made up, these are pointers into FSYS_BUF */
+/* read once, always stays there: */
+#define SUPERBLOCK \
+     ((struct romfs_super_block *)(FSYS_BUF))
+#define INODE \
+     ((struct romfs_inode *)((int)SUPERBLOCK + sizeof(struct romfs_super_block)))
+
+int rootdir_offset;
+
+static int find_string_len(unsigned char *buf, int offset) {
+  int i=0;
+  /* all strings are nul-padded to even 16 bytes */
+
+  do {
+    devread ( (offset+i*16) / SECTOR_SIZE,
+	      (offset+i*16) % SECTOR_SIZE,
+	      16, buf+(i*16));
+    printf("reading name, i=%d, buf=%s\n", i, buf);
+    i++;
+  } while (buf[i*16-1] != '\0');
+  return i*16;
+}
+
+/* return disk offset of file data. */
+static int load_inode(int offset) {
+  //printy("load_inode at %d\n", offset);
+
+  disk_read_func = disk_read_hook;
+  
+  devread (offset / SECTOR_SIZE,
+	   offset % SECTOR_SIZE,
+	   sizeof(*INODE)+16, (unsigned char*)INODE);
+
+  INODE->next=ntohl(INODE->next);
+  INODE->spec=ntohl(INODE->spec);
+  INODE->size=ntohl(INODE->size);
+  INODE->checksum=ntohl(INODE->checksum);
+
+  disk_read_func = NULL;
+  {
+    int namelen;
+    namelen = find_string_len(((unsigned char*)INODE)+sizeof(*INODE),
+			      offset+16);
+    //printy("name=%s\n", INODE->name);
+    return offset+16+namelen;
+  }
+}
+
+/* check filesystem types and read superblock into memory buffer */
+int
+romfs_mount (void)
+{
+  int retval = 1;
+
+  errnum=0;
+  if ((((current_drive & 0x80) || (current_slice != 0))
+       && (current_slice != PC_SLICE_TYPE_EXT2FS)
+       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS))
+       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER)))) {
+    retval = 0;
+  } else if (!devread (0, 0, sizeof (struct romfs_super_block),
+		       (char *) SUPERBLOCK)) {
+    retval = 0;
+  } else if (SUPERBLOCK->word0 != ROMSB_WORD0
+	     || SUPERBLOCK->word1 != ROMSB_WORD1) {
+    retval = 0;
+  }
+  //TODO checksum?
+
+  {
+    int vollen = find_string_len(&SUPERBLOCK->name, 16);
+    rootdir_offset = 16+vollen;
+    printf("rootdir_offset=%d\n", rootdir_offset);
+  }
+  
+  return retval;
+}
+
+static int disk_offset;
+static int is_eof;
+
+int
+romfs_read (char *buf, int len)
+{
+  int ret = 0;
+  
+  if (is_eof)
+    return 0;
+
+  disk_read_func = disk_read_hook;
+
+  devread (disk_offset / SECTOR_SIZE,
+	   disk_offset % SECTOR_SIZE,
+	   len, buf);
+  
+  disk_read_func = NULL;
+  
+  disk_offset += len;
+  filepos += len;
+  ret = len;
+  
+  if (errnum)
+    ret = 0;
+  
+  if (filepos==filemax)
+    is_eof=1;
+  return ret;
+}
+
+int
+romfs_dir (char *dirname)
+{
+  int link_count = 0;
+  char *rest;
+  char ch;			/* temp char holder */
+  int str_chk;			/* used to hold the results of a string compare */
+
+  disk_offset = rootdir_offset;
+
+  /* loop invariants:
+     current_ino = inode to lookup
+     dirname = pointer to filename component we are cur looking up within
+     the directory known pointed to by current_ino (if any)
+  */
+  
+  while (1) {
+    int type;
+
+    /* look up an inode */
+
+    load_inode(disk_offset);
+
+    type = INODE->next&ROMFH_TYPE;
+
+    if (type==ROMFH_HRD) {
+      disk_offset = INODE->spec;
+      continue;
+    } else if (type==ROMFH_SYM) {
+      errnum = ERR_SYMLINK_LOOP;
+      return 0;
+    } else {
+      //printy("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__);
+      /* if end of filename, INODE points to the file's inode */
+      if (!*dirname || isspace (*dirname)) {
+	//printy("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__);
+	if (type!=ROMFH_REG) {
+	  //printy("type=%d\n", type);
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+	
+	filemax = INODE->size;
+	return 1;
+      } else {
+	//printy("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__);
+	/* else we have to traverse a directory */
+	
+	/* skip over slashes */
+	while (*dirname == '/')
+	  dirname++;
+	
+	/* if this isn't a directory of sufficient size to hold our file, abort */
+	if (type!=ROMFH_DIR) {
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+	
+	/* skip to next slash or end of filename (space) */
+	for (rest = dirname;
+	     (ch = *rest) && !isspace (ch) && ch != '/';
+	     rest++)
+	  ;
+	
+	/* look through this directory and find the next filename
+	   component */
+	/* invariant: rest points to slash after the next filename
+	   component */
+	*rest = 0;
+	
+	//printy("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__);
+	{
+	  int dir_offset=INODE->spec;	/* disk offset for this dir search */
+	  
+	  do {
+	    if (!dir_offset) {
+	      /* not found */
+	      if (print_possibilities >= 0) {
+		errnum = ERR_FILE_NOT_FOUND;
+		*rest = ch;
+	      }
+	      return (print_possibilities < 0);
+	    }
+
+	    //printy("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__);
+	    load_inode(dir_offset);
+	    str_chk = strcmp(dirname, INODE->name);
+	    //printy("strcmp(%s, %s)=%d\n", dirname, INODE->name, str_chk);
+	    
+#ifndef STAGE1_5
+	    if (print_possibilities && ch != '/'
+		&& (!*dirname || str_chk <= 0)) {
+	      if (print_possibilities > 0)
+		print_possibilities = -print_possibilities;
+	      print_a_completion (INODE->name);
+	    }
+#endif
+	    
+	    if (str_chk)
+	      dir_offset=INODE->next & ROMFH_SIZE_MASK;
+	  } while (str_chk || (print_possibilities && ch != '/'));
+	  
+	  disk_offset = dir_offset;
+	  *(dirname = rest) = ch;
+	}
+      }
+    }
+  }
+  /* never get here */
+}
+
+#endif /* FSYS_ROMFS */
diff -x stage2_size.h -x start -x grub-image -x grub-install -x grub-md5-crypt -x mbchk -x stamp-h -x stamp-h1 -x config.* -x building* -x *_stage1_5 -x *.exec -x *.[ao] -x .deps -x Makefile -Nur grub-0.91-original/stage2/romfs_fs.h grub-0.91/stage2/romfs_fs.h
--- grub-0.91-original/stage2/romfs_fs.h	Thu Jan  1 02:00:00 1970
+++ grub-0.91/stage2/romfs_fs.h	Thu Feb 28 11:16:43 2002
@@ -0,0 +1,64 @@
+#ifndef __LINUX_ROMFS_FS_H
+#define __LINUX_ROMFS_FS_H
+
+#include <netinet/in.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_SIZE_MASK (~15)
+#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
