diff -ruNa grub2/commands/i386/pc/romfst.c grub2_romfs/commands/i386/pc/romfst.c
--- grub2/commands/i386/pc/romfst.c	1970-01-01 08:00:00.000000000 +0800
+++ grub2_romfs/commands/i386/pc/romfst.c	2008-08-17 09:14:15.000000000 +0800
@@ -0,0 +1,111 @@
+/* romfst.c -- init a romfs from a disk file.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/arg.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/gzio.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/machine/romfs.h>
+
+
+static grub_err_t
+grub_cmd_romfst (struct grub_arg_list *state __attribute__ ((unused)), int argc,
+	       char **args)
+{
+  grub_file_t file;
+  char chHead[8];
+
+  DBG_MSG ("\n\n ------- romfst get in. ----------\n");
+
+  /* check for existence of this file */
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  file = grub_gzfile_open (args[0], 1);
+  if (! file)
+      return 0;
+  
+  /* check for "-romfs-" */
+  if (grub_file_read (file, chHead, 8) != 8)
+  {
+      grub_file_close ( file );
+      return grub_error(GRUB_ERR_FILE_READ_ERROR, "read file header failed");
+  }
+
+  DBG_MSG ("\t seek to begin.\n");
+  grub_file_seek (file, 0);
+  
+  if(grub_memcmp(chHead, "-rom1fs-", 8) !=0)
+  {
+      grub_file_close( file );
+      return grub_error(GRUB_ERR_UNKNOWN_FS, "not a valid romfs");
+  }
+
+  DBG_MSG ("\t file header verified.\n");
+  
+  /* reset the basic romfs information */
+  if (romdisk_addr)
+    grub_free (romdisk_addr);
+
+  romdisk_size = 0;
+
+  DBG_MSG ("\t malloc the romdisk_addr.\n");
+
+  /* prepare the memory */
+  romdisk_addr = grub_malloc (grub_file_size(file));
+  if (!romdisk_addr)
+  {
+      grub_file_close(file);
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "romfs base memory alloc failed");
+  }
+
+  romdisk_size = grub_file_size(file);
+
+  /* read this all */
+  grub_file_read (file, romdisk_addr, romdisk_size);
+  grub_file_close(file);
+
+  DBG_MSG ("\t load this file whole.\n");
+
+  /* O.K. reinit this disk */
+  re_init_romdisk ();
+
+  DBG_MSG ("\t romfs re-inited..\n");
+
+  return grub_errno;
+}
+
+
+
+GRUB_MOD_INIT(romfst)
+{
+  (void)mod;			/* To stop warning. */
+  grub_register_command ("romfst", grub_cmd_romfst, GRUB_COMMAND_FLAG_BOTH,
+			 "romfst FILE", "Init romfs from a file", 0);
+}
+
+GRUB_MOD_FINI(romfst)
+{
+  grub_unregister_command ("romfst");
+}
diff -ruNa grub2/conf/i386-pc.rmk grub2_romfs/conf/i386-pc.rmk
--- grub2/conf/i386-pc.rmk	2008-08-17 09:17:30.000000000 +0800
+++ grub2_romfs/conf/i386-pc.rmk	2008-08-17 09:05:52.000000000 +0800
@@ -164,7 +164,7 @@
 	videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod	\
 	ata.mod vga.mod memdisk.mod jpeg.mod png.mod pci.mod lspci.mod \
 	aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
-	datehook.mod
+	datehook.mod romfst.mod romfs.mod
 
 # For biosdisk.mod.
 biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
@@ -356,4 +356,14 @@
 datehook_mod_CFLAGS = $(COMMON_CFLAGS)
 datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For romfs.mod.
