Index: configure.ac =================================================================== RCS file: /cvsroot/grub/grub/configure.ac,v retrieving revision 1.7 diff -u -a -u -r1.7 configure.ac --- configure.ac 20 Jun 2004 13:48:46 -0000 1.7 +++ configure.ac 2 Jan 2005 01:15:24 -0000 @@ -291,6 +291,13 @@ FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_ISO9660=1" fi +AC_ARG_ENABLE(romfs, + [ --disable-romfs disable ROMFS support in Stage 2]) + +if test x"$enable_romfs" != xno; then + FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_ROMFS=1" +fi + dnl AC_ARG_ENABLE(tftp, dnl [ --enable-tftp enable TFTP support in Stage 2]) dnl Index: stage2/Makefile.am =================================================================== RCS file: /cvsroot/grub/grub/stage2/Makefile.am,v retrieving revision 1.46 diff -u -a -u -r1.46 Makefile.am --- stage2/Makefile.am 24 Jun 2004 17:04:37 -0000 1.46 +++ stage2/Makefile.am 2 Jan 2005 01:15:24 -0000 @@ -17,13 +17,13 @@ noinst_LIBRARIES = libgrub.a libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \ disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \ - fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ + fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_romfs.c fsys_ufs2.c \ fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \ terminfo.c tparm.c libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \ -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \ - -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \ + -DFSYS_ROMFS=1 -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \ -DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1 \ -fwritable-strings @@ -35,24 +35,26 @@ if DISKLESS_SUPPORT pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \ - reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \ - nbgrub pxegrub + reiserfs_stage1_5 romfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 \ + xfs_stage1_5 nbgrub pxegrub noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \ e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \ iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \ - reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \ - xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec + reiserfs_stage1_5.exec romfs_stage1_5.exec ufs2_stage1_5.exec \ + vstafs_stage1_5.exec xfs_stage1_5.exec nbloader.exec \ + pxeloader.exec diskless.exec else pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \ - reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 + reiserfs_stage1_5 romfs_stage_1_5 ufs2_stage1_5 vstafs_stage1_5 \ + xfs_stage1_5 noinst_DATA = pre_stage2 start start_eltorito noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \ e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \ iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \ - reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \ - xfs_stage1_5.exec + reiserfs_stage1_5.exec romfs_stage1_5.exec ufs2_stage1_5.exec \ + vstafs_stage1_5.exec xfs_stage1_5.exec endif MOSTLYCLEANFILES = $(noinst_PROGRAMS) @@ -90,8 +92,9 @@ pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \ cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ - fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \ - hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c + fsys_reiserfs.c fsys_romfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c \ + gunzip.c hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c \ + tparm.c pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK) @@ -191,6 +194,15 @@ -DNO_BLOCK_FILES=1 reiserfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) +# For romfs_stage1_5 target. +romfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \ + disk_io.c stage1_5.c fsys_romfs.c bios.c +romfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ROMFS=1 \ + -DNO_BLOCK_FILES=1 +romfs_stage1_5_exec_ASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ROMFS=1 \ + -DNO_BLOCK_FILES=1 +romfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) + # For vstafs_stage1_5 target. vstafs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \ disk_io.c stage1_5.c fsys_vstafs.c bios.c Index: stage2/builtins.c =================================================================== RCS file: /cvsroot/grub/grub/stage2/builtins.c,v retrieving revision 1.149 diff -u -a -u -r1.149 builtins.c --- stage2/builtins.c 20 Jun 2004 13:48:46 -0000 1.149 +++ stage2/builtins.c 2 Jan 2005 01:15:25 -0000 @@ -3868,6 +3868,7 @@ {"jfs", "/jfs_stage1_5"}, {"minix", "/minix_stage1_5"}, {"reiserfs", "/reiserfs_stage1_5"}, + {"romfs", "/romfs_stage1_5"}, {"vstafs", "/vstafs_stage1_5"}, {"xfs", "/xfs_stage1_5"} }; Index: stage2/char_io.c =================================================================== RCS file: /cvsroot/grub/grub/stage2/char_io.c,v retrieving revision 1.56 diff -u -a -u -r1.56 char_io.c --- stage2/char_io.c 23 May 2004 16:45:44 -0000 1.56 +++ stage2/char_io.c 2 Jan 2005 01:15:25 -0000 @@ -972,7 +972,7 @@ a static library supporting minimal standard C functions and link each image with the library. Complicated things should be left to computer, definitely. -okuji */ -#if !defined(STAGE1_5) || defined(FSYS_VSTAFS) +#if !defined(STAGE1_5) || defined(FSYS_VSTAFS) || defined(FSYS_ROMFS) int grub_strcmp (const char *s1, const char *s2) { Index: stage2/disk_io.c =================================================================== RCS file: /cvsroot/grub/grub/stage2/disk_io.c,v retrieving revision 1.58 diff -u -a -u -r1.58 disk_io.c --- stage2/disk_io.c 23 May 2004 16:45:45 -0000 1.58 +++ stage2/disk_io.c 2 Jan 2005 01:15:25 -0000 @@ -78,6 +78,9 @@ # ifdef FSYS_ISO9660 {"iso9660", iso9660_mount, iso9660_read, iso9660_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 Index: stage2/filesys.h =================================================================== RCS file: /cvsroot/grub/grub/stage2/filesys.h,v retrieving revision 1.12 diff -u -a -u -r1.12 filesys.h --- stage2/filesys.h 14 May 2004 20:16:55 -0000 1.12 +++ stage2/filesys.h 2 Jan 2005 01:15:25 -0000 @@ -105,6 +105,15 @@ #define FSYS_XFS_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 + #ifdef FSYS_TFTP #define FSYS_TFTP_NUM 1 int tftp_mount (void); @@ -128,7 +137,7 @@ #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_ISO9660_NUM + FSYS_UFS2_NUM) + + FSYS_ROMFS_NUM + FSYS_TFTP_NUM + FSYS_ISO9660_NUM + FSYS_UFS2_NUM) #endif /* defines for the block filesystem info area */ Index: stage2/fsys_romfs.c =================================================================== RCS file: grub-0.93/stage2/fsys_romfs.c diff -N stage2/fsys_romfs.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ stage2/fsys_romfs.c 3 Jun 2003 04:37:52 -0000 1.2 @@ -0,0 +1,288 @@ +/* + * 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.h" + +static inline __const__ __u32 +le32 (__u32 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; +} + + +/* 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=le32(INODE->next); + INODE->spec=le32(INODE->spec); + INODE->size=le32(INODE->size); + INODE->checksum=le32(INODE->checksum); + + disk_read_func = NULL; + { + int namelen; + namelen = find_string_len(((unsigned char*)INODE)+sizeof(*INODE), + offset+16); + // printf("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((unsigned char *)&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) + { + printf("got eof\n"); + return 0; + } + + disk_read_func = disk_read_hook; + + devread ((disk_offset+filepos) / SECTOR_SIZE, + (disk_offset+filepos) % SECTOR_SIZE, + len, buf); + + disk_read_func = NULL; + + filepos += len; + ret = len; + + if (errnum) + ret = 0; + + if (filepos==filemax) + is_eof=1; + return ret; +} + +int +romfs_dir (char *dirname) +{ + char *rest; + char ch; /* temp char holder */ + int str_chk; /* used to hold the results of a string compare */ + int inode_ret=0; + + 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 */ + + inode_ret=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; + } + disk_offset += rootdir_offset; + is_eof=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 = grub_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 */ Index: stage2/romfs.h =================================================================== RCS file: grub-0.93/stage2/romfs.h diff -N stage2/romfs.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ stage2/romfs.h 3 Jun 2003 04:37:52 -0000 1.2 @@ -0,0 +1,62 @@ +#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) le32(__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 Index: stage2/shared.h =================================================================== RCS file: /cvsroot/grub/grub/stage2/shared.h,v retrieving revision 1.99 diff -u -a -u -r1.99 shared.h --- stage2/shared.h 20 Jun 2004 13:48:47 -0000 1.99 +++ stage2/shared.h 2 Jan 2005 01:15:25 -0000 @@ -210,6 +210,7 @@ #define STAGE2_ID_VSTAFS_STAGE1_5 6 #define STAGE2_ID_JFS_STAGE1_5 7 #define STAGE2_ID_XFS_STAGE1_5 8 +#define STAGE2_ID_ROMFS_STAGE1_5 9 #define STAGE2_ID_ISO9660_STAGE1_5 9 #define STAGE2_ID_UFS2_STAGE1_5 10 @@ -232,6 +233,8 @@ # define STAGE2_ID STAGE2_ID_JFS_STAGE1_5 # elif defined(FSYS_XFS) # define STAGE2_ID STAGE2_ID_XFS_STAGE1_5 +# elif defined(FSYS_ROMFS) +# define STAGE2_ID STAGE2_ID_ROMFS_STAGE1_5 # elif defined(FSYS_ISO9660) # define STAGE2_ID STAGE2_ID_ISO9660_STAGE1_5 # elif defined(FSYS_UFS2)