* [PATCH] romfs support for Grub2
[not found] <48A6FA9A.45473C.07156@m12-70.163.com>
@ 2008-08-17 2:43 ` y.volta
2008-08-17 4:05 ` Bean
0 siblings, 1 reply; 8+ messages in thread
From: y.volta @ 2008-08-17 2:43 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 1586 bytes --]
Hi,
I made a small patch for grub2 using a romfs file ( zip compressing support ). there are 3 files added:
-/commands/i386/pc/romfst.c command to mount a romfs image file.
-/fs/i386/pc/romfs.c fs and disk layer for romfs.
-/include/grub/i386/pc/romfs.h header file.
usage:
grub>romfst /romfs.gz
grub>cat (rd)/readme.txt
info
------------------------------------------------------------
i make this patch have two resources: the grub legancy romfs patch and the bean's pxe patch.
i get to know the pxe mod merged the disk&fs into a fs source file. this will make mod more simple to implement.
the romfst command will load the specify file to a new memory block. when user access (rd), the new files are ready for him.
limitations
------------------------------------------------------------
* this patch is for file only: if you want to use it on a disk/partition, we should improve it.
* grub_romfs_data *data, has not set to file->data - i used several global varibles to store releated stuffs.
well, this is just a work-able patch, not too professional. ;-)
btw, i think the grub_dprintf should output to non-display device, this will make debuging more easier and comfort . i think the low-cost device is a com-port. for, now time virtual machine software has this legancy device full supported.
the freeldr coming with ReactOS have this kind of function (only display a string, but can do kernal debug also )
y.volta
[-- Attachment #2: rev_1813.romfs.patch --]
[-- Type: application/octet-stream, Size: 23219 bytes --]
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;
+}
+
+
+\f
+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 */
^ permalink raw reply [flat|nested] 8+ messages in thread