Valid HTML 4.01! Valid CSS
Anybrowser

Navigatie:


Home - Linux gevorderden - Bootable CD

logo

.


Home

Printbaar

Nieuws

Nieuwe distributie
Onlangs zijn we overgestapt op een nieuwe Linux-distributie, nl. Pardus Linux

Dit lijkt ons een prima distributie, zowel voor beginners als experts.

1. LINUX VAN CD NAAR RAMDISK

Door Jan Gnodde (linux@gnodde.com)

Inhoud

  1. Theorie
    1. Inleiding
    2. Booten vanaf CD
    3. Het bootproces
  2. De kernel
  3. Root-bestandssysteem opzetten
    1. Het root-bestandssysteem
    2. De binary's
  4. Scripts en configratiebestanden
    1. fstab
    2. inittab
    3. rcS
  5. Opstartdiskette maken
    1. Het root-bestandssyteem comprimeren
    2. Lilo en zo
    3. Alles op de flop
  6. CD invullen
  7. Iso-bestand maken en CD branden
  8. Bronnen

1. Theorie

1.1 Inleiding

Een Linux bootdisk, oftewel: Linux op een diskette, kan in een aantal gevallen erg handig zijn, bijv. bij het testen van een nieuwe kernel, of om je Linux installatie te repareren na een crash, of om op een Windows-computer Linux te laten draaien, zonder aan de harde schijf te komen.

Er zijn verschillende manieren om aan zo'n bootdisk te komen:

  • Gebruik de bootdisk van je bestaande installatie
  • Pluk een resue-pakket van internet en maak daarmee je bootdisk
  • Leer hoe zo'n disk werkt en maak hem zelf

Van deze laatste manier kun je veel over Linux leren.

We gaan in dit artikel echter nog een stapje verder: we gaan een bootable CD met Linux maken, waarbij na het opstarten Linux helemaal in het geheugen, op een zgn ramdisk, komt te staan.

Let wel: dit is niet bedoeld voor Linux-newbies. Je hoeft echter ook geen guru te zijn om tot een goed eindresultaat te komen...

1.2 Booten vanaf CD

Om te kunnen opstarten vanaf een CD moet aan een paar voorwaarden voldaan worden:

  • Je computer moet ervoor geschikt zijn. De meeste, redelijk moderne bios'en kunnen dit tegenwoordig wel aan. Kijk evt. in de bios-setup en verander zo nodig de opstart-volgorde.
  • De CD moet geschikt zijn om van op te starten. Hij moet voldoen aan de zgn. El Torito-standaard.
    Deze El Torito-standaard werkt, doordat het bios de CD-drive even ziet als een floppy-drive. Op de CD moet een image van een opstart-diskette (van precies 1440kB) staan. En in de headers van de CD wordt verwezen naar deze image. Het bios leest de diskette-image van de CD en behandelt deze als een normale flop (/dev/fd0).

We hebben dus, om een bootable CD te maken, eerst een opstart-diskette nodig. Een extra eis hierbij is, dat het opstarten van die diskette gebeurt m.b.v. een bootloader, zoals Lilo. Er mag dus niet rechtstreeks met de kernel opgestart worden.

Het is belangrijk om alle bestanden voor de opstartdiskette, incl. de kernel, zo klein mogelijk te houden: het moet tenslotte allemaal binnen die 1440kb passen. Na de eerste opstartfase kunnen de overige bestanden dan, eventueel via een script, van de CD naar de ramdisk gekopieerd worden.

1.3 Het boot-proces

Voordat we aan het werk gaan is enige achtergrond-kennis over het boot-proces nodig.

Elke PC start op met het uitvoeren van een programma in het bios. Dit programma leest de eerste sector van de opstartschijf (meestal harde schijf, diskette of CD, afhankelijk van de bios-instellingen). Het bios probeert de code van die eerste sector uit te voeren. En die code zal, als het goed is, de kernel lezen en laden.

Als de kernel geladen is, zal die de nodige device-drivers en data-strukturen initialiseren. Daarna wordt het root-bestandssysteem gemount. Dit is simpelweg een bestandssysteem, dat als "/" gemount wordt. De kernel moet echter wel weten, waar dat bestandssysteem te vinden is. In ons geval zorgt Lilo voor die wetenschap (via lilo.conf).

