public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Re: / on ramfs, possible? [yes! - patch included]
@ 2000-10-31  3:06 Matt Yourst
  0 siblings, 0 replies; only message in thread
From: Matt Yourst @ 2000-10-31  3:06 UTC (permalink / raw)
  To: aer-list; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2622 bytes --]

Hi,

I read your post and I think I have just what you're looking for. I've
attached a patch that allows you to mount root as ramfs and populate
it directly from a tar archive (specified just like an initrd image,
but without having to deal with a fixed-size initrd or pivot_root at
all.) This was based on some earlier work from the Linux router
project that I rewrote and ported to 2.2 and 2.4 a few months ago. I
didn't post it to the list since I figured it was too late for 2.4.0,
but if you're interested, here it is.

Here's the Configure.help description:

CONFIG_RAMFS_ROOT
  Allow the kernel to mount a ramfs namespace as the root filesystem
  or as a pre-root filesystem for running a /linuxrc script (similar
  to how initial RAM disk (initrd) support works.)
 
  Since ramfs has no physical or virtual block device to provide its
  data as an initrd image would, you must provide a standard tar
format
  archive to be extracted into the empty ramfs root filesystem.
Currently
  this tar archive may *not* be compressed (i.e., tar.gz style); if
  compression is desired, use a bootloader with automatic gunzip
support
  such as GRUB.
 
  To specify the tar archive used to build the root filesystem, use
the
  initrd=<filename> kernel command line option (except with a tar
archive
  instead of a real ext2/minix/romfs filesystem image.)
 
  To mount the tar archive as the actual root filesystem, specify the
  same initrd=<filename> option above and also include
"root=/dev/ramfs"
  in the kernel command line.
 
  You may enable both this option and initrd support; however, if a
  tar archive is detected instead of an initrd-supported filesystem
  image, this option will override initrd support.
 
  Note: Some versions of GNU tar create invalid archives that cannot
  be extracted by the kernel. In particular, tar may add a file to an
  archive without previously adding its containing directory. If your
  ramfs archive does not mount correctly because of this, try creating
  it in another way or with another file order.

(Patch should apply to 2.4.0-test10-pre6 on i386. It needs to be
updated for other architectures, mostly in setup.c though.) 

I hope this is helpful. Maybe the maintainers would like to comment on
this too (i.e., might it be considered for 2.4.1, etc.?)

- Matt Yourst

-------------------------------------------------------------
 Matt T. Yourst        Massachusetts Institute of Technology
 yourst@mit.edu                                 617.225.7690
 513 French House - 476 Memorial Drive - Cambridge, MA 02136
-------------------------------------------------------------

