DSL Tips and Tricks :: How-to: PXE - Packing the KNOPPIX image in initrd

There is a very interesting site http://www.damnsmalllinux.org/talk/node/248 that discusses booting DSL over PXE. The author of the mentioned site, had the rather ingenious idea of loading the whole dsl distro into the initrd, eliminating the need for an nfs server and continued internet access. The problem is: all the files on his ftp are for DSL 1.5.  At the time of this writing, the lastest version is 3.0.1.  After studying Mattias' files, I have come up with this method for converting the latest version of DSL to boot over PXE from initrd.  Hopefully, this will be useful to others in the future for future versions of PXE.  I document this method also for my own benefit :).

Booting DSL over PXE with the KNOPPIX image
embedded in the initrd.

0. Background: (What is PXE? Setting up a server?)

If you already know this kind of stuff, skip down to step 1.

A good tutorial to set up a server is here:PXE tutorial.  But you don't have to do everything it says there.  So read what i have to say first unless you know what you're doing already. Also, take a look at the links referenced in the beginning of that article.  They are very good.  

PXE stands for Preboot eXecution Environment.  The idea is to load the operating system via a network PXE server instead of a hard drive.  Basically, when you turn on the computer, it goes through its POST normally.  But when it comes time to actually boot an operating system, the computer loads a very limited set of tools from ROM located on the ethernet card.  

Then the computer sends a DHCP request to the network to get an IP address.  (So you need a dhcp server).  The DHCP server assigns an ip address and also sends a location where the operating system can be found (on a tftp server).  Sadly, the DHCP servers on most routers are not capable of sending this tftp server location.  Therefore, you will probably have to disable the DHCP server on your router (if you are using one) and run one on another computer on the network.  Wireless should be able to work correctly even if the DHCP server on the router is turned off.  It is possible to run a tftp server and a dhcp server on the same computer.  For my implementation, i used a PXE bootloader called pxelinux, so the file that I told the computer to download via tftp was called pxelinux.0.  Here is a clip from my dhcpd.conf