Ons root-bestandssysteem zal in ramdisk geladen worden. Ramdisk is een stukje geheugen, dat door het systeem als een schijf behandeld wordt. De kernel is in staat een gecomprimeerd root-bestandssysteem van de diskette (of CD) te lezen en dit uit te pakken in de ramdisk. Zo passen er veel meer bestanden op een diskette.

Na het mounten van "/" zal de kernel het init-programma uitvoeren. Init leest z'n configuratie uit het bestand /etc/inittab, zoekt o.a. naar een regel die begint met "sysinit" en voert het script, dat in die regel vermeld wordt, uit.

Sysinit verwijst vaak naar /etc/rc of /etc/init.d/boot o.i.d.. Dit script bevat een serie shell-opdrachten o.a. om een aantal services op te starten (bijv. een fsck), de nodige kernel-modules te laden en verschillende bestandssystemen (benoemd in /etc/fstab) te mounten. Bij het bouwen van ons systeem zullen we het sysinit-script echter heel eenvoudig houden.

Als het sysinit-script klaar is, krijgt init weer de controle, die naar het juiste runlevel door zal starten. Dit runlevel wordt in /etc/inittab gespecificeerd met "initdefault". De op te starten services en programma's voor dit runlevel worden in verschillende scripts aangegeven.

2. De kernel

Onze opstartdiskette zal dus een kernel moeten bevatten en een root-bestandssysteem. We gaan hier niet in op het zelf configureren en compileren van een kernel. Het is echter wel belangrijk, dat een aantal zaken in de kernel meegecompileerd wordt (dus niet als module):

  • Natuurlijk de ondersteuning van de hardware, die nodig is bij het opstarten, zoals de CD-speler (IDE of SCSI) en de floppy-drive.
  • Ook ondersteuning voor ramdisk en ext2 moet meegecompileerd worden.

Laat verder alles weg, wat niet nodig is. Het is belangrijk, dat de kernel klein blijft. Hij moet tenslotte, samen het het root-bestandssysteem, op een enkele diskette passen. Zaken, die niet direct nodig zijn bij het opstart-proces kun je als module compileren, om ze na de eerste opstartfase alsnog te laden vanaf de CD.

Comprimeer de kernel met een "make bzImage".

3. Het root-bestandssysteem opzetten

3.1 Het root-bestandssysteem

Het root-bestandssysteem kan in eerste instantie opgebouwd worden in een directory binnen een bestaand linux-systeem, bv. de directory ~/rfs.

Maak daar eerst een aantal (sub-) directory's aan: dev, etc, etc/init.d, proc, bin, sbin, usr, usr/bin, usr/sbin, tmp en mnt.

In de dev-directory moet een aantal devices aangemaakt worden. Dat kan met de Linux-opdracht "mknod", maar eenvoudiger is het ze gewoon te kopieren uit het bestaande Linux-systeem. Maak alleen die devices aan, die je echt nodig hebt (ook devices kosten ruimte, of in ieder geval inodes). In ieder geval heb je nodig: fd0, hdc (als dat je CD-speler is), tty0-3, console, kmem, mem, null en ram0. Bij het kopieren van de devices met de opdracht "cp" moet je de optie "-R" (hoofdletter R!) gebruiken, bijv. "cp -R /dev/fd0 ~/rfs/dev/".

3.2 De binary's

Omdat het bestandssyteem klein moet blijven, maken we gebruik van BusyBox. BusyBox is een programma, dat veel Linux-utilities vervangt, als is het wel vaak met wat minder opties.

Als je een link maakt naar BusyBox met de naam van de functie, die je wilt hebben, dan zal BusyBox, als hij via die link aangeroepen wordt, zich gedragen als die functie.

Bijvoorbeeld: maak een link met de naam "ls":

        ln -s ./busybox ls

Type daarna "./ls" en je krijgt de uitvoer, die je van de opdracht "ls" mag verwachten.