[-- Attachment #2: linux-ramfs-tar-root.diff --]
[-- Type: application/octet-stream, Size: 19400 bytes --]

--- linux/fs/ramfs/Makefile.orig	Sat Oct 28 21:56:12 2000
+++ linux/fs/ramfs/Makefile	Sat Oct 28 21:56:25 2000
@@ -5,6 +5,9 @@
 O_TARGET := ramfs.o
 
 O_OBJS := inode.o
+ifeq ($(CONFIG_RAMFS_ROOT),y)
+	O_OBJS += untar.o
+endif
 
 M_OBJS := $(O_TARGET)
 
--- linux/fs/ramfs/untar.c.empty	Wed Dec 31 19:00:00 1969
+++ linux/fs/ramfs/untar.c	Sat Oct 28 22:52:15 2000
@@ -0,0 +1,307 @@
+/*
+ * linux/fs/ramfs/untar.c
+ * Mount a RAM-based root filesystem from the contents of a tar archive
+ *
+ * Linux 2.4 version Copyright (c) 2000 Matt T. Yourst <yourst@mit.edu>
+ * Original code for Linux 2.0 Copyright (c) 1998 Dimitri Maziuk and Dave Cinege
+ * 
+ * 2000-07-29 Matt T. Yourst <yourst@mit.edu>
+ * Upgraded all code to Linux 2.4. Now extracts to a full read-write ramfs 
+ * based root running directly out of the page cache.
+ *
+ * 1998-03-31
+ * Submission for linux kernel 2.0.34
+ * This version is exectly like the 1998-01-17 version, plus the addition
+ * of a wrapper function to deal with the the simple_strtoul spaces issue.
+ * I did not feel it was wise (and would mean this patch is rejected : >) 
+ * to require the vsprintf change in the stable kernel series.
+ *
+ * 1998-01-17
+ * Is GNUtar the biggest fuck-up in released software since MS-DOS? 
+ * It could be.
+ * 
+ * Tar decides it sometimes likes to make a dir entry that is blank or "./".
+ * We now check for this, and modified our exit pattern to deal with it.
+ * 
+ * Although both Dima and I thought it wasn't possible, tar can  
+ * stor files without first storing the dir they require.
+ * If your nice freshly made archive doesn't work don't be surprised.
+ * Try specing a different way to make it.
+ *
+ * Dima has a forthcoming mini tar archive creator (ctar) that should
+ * better deal with these problems. You may want to look for it if normal
+ * tar does not suite your needs when using this kernel feature.
+ *
+ * 1998-01-10
+ * This version of untar is very limited. It expects a fairly good archive, 
+ * as well as expansion to a clean root.
+ * 
+ * It does not:
+ * 
+ * Look for a leading '/'
+ * Check before making links
+ * Look at the header checksum
+ * Check or create any leading directory structure
+ * 
+ */
+
+#include <linux/unistd.h>
+#include <linux/stat.h>
+#include <linux/fs.h>
+#include <linux/stddef.h>
+#include <linux/utime.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#ifndef min
+#define min(x, y) (((x) < (y)) ? (x) : (y))
+#endif
+
+extern unsigned long initrd_start;
+extern unsigned long initrd_end;
+extern int mount_initrd;
+
+#define E_NAMETOOLONG	1
+#define E_CANNOTSTAT	2
+#define E_READLINK	3
+#define E_SHORTWRITE	4
+#define E_FOPEN		5
+#define E_MALLOC	6
+#define E_OPENDIR	7
+#define E_WRONG_FTYPE	8
+
+#define	TARBLOCKSIZE	512
+
+#define NAME_FIELD_SIZE   100
+#define PREFIX_FIELD_SIZE 155
+#define UNAME_FIELD_SIZE   32
+#define GNAME_FIELD_SIZE   32
+
+#define TMAGIC   "ustar"	/* ustar signature */
+#define TMAGLEN  5
+#define TVERSION " \0"		/* 00 and no null */
+#define TVERSLEN 2
+
+#define REGTYPE	 '0'		/* regular file */
+#define AREGTYPE '\0'		/* regular file */
+#define LNKTYPE  '1'		/* link */
+#define SYMTYPE  '2'		/* reserved */
+#define CHRTYPE  '3'		/* character special */
+#define BLKTYPE  '4'		/* block special */
+#define DIRTYPE  '5'		/* directory */
+#define FIFOTYPE '6'		/* FIFO special */
+#define CONTTYPE '7'		/* reserved */
+
+/* POSIX tar header */
+struct fileHeader
+{					/* byte offset */
+  char name[NAME_FIELD_SIZE];		/*   0 */
+  char mode[8];				/* 100 */
+  char uid[8];				/* 108 */
+  char gid[8];				/* 116 */
+  char size[12];			/* 124 */
+  char mtime[12];			/* 136 */
+  char chksum[8];			/* 148 */
+  char typeflag;			/* 156 */
+  char linkname[NAME_FIELD_SIZE];	/* 157 */
+  char magic[TMAGLEN];			/* 257 */
+  char version[TVERSLEN];		/* 263 */
+  char uname[UNAME_FIELD_SIZE];		/* 265 */
+  char gname[GNAME_FIELD_SIZE];		/* 297 */
+  char devmajor[8];			/* 329 */
+  char devminor[8];			/* 337 */
+  char prefix[PREFIX_FIELD_SIZE];	/* 345 */
+					/* 500 */
+};
+
+union TarInfo 
+{
+  char buf[TARBLOCKSIZE];
+  struct fileHeader header;
+};
+
+typedef union TarInfo	TarInfo;
+
+/* We use the normal system calls to build the filesystem: */
+extern int sys_write(unsigned int fd, char *buf,unsigned int count);
+extern int sys_chmod(const char *filename, mode_t mode);
+extern int sys_chown(const char *filename, uid_t user, gid_t group);
+extern int sys_mknod(const char *filename, int mode, dev_t dev);
+extern int sys_mkdir(const char *pathname, int mode);
+extern int sys_chdir(const char *filename);
+extern int sys_link(const char *oldname, const char *newname);
+extern int sys_symlink(const char *oldname, const char *newname);
+extern int sys_utime(char *filename, struct utimbuf *times);
+extern int sys_time(int *t);
+
+/*
+ * Find out how much space is left in the in-memory tar archive,
+ * then return the amount actually "read" just like read() does.
+ * The caller should note the pointer to the actual data (at 
+ * fileptr) before calling this routine.
+ */
+static inline int __init read_tar_memory(char** fileptr, char* fileend, size_t size)
+{
+  size_t bytes_to_read = min(size, fileend - *fileptr);
+  *fileptr += bytes_to_read;
+  return bytes_to_read;
+}
+
+/*
+ * This is called by setup.c to let the ramfs image take control
+ * before the traditional initrd code fails to recognize it and
+ * hence frees the memory.
+ *
+ * If this is a ramfs tar file image, return 1. Otherwise, return 0.
+ */
+int __init ramfs_check_root(void)
+{
+  char* magic = (char*)(initrd_start + 0x101);
+	if (initrd_start && (!strncmp(magic, TMAGIC, TMAGLEN))) {
+		mount_initrd = 0;
+		return 1;
+	}
+	return 0;
+}
+
+extern void free_initrd_mem(unsigned long start, unsigned long end);
+
+/*
+ * This routine reads in a standard tar archive stream in 
+ * contiguous memory starting at start and ending at end.
+ */
+int __init ramfs_untar(char* start, char* end)
+{
+ 	char *buf = 0;
+	int err, fd;
+	unsigned long fsize;
+	mode_t fmode;
+	kdev_t fdev;
+	struct utimbuf ut;
+	union TarInfo *tarInfo;	
+
+	printk(KERN_NOTICE "ramfs: Building root...");
+
+	for (;;) {
+		/* Read header or return short read */
+		tarInfo = (TarInfo*)start;
+		err = read_tar_memory(&start, end, TARBLOCKSIZE);
+		if (err < TARBLOCKSIZE) {
+			if (err == 0) {
+				goto exit;
+			} else {
+				printk(KERN_ERR "ramfs: Corrupt tar archive\n");
+				err = -1;
+				goto exit;
+			}
+		}
+
+		fmode = simple_strtoul(tarInfo->header.mode, NULL, 8);
+		fsize = simple_strtoul(tarInfo->header.size, NULL, 8);
+
+#ifdef DEBUG_UNTAR
+		printk("\n%c/%012o %013d %s", tarInfo->header.typeflag, fmode, fsize, tarInfo->header.name);
+#endif
+
+    /*
+     * This should fix the problem with '\0' named dirs killing the archive
+     * extraction. A better way would be to look to see if fsize[0] contains 
+     * '\0' as a normal header would either have a number their or pad it with
+     * a ' '. Not sure if all tar's do this, so it may not be safe
+     */
+		if ((tarInfo->header.name[0] == '\0') && (fmode == 0) && (fsize == 0)) {
+			err = 0;
+			goto exit;
+		}
+
+		err = 0;
+
+		/* Check the file type and extract as appropriate */
+		switch (tarInfo->header.typeflag) {
+			case AREGTYPE: 
+			case REGTYPE:
+				fd = sys_open(tarInfo->header.name, O_CREAT|O_WRONLY|O_TRUNC, fmode);
+				if (fd < 0) {
+					err = 1;
+					break;
+				}
+
+        buf = (char*)start;
+				if (read_tar_memory(&start, end, fsize) < fsize) 
+					err=1;
+		
+				if (sys_write(fd, buf, fsize) < fsize)
+					err=1;
+
+				sys_close(fd);
+	
+				if (fsize % TARBLOCKSIZE != 0) 
+					start += (TARBLOCKSIZE * (fsize / TARBLOCKSIZE + 1)) - fsize;
+				break;
+
+			case DIRTYPE:
+				/* Skip if name is "" "./" "." ".." */
+				if ((tarInfo->header.name[0] != '.' && tarInfo->header.name[0] != '\0') &&
+						(tarInfo->header.name[1] != '/' && tarInfo->header.name[1] != '\0') &&
+						(tarInfo->header.name[1] != '\0'))
+					err=sys_mkdir(tarInfo->header.name,fmode);
+				else continue;
+				break;
+
+			case SYMTYPE:			
+				err = sys_symlink(tarInfo->header.linkname, tarInfo->header.name);
+				break;
+
+			case LNKTYPE:	 
+				err = sys_link(tarInfo->header.linkname, tarInfo->header.name);
+				break;
+
+			case FIFOTYPE:
+			case CHRTYPE:
+			case BLKTYPE:
+				fdev = MKDEV(simple_strtoul(tarInfo->header.devmajor, NULL, 8),
+										 simple_strtoul(tarInfo->header.devminor, NULL, 8));
+				err = sys_mknod(tarInfo->header.name, fmode, fdev);
+				break;
+
+			default:
+				printk(KERN_ERR "\nramfs: Corrupt tar archive\n");
+				err = -1;
+				goto exit;
+		}
+
+		if (err) printk(KERN_WARNING "\nramfs: Error creating %s\n", tarInfo->header.name);
+
+		/* Set the owner/group and permissions */
+		if (tarInfo->header.typeflag != LNKTYPE && tarInfo->header.typeflag != SYMTYPE) {
+			err = sys_chown(tarInfo->header.name,
+											simple_strtoul(tarInfo->header.uid, NULL, 8),
+											simple_strtoul(tarInfo->header.gid, NULL, 8));
+			if (err) {
+				printk(KERN_WARNING "\nramfs: Error setting owner on %s\n", tarInfo->header.name);
+				sys_chown(tarInfo->header.name, 0, 0); /* Just to be safe */
+			}
+
+			err = sys_chmod(tarInfo->header.name, fmode);
+			if (err) {
+				if (err) printk(KERN_WARNING "\nramfs: Error setting permissions on %s\n", tarInfo->header.name);
+				sys_chmod(tarInfo->header.name, S_IRWXU | S_IRWXG | S_IROTH); /* Just to be safe */
+			}
+		}
+
+		/* Update the timestamps */
+		ut.actime = sys_time(NULL);
+		ut.modtime = simple_strtoul(tarInfo->header.mtime, NULL, 8);
+		sys_utime(tarInfo->header.name, &ut);
+	}
+
+exit:
+	printk(KERN_NOTICE "done\n");
+
+	free_initrd_mem(initrd_start, initrd_end);
+#ifdef DEBUG_UNTAR
+	printk(KERN_NOTICE "initrd memory for ramfs tar freed: 0x%08x to 0x%08x\n", initrd_start, initrd_end);
+#endif
+	initrd_start = 0;
+	return err;
+}
--- linux/fs/Config.in.orig	Sat Oct 28 21:56:12 2000
+++ linux/fs/Config.in	Sat Oct 28 21:56:25 2000
@@ -40,6 +40,7 @@
 fi
 tristate 'Compressed ROM file system support' CONFIG_CRAMFS
 tristate 'Simple RAM-based file system support' CONFIG_RAMFS
+dep_bool '  RAM-based root filesystem from tar archive' CONFIG_RAMFS_ROOT $CONFIG_RAMFS
 
 tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS
 dep_mbool '  Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS
--- linux/arch/i386/mm/init.c.orig	Sat Oct 28 21:56:12 2000
+++ linux/arch/i386/mm/init.c	Sat Oct 28 21:56:25 2000
@@ -669,7 +669,7 @@
 	printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
+#if (defined(CONFIG_BLK_DEV_INITRD) || defined(CONFIG_RAMFS_ROOT))
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
 	if (start < end)
--- linux/arch/i386/kernel/setup.c.orig	Sat Oct 28 21:56:12 2000
+++ linux/arch/i386/kernel/setup.c	Sat Oct 28 22:06:45 2000
@@ -140,6 +140,16 @@
 extern int rd_image_start;	/* starting block # of image */
 #endif
 
+#if (defined(CONFIG_RAMFS_ROOT) || defined(CONFIG_BLK_DEV_INITRD))
+unsigned long initrd_start, initrd_end;
+int mount_initrd = 1;		/* zero if initrd should not be mounted */
+int initrd_below_start_ok;
+#endif
+
+#ifdef CONFIG_RAMFS_ROOT
+extern int ramfs_check_root(void);
+#endif
+
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
 extern unsigned long cpu_khz;
@@ -900,7 +910,7 @@
 #ifdef CONFIG_X86_LOCAL_APIC
 	init_apic_mappings();
 #endif
-#ifdef CONFIG_BLK_DEV_INITRD
+#if (defined(CONFIG_BLK_DEV_INITRD) || defined(CONFIG_RAMFS_ROOT))
 	if (LOADER_TYPE && INITRD_START) {
 		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
 			reserve_bootmem(INITRD_START, INITRD_SIZE);
@@ -916,6 +926,13 @@
 			initrd_start = 0;
 		}
 	}
