On 12 Oct 2006, Christopher Marshall told this:
> The other thing you can try is to make a simple initrd file with some
> busybox commands in it, enough to give you the ash shell and some
> commands like mount, pivot_root, chroot, so you can try to mount the
> root filesystem yourself then pivot_root and chroot into it.

As an aside, initrd is obsolete and rather annoying to construct. If
I were you I'd use an initramfs instead, which is utterly trivial to
build (modulo the usual annoyances getting the tools together) and
can't *ever* get out of synch with the kernel because they're built
at the same time.

(It seems likely that a large part of the boot process will move
obligatorily into an initramfs quite soon. Nobody is likely to notice
unless they're watching the kernel build closely. That's how transparent
it is to users.)


Rough procedure for an uClibc/busybox-based initrd:

 - make a cross-compiler and cross-assembler for uClibc. (The uClibc
   site has patches to GCC and binutils to add a *-pc-linux-uclibc
   target.)
 - make uClibc from CVS
 - make busybox, 1.2 or later
 - write a file usr/initramfs in the kernel tree, containing a list
   of files to include in the initramfs, viz

,----
| file /init usr/init 0755 0 0
| dir /bin 0755 0 0
| file /bin/busybox /usr/i686-pc-linux-uclibc/bin/busybox 0755 0 0
| slink /bin/sh /bin/busybox 0755 0 0
| slink /bin/ash /bin/busybox 0755 0 0
[...]
| # supporting directories
| dir /proc 0755 0 0
| dir /sys 0755 0 0
| dir /new-root 0755 0 0
| dir /etc 0755 0 0
[...]
| # initial device files required (mdev creates the rest)
| dir /dev 0755 0 0
| nod /dev/console 0600 0 0 c 5 1
| nod /dev/null 0666 0 0 c 1 3
`----

Make a shell script usr/init (what whever you like: you can name it anything
and rename it to /init with the usr/initramfs file, which you can *also*
name whatever you want). This script gets passed *all* parameters that the
kernel was passed (except for a few which it parses itself) and can do
whatever it likes with them. e.g. the start of mine:

,----
| export PATH=/sbin:/bin
| 
| /bin/mount -t proc proc /proc
| /bin/mount -t sysfs sysfs /sys
| CMDLINE=`cat /proc/cmdline`
| 
| # Populate /dev from /sys
| 
| /bin/mount -t tmpfs tmpfs /dev
| /sbin/mdev -s
| 
| # Locate the root filesystem's fstab entry; collapse spaces and tabs in it:
| # extract its significant components. (There are three raw tabs in the next
| # line.)
| 
| FSENT=`sed -n '/[     ]\/[    ]/ { s,[        ][      ]*, ,g; p; }' < 
/etc/fstab`
| ROOT="`echo $FSENT | tr ' ' '\n' | sed -n '1p'`"
| TYPE="`echo $FSENT | tr ' ' '\n' | sed -n '3p'`"
| OPTS="`echo $FSENT | tr ' ' '\n' | sed -n '4p'`"
| 
| # Parse arguments, engaging trace mode or dropping to rescue or emergency 
shells
| # as needed. If there is a forced init program, root filesystem, root fs type 
or
| # root fs options, accept the forcing.
| 
| INIT_ARGS=
| 
| for param in $CMDLINE; do
|     case "$param" in
|         init=*) eval "$param";;
|       -b|single|s|S|[1-5]) INIT_ARGS="$INIT_ARGS $param";;
|         trace) echo "Tracing init script.";
|                set -x;;
|         rescue) echo "Rescue boot mode: invoking ash.";
|                 init=/bin/ash;
|                 INIT_ARGS="-";;
|         emergency) echo "Emergency boot mode. Dropping to a minimal shell.";
|                    echo "Reboot with Ctrl-Alt-Delete.";
|                    exec /bin/sh;;
|         root=LABEL=*) ROOT=$(echo $1 | cut -d= -f3-);;
|         root-type=*) TYPE=$(echo $1 | cut -d= -f2-);;
|         root-options=*) OPTS=$(echo $1 | cut -d= -f2-);;
|     esac
| done
`----

The last thing it does (after finding the root filesystem, of course)
should be to unmount everything but / and the newly mounted root, and
switch_root into it:

,----
| if [ -z "$init" ]; then
|     init=/sbin/init
| fi
| 
| # Unmount everything and switch root filesystems for good:
| # exec the real init and begin the real boot process.
| /bin/umount -l /proc
| /bin/umount -l /sys
| /bin/umount -l /dev
| 
| echo "Switching to /new-root and running '$init'"
| exec switch_root /new-root $init $INIT_ARGS
`----

(switch_root is a tool in busybox that recursively deletes everything on
the same filesystem as /, as initramfses are nonswappable and anything
left there will eat memory forever. Then it chroots to the new
filesystem and exec's init. --- so look out, you'd better make sure you
still have PID 1 at that point...

The filesystem will be auto-built and gzipped into the kernel image at
kernel build time. As of 2.6.18, any C code mentioned in the initramfs
source file will also be compiled for you!


The last part in particular is *vastly* less fiddly than switching to
the real root filesystem with an initrd, which has about three possible
conflicting methods none of which work terribly well in my experience :(

-- 
`When we are born we have plenty of Hydrogen but as we age our
 Hydrogen pool becomes depleted.'

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
User-mode-linux-user mailing list
User-mode-linux-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-user

Reply via email to