>
>
>Richard Fish <[EMAIL PROTECTED]> writes:
>
>>> carcharias root # cat /boot/grub/grub.conf
>>> default 0
>>> timeout 5
>>> splashimage=(hd0,0)/grub/splash.xpm.gz
>>>
>>> title Linux
>>> kernel (hd0,0)/vmlinuz-2.6 root=/dev/sys/root
>>> video=radeonfb:[EMAIL PROTECTED] noapic quiet
>>> initrd (hd0,0)/initrd-2.6
>>>
>>> title Safe
>>> kernel (hd0,0)/vmlinuz-safe root=/dev/system/root
>>> video=radeonfb:[EMAIL PROTECTED] noapic 1
>>> initrd (hd0,0)/initrd-safe
>>
>
>As an aside [ I don't want to change thread subject here ]
> I don't understand what your setup is doing or what some of the
> appended stuff is.
>
Well, my setup is pretty custom (that's why I love Gentoo!). But it
might be educational for the curious or new users...
So, I will explain what happens on my system from grub-to-init. Since
my system uses software RAID0, loop-AES encryption (including the root
filesystem), swsusp2, and possibly boot-splash, it is fairly complex.
Most setups will be far simpler, but maybe this will give you some ideas
for customizing your startup
First for 'title Linux'. The 'noapic' and 'quiet' options are standard
kernel options (see Documentation/kernel-parameters.txt in the kernel
sources). I require noapic for software suspend to work correctly, and
quiet because I don't need to see all of the kernel verbosity during
boot. The video option you can probably guess...it is for setting up
the framebuffer on my Mobility Radeon 9700.
The root= option is the equivalent of your 'real_root' option. It is
interpreted by the initrd scripts, and ignored by the kernel. I use
LVM, so I have a volume group named 'sys' with a logical volume named
'root', hence the device path /dev/sys/root. I also have /dev/sys/home,
/dev/sys/tmp, /dev/sys/var, /dev/sys/swap, /dev/external/backups, etc.
The 'title Safe' group is essentially the same, just using a backup (and
hopefully working!) copy of my kernel and initrd. Since it is 'Safe'
mode, I want as much verbosity as possible, so no 'quiet' option here.
Oh, I just noticed that I still have my old volume group name 'system'
there...oops. It doesn't matter though...keep reading.
Like any linux system, the kernel boots and any device drivers built
into the kernel get initialized and start controlling their hardware.
All of the drivers I need to boot are built into my kernel, except for
the loop-AES encryption module. When you use an initrd, the kernel
extracts that to ram, mounts it (hopefully, assuming your didn't compile
your initrd filesystem driver as a module!) and executes /linuxrc
there. Although it could be a binary, it is almost always a shell
script, so the shell and any required libraries must be present in the
initrd.
My system using software raid0 on partitions /dev/hda2 and /dev/hdd2,
which have type 'fd' (Linux Raid autodetect) and persistent superblocks,
so the kernel finds and starts my RAID setup automatically.
This is where things get complex. On top of the RAID0 array, I use
loop-AES for encryption. (/dev/loop/0). THAT in turn is my physical
volume for the LVM setup. The problem with this is that the memory used
by my initrd is *never* freed by the system, because two device nodes
(/dev/md0, /dev/loop/0) get locked by the initrd sequence. So I have
stripped my initrd down as much as reasonably possible, and it now fits
in 2M of memory (with 1G of ram, I don't miss the 2M...really. ;->)
Note that 2M is the uncompressed size.
To do this, I moved most of the programs and libraries that would
normally reside in initrd to /boot, and use /boot as a miniature root
filesystem to get the encryption and LVM drivers up and running.
So, the /linuxrc script in my initrd is very short, it basically just
mounts /proc, /sys, and /boot and punts to /boot/linuxrc. I added some
comments for this message:
----------------------------------------------------------------------
carcharias root # cat /initrd/linuxrc
#!/bin/ash
# Using ash to make initrd a bit smaller, since
# this memory will never be freed due to the loop-AES
# setup.
export PATH=/bin:/boot/bin
export LD_LIBRARY_PATH=/boot/lib
# must have these to do anything with the system
mount -n -t proc /proc /proc
mount -n -t sysfs /sys /sys
# mount mini-root (/boot) read-only. There is a chance
# of corrupting the filesystem when we resume from a
# suspend cycle if it is mounted read-write, so better
# to be safe.
mount -n -t xfs /dev/hda1 -o ro /boot
# Punt...
/boot/linuxrc /dev/sys/root
----------------------------------------------------------------------
Notice that /boot/linuxrc is given the name of the real root device, in
this case hard-coded to /dev/sys/root. The root= parameter on my kernel
command line is completely ignored.
The /boot/linuxrc script is fairly long, but in the interests of
education, I have included it and added some comments
----------------------------------------------------------------------
carcharias root # cat /boot/linuxrc
#!/boot/bin/bash
rootdev="$1" # root device passed on command line
# uname -r looks up the current kernel version. I have a build script
# so that every time I rebuild the kernel, I also rebuild the loop-AES
# module and copy it to the correct location under /boot
# The lo_prealloc option adds some buffering for the loop/0 device.
insmod /boot/lib/modules/`uname -r`/block/loop.ko lo_prealloc=128,0,256
# I switch back and forth between boot-splash and radeonfb. Boot-splash
# only works with the vesafb driver, but the radeonfb driver is faster
# and gives me a higher resolution.
# This next section determines whether bootsplash is being used or not,
# because I need a text window for the password prompt below
silentmode=""
if test -f /proc/splash; then
grep ", silent" < /proc/splash >/dev/null
test $? -eq 0 && silentmode="silent"
fi
# If bootsplash is used in silent mode, put it into
# verbose mode to get a text prompt
test -n "$silentmode" && echo "verbose" >/proc/splash
clear # clears the display...
# A nice, polite banner...
# No contact info...I don't need the person who steals my laptop to call
# me for the password.
echo
"**********************************************************************"
echo "*** This computer is the private property of Richard Fish
***"
echo
"**********************************************************************"
echo ""
loopdone=0
while test $loopdone -ne 1; do
# and a password prompt. I could have losetup/gpg ask for the
password directly,
# but one configuration I used had /dev/hda2 and /dev/hdd2 as
separate loop
# volumes, that were then LVM physical volumes and stiped by LVM.
So to avoid
# having to enter my password twice on bootup, I decided to have the
script read
# the password, then I found that I liked this setup better.
read -s -p "Password: " passwd
echo "" # so that any errors appear in 1st column
# ...um...man gpg.
echo "$passwd" | gpg --quiet --batch --homedir=/ \
--no-tty --passphrase-fd 0 -d /boot/systemkey.gpg 2>/dev/null \
| losetup -p0 -e AES128 /dev/loop0 /dev/md0 >/dev/null 2>&1
# Note that my losetup command is patched by the loop-AES distribution.
# Normal losetup doesn't have the -p or -e options.
loopdone=1 # optimistic...
# test that loop is setup
losetup -a | grep "/dev/md0" >/dev/null
test $? -ne 0 && loopdone=0
if test $loopdone -eq 0; then
# cleanup for next attempt
losetup -d /dev/loop0 >/dev/null 2>&1
echo
"**********************************************************************"
echo "*** ENCRYPTION SETUP FAILED...INVALID
PASSWORD? ***"
echo
"**********************************************************************"
echo ""
fi
done
# Now to restore the nice bootsplash screen, if any
test -n "$silentmode" && echo "silent" >/proc/splash
# From here, things get normal...scan for LVM volumes,
# activate them, etc etc.
echo "Scanning logical volumes"
vgscan
echo "Activating logical volumes"
vgchange -a y sys
# My swap is on an LVM volume that is encrypted with loop-AES,
# so suspending does not leak any keys to unencrypted parts of
# the disk. But that means I have to setup the suspend
# device manually, which is what I do here.
if test -f /proc/software_suspend/resume2; then
# With LVM, /dev/sys/swap is really a symbolic link to /dev/mapper/sys-swap.
# But I can never remember if test -b works with symbolic links or not, so
# I use the real block device node below.
if test -b /dev/mapper/sys-swap; then
devnum=`stat -L --format="0x%.2t%.2T" /dev/mapper/sys-swap`
printf "0x%x\n" "$devnum" >/proc/software_suspend/resume2
else
printf "CANNOT SET SWSUSP RESUME DEVICE:"
printf "missing /dev/mapper/sys-swap\n"
fi
fi
# Here is where the kernel gets notified about the
# real root device.
devnum=`stat -L --format="0x%.2t%.2T" $rootdev`
devnum=`printf "%d" "$devnum"`
echo "$devnum" >/proc/sys/kernel/real-root-dev
----------------------------------------------------------------------
>From here, the system returns back to the /linuxrc script in the initrd,
which has just two things left to do: unmount /boot and tell swsusp2
that it should try to resume now. If there is no resume image in swap,
the script just keeps executing
----------------------------------------------------------------------
umount /boot
if test -f /proc/software_suspend/do_resume; then
echo > /proc/software_suspend/do_resume
fi
umount /sys
umount /proc
----------------------------------------------------------------------
That's it. Assuming we didn't resume, the kernel next mounts the root
filesystem, runs /sbin/init, and the system boots normally.
There are a few things that I will fix up when I get around to them.
The /boot/linuxrc should really look at the kernel command line for the
root volume, so I could theoretically change it at boot time. I could
also add a parameter for which /boot/linuxrc script to run, so I could
have /boot/linuxrc-safe, for example.
Comments and questions are welcome.
-Richard
--
[email protected] mailing list