+#ifdef CONFIG_RAMFS_ROOT
+	/* 
+	 * Give ramfs a chance to take control before initrd
+	 * doesn't recognize the tar format and frees the memory 
+	 */
+	ramfs_check_root();
+#endif
 #endif
 
 	/*
--- linux/init/main.c.orig	Sat Oct 28 21:56:12 2000
+++ linux/init/main.c	Sat Oct 28 23:00:33 2000
@@ -123,10 +123,14 @@
 
 int rows, cols;
 
-#ifdef CONFIG_BLK_DEV_INITRD
+#if (defined(CONFIG_BLK_DEV_INITRD) || defined(CONFIG_RAMFS_ROOT))
 kdev_t real_root_dev;
 #endif
 
+#ifdef CONFIG_RAMFS_ROOT
+extern int ramfs_check_root(void);
+#endif
+
 int root_mountflags = MS_RDONLY;
 char *execute_command;
 char root_device_name[64];
@@ -144,12 +148,12 @@
 
 __setup("profile=", profile_setup);
 
-
 static struct dev_name_struct {
 	const char *name;
 	const int num;
 } root_dev_names[] __initdata = {
 	{ "nfs",     0x00ff },
+	{ "ramfs",   0x00fe },
 	{ "hda",     0x0300 },
 	{ "hdb",     0x0340 },
 	{ "hdc",     0x1600 },
@@ -542,7 +546,7 @@
 	kmem_cache_init();
 	sti();
 	calibrate_delay();
-#ifdef CONFIG_BLK_DEV_INITRD
+#if (defined(CONFIG_BLK_DEV_INITRD) || defined(CONFIG_RAMFS_ROOT))
 	if (initrd_start && !initrd_below_start_ok &&
 			initrd_start < min_low_pfn << PAGE_SHIFT) {
 		printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
@@ -590,7 +594,7 @@
  	cpu_idle();
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
+#if (defined(CONFIG_BLK_DEV_INITRD) || defined(CONFIG_RAMFS_ROOT))
 static int do_linuxrc(void * shell)
 {
 	static char *argv[] = { "linuxrc", NULL, };
@@ -627,8 +631,9 @@
  */
 static void __init do_basic_setup(void)
 {
-#ifdef CONFIG_BLK_DEV_INITRD
+#if (defined(CONFIG_BLK_DEV_INITRD) || defined(CONFIG_RAMFS_ROOT))
 	int real_root_mountflags;
+	int init_ramfs;
 #endif
 
 	/*
@@ -692,11 +697,16 @@
 	/* Networking initialization needs a process context */ 
 	sock_init();
 
-#ifdef CONFIG_BLK_DEV_INITRD
+#if (defined(CONFIG_BLK_DEV_INITRD) || defined(CONFIG_RAMFS_ROOT))
 	real_root_dev = ROOT_DEV;
 	real_root_mountflags = root_mountflags;
+#ifdef CONFIG_RAMFS_ROOT
+	init_ramfs = ramfs_check_root();
+#else
+	init_ramfs = 0;
+#endif
 	if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY;
-	else mount_initrd =0;
+	else mount_initrd = 0;
 #endif
 
 	do_initcalls();
@@ -715,13 +725,13 @@
 
 	mount_devfs_fs ();
 
-#ifdef CONFIG_BLK_DEV_INITRD
+#if (defined(CONFIG_BLK_DEV_INITRD) || defined(CONFIG_RAMFS_ROOT))
 	root_mountflags = real_root_mountflags;
-	if (mount_initrd && ROOT_DEV != real_root_dev
-	    && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
+	if ((mount_initrd && ROOT_DEV != real_root_dev
+	    && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) 
+      || init_ramfs) {
 		int error;
 		int i, pid;
-
 		pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
 		if (pid>0)
 			while (pid != wait(&i));
--- linux/drivers/block/rd.c.orig	Sat Oct 28 21:56:12 2000
+++ linux/drivers/block/rd.c	Sat Oct 28 21:56:25 2000
@@ -128,9 +128,10 @@
 int rd_prompt = 1;		/* 1 = prompt for RAM disk, 0 = don't prompt */
 int rd_image_start;		/* starting block # of image */
 #ifdef CONFIG_BLK_DEV_INITRD
-unsigned long initrd_start, initrd_end;
-int mount_initrd = 1;		/* zero if initrd should not be mounted */
-int initrd_below_start_ok;
+/* These three are now in arch/.../setup.c: */
+extern unsigned long initrd_start, initrd_end;
+extern int mount_initrd;		/* zero if initrd should not be mounted */
+extern int initrd_below_start_ok;
 
 static int __init no_initrd(char *str)
 {
--- linux/fs/super.c.orig	Sat Oct 28 21:56:12 2000
+++ linux/fs/super.c	Sat Oct 28 22:52:31 2000
@@ -36,6 +36,7 @@
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_mount.h>
+#include <linux/blk.h>
 
 #include <linux/kmod.h>
 #define __NO_VERSION__
@@ -53,6 +54,11 @@
 
 extern int root_mountflags;
 
+#ifdef CONFIG_RAMFS_ROOT
+extern int ramfs_untar(char* start, char* end);
+extern int ramfs_check_root(void);
+#endif
+
 static int do_remount_sb(struct super_block *sb, int flags, char * data);
 
 /* this is initialized in init/main.c */
@@ -1470,10 +1476,31 @@
 	void *handle;
 	char path[64];
 	int path_start = -1;
+	void *data;
+	int using_ramfs = 1;
+
+#ifdef CONFIG_RAMFS_ROOT
+	if ((!ramfs_check_root()) && (ROOT_DEV != MKDEV(UNNAMED_MAJOR, 0xfe)))
+		goto skip_ramfs;
+	fs_type = get_fs_type("ramfs");
+	if (!fs_type)
+		goto no_ramfs;
+	ROOT_DEV = get_unnamed_dev();
+	if (!ROOT_DEV)
+		goto no_anon_ramfs;
+	sb = read_super(ROOT_DEV, NULL, fs_type, 0, initrd_start, 1);
+	if (sb)
+		goto mount_it;
+no_anon_ramfs:
+	put_filesystem(fs_type);
+no_ramfs:
+	panic(KERN_ERR "VFS: Unable to mount root ramfs.\n");
+skip_ramfs:
+	using_ramfs = 0;
+#endif
 
 #ifdef CONFIG_ROOT_NFS
-	void *data;
-	if (MAJOR(ROOT_DEV) != UNNAMED_MAJOR)
+	if (ROOT_DEV != MKDEV(UNNAMED_MAJOR, 0xff))
 		goto skip_nfs;
 	fs_type = get_fs_type("nfs");
 	if (!fs_type)
@@ -1613,6 +1640,10 @@
 		set_fs_pwd(current->fs, vfsmnt, sb->s_root);
 		if (bdev)
 			bdput(bdev); /* sb holds a reference */
+#ifdef CONFIG_RAMFS_ROOT
+	if (using_ramfs)
+		ramfs_untar((char*)initrd_start, (char*)initrd_end);
+#endif
 		return;
 	}
 	panic("VFS: add_vfsmnt failed for root fs");
@@ -1746,8 +1777,7 @@
 	goto out2;
 }
 
-
-#ifdef CONFIG_BLK_DEV_INITRD
+#if (defined(CONFIG_BLK_DEV_INITRD) || defined(CONFIG_RAMFS_ROOT))
 
 int __init change_root(kdev_t new_root_dev,const char *put_old)
 {
--- linux/Documentation/Configure.help.old	Sun Oct 29 14:56:42 2000
+++ linux/Documentation/Configure.help	Sun Oct 29 15:02:38 2000
@@ -10826,6 +10826,37 @@
   say M here and read Documentation/modules.txt. The module will be
   called ramfs.o.
 
+RAM-based root filesystem from tar archive
+CONFIG_RAMFS_ROOT
+  Allow the kernel to mount a ramfs namespace as the root filesystem
+  or as a pre-root filesystem for running a /linuxrc script (similar
+  to how initial RAM disk (initrd) support works.)
+
+  Since ramfs has no physical or virtual block device to provide its
+  data as an initrd image would, you must provide a standard tar format
+  archive to be extracted into the empty ramfs root filesystem. Currently
+  this tar archive may *not* be compressed (i.e., tar.gz style); if
+  compression is desired, use a bootloader with automatic gunzip support
+  such as GRUB.
+
+  To specify the tar archive used to build the root filesystem, use the
+  initrd=<filename> kernel command line option (except with a tar archive
+  instead of a real ext2/minix/romfs filesystem image.)
+
+  To mount the tar archive as the actual root filesystem, specify the
+  same initrd=<filename> option above and also include "root=/dev/ramfs"
+  in the kernel command line.
+
+  You may enable both this option and initrd support; however, if a
+  tar archive is detected instead of an initrd-supported filesystem
+  image, this option will override initrd support.
+
+  Note: Some versions of GNU tar create invalid archives that cannot
+  be extracted by the kernel. In particular, tar may add a file to an
+  archive without previously adding its containing directory. If your
+  ramfs archive does not mount correctly because of this, try creating
+  it in another way or with another file order.
+
 ISO 9660 CDROM file system support
 CONFIG_ISO9660_FS
   This is the standard file system used on CDROMs. It was previously
--- linux/CREDITS.old	Mon Oct 30 21:49:35 2000
+++ linux/CREDITS	Mon Oct 30 21:51:20 2000
@@ -2928,6 +2928,13 @@
 S: Alexandria, Virginia 22304
 S: USA
 
+N: Matt Yourst
+E: yourst@mit.edu
+D: ramfs root filesystem support
+S: 476 Memorial Drive
+S: Cambridge, MA 02139
+S: USA
+
 N: Niibe Yutaka
 E: gniibe@mri.co.jp
 D: PLIP driver

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2000-10-31  3:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-10-31  3:06 / on ramfs, possible? [yes! - patch included] Matt Yourst

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox