Re: Patch to support initrd with dynamic ramdisks.

G.W. Wettstein (greg@wind.enjellic.com)
Fri, 6 Dec 1996 12:55:41 +0000


Good morning again to everyone on the list. From the responses I
received to my first post I should probably stick with cross-country
skiing and give up the computers.... :-) Some more comments on the
initrd matter follow.

> From tytso@MIT.EDU Thu Dec 5 19:40:01 1996

> Just to give credit where credit is due, the dynamic and compressed
> ramdisk support was done by Chad Page and myself. Chad did the initial
> implementation, and I then cleaned it up (and modularized the
> decompression code so it was shared by the ramdisk and kernel loader
> routines), and submitted it to Linus.
>
> Paul Gortmaker wrote the documentation in the Documentation subtree,
> which is very important, and deserving of credit. However, the real
> kudus for the actual work on the dynamic compressed ramdisk needs to go
> to Chad Page.
>
> - Ted

First my profuse apologies to Chad, if you're listening in on this I
didn't mean to slight your contributions to the kernel. When Ted
brought this to my attention I immediately rememberd the discussions
on the list when the ramdisk changes were proposed. I erred by taking
the name from the documentation (which I read numerous times). After
20 years in the computer business I should have known that the
programmer would probably be the last person to write the
documentation... :-)

Also my apologies to Ted for slighting his contributions which were
significant. In any event suffice it to say that I find all the
functionality very useful regardless of its origin.

>From lermen@elserv.ffm.fgan.de Thu Dec 5 19:40:01 1996

>> As I was developing our starter disk system last week I ran into what
>> appears to be some inconsistencies between the initrd code and the
> ^^^^^^^^^^^^^^^^^^^
>> dynamic ramdisk code.
>
>Don't think so, see below.

>Well, AFAIK the docs are ok (hey, Werner writes excellent docs;-),
>but there are two different ones
>
> Documentation/ramdisk.txt (Paul Gortmaker)
> Documentation/initrd.txt (Werner Almesberger, and a bit from me)
>
>which should not be mixed together in relation to the goal.

This was probably where some of the confusion came from. I read both
pieces of documentation at length and tried to deduce functionality by
filling in the blanks which were left after reading both sets of
documentation. I didn't mentally differentiate that the ramdisk code
should be thought of as something completely separate from the initrd
code. I should probably write some clarifying documentation based on
my experiences.

>Ok Greg, let me try (with my german style English) to explain _for what_
>initrd was intended to be used. Given that ...
>
> A) You have many ramdisk devices (/dev/ramX).
>
> B) You want to load them with valuable stuff, e.g a disk image
>
> C) You want to do something _before_ you mount the final root FS.
>
>... then for B you can _either_ use 'load_ramdisk=1' (part of the ramdisk
>code of A) _or_ you use initrd. It was _not_ intended to use both.
>With initrd you also can realize C.

The problem that I ran into was that I was trying to realize
objectives B and C simultaneously. I was working on developing a
starter disk system which fulfills three objectives:

1.) Kernel and root file system fits on a single diskette.
With the standard libc and even a small utility set a
single floppy setup is impossible without using a
compressed ramdisk setup.

2.) The ability to setup a starter system on hard disk and
than change to this starter system and continue
installation without reboot.

3.) The ability to boot from a floppy, repair or modify a
root filesystem on a hard-disk partition and than
mount and continue execution on the repaired partition.

My overall goal was to be able to use a compressed ramdisk and gain
the functionality of linuxrc without either using loadlin or lilo.

This is probably possible without my proposed kernel modifications but
it would seem that the rdev utility may need to be given extra
functionality. I noted this when I was studying the kernel sources
but didn't have time to figure that end of the equation out.

>From kernel sources: $srcroot/linux/arch/i386/kernel/setup.c:

#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
#define KERNEL_START (*(unsigned long *) (PARAM+0x214))
#define INITRD_START (*(unsigned long *) (PARAM+0x218))
#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
#ifdef CONFIG_BLK_DEV_INITRD

