Hi. I've been implementing romfs support into grub, and need
        help with regard to automake/autoconf and friends.

        First, about romfs. It's a simple, read-only filesystem,
        included in Linux 2.4. There's a file documenting the on-disk
        layout in the kernel source, you can browse it at
        http://lxr.linux.no/source/Documentation/filesystems/romfs.txt?v=2.4.17
        and the actual implementation is at
        http://lxr.linux.no/source/fs/romfs/?v=2.4.17

        Now, I have a patch that implements the first steps towards
        romfs support in grub. The code is still very raw, and I have
        only tested it with the grub shell tool, not booted from it.
        However, I can't progress any further without some help from
        you.

        It seems that I can't create Makefile.in etc from Makefile.am
        succesfully. Rather than drag you down into debugging auto* for
        me, could you apply the patch (fix the Makefile.am part if I
        misunderstood something), regenerate the generated files, and
        send them to me? Thank you.


        Any input as to the functioning of fsys_romfs.c is
        appreciated, the interface is very sketchy and I had to guess
        what global variables to manipulate. I will format the code to
        fit the existing coding style before proper submission.

diff -Naur grub-0.91.orig/stage2/Makefile.am grub-0.91/stage2/Makefile.am
--- grub-0.91.orig/stage2/Makefile.am	Sat Oct 27 19:04:24 2001
+++ grub-0.91/stage2/Makefile.am	Thu Feb 28 14:05:55 2002
@@ -17,11 +17,11 @@
 libgrub_a_SOURCES = boot.c builtins.c common.c char_io.c cmdline.c \
 	disk_io.c gunzip.c fsys_ffs.c fsys_ext2fs.c fsys_fat.c \
 	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_vstafs.c \
-	fsys_xfs.c stage2.c md5.c
+	fsys_xfs.c fsys_romfs.c stage2.c md5.c
 libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
 	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
-	-DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 -DFSYS_VSTAFS=1
-	-DFSYS_XFS=1 -DUSE_MD5_PASSWORDS=1 \
+	-DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 -DFSYS_VSTAFS=1 \
+	-DFSYS_XFS=1 -DFSYS_ROMFS=1 -DUSE_MD5_PASSWORDS=1 \
 	-DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1 -fwritable-strings
 
 # Stage 2 and Stage 1.5's.
@@ -32,7 +32,7 @@
 if DISKLESS_SUPPORT
 pkgdata_DATA = stage2 e2fs_stage1_5 fat_stage1_5 ffs_stage1_5 \
 	jfs_stage1_5 minix_stage1_5 reiserfs_stage1_5 vstafs_stage1_5 \
-	xfs_stage1_5 nbgrub pxegrub
+	xfs_stage1_5 nbgrub pxegrub romfs_stage1_5
 noinst_DATA = pre_stage2 start nbloader pxeloader diskless
 noinst_PROGRAMS = pre_stage2.exec start.exec e2fs_stage1_5.exec \
 	fat_stage1_5.exec ffs_stage1_5.exec jfs_stage1_5.exec \
@@ -42,12 +42,12 @@
 else
 pkgdata_DATA = stage2 e2fs_stage1_5 fat_stage1_5 ffs_stage1_5 \
 	jfs_stage1_5 minix_stage1_5 reiserfs_stage1_5 vstafs_stage1_5 \
-	xfs_stage1_5
+	xfs_stage1_5 romfs_stage1_5
 noinst_DATA = pre_stage2 start
 noinst_PROGRAMS = pre_stage2.exec start.exec e2fs_stage1_5.exec \
 	fat_stage1_5.exec ffs_stage1_5.exec jfs_stage1_5.exec \
 	minix_stage1_5.exec reiserfs_stage1_5.exec \
-	vstafs_stage1_5.exec xfs_stage1_5.exec
+	vstafs_stage1_5.exec xfs_stage1_5.exec romfs_stage1_5.exec
 endif
 MOSTLYCLEANFILES = $(noinst_PROGRAMS)
 
@@ -85,7 +85,7 @@
 	char_io.c cmdline.c disk_io.c gunzip.c fsys_ext2fs.c \
 	fsys_fat.c fsys_ffs.c fsys_jfs.c fsys_minix.c fsys_reiserfs.c \
 	fsys_vstafs.c fsys_xfs.c hercules.c serial.c smp-imps.c \
-	stage2.c md5.c
+	stage2.c md5.c fsys_romfs.c
 pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 pre_stage2_exec_ASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
@@ -192,6 +192,15 @@
 xfs_stage1_5_exec_ASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_XFS=1 \
 	-DNO_BLOCK_FILES=1
 xfs_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 diskless target.
 diskless_exec_SOURCES = $(pre_stage2_exec_SOURCES)
diff -Naur grub-0.91.orig/stage2/disk_io.c grub-0.91/stage2/disk_io.c
--- grub-0.91.orig/stage2/disk_io.c	Wed Nov 28 20:43:56 2001
+++ grub-0.91/stage2/disk_io.c	Thu Feb 28 14:05:55 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 -Naur grub-0.91.orig/stage2/filesys.h grub-0.91/stage2/filesys.h
--- grub-0.91.orig/stage2/filesys.h	Mon Nov 12 08:57:29 2001
+++ grub-0.91/stage2/filesys.h	Thu Feb 28 14:05:55 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 -Naur grub-0.91.orig/stage2/fsys_romfs.c grub-0.91/stage2/fsys_romfs.c
--- grub-0.91.orig/stage2/fsys_romfs.c	Thu Jan  1 02:00:00 1970
+++ grub-0.91/stage2/fsys_romfs.c	Thu Feb 28 14:11:22 2002
@@ -0,0 +1,235 @@
+/*
+ *  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 "romfs_fs.h"
+
+/* "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));
+    i++;
+  } while (buf[i*16-1] != '\0');
+  return i*16;
+}
+
+/* return disk offset of file data. */
+static int load_inode(int 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);
+    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 verify checksum */
+
+  rootdir_offset = 16+find_string_len(&SUPERBLOCK->name, 16);
+
+  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 {
+      /* if end of filename, INODE points to the file's inode */
+      if (!*dirname || isspace (*dirname)) {
+	if (type!=ROMFH_REG) {
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+	
+	filemax = INODE->size;
+	return 1;
+      } else {
+	/* 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;
+	
+	{
+	  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);
+	    }
+
+	    load_inode(dir_offset);
+	    str_chk = strcmp(dirname, INODE->name);
+	    
+#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 -Naur grub-0.91.orig/stage2/romfs_fs.h grub-0.91/stage2/romfs_fs.h
--- grub-0.91.orig/stage2/romfs_fs.h	Thu Jan  1 02:00:00 1970
+++ grub-0.91/stage2/romfs_fs.h	Thu Feb 28 14:08:00 2002
@@ -0,0 +1,46 @@
+#ifndef __LINUX_ROMFS_FS_H
+#define __LINUX_ROMFS_FS_H
+
+#include <netinet/in.h>
+
+/* The basic structures of the romfs filesystem */
+
+#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
+
+#endif

-- 
tv@{{hq.yok.utu,havoc,gaeshido}.fi,{debian,wanderer}.org,stonesoft.com}
double a,b=4,c;main(){for(;++a<2e6;c-=(b=-b)/a++);printf("%f\n",c);}

Reply via email to