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 + +/* 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