...

if (LOADER_TYPE) {
initrd_start = INITRD_START;
initrd_end = INITRD_START+INITRD_SIZE;
if (initrd_end > memory_end) {
printk("initrd extends beyond end of memory "
"(0x%08lx > 0x%08lx)\ndisabling initrd\n",
initrd_end,memory_end);
initrd_start = 0;
}
}

My assumption was that the stock compressed ramdisk code could be
given initrd functionality if the appropriate information could be
written into the kernel parameter block. I putzed around with this
for awhile and even looked at the lilo sources but didn't have any
time to figure out exactly what I needed to write into these
locations. Other than the fact that LOADER_TYPE had to be
non-zero.. :-)

After looking at the code in $srcroot/linux/init/main.c it seemed that
my modifications would produce the linuxrc behavior to a simple
compressed ramdisk with fairly simplistic modifications. Since both
portions of the patch were wrapped by CONFIG_BLK_DEV_INITRD I felt
fairly confident that standard ramdisk support would not be threatened
by these modifications.

>However, the initrd stuff _uses_ the ramdisk code internally, so you
>always have to configure both into the kernel, if you want initrd
>support.
>
>In detail you have the following possibilities to load a ramdisk:
>
> 1. Do it as described in Documentation/ramdisk.txt in order to load a
> ramdisk image from a floppy that gets mounted as root FS.
> (NOTE: only from a floppy).

This was what I was attempting to do AND gain the linuxrc behavior.

> 2. Use Loadlin to load it (via the initrd code) from any DOS accessible
> medium (harddisk, floppy, CDrom, network, flashram-card, e.t.c).
> For this you have to specify
>
> loadlin ... root=/dev/ram initrd=<DOSfilename>
> ^^^^^^^^
> You then have in principal the same as with (1), but you are not
> restricted on the floppy. For (2) /linuxrc will _not_ be executed.
> ( This feature also works with LILO, but it doesn't make much
> sense )

I haven't had any DOS based stuff on my Linux workstations for at
least 3-4 years... :-) In fact I was a little embarrassed the other
day when I was working on some cross-platform stuff and had to ask one
of the users how to configure some stuff under Windoze 95.

> 3. Use the initrd stuff for its _real_ purpose and let /linuxrc load
> and/or mount what ever you want. For this you have to define
>
> ... root=<_not_ /dev/ram> initrd=<filename>
> ^^^^^
> And (important), the final goal is not what the _initrd code_ does ,
> but what _your /linuxrc_ does. ( I'll give some examples
> below. )

One of my major goals was to get at the /linuxrc behavior. My old
starter systems which were based on a single bootable/rootable floppy
used LILO and required a reboot in between. I was trying to use a
compressed root filesystem, not use LILO and avoid a reboot between
the hard-disk setup and the completion of installation.

>Here are some examples what initrd can be used for:

>3. A general purpose starter disk (as you seem to need, Greg)
> ---------------------------------------------------------
>
> - Make _one_ ext2 FS floppy, copy the zImage, the LILO-files and the
> initrd.gz image onto it. The initrd.gz also must contain all needed
> modules and of course /linuxrc.
>
> - Install LILO on the floppy.
>
> - When /linuxrc gets started it asks (or probes) for the modules needed,
> loads them, set the final root device, ...

This is what the patch basically accomplishes without needing LILO to
be installed on the floppy. The mistake that I made was in not
realizing that the floppy had to have a filesystem written to it and
everything else installed within the context of this filesystem. I
was trying to accomplish the same thing in a somewhat more simplistic
fashion.

>As you see, there is no need to use initrd in conjunction with the normal
>load_ramdisk type stuff. If you realy need it, well, let /linuxrc load
>as many ramdisks as you want. This is much more flexible and doesn't need
>any kernel patch. BTW, I 'suspect' your patch may break the current behave
>of initrd (when to mount, when to keep /dev/initrd, when to just load).