Code Sample
host tablet {
       hardware ethernet ************; //MAC address of pxe booting computer
       fixed-address;   //ip of pxe booting computer
       option host-name "tablet";
       filename "pxelinux.0";           //file should be in the tftp root dir
       next-server;       //this can be the same as the dhcp server

Back to the process...

Once the computer obtains an ip address and download location, it uses a tftp client to access the tftp server.  TFTP stands for  trivial file transfer protocol (i believe).  It's been around forever, from what i read.  Using pxelinux, the file downloaded will be pxelinux.0.  This tells the computer to look for a pxelinux config file in the directory pxelinux.cfg/ in the tftp root directory.  There are several naming options for the config file.  You can do per-MAC-address configurations by naming each config file the MAC address of the computer that will be accessing the tftp server.  This name should include dashes and start with "01-"  followed by the MAC address.  Also, you can use a hex representation of the IP address that will be accessing the tftp server.  Truncating the hex IP address allows you to represent multiple ip addresses, (i.e. = c0a8).  Each number in the ip address corresponds to two hex digits.  Finally, if no suitable config file is found, "default" is used.  The computer downloads the config file and proceeds according to it.

In my case, the computer then downloads the vmlinuz compressed linux image and the minirt24.gz (compressed initrd image).  After that, the boot process is the same as if you were booting from a hard drive.  The parameters passed to the kernel are written in the pxelinux config file.  It is possible to use other boot loaders, but I haven't investigated that.  If you just copy the isolinux.cfg file into the pxelinux.cfg/ directory and rename it appropriately, the boot process will be exactly the same as with the dsl cd (complete with the logo and boot prompt).  Mind you, you should copy all the files from the isolinux directory into the tftp root directory if you wish to do this.  

That is a lot of background, but the general idea is this:  you can boot a computer without any kind of bootable media (hard drive, floppy, usb boot support, cd drive) using PXE provided you have a network connection and  a computer running tftp and dhcp.  If you did not load the KNOPPIX cd image into the initrd (as we will do in a second) you would also need a nfs server to host the root filesystem for the computer you wish to boot via PXE.  Now let's actually get started...

1. Download latest DSL distribution iso and mount it.
   We will need the following files from the cd.

KNOPPIX/KNOPPIX         //compressed image
minirt24.gz                        //original initrd
vmlinuz24                         //kernel image

   keep it mounted, because we will need to copy from the
   isolinux.cfg file later.

2. unzip minirt24.gz and mount it in an appropriate location.
For those of you who don't know, an initrd is merely a gzipped
ext2 filesystem in a file.  
Code Sample
gunzip minirt24.gz
mkdir /mnt/initrd-dsl
mount -o loop ./minirt24 /mnt/initrd-dsl

3. Make a new initrd.  As I mentioned, an initrd is just a gzipped ext2 filesystem in a file.  So we are going to make a blank one big enough to hold the files from the original initrd plus the KNOPPIX image.  For me, 53MB was large enough to hold everything.  And since DSL vows to never exceed 50MB, I doubt that the size will ever need to grow.  Of course, if you remaster it (my next project) it might.

Code Sample
touch initrd
dd if=/dev/zero of=./initrd bs=1M count=53
mke2fs ./initrd
mkdir /mnt/initrd-custom
mount -o loop ./initrd /mnt/initrd-custom

4. Copy all the files from the dsl initrd to the new one
Code Sample
cp -a /mnt/initrd-dsl/* /mnt/initrd-custom/

Using cp -a will reserve the ownership, not dereference symlinks, and copy recursively.  
****Note: this is a correction from the original ******

5. Add the compressed KNOPPIX image to the new initrd.  DSL expects the KNOPPIX image to be on the burned DSL cdrom inside the KNOPPIX directory (where you found it in the iso).  So that is where we must put it.  We will later modify the linuxrc to check for the image in /cdrom/KNOPPIX before mounting anything in /cdrom.

Code Sample
mkdir /mnt/initrd-custom/cdrom/KNOPPIX
cp /path-to-KNOPPIX-file /mnt/initrd-custom/cdrom/KNOPPIX/

6. Edit the linuxrc file based on the diff file.  This is straight from the site listed at the top of the how-to.  The linuxrc file should go inside the initrd in the top directlry. It may have to be executable, I'm not sure.  The linuxrc file is a big part of what governs the linux boot process.  If you watch the boot messages as they come up, you can see where the "Accessing KNOPPIX image at...from initrd" message shows up.  To make the correct changes in the linuxrc script, I just looked at the diff file and inserted the lines manually.  It will be difficult to try to apply a diff file to patch the linuxrc when the surrounding text and line numbers will probably change with every release of DSL.  Here is what was in the original diff file.
*** linuxrc.orig 2005-09-16 13:46:47.000000000 +0000
--- linuxrc 2005-09-16 13:46:33.000000000 +0000
*** 323,328 ****
--- 323,330 ----
 test -n "$FOUND_SCSI" -a -z "$NOSCSI" && DEVICES="$DEVICES /dev/sd?[1-9] /dev/sd?[1-9][0-9]"
 DEVICES="$DEVICES /dev/hd?[1-9] /dev/hd?[1-9][0-9]"
 case "$CMDLINE" in *fromhd=/dev/*) DEVICES="$fromhd"; ;; esac
+ # Unset all devices if bootet from initrd
+ case "$CMDLINE" in *frominitrd*) DEVICES=""; ;; esac
 for i in $DEVICES
 echo -n "${CRE}${BLUE}Looking for CDROM in: ${MAGENTA}$i${NORMAL}   "
*** 338,343 ****
--- 340,355 ----
+ # Look for KNOPPIX directory without mounting anything
+ case "$CMDLINE" in *frominitrd*)
+ if test -f /cdrom/$KNOPPIX_DIR/$KNOPPIX_NAME
+ then
+ echo -n "${CRE} ${GREEN}Accessing DSL image at ${MAGENTA}/cdrom/${KNOPPIX_DIR}/${KNOPPIX_NAME}${GREEN} on initrd...${NORMAL}" ;
+ FOUND_KNOPPIX="initrd" ;
+ fi
+ ;;
+ esac
 # Harddisk-installed script part version has been removed
 # (KNOPPIX can be booted directly from HD now).

The line numbers in 3.0.1 are close to those listed in the diff file.  For those of you who don't know how to read a diff file (and I was very recently one of you) you should add the lines with the +'s between the lines without the +'s.  Ok, maybe it's self-explanitory, but for the sake of being user-friendly I spell it out.  The linuxrc looked very much the same for the 3.0.1 version.  It added some usb recognition stuff, from what I remember, so it was a bit longer.  Anyway, put the text in the right place and go on to the next step.  

7. Unmount the two initrds
Code Sample
umount /mnt/initrd-custom /mnt/initrd-dsl

8. Gzip the new initrd
Code Sample
mv initrd minirt24
gzip minirt24

9. put it in the tftpboot
Code Sample
cp ./minirt24.gz /tftpboot

10. create the appropriate pxelinux.cfg/default or specialized file based on the isolinux.cfg file found in the dsl iso.  Make sure you add the "frominitrd" option so that it will trigger the modified linuxrc. Other than that,  you will basically copy the isolinux.cfg from the DSL iso and rename it accordingly.  This step is a bit beyond the scope of this little how-to.  There are plenty of excellent tutorials about PXE configurations out there.  Mattias provided a tar file on his server that includes the pxelinux.0 file and default config files.  

On a side note, however... Personally,  I didn't want to be prompted for the boot options, so I cut the config way down.  All you need is the default and append options with a prompt option.  you may be able to cut out the prompt, I'm not sure.   Here is my auto-booting config file that includes some options I added myself.  

DEFAULT linux24
APPEND ramdisk_size=100000 init=/etc/init lang=us apm=power-off vga=789 initrd=minirt24.gz nomce noapic quiet BOOT_IMAGE=knoppix frominitrd nopcmcia noagp noswap base

That's it.  I hope that I haven't made any mistakes here.  And I hope the post will be useful to those wishing to do something like this.  Keep in mind that DSL will be loaded and run entirely from ram.  It runs fine for me on 192Mb.  Also, the thing goes to sleep and wakes up in about 2 seconds. :) Good luck.


A nice guide - quite clear and concise :)

About the diff stuff - you can use "patch -p0 < file.diff"
Why do you want to use diffs? Takes less time, and there's less human error when changing the lines manually.

This is interesting though... placing it in the initrd.  This could help some who can't solve their "no knoppix image found" problems - guess the only drawback is the memory requirement.

Newbie questions....
In Jungle's Step 7 above the command
umount  /mnt/intrd-custom
apparently copies the contents of the new modified ramdrive back into the source image file "initrd".  

Correct?  I have looked and looked at linux man pages and other web sources and never come across such obscure tips.  What is the best source for such?  Harcopy books?  Got a title?

Nice. It's missing some parts though.

- It doesn't mention what PXE booting is. Or who might need/want it.
- Requirements are never mentioned (two systems? big requirement).
- It doesn't mention what tftp is.
- It mentions linuxrc, but does not specify what it does. Or where to find it, or where to put the modified version.

It really glosses over everything PXE. It doesn't say what it is, how to set up a server or client, or where on the network to put these files that the user creates. If knowing how to boot PXE is assumed prior knowledge, that should be mentioned at the top under pre-requisites.

It seems all this tutorial does it create the files. That is an ok tutorial, but, if that is the case, it should say so at the top. The promise at the top is: "I have come up with this method for converting the latest version of DSL to boot over PXE from initrd."  This should be reworded if you aren't actually going to explain how to boot.

Thanks for taking the time out to write this. I didn't mean to bag or sack or anything, I just thought I might be helpful.

umount is to unmount that file system (ie unlinking that file system from the target directory).  It's not obscure - I use it manually and the mount tool in DSL uses it.

Winter Knight:
I think your first 3 points are covered under the first if the reader knows how a general PXE environment is like.  I suppose a link to a wikipedia article or something could help though.

About linuxrc: it's found in the root of the mounted initrd dir, and in the given in the directions, initrd-custom is where to place the files for the newly modified initrd.

Next Page...
original here.