De homepage van BusyBox is te vinden op www.busybox.net; daar kun je het ook, als broncode, downloaden.

Het compileren is erg eenvoudig, al moet er voor ons doel nog wel wat veranderd worden in het bestand "Makefile". Daar staat achter de variabele DOSTATIC "false" vermeld. Verander dit in "true" om een statisch gelinkte BusyBox te krijgen. Dan hebben we verder geen library's in ons root-bestandssysteem nodig. Mocht je die toch nodig hebben voor andere programma's, dan is het beter ze later, via een opstart-script van de CD naar de ramdisk te kopieren.

Na het veranderen van de DOSTATIC-variabele is het nog een kwestie van

        make
        make install

en het hele BusyBox-systeem, incl. de subdirectory's en de links is te vinden in de directory "_install". Kopieer ze vandaar naar de betreffende directory's in je root-bestandssysteem en je hebt al de Linux basis-programma's bij de hand!

4. De configuratie-scripts

4.1 fstab

Deze staan allemaal in de etc-directory. Er is niet veel nodig: alleen fstab, inittab en etc/init.d/rcS. Het init-onderdeel van BusyBox kent nl. geen verschillende runlevels. Het start altijd op in de single-user-mode. Mede daardoor kan alles erg eenvoudig gehouden worden.

In fstab komt minimaal het volgende te staan:

        /dev/ram0   /       ext2      defaults
        /proc       /proc   proc      defaults

Wellicht is het handig om ook nog een regeltje voor de CD-speler toe te voegen (we gaan ervan uit dat /dev/hdc de cd-speler is):

        /dev/hdc    /mnt    iso9660   noauto

Omdat we de CD-speler niet automatisch mounten, moet dat later eventueel in de scripts nog gebeuren.

Zet de mode van fstab juist: chmod 644 fstab.

4.2 inittab

Het volgende script is inittab. Dit ziet er als volgt uit:

        ::sysinit:/etc/init.d/rcS
        ::askfirst:/bin/sh
        tty2::askfirst:/bin/sh
        tty3::askfirst:/bin/sh
        ::restart:/sbin/init
        ::ctrlaltdel:/sbin/reboot
        ::shutdown:/bin/umount -a -r

Ook hier weer de juiste mode zetten: chmod 644 inittab.

4.3 rcS

Als laatste is er nog het rcS script (etc/ini.d/rcS). Dit moet minimaal het volgende bevatten:

        #!/bin/sh
        mount -a #mount alle default bestandssystemen, vermeld in fstab

Omdat het rcS script in het root-bestandssysteem hoort, dat straks gecomprimeerd wordt en samen met de kernel "versmolten" tot een diskette-image, is het lastig om er naderhand nog iets aan te wijzigen. Daarom laten we rcS de CD mounten en vandaar een script kopieren naar ramdisk, wat dan uitgevoerd wordt. Dit script (laten we het "sec" noemen, als vervolg op "init") is wat eenvoudiger te veranderen.

Aan rcS voegen we het volgende toe:

        mount /mnt       # meer hoeft niet, dankzij de vermelding in fstab
        cp /mnt/sec /usr/bin  # sec kopieren van CD naar ramdisk
        sec                   # script "sec" uitvoeren
        umount /mnt           # CD unmounten

Het script "sec" kun je verder alles laten uitvoeren, wat je wilt: modules laden, bestanden van CD naar ramdisk kopieren, enz. Vergeet dan niet de CD eerst weer te mounten...

Zorg dat rcS uitvoerbaar is: chmod 755 rcS.

En dat waren alle nodige configuratie-scripts!

5. Opstartdiskette maken

5.1 Het root-bestandssysteem comprimeren

Nu gaan we het hele root-bestandssysteem in een bestand zetten, dat we "rootfs" gaan noemen. De grootte van rootfs bepaalt straks de groote van de ramdisk. Minimaal heb je zo'n 4Mb nodig, maar op een moderne computer, met minimaal 128Mb geheugen mag de ramdisk best 32Mb zijn.

