Posted by Thomas Thu, 10 Mar 2005 22:06:05 +0000
The goal of this project is to create a bootable cd that contains a kernel and initrd image that will load appropriate modules as to allow an external storage device (primarily, but not limited to, either Firewire or USB2) to be mounted as the root partition of a full Debian/GNU Linux distribution. In addition to this functionality, the bootable cd will retrieve a new kernel and initrd image from the external storage device and boot to that new kernel and initrd image using Kexec.
First we’ll install a bare Debian distribution onto the external drive. For my purposes, I will be doing this from an existing Debian machine. We’ll use the new Debian GNU/Linux Installation Guide and Installing Debian GNU/Linux from a Unix/Linux System as a reference.
Partition the external disk, using your favorite partitioner (e.g. fdisk
, et. al.). My disk is /dev/sdc
.
# fdisk /dev/sdc |
Format the partitions. My swap is /dev/sdc1
and my root is /dev/sdc2
.
# mkswap /dev/sdc1 # mkfs.xfs /dev/sdc2 |
Mount the new root (as root) on [prexisting] /mnt/sdc2
:
# sudo mount /dev/sdc2 /mnt/sdc2 |
Install deboostrap
(as root):
# sudo apt-get install deboostrap |
Run deboostrap
. I ran mine from the d-i image that I happened to already have burned to disc. Adapt to your own use. Check out directions here.
# sudo debootstrap --arch i386 sarge /mnt/sdc2/ file:/cdrw/debian |
Chroot
into the new base to finish up the job:
# sudo chroot /mnt/sdc2 /bin/bash |
You need to create /etc/fstab
.
# editor /etc/fstab |
Here is a sample you can modify to suit. I will assume that your linux guru self can edit the file appropriately.
Note that I have to change from /dev/sdc
to /dev/sda
. This change is due to the fact that I know that it will be /dev/sda
instead of /dev/sdc
as it is detected by the machine that I am installing from.
# /etc/fstab: static file system information. # # file system mount point type options dump pass /dev/sda1 none swap sw 0 0 /dev/sda2 / xfs defaults 0 1 proc /proc proc defaults 0 0 |
Mount /proc
.
# mount -t proc proc /proc |
Configure your keyboard:
# dpkg-reconfigure console-data |
Configure networking, edit /etc/network/interfaces
and /etc/hostname
.
# editor /etc/network/interfaces |
Here are some simple examples from /usr/share/doc/ifupdown/examples
:
###################################################################### # /etc/network/interfaces -- configuration file for ifup(8), ifdown(8) # See the interfaces(5) manpage for information on what options are # available. ###################################################################### # We always want the loopback interface. # auto lo iface lo inet loopback # To use dhcp: # auto eth0 iface eth0 inet dhcp # An example static IP setup: (broadcast and gateway are optional) # # auto eth0 # iface eth0 inet static # address 192.168.0.42 # network 192.168.0.0 # netmask 255.255.255.0 # broadcast 192.168.0.255 # gateway 192.168.0.1 |
Enter your system’s host name (2 to 63 characters):
# echo DebianHostName > /etc/hostname |
Set your timezone, add a normal user, and choose your apt
sources.
# /usr/sbin/base-config new |
Note: I had some trouble with the above command (/usr/sbin/base-config new
). For whatever reason, it just crapped out on me. I setup the timezone manually (tzconfig
), added my usual user (useradd
& passwd
), and used apt-cdrom
to setup my apt sources. Using apt-cdrom
made me use the following.
I have a certain way that I like my cdrom to be structured in my filesystem. I use /cdrom
as a link to /mnt/cdrom.
Create symlink for /dev/cdrom
. My actual cdrom is /dev/hdb
.
# ln -s /dev/hdb /dev/cdrom # mkdir /mnt/cdrom # ln -s /cdrom /mnt/cdrom # mount /mnt/cdrom # apt-cdrom add |
To configure your locale settings to use a language other than English, install the locales support package and configure it:
# apt-get install locales # dpkg-reconfigure locales |
NOTE: Apt must be configured before, ie. during the base-config phase. Before using locales with character sets other than ASCII or latin1, please consult the appropriate localization HOWTO.
If you intend to boot this system, you probably want a Linux kernel and a boot loader. Identify available pre-packaged kernels and install.
# apt-cache search kernel-image # apt-get install kernel-image-2.6.8-1-386 |
Normally, you might setup the boot loader here, but we don’t care, since we boot from cd.
Make sure that the config files in /etc/mkinitrd/
are setup correctly. Shown below are, respectively, /etc/mkinitrd/mkinitrd.conf
and /etc/mkinitrd/modules
.
# /etc/mkinitrd/mkinitrd.conf: # Configuration file for mkinitrd(8). See mkinitrd.conf(5). # # This file is meant to be parsed as a shell script. # What modules to install. MODULES=dep # The length (in seconds) of the startup delay during which linuxrc may be # interrupted. DELAY=10 # If this is set to probe mkinitrd will try to figure out what's needed to # mount the root file system. This is equivalent to the old PROBE=on setting. ROOT=/dev/sda2 # This controls the permission of the resulting initrd image. UMASK=022 # Command to generate the initrd image. MKIMAGE='mkcramfs %s %s > /dev/null' # Set this to yes if you want to use busybox(1). BUSYBOX=no # Set this to no if you want to disable /usr/share/initrd-tools/scripts. PKGSCRIPTS=yes |
# /etc/mkinitrd/modules: Kernel modules to load for initrd. # # This file should contain the names of kernel modules and their arguments # (if any) that are needed to mount the root file system, one per line. # Comments begin with a `#', and everything on the line after them are ignored. # # You must run mkinitrd(8) to effect this change. # # Examples: # # ext2 # wd io=0x300 # # for 1394/firewire ieee1394 ohci1394 sbp2 # # for usb usbcore ohci-hcd uhci-hcd usb-storage |
Next we need to create the bootable cd that contains our kexec kernel and initrd image. I created a working directory called firewire-debian-2.0/
to work in.
# mkdir firewire-debian-2.0 # cd firewire-debian-2.0 |
Download, compile, install tools. The lastest version of Kexec as of the writing of this document is version 1.101.
# wget http://www.xmission.com/~ebiederm/files/kexec/kexec-tools-1.101.tar.gz # tar zxvf kexec-tools-1.101.tar.gz # cd kexec-tools-1.101 # ./configure # make # sudo make install |
This installs kexec
and kdump
in /usr/local/bin
.
We’ll go ahead and create the necessary mkinitrd files for Debian’s mkinitrd. You would normally just edit the files that already exist in /etc/mkinitrd
, but since this is a special case of installing a kernel, we will leave those files alone so that next time we upgrade our kernel, we don’t get kernel panics.
# mkdir -p mkinitrd/scripts # cd mkinitrd |
Debian’s mkinitrd, for our purposes, will take a directory as an argument. This directory has several config files in it, exe
, mkinitrd.conf
, and modules
. Respectively, shown below are the contents of my files:
/usr/local/sbin/kexec |
# mkinitrd/mkinitrd.conf: # Configuration file for mkinitrd(8). See mkinitrd.conf(5). # # This file is meant to be parsed as a shell script. # What modules to install. MODULES=dep # The length (in seconds) of the startup delay during which linuxrc may be # interrupted. DELAY=10 # If this is set to probe mkinitrd will try to figure out what's needed to # mount the root file system. This is equivalent to the old PROBE=on setting. ROOT=/dev/sda2 # This controls the permission of the resulting initrd image. UMASK=022 # Command to generate the initrd image. MKIMAGE='mkcramfs %s %s > /dev/null' # Set this to yes if you want to use busybox(1). BUSYBOX=no # Set this to no if you want to disable /usr/share/initrd-tools/scripts. PKGSCRIPTS=yes |
# mkinitrd/modules: Kernel modules to load for initrd. # # This file should contain the names of kernel modules and their arguments # (if any) that are needed to mount the root file system, one per line. # Comments begin with a `#', and everything on the line after them are ignored. # # You must run mkinitrd(8) to effect this change. # # Examples: # # ext2 # wd io=0x300 # # for 1394/firewire ieee1394 ohci1394 sbp2 # # for usb usbcore ohci-hcd uhci-hcd usb-storage |
The standard /usr/share/initrd-tools/init
file must be edited to reflect the new usage of Kexec. The diff is shown below:
*** /tmp/init Sat Oct 2 13:35:43 2004 --- /usr/share/initrd-tools/init Fri Aug 27 13:43:34 2004 *************** *** 416,427 **** mount_root cd mnt [ $DEVFS ] && mount -nt devfs devfs dev - # must mount proc for kexec - mount -nt proc proc /proc - kexec -l --append="$cmdline" --initrd=initrd.img vmlinuz - #kexec -l --append="$cmdline" --initrd=initrd.img.old vmlinuz.old - kexec -e - umount -n /proc pivot_root . initrd fi if ! [ -x ${init#/} ]; then --- 416,421 ---- |
I will be using version 2.6.10-mm2 of the Linux kernel. Download 2.6.10 tarball and mm2 patch. Package kernel. I prefer to do this all as root.
# sudo su |
Download all the files.
# cd /usr/src # wget http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.10.tar.bz2 # wget http://kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.10/2.6.10-mm2/2.6.10-mm2.bz2 |
Untar and/or unzip the files.
# tar jvf linux-2.6.10.tar.bz2 # tar zxvf 2.6.10-mm2-kexec3.tgz |
Cautiosly remove linux symlink. Rename the stock 2.6.10 directory to reflect the changes. Replace symlink. Patch the stock 2.6.10 kernel with the mm2 patch.
# rm linux # mv linux-2.6.10 linux-2.6.10-mm2 # ln -s linux-2.6.10-mm2 linux # cd linux # cat ../2.6.10-mm2 | patch -p1 |
Configure the kernel. I prefer menuconfig
.
# make menuconfig |
Here is a copy of my .config file
I use a script to make my kernels for me. This script handles [first time setup of] distcc
, appends the date to the kernel, and times how long it takes.
#!/bin/bash MAKE_KPKG=/usr/bin/make-kpkg KERNEL_DIR=/usr/src/linux CONFIG_TYPE=oldconfig export CONCURRENCY_LEVEL=8 export DISTCC_HOSTS='localhost ezekiel' # make sure /root/bin instead of ~/bin export PATH="/root/bin:$PATH" # Assume that symlinks to distcc are already in place # ln -s /usr/bin/distcc ~/bin/cc # ln -s /usr/bin/distcc ~/bin/gcc # ln -s /usr/bin/distcc ~/bin/c++ # ln -s /usr/bin/distcc ~/bin/g++ # Assume that /usr/src/linux symlink is already in place cd $KERNEL_DIR # Make everything $MAKE_KPKG clean time $MAKE_KPKG --append-to-version=.`date +%m%d%y` \ --config=$CONFIG_TYPE kernel_image modules_image |
After the kernel-image package has been compiled, move it to your firewire-debian-2.0/
working directory.
# cd /usr/src/linux # mv kernel-image-2.6.10-mm2.031005_10.00.Custom_i386.deb ~/firewire-debian-2.0 |
I use this Makefile to create the appropriate initrd image and iso for the cd. Be sure that you use tabs in the appropriate places!
KERNEL_VERSION=2.6.10-mm2.031005 KERNEL_IMAGE_DEB=kernel-image-2.6.10-mm2.031005_10.00.Custom_i386.deb ISO=cd_image.iso CDRW_DEV=/dev/hdb all: clean clean_tmp initrd iso clean_tmp iso initrd: # create directorires mkdir -p master/isolinux # create initrd image from debian kernel-image package dpkg -x ${KERNEL_IMAGE_DEB} . cp boot/config-${KERNEL_VERSION} master/isolinux/config gzip -f master/isolinux/config cp boot/System.map-${KERNEL_VERSION} master/isolinux/sys_map gzip -f master/isolinux/sys_map cp boot/vmlinuz-${KERNEL_VERSION} master/isolinux/vmlinuz # try to get around mkinitrd's inability to specify a modules directory sudo mv lib/modules/${KERNEL_VERSION} /lib/modules/ sudo chown -R root.root /lib/modules/${KERNEL_VERSION} # make first initrd to boot to /vmlinuz (and /intird) sudo vim /usr/share/initrd-tools/init sudo mkinitrd -d mkinitrd/ -o miniroot ${KERNEL_VERSION} # move to cd mv -f miniroot master/isolinux/miniroot sudo chown tlg1466.tlg1466 master/isolinux/miniroot # make second initrd to boot to /vmlinuz.old (and /initrd.old) sudo vim /usr/share/initrd-tools/init sudo mkinitrd -d mkinitrd/ -o miniroot ${KERNEL_VERSION} # move to cd mv -f miniroot master/isolinux/miniroo2 sudo chown tlg1466.tlg1466 master/isolinux/miniroo2 # clean up sudo rm -rf /lib/modules/${KERNEL_VERSION} iso: ./bin/mkiso ${ISO} burn: /usr/bin/cdrecord -v -pad -overburn -eject -tao speed=48 gracetime=2 \ dev=${CDRW_DEV} driveropts=burnproof fs=400x53k ${ISO} clean: rm -f ${ISO} clean_tmp: # remove tmp directories rm -rf boot/ lib/ usr/ rm -f miniroot sudo rm -rf /lib/modules/${KERNEL_VERSION} |
I use this script to actually make the iso. Place it in a directory called bin.
#!/bin/sh # helper script, because makefiles are stupid # argument is output cd iso filename cd master /usr/bin/mkisofs -R -o ../$1 -b isolinux/isolinux.bin -c isolinux/boot.cat \ -no-emul-boot -boot-load-size 4 -boot-info-table . |
You also must copy the isolinux.bin file to the master/isolinux/ directory.
# cp /usr/lib/syslinux/isolinux.bin master/isolinux/ |
AND, you also create a isolinux.cfg file in the master/isolinux/ directory. My file is below:
FONT font.psf # see /usr/doc/syslinux/syslinux.doc.gz for file format description DEFAULT linux APPEND vga=normal load_ramdisk=1 ramdisk_size=4096 TIMEOUT 0 #DISPLAY debian.txt PROMPT 1 LABEL linux KERNEL vmlinuz APPEND initrd=miniroot root=/dev/ram0 LABEL linux.old KERNEL vmlinuz APPEND initrd=miniroo2 root=/dev/ram0 |
Now, you can finally run make
to create the iso and make burn
to burn it to disc.
# make # make burn |
Hopefully, now you have a bootable iso. I know that these instructions are quite terse, and there are bound to be things that I left out, but hopefully they give somebody who wants to try and replicate this project can do it. It might take some work, but hopefully they can fill in the details from the big picture.
Here are a bunch of links that I guarantee are relevant, but maybe not obviously…
kexec
Current kexec files
Original kexec files
Reboot Linux faster using kexec
Booting Linux from a Firewire Drive
HowTo: Boot Yellow Dog Linux From a External FireWire Disk.
Boot Linux from a FireWire device
Installing Debian
Installing Debian – Juerd’s site
Debian GNU/Linux Installation Guide
Debian — Debian-Installer
Building initrd images
The Linux Bootdisk HOWTO
ELJOnline: Brian Writes about His BOEL (Part 1)
Build the initrd image
Appendix A – Creating initrd.img file
Jason’s postings and stuff – Creating an initrd image on Debian GNU/Linux
[...] , but not so much for Intel-type products. You can check out my preliminary documentation here. It could use some polishing, and it may be quite wordy, but, hey, all the info is there. If you r [...]