I would still argue that my patch has a role for those individuals who
want the linuxrc behavior without the need to lay a filesystem on the
floppy, install LILO on the floppy and make LILO boot the floppy.
With the kernel patch installed one can get the linuxrc functionality
by simply requesting initrd when the kernel is compiled.

I did worry about breaking initrd semantics when I made the
modifications. I tried to verify the functioning of the patch with
respect to the proscribed behavior in the initrd documentation. I
believe that my patch retains the following characteristics:

1.) If no linuxrc is found the root filesystem that gets
loaded as the ramdisk remains mounted as root and
standard startup is performed.

2.) If a linuxrc is found it is executed before the final
disposition of root is selected. If no change (via
/proc/sys/kernel/real-root-dev) is specified the ramdisk
based filesystem is used as root.

If an alternate root is selected by writing to the
proc pseudo-file the change_root function called after
linuxrc termination will pick this up and specified
device will be used as the new root.

3.) If an alternate root is specified the final disposition
of the filesystem loaded into the ramdisk is determined
by the presence or absence of a /initrd directory on
the destination filesystem. If this directory is present
the ramdisk based filesystem will get transferred to this
directory. If not it vanishes.

The only thing that I haven't verified is whether or not
the ramdisk actually vanished. I suspect that it is
still hanging around in the buffer cache. If it is still
hanging around I suspect that using a flushb on the
/dev/ram device will finish it off.

The behavior that is essentially emulated is the same as would occur
if root=/dev/ram is specified via LILO. My assumption was that if a
kernel was generated with ramdisk and initrd support AND the user was
booting and loading a compressed ramdisk as root AND if the /linuxrc
script was present then the user would be justified in getting
/linuxrc semantics at boot time.

There is probably lots of room for philosophical debate on this
points. My believe is that the patch provides a reasonably simplistic
mechanism for obtaining linuxrc behavior under a given set of
controlled circumstances.

As mentioned previously I would suspect that the same behavior could
be obtained by loading a compressed ramdisk from floppy with a kernel
which has had its control block suitably modified. At the time the
patch was the fastest way of getting the behavior that I wanted.

>> working out this problem and it would appear that the initrd code
>> still has some major assumptions that the ramdisk will be allocated as
>> a fixed memory segment. A more complete solution to the problem that
> ^^^^^^^^^^^^
>This isn't correct. The boot-loader just temporary loads the image into
>_some_ location above the kernel and notifies the kernel _where_ the image
>is. ( Note: this is a param in the setup.S header that the loader sets )
>The kernel marks these pages as used, the initrd driver code makes a
>device out of it (/dev/initrd, major=1,minor=250) and uses the ramdisk
>code to load from that device into /dev/ram. Once /dev/initrd gets closed
>it destroyes itself and frees the memory.
>( Note: opening /dev/initrd is a 'one shot' )

I will apologize for not understanding the initrd driver code more
thoroughly.

>Hope this has clarified understanding.

Hans' note did clear up a lot of confusion on my part. Hopefully
everyone else reading along at home was entertained as well by this
discussion.

I am ambivalent as to what happens with the patch. I do feel that it
adds useful behavior for those who may be seeking it. Whether it gets
into the kernel probably depends on whether or not anyone else would
find this behavior to be useful.

As usual I have probably stumbled on aimlessly far longer than anyone
is interested in reading. My golden retriever is looking at me rather
mournfully so its probably time for our daily cross-country ski.

A pleasant weekend wish for everyone on the list.

Greg

As always,
Dr. G.W. Wettstein Velocity, LLC - Specialists in leveraging
4206 N. 19th Ave. inter-networking technology for enterprise groups.
Fargo, ND 58102
Phone: 701-281-1686 INTERNET: greg@wind.enjellic.com
------------------------------------------------------------------------------
"God made man, the appendix was the result of a committee."
-- Dr. G.W. Wettstein
Guerrilla Tactics for Corporate Survival