Daarom maken we eerst een leeg bestand van 32Mb. Hoewel: het is niet leeg, maar gevuld met nullen. Dat zorgt ervoor, dat de ongebruikte ruimte straks goed gecomprimeerd kan worden.

        dd if=/dev/zero of=rootfs bs=1k count=32768

In dat bestand maken we een bestandssysteem aan:

        mke2fs -m 0 -N 4000 rootfs

De optie -N 4000 geeft het aantal inodes aan, en is aan te passen aan de eigen behoefte.

Nu kun je het rootfs-bestand mounten via een loopdevice:

        mount -o loop -t ext2 rootfs /mnt

En tenslotte kun je het eerder aangemaakte root-bestandssysteem naar het gemounte rootfs-bestand kopieren:

        cp -dpR ~/rfs/* /mnt/

Vergeet de optie -dpR niet!

Nu het bestand nog unmounten:

        umount /mnt

Rootfs bevat nu het root-bestandssysteem en is 32Mb groot. Dat past natuurlijk nooit op een diskette. Dus moeten we het comprimeren:

        gzip -v9 rootfs

Nu heb je een bestand "rootfs.gz" van nog maar enkele honderden kilobytes!

5.2 Lilo en zo

We hebben nu dus een root-bestandssysteem gecomprimeerd in het bestand rootfs.gz en we hebben een zelfgebakken kernel bzImage. Controleer of beide bestanden samen op een diskette passen. Er moet ook nog wat ruimte overblijven voor wat andere zaken, o.a. voor het lilo configuratie-bestand. Dit bevat de volgende tekst:

        boot=/dev/fd0
        install=/boot/boot.b
        map=/boot/map
        read-write
        backup=/dev/null
        compact
        image=/bzImage
        label=linuxCD
        initrd=/rootfs.gz
        root=/dev/ram0
        append="ramdisk_size=32768"

Sla het op onder de naam cdlilo.conf.

5.3 Alles op een flop

Stop een diskette in de drive en maak er een ext2 bestandssysteem op aan:

        mke2fs -m 0 /dev/fd0

Mount dit bestandssyteem, verwijder de lost+found directory en maak de directory's dev en boot aan:

        mount -o dev /dev/fd0 /mnt
        rm -rf /mnt/lost+found
        mkdir /mnt/{boot,dev}

In de dev-directory hebben we weer wat devices nodig, die je kunt kopieren (met de -R optie) van de harde schijf:

        cp -R /dev/{null,fd0,ram0} /mnt/dev/

Dan moet voor lilo boot.b op de diskette gezet worden, wat je ook kunt kopieren van de harde schijf:

        cp /boot/boot.b /mnt/boot/

Tenslotte moeten cdlilo.conf, de kernel en ons gecomprimeerde root-bestandssysteem nog op de flop geplaatst worden:

        cp cdlilo.conf bzImage rootfs.gz /mnt/

Zo, alles wat lilo nodig heeft staat op de diskette. Nu moeten we lilo nog draaien:

        lilo -v -C cdlilo.conf -r /mnt

De -C optie vertelt lilo dat cdlilo.conf het te gebruiken configuratie-bestand is en de -r optie dat /mnt even als rootdirectory ("/") gezien moet worden.

Lilo moet werken zonder foutmeldingen (de eventuele waarschuwingen van lilo over LBA32 mag je negeren).

De inhoud van de diskette is, na al dat harde werk, als volgt:

     /mnt:
     totaal 537
     -rw-r--r--    1 root     root          182 aug  5 11:07 cdlilo.conf
     drwxr-xr-x    2 root     root         1024 aug  5 11:11 boot/
     -rw-r--r--    1 root     root       542268 aug  2 20:16 bzImage
     drwxr-xr-x    2 root     root         1024 aug  4 22:08 dev/
     -rw-r--r--    1 root     root       367534 aug  4 23:16 rootfs.gz

     /mnt/boot:
     totaal 11
     -rw-r--r--    1 root     root         5824 aug  4 22:08 boot.b
     -rw-------    1 root     root         4608 aug  5 11:11 map

     /mnt/dev:
     totaal 0
     brw-r-----    1 root     root       2,   0 aug  4 22:08 fd0
     crw-r--r--    1 root     root       1,   3 aug  4 22:08 null
     brw-r-----    1 root     root       1,   0 aug  4 22:08 ram0

Je hoeft je niet druk te maken over eventuele kleine verschillen.

Nu kunnen we de proef op de som nemen: we gaan de computer opstarten van onze vers gebakken boot-flop. Denk wel aan de bios-opstartopties...

Als je alles goed gedaan hebt, zie je eerst de woorden "LILO 22.1 loading linuxCD", waarna de lappen tekst van de kernel over je scherm vliegen. Aan het eind zul je wat foutmeldingen krijgen, omdat het bestand "sec" niet gevonden kan worden (en waarschijnlijk de CD niet gemount). Druk, als alles op het scherm stil staat, op enter, en je hebt een prachtige prompt van BusyBox.

Geef nu even de opdracht "df", en je ziet, dat je ramdisk een kleine 32Mb groot is (er is wat afgesnoept voor de inodes) en dat maar een klein deel ervan gevuld is door het root-bestandssyteem. Er kan dus nog heel wat bij...

6. CD invullen

Nu hebben we een opstartdiskette, maar nog geen CD. De directory's en bestanden, die straks op de CD komen, zetten we eerst nog even in een aparte directory op de harde schijf (bijv. "~/cd"). Maak daar eerst de sub-directory "boot" aan en cd daar naar toe. Dit wordt de plaats waar de image van de opstart-diskette komt te staan:

        dd if=/dev/fd0 of=boot.img bs=10k count=144

Verder kun je onder de cd-directory alles kwijt, wat je in je ramdisk wilt hebben, zolang je maar rekening houdt met de maximale ruimte van ongeveer 30Mb van die ramdisk.

Als je nog drivers, modules, programma's, library's, e.d. wilt laden, nadat het root-bestandssyteem in de ramdisk is opgezet, dan zet je die in de cd-directory, zonodig in een sub-directory daarvan.

Daarna moet het "sec"-script nog gemaakt worden.

Stel, dat je de sub-directory's "lib" en "bin" hebt aangemaakt, en die gevuld hebt met resp. library's en binary's, die naar de ramdisk geschreven moeten worden, dan zou het "sec"-script er als volgt uit kunnen zien:

        #!/bin/sh
        mkdir /lib                  # als die nog niet bestaat...
        mount /mnt                  # staat in inittab
        cp /mnt/lib/* /lib/
        cp /mnt/bin/* /usr/bin/     # of een andere directory
        umount /mnt

Dit is natuurlijk een eenvoudig voorbeeld, maar je kunt het zo ingewikkeld maken als je wilt. Dat is helemaal afhankelijk van het doel, waarvoor je de CD wilt maken. Dat laten we dan ook verder aan je eigen inventiviteit over.

7. Iso-bestand maken en CD branden

De El Torito standaard vereist eigenlijk ook nog een boot.catalog bestand van 2048 bytes. Echter, de opdracht "mkisofs" regelt dat automatisch (hulde aan de makers ervan!). We zijn dus helemaal klaar om het iso-bestand te maken.

Ga naar de cd-directory en geef de volgende opdracht:

     mkisofs -r -b boot/boot.img -c boot/boot/catalog -o bootcd.iso .

(Vergeet die laatste punt niet!).
Je iso-bestand is klaar en kan op CD gebrand worden. Daarvoor kun je "cdrecord" gebruiken, of een van de grafische frontends daarvan. Ook dat laten we aan je eigen wensen over.

Tenslotte is het tijd om de CD te testen. Stop hem in de drive en reboot je computer (denk aan de opstart-instellingen in het bios). Als je alles goed gedaan hebt, start de computer netjes op, en zal op het laatst ook je "sec"-script uitgevoerd worden.

Veel succes!

Bronnen

Linux Bootdisk HOWTO
http://nl.linux.org/doc/books/bootdisk/t1.html

BusyBox
http://www.busybox.net/downloads/BusyBox.html

Ramdisk.txt
http://www.linuxhq.com/kernel/v2.4/doc/ramdisk.txt.html



Laatst herzien op 25-09-2005