+romfs_mod_SOURCES = fs/i386/pc/romfs.c
+romfs_mod_CFLAGS = $(COMMON_CFLAGS)
+romfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For romfst.mod.
+romfst_mod_SOURCES = commands/i386/pc/romfst.c
+romfst_mod_CFLAGS = $(COMMON_CFLAGS)
+romfst_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 include $(srcdir)/conf/common.mk
diff -ruNa grub2/fs/i386/pc/romfs.c grub2_romfs/fs/i386/pc/romfs.c
--- grub2/fs/i386/pc/romfs.c	1970-01-01 08:00:00.000000000 +0800
+++ grub2_romfs/fs/i386/pc/romfs.c	2008-08-17 09:13:27.000000000 +0800
@@ -0,0 +1,653 @@
+/* romfs.c - rom filesystem and romdisk layer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/romfs.h>
+
+
+struct grub_romfs_data
+{
+	grub_disk_t disk;
+	
+	char *plabel;						/* volume name */
+
+	grub_uint32_t rootdir_offset;		/* root offset */
+	
+	grub_uint32_t dir_offset;           /* dir offset */
+
+	grub_uint32_t filesize;             /* file size */
+
+	grub_uint32_t file_type;			/* object type: dir, file, ... */
+
+};
+
+
+/* internal buffer for block using */
+char blk_buf[GRUB_DISK_SECTOR_SIZE] = {0};
+
+/* file data offset to load */
+grub_uint32_t file_offset;			/* file data offset */
+
+/* romfs memory data start address */
+char *romdisk_addr = 0;
+grub_off_t romdisk_size = 0;
+
+
+/* made up, these are pointers into blk_buf, 512 bytes is enough for internal use */
+/* read once, always stays there: */
+#define SUPERBLOCK \
+	((struct romfs_super_block *)(blk_buf))
+#define INODE \
+	((struct romfs_inode *)((int)SUPERBLOCK + sizeof(struct romfs_super_block)))
+
+
+#ifndef GRUB_UTIL
+static grub_dl_t my_mod;
+#endif
+
+static inline /*__const__*/ grub_uint32_t
+le32 (grub_uint32_t x)
+{
+#if 0
+  /* 386 doesn't have bswap.  */
+  __asm__("bswap %0" : "=r" (x) : "0" (x));
+#else
+  /* This is slower but this works on all x86 architectures.  */
+  __asm__("xchgb %b0, %h0" \
+          "\n\troll $16, %0" \
+          "\n\txchgb %b0, %h0" \
+          : "=q" (x) : "0" (x));
+#endif
+  return x;
+}
+
+static int
+//romfs_devread (int sector, int byte_offset, int byte_len, unsigned char *buf)
+romfs_devread (grub_uint32_t offset, int byte_len, unsigned char *buf)
+{ 
+	/* range check */
+	if ( offset + byte_len > romdisk_size )
+	{
+		grub_error (GRUB_ERR_OUT_OF_RANGE, "romfs_devread out of range");
+		return 0;
+	}
+
+	grub_memmove(buf, romdisk_addr + offset, byte_len);
+
+	return 1;
+}
+
+
+static int 
+find_string_len(unsigned char *buf, grub_uint32_t offset) 
+{
+  int i=0;
+
+  int ix;
+  /* all strings are nul-padded to even 16 bytes */
+  do 
+  {
+	  ix = i << 4;
+// 	  romfs_devread ( (offset+i*16) / GRUB_DISK_SECTOR_SIZE,
+// 		  (offset+i*16) % GRUB_DISK_SECTOR_SIZE,
+// 		  16, buf+(i*16));
+	  
+	  romfs_devread (offset + ix, 16, buf + ix);
+
+    /* grub_dprintf("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) 
+{
+  int namelen;
+  DBG_MSG (" load_inode at %d.\n", offset);
+     
+  romfs_devread (offset, sizeof(*INODE)+16, (unsigned char*)INODE);
+
+  INODE->next = le32(INODE->next);  /* grub_cpu_to_le32 */
+  INODE->spec = le32(INODE->spec);
+  INODE->size = le32(INODE->size);
+  INODE->checksum = le32(INODE->checksum);
+
+  namelen = find_string_len(((unsigned char*)INODE)+sizeof(*INODE),
+			                offset+16);
+
+  /* grub_printf(" name=%s\n", INODE->name); */
+
+  return offset+16+namelen;
+}
+
+
+static int
+grub_romdisk_iterate (int (*hook) (const char *name))
+{
+	DBG_MSG ("dbg: grub_romdisk_iterate().++\n");
+
+	if (hook ("rd"))
+		return 1;
+	return 0;
+}
+
+static grub_err_t
+grub_romdisk_open (const char *name, grub_disk_t disk)
+{
+	DBG_MSG ("dbg: grub_romdisk_open(%s).++\n", name);
+
+	if (grub_strcmp (name, "rd"))
+	{
+		DBG_MSG ("\t %s. not a rd disk.\n", name);
+		return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a romdisk");
+	}
+
+	DBG_MSG ("\t %s. is a rd disk.\n", name);
+
+	disk->total_sectors = 0; /* romdisk_size / GRUB_DISK_SECTOR_SIZE; */
+	disk->id = (unsigned long) "rd";
+	disk->has_partitions = 0;
+	disk->data = 0;
+
+	return GRUB_ERR_NONE;
+}
+
+
+static void
+grub_romdisk_close (grub_disk_t disk __attribute((unused)))
+{
+	DBG_MSG ("dbg: grub_romdisk_close().++\n");
+}
+
+static grub_err_t
+grub_romdisk_read (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector,
+				   grub_size_t size, char *buf)
+{
+	DBG_MSG ("dbg: grub_romdisk_read().++\n");
+
+	grub_memcpy (buf, romdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), size << GRUB_DISK_SECTOR_BITS);
+	return 0;
+}
+
+static grub_err_t
+grub_romdisk_write (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector,
+					grub_size_t size, const char *buf)
+{
+	DBG_MSG ("dbg: grub_romdisk_write().++\n");
+
+	/* romdisk is read-only disk. */
+	grub_error (GRUB_ERR_WRITE_ERROR, "romdisk is read only");
+	return 0;
+}
+
+static struct grub_disk_dev grub_romdisk_dev =
+{
+	.name = "rd",
+	.id = GRUB_DISK_DEVICE_ROMDISK_ID,
+	.iterate = grub_romdisk_iterate,
+	.open = grub_romdisk_open,
+	.close = grub_romdisk_close,
+	.read = grub_romdisk_read,
+	.write = grub_romdisk_write,
+	.next = 0
+};
+
+static struct grub_romfs_data *
+grub_romfs_mount (grub_disk_t disk)
+{
+  DBG_MSG (" grub_romfs_mount()++. \n");
+
+  int vollen = 0;
+  struct grub_romfs_data *data;
+
+  /* read the super block */
+  if (!romfs_devread (0, 
+						sizeof (struct romfs_super_block),
+						(unsigned char *) SUPERBLOCK))
+  {
+    grub_print_error();
+    DBG_MSG (" \t grub_disk_read() failed.\n");
+    goto fail;  
+  }
+
+  /* check the "-romfs-" header */
+  if (SUPERBLOCK->word0 != 0x6d6f722d
+      || SUPERBLOCK->word1 != 0x2d736631 )
+  {
+    DBG_MSG (" \t check header failed.\n");
+    goto fail;
+  }
+
+  grub_errno = GRUB_ERR_NONE;
+  data = (struct grub_romfs_data *) grub_malloc (sizeof (*data));
+  if (!data)
+  {
+	  DBG_MSG (" \t malloc romfs data failed.\n");
+	  goto fail;
+  }
+  grub_memset (data, 0x0, sizeof (struct grub_romfs_data));
+
+  data->disk = disk;
+  data->plabel = (char *)&SUPERBLOCK->name;
+
+  vollen = find_string_len((unsigned char *)&SUPERBLOCK->name, 16);
+  data ->rootdir_offset = 16 + vollen;
+  DBG_MSG (" \t rootdir_offset = %d.\n", data ->rootdir_offset);
+
+  return data;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FS, "not a romfs filesystem");
+  return 0;
+}
+
+
+int grub_stricmp(const char *string1, const char *string2)
+{
+	while(grub_tolower(*string1) == grub_tolower(*string2))
+	{
+		if(*string1 == 0)
+			return 0;
+
+		string1++;
+		string2++;
+	}
+
+	return (int)grub_tolower(*string1) - (int)grub_tolower(*string2);
+}
+
+
+static char *
+grub_find_dir (char *path, struct grub_romfs_data *data,
+		  int (*hook) (const char *filename, int dir))
+{
+	char *rest;
+	char ch;
+	int dir_nofound;
+	int call_hook = 0;
+	int dir_offset = 0;
+	unsigned int    pathlen;
+
+	DBG_MSG (" grub_find_dir()++.\n");
+
+	if ( hook )
+		call_hook = 1;
+
+	/* skip over slashes */
+	while (*path == '/')
+		path++;
+
+	for (pathlen = 0 ;
+		path[pathlen]
+	&& !grub_isspace(path[pathlen]) && path[pathlen] != '/' ;
+	pathlen++)
+		;
+
+	/* if this isn't a directory of sufficient size to hold our file, abort */
+	if (data->file_type != ROMFH_DIR) 
+	{
+		DBG_MSG ("\t grub_errno = GRUB_ERR_BAD_FILE_TYPE;\n");
+		grub_errno = GRUB_ERR_BAD_FILE_TYPE;
+		return 0;
+	}
+
+	/* skip to next slash or end of filename (space) */
+	for (rest = path;
+		(ch = *rest) && !grub_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;
+
+	dir_offset = INODE->spec;	/* disk offset for this dir search */
+
+	DBG_MSG ("\t dir_offset=%d.\n", dir_offset);
+
+	do {
+		if (!dir_offset) 
+		{
+			/* not found */
+			if ( call_hook >=0 ) 
+			{
+				grub_errno = GRUB_ERR_FILE_NOT_FOUND;
+				*rest = ch;
+			}
+
+			return 0;
+		}
+
+		load_inode(dir_offset);
+
+		DBG_MSG ("\t %s<->%s.\n", path, INODE->name);
+		dir_nofound = grub_stricmp(path, INODE->name);
+
+		if (grub_strlen(INODE->name) >= pathlen && call_hook
+			&& !grub_memcmp(INODE->name, path, pathlen) && ch != '/')
+		{
+			if (call_hook > 0)
+				call_hook = -call_hook;
+
+			/* skip the `.' and `..' */
+			if (!(grub_strcmp(INODE->name, ".") == 0 || 
+				grub_strcmp(INODE->name, "..") == 0))
+				hook (INODE->name, ((INODE->next & ROMFH_TYPE) == ROMFH_DIR) );
+
+			dir_nofound = -1;
+		}
+
+		if (dir_nofound)
+		{
+			dir_offset = INODE->next & ROMFH_SIZE_MASK;
+		}
+	} while (dir_nofound || (call_hook && ch != '/'));
+
+	data->dir_offset = dir_offset;
+
+	*(path = rest) = ch;
+
+	return path;
+}
+
+
+static grub_err_t
+grub_romfs_dir (grub_device_t device, const char *path,
+	       int (*hook) (const char *filename, int dir))
+{
+  char *p, *dirname = 0;
+  int len = 0;
+  struct grub_romfs_data *data;
+
+  DBG_MSG (" grub_romfs_dir(%s, 0x%x)++. \n", path, hook);
+
+  if (device->disk->id != (unsigned long) "rd")
+	  return grub_error (GRUB_ERR_BAD_FS, "romfs is only for romdisk");
+
+  data = grub_romfs_mount (device->disk);
+  if (!data)
+  {
+	  grub_print_error();
+	  DBG_MSG (" mount disk failed.\n");
+      goto clean;
+  }
+
+  /* Make sure that DIRNAME terminates with '/'.  */
+  len = grub_strlen (path);
+  dirname = grub_malloc (len + 1 + 1);
+  if (! dirname)
+	  goto clean;
+
+  grub_memcpy (dirname, path, len);
+  p = dirname + len;
+  *p = '\0';
+  p = dirname;
+
+  data->dir_offset = data->rootdir_offset;
+  do
+  {
+	  load_inode(data->dir_offset);
+
+	  data->file_type = INODE->next & ROMFH_TYPE;
+
+	  if (data->file_type == ROMFH_HRD) 
+	  {
+		  data->dir_offset = INODE->spec;
+		  continue;
+	  }
+	  else if (data->file_type == ROMFH_SYM) 
+	  {
+		  grub_errno = GRUB_ERR_SYMLINK_LOOP;
+		  goto clean;
+	  }
+	  else 
+	  {
+		  /* if end of filename, INODE points to the file's inode */
+		  if (!*p || grub_isspace (*p)) 
+		  {
+			  DBG_MSG ("\t end of filename.\n");
+			  if (data->file_type != ROMFH_REG) 
+			  {
+				  grub_errno = GRUB_ERR_BAD_FILE_TYPE;
+				  goto clean;
+			  }
+
+			  data->filesize = INODE->size;
+			  file_offset = data->dir_offset;
+			
+			  DBG_MSG ("\t file with size=%d, offset=0x%x.\n", data->filesize, file_offset);
+			  goto clean;
+		  }
+		  else
+		  {
+			  DBG_MSG ("\t grub_find_dir>\n");
+			  p = grub_find_dir (p, data, hook);
+		  }
+	  }
+  }
+  while (p && grub_errno == GRUB_ERR_NONE);
+
+clean:
+
+  if (data)
+  {
+	  grub_free (data);
+	  data = 0;
+  }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_romfs_open (grub_file_t file, const char *name)
+{
+	char *p, *dirname = 0;
+	int len = 0;
+	struct grub_romfs_data *data;
+
+	if (file->device->disk->id != (unsigned long) "rd")
+		return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a romdisk");
+
+	DBG_MSG(" grub_romfs_open(%s)++. \n", name);
+
+	if (!name || name[0] != '/')
+	{
+		grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+		return grub_errno;
+	}
+
+	data = grub_romfs_mount (file->device->disk);
+	if (!data)
+	{
+		grub_print_error();
+		DBG_MSG (" mount disk failed.\n");
+		goto clean;
+	}
+
+	/* Make sure that DIRNAME terminates with '/'.  */
+	len = grub_strlen (name);
+	dirname = grub_malloc (len + 1 + 1);
+	if (! dirname)
+		goto clean;
+
+	grub_memcpy (dirname, name, len);
+	p = dirname + len;
+	*p = '\0';
+	p = dirname;
+
+	data->dir_offset = data->rootdir_offset;
+	do
+	{
+		load_inode(data->dir_offset);
+
+		data->file_type = INODE->next & ROMFH_TYPE;
+
+		if (data->file_type == ROMFH_HRD) 
+		{
+			data->dir_offset = INODE->spec;
+			continue;
+		}
+		else if (data->file_type == ROMFH_SYM) 
+		{
+			grub_errno = GRUB_ERR_SYMLINK_LOOP;
+			goto clean;
+		}
+		else 
+		{
+			/* if end of filename, INODE points to the file's inode */
+			if (!*p || grub_isspace (*p)) 
+			{
+				DBG_MSG ("\t end of filename.\n");
+				if (data->file_type != ROMFH_REG) 
+				{
+					grub_errno = GRUB_ERR_BAD_FILE_TYPE;
+					goto clean;
+				}
+
+				data->filesize = INODE->size;
+				file_offset = data->dir_offset + data->rootdir_offset;
+
+				file->data = 0;
+				file->size = data->filesize;
+
+				DBG_MSG ("\t file with size=%d, offset=0x%x.\n", data->filesize, file_offset);
+				goto clean;
+			}
+			else
+			{
+				DBG_MSG ("\t grub_find_dir>\n");
+				p = grub_find_dir (p, data, 0);
+			}
+		}
+	}
+	while (p && grub_errno == GRUB_ERR_NONE);
+
+clean:
+
+	if (data)
+	{
+		grub_free (data);
+		data = 0;
+	}
+
+	return grub_errno;
+}
+
+static grub_ssize_t
+grub_romfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+	int x = 0;
+	DBG_MSG (" grub_romfs_read(%d, %d, %d, fsize=%d)++2. \n", file_offset, file->offset, len, file->size);
+
+	if (len>0)
+	{
+		x = file_offset;
+		DBG_MSG ("\t x=%d. \n", x);
+
+		romfs_devread (x + file->offset, len, buf);
+	}
+
+	return len;
+}
+
+static grub_err_t
+grub_romfs_close (grub_file_t file)
+{
+  DBG_MSG (" grub_romfs_close(). \n");
+
+#ifndef GRUB_UTIL
+  grub_dl_unref (my_mod);
+#endif
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_romfs_label (grub_device_t device, char **label)
+{
+  struct grub_romfs_data *data;
+  DBG_MSG (" grub_romfs_label(). \n");
+
+  data = grub_romfs_mount (device->disk);
+  if (!data)
+  {
+	  DBG_MSG (" mount disk failed.\n");
+	  *label = 0;
+  }
+  else
+  {
+	  *label = data->plabel;
+  }
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_fs grub_romfs_fs = {
+  .name = "romfs",
+  .dir = grub_romfs_dir,
+  .open = grub_romfs_open,
+  .read = grub_romfs_read,
+  .close = grub_romfs_close,
+  .label = grub_romfs_label,
+  .next = 0
+};
+
+void re_init_romdisk ()
+{
+  //grub_disk_dev_unregister (&grub_romdisk_dev);
+  //grub_fs_unregister (&grub_romfs_fs);
+
+  if ( romdisk_addr )
+  {
+    grub_disk_dev_register (&grub_romdisk_dev);
+	grub_fs_register (&grub_romfs_fs);
+  }
+}
+
+GRUB_MOD_INIT (romfs)
+{
+#ifndef GRUB_UTIL
+	my_mod = mod;
+#endif
+  
+}
+
+GRUB_MOD_FINI (romfs)
+{
+  grub_fs_unregister (&grub_romfs_fs);
+
+/*
+grub_free (romdisk_addr);
+romdisk_addr = 0;
+
+grub_disk_dev_unregister (&grub_romdisk_dev);
+ */
+}
+
diff -ruNa grub2/include/grub/disk.h grub2_romfs/include/grub/disk.h
--- grub2/include/grub/disk.h	2008-08-17 09:17:24.000000000 +0800
+++ grub2_romfs/include/grub/disk.h	2008-08-17 09:09:19.000000000 +0800
@@ -40,6 +40,7 @@
     GRUB_DISK_DEVICE_NAND_ID,
     GRUB_DISK_DEVICE_UUID_ID,
     GRUB_DISK_DEVICE_PXE_ID,
+	GRUB_DISK_DEVICE_ROMDISK_ID,
   };
 
 struct grub_disk;
diff -ruNa grub2/include/grub/i386/pc/romfs.h grub2_romfs/include/grub/i386/pc/romfs.h
--- grub2/include/grub/i386/pc/romfs.h	1970-01-01 08:00:00.000000000 +0800
+++ grub2_romfs/include/grub/i386/pc/romfs.h	2008-08-17 09:13:27.000000000 +0800
@@ -0,0 +1,72 @@
+/* romfs - prototypes for romfs and romdisk */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ROMDISK_H
+#define GRUB_ROMDISK_H	1
+
+#include <grub/types.h>
+
+#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)
+
+#define NAME_MAX         255	/* # chars in a file name */
+
+/* On-disk "super block" */
+struct romfs_super_block 
+{
+	grub_uint32_t word0;                                                                                  
+	grub_uint32_t word1;                                                                                  
+	grub_uint32_t size;                                                                                   
+	grub_uint32_t checksum;                                                                               
+	char name[0];		/* volume name */                                                             
+};                                                                                             
+
+/* On disk inode */
+struct romfs_inode 
+{
+	grub_uint32_t next;		/* low 4 bits see ROMFH_ */                                                     
+	grub_uint32_t spec;                                                                                   
+	grub_uint32_t size;                                                                                   
+	grub_uint32_t checksum;                                                                               
+	char name[0];                                                                                 
+};
+
+extern char *EXPORT_VAR(romdisk_addr);
+extern grub_off_t EXPORT_VAR(romdisk_size);
+void EXPORT_FUNC(re_init_romdisk) ();
+
+/* debug support */
+/* #define DBG_MSG grub_dprintf */
+#define DBG_MSG
+
+#endif /* ! GRUB_ROMDISK_H */
