Inhalt

3. Wie ein Loop-Root-Device erzeugt wird

Nun, wo die grundlegenden Prinzipien erläutert sind, kann die Erstellung eines Loop-Devices erklärt werden.

3.1 Voraussetzungen

Um ein Loop-Device zu erstellen, werden mehrere Dinge benötigt.

Am wichtigsten ist der Zugriff auf ein installiertes Linux-System, denn das Loop-Device kann nur unter Linux erstellt werden. Das heißt, daß es nicht möglich ist, ein funktionierendes System aus dem Nichts zu erstellen (Boot Strapping). Mit dem Linux-System, das Sie verwenden, müssen Sie einen neuen Kernel kompilieren können.

Wenn das Loop-Device erst einmal erzeugt ist, wird es eine sehr große Datei sein. Ich habe Dateien mit einer Größe von 80 MB verwendet. Aber obwohl das ausreichte, um ein X-Terminal zu betreiben, könnte es zu klein sein, wenn Sie es für etwas anderes verwenden möchten. Diese Datei muß auf die DOS-Partition kopiert werden; also müssen entweder ein Netzwerk oder eine große Anzahl von Disketten verwendet werden.

Die benötigten Programme sind:

Das sollte aber bei den jüngeren Linux-Distributionen Standard sein.

3.2 Den Linux-Kernel erzeugen

Ich erzeugte das Loop-Device unter Verwendung des Linux-Kernels 2.0.31. Andere Versionen sollten ebenfalls funktionieren. Sie müssen aber zumindest die unten aufgelisteten Optionen haben.

Folgende Kernel-Optionen werden verwendet:

Die ersten beiden sind für die RAM-Disk und die Intitial-RAM-Disk. Die nächste ist für das Loop-Device. Die letzten beiden sind für Unterstützung des DOS-Dateisystems, das gebraucht wird, um die DOS-Partition zu mounten.

Die einfachste Möglichkeit ist es, einen Kernel ohne nachladbare Module zu erzeugen. Mit Modulen sollte es auch funktionieren, obgleich ich es nicht ausprobiert habe. Wenn Module verwendet werden, sollten Sie sich vergewissern, daß zumindest die o.g. Optionen fest in den Kernel eingebunden und nicht als Module erzeugt werden, damit sie gleich zu Beginn zur Verfügung stehen.

Je nachdem welche Kernel-Version verwendet wird, könnte es sein, daß Sie einen Kernel-Patch anwenden müssen. Es ist eine sehr einfache Anpassung, die es erlaubt, ein Loop-Device als Root-Partition zu verwenden.

Kernel-Versionen älter als 2.0.0

Es liegen mir keine weiteren Informationen darüber vor.

Kernel-Versionen 2.0.0 bis 2.0.34

Sie müssen den Kernel-Patch für die 2.0.x Kernels anwenden, wie unten beschrieben.

Kernel-Versionen 2.0.35 bis 2.0.x

Ein Kernel-Patch ist nicht erforderlich.

Kernel version 2.1.x

Sie müssen den Kernel-Patch für die 2.0.x-Kernels oder 2.2.x-Kernels anwenden, je nach genauer Version des 2.1.x-Kernels, wie unten beschrieben.

Kernel-Versionen 2.2.0 bis 2.2.10

Sie müssen den Kernel-Patch für die 2.2.x-Kernels anwenden, wie unten beschrieben.

Kernel-Version 2.3.x

Sie müssen den Kernel-Patch für die 2.2.x-Kernels anwenden, wie unten beschrieben.

Für die 2.0.x-Kernels muß eine einzelne Zeile in die Datei init/main.c eingefügt werden. Die einzufügende Zeile lautet:

{ "loop", 0x0700 }

Das sollte dann so aussehen:

static void parse_root_dev(char * line)
{
        int base = 0;
        static struct dev_name_struct {
                const char *name;
                const int num;
        } devices[] = {
                { "nfs",     0x00ff },
                { "loop",    0x0700 },
                { "hda",     0x0300 },

...

                { "sonycd",  0x1800 },
                { NULL, 0 }
        };

...

}

Für die 2.2.x-Kernels müssen drei Zeilen in die Datei init/main.c eingefügt werden. Die eingefügten Zeilen sind

{ "loop", 0x0700 }
und die Zeilen die davor und dahinter stehen:

static struct dev_name_struct {
        const char *name;
        const int num;
} root_dev_names[] __initdata = {
#ifdef CONFIG_ROOT_NFS
        { "nfs",     0x00ff },
#endif
#ifdef CONFIG_BLK_DEV_LOOP
        { "loop",    0x0700 },
#endif
#ifdef CONFIG_BLK_DEV_IDE
        { "hda",     0x0300 },

...

        { "ddv", DDV_MAJOR << 8},
#endif
        { NULL, 0 }
};

Wenn der Kernel konfiguriert ist, sollte er übersetzt werden, um eine zImage-Datei zu erhalten (make zImage). Nach dem Übersetzen wird die entstandene Datei arch/i386/boot/zImage heißen.

3.3 Die Initial-RAM-Disk erstellen

Die Initial-RAM-Disk wird für den Startvorgang meistens als ein Loop-Device angelegt. Sie müssen das als Systemverwalterin (Super-User) tun, weil es Root-Rechte erfordert. Die Programme, die dazu ausgeführt werden müssen, sind unten aufgelistet. Es wird hier davon ausgegangen, daß Sie vom Heimatverzeichnis der Systemverwalterin gestartet werden (/root).

mkdir /root/initrd
dd if=/dev/zero of=initrd.img bs=1k count=1024
mke2fs -i 1024 -b 1024 -m 5 -F -v initrd.img
mount initrd.img /root/initrd -t ext2 -o loop
cd initrd
[Erzeuge die Dateien]
cd ..
umount /root/initrd
gzip -c -9 initrd.img > initrdgz.img

Es sind eine Reihe von Schritten erforderlich, die wie folgt beschrieben werden können.

  1. Erzeugen Sie einen Mount-Point, ein leeres Verzeichnis, für die Initial-RAM-Disk.
  2. Erzeugen Sie eine leere Datei in der benötigten Größe. Hier habe ich 1024 kB verwendet. Sie werden mehr oder weniger benötigen, je nach Verwendungszweck; die Größe ist der letzte Parameter.
  3. Erzeugen Sie in der leeren Datei das Ext2-Format.
  4. Mounten Sie die Datei auf den Mount-Point; dadurch wird das Loop-Device verwendet.
  5. Wechseln Sie auf das gemountete Loop-Device.
  6. Erstellen Sie die benötigten Dateien (siehe unten).
  7. Wechseln Sie in ein anderes Verzeichnis außerhalb des Loop-Devices.
  8. Entfernen Sie das Loop-Device aus der Verzeichnisstruktur (umount).
  9. Erzeugen Sie eine komprimierte Version für die spätere Verwendung.

Inhalt der Initial-RAM-Disk

Die Dateien, die Sie auf der RAM-Disk benötigen, sind die minimalen Voraussetzungen, um irgendwelche Kommandos auszuführen zu können.

/linuxrc

Das Programm (Skript-Datei), das gestartet wird, um die DOS-Partition zu mounten (siehe unten).

/lib/*

Die Link-Programme und die Laufzeit-Bibliotheken, die von den Programmen verwendet werden.

/etc/*

Die Umgebung, die von den Link-Programmen verwendet wird (für alle Fälle).

/bin/*

Eine Shell (am besten ash weil sie kleiner ist als bash). Die Programme mount und losetup für den Zugriff auf die DOS-Partition und zum Erstellen des Loop-Devices.

/dev/*

Die Geräte-Dateien der verwendeten Geräte. Sie benötigen /dev/zero für ld-linux.so, /dev/hda* um die DOS-Partition zu mounten und /dev/loop* für das Loop-Device.

/mnt

Ein leeres Verzeichnis, um die DOS-Partition darauf zu mounten.

Die Initial-RAM-Disk die ich verwendete, ist unten aufgelistet. Der Inhalt beträgt etwa 800 kB, wenn man den zusätzlichen Platz mitberücksichtigt, der beim Abspeichern im Dateisystem benötigt wird.

total 18
drwxr-xr-x   2 root     root         1024 Jun  2 13:57 bin
drwxr-xr-x   2 root     root         1024 Jun  2 13:47 dev
drwxr-xr-x   2 root     root         1024 May 20 07:43 etc
drwxr-xr-x   2 root     root         1024 May 27 07:57 lib
-rwxr-xr-x   1 root     root          964 Jun  3 08:47 linuxrc
drwxr-xr-x   2 root     root        12288 May 27 08:08 lost+found
drwxr-xr-x   2 root     root         1024 Jun  2 14:16 mnt

./bin:
total 168
-rwxr-xr-x   1 root     root        60880 May 27 07:56 ash
-rwxr-xr-x   1 root     root         5484 May 27 07:56 losetup
-rwsr-xr-x   1 root     root        28216 May 27 07:56 mount
lrwxrwxrwx   1 root     root            3 May 27 08:08 sh -> ash

./dev:
total 0
brw-r--r--   1 root     root       3,   0 May 20 07:43 hda
brw-r--r--   1 root     root       3,   1 May 20 07:43 hda1
brw-r--r--   1 root     root       3,   2 Jun  2 13:46 hda2
brw-r--r--   1 root     root       3,   3 Jun  2 13:46 hda3
brw-r--r--   1 root     root       7,   0 May 20 07:43 loop0
brw-r--r--   1 root     root       7,   1 Jun  2 13:47 loop1
crw-r--r--   1 root     root       1,   3 May 20 07:42 null
crw-r--r--   1 root     root       5,   0 May 20 07:43 tty
crw-r--r--   1 root     root       4,   1 May 20 07:43 tty1
crw-r--r--   1 root     root       1,   5 May 20 07:42 zero

./etc:
total 3
-rw-r--r--   1 root     root         2539 May 20 07:43 ld.so.cache

./lib:
total 649
lrwxrwxrwx   1 root     root           18 May 27 08:08 ld-linux.so.1 -> ld-linux.so.1.7.14
-rwxr-xr-x   1 root     root        21367 May 20 07:44 ld-linux.so.1.7.14
lrwxrwxrwx   1 root     root           14 May 27 08:08 libc.so.5 -> libc.so.5.3.12
-rwxr-xr-x   1 root     root       583795 May 20 07:44 libc.so.5.3.12

./lost+found:
total 0

./mnt:
total 0

Die einzig schwierigen Schritte betreffen die Geräte in /dev. Verwenden Sie das Programm mknod, um sie zu erstellen und gebrauchen Sie dabei die bestehenden Gerätedateien als Vorlagen, um die benötigten Parameter zu erhalten.

Die Skript-Datei /linuxrc

Die Datei /linuxrc auf der Initial-RAM-Disk wird benötigt, um alle Vorbereitungen zu treffen, damit das Loop-Device als Root-Partition verwendet werden kann.

Im untenstehenden Beispiel wird versucht, /dev/hda1 als DOS-Laufwerk zu mounten und wenn das geklappt hat, die Dateien /linux/linuxdsk.img als /dev/loop0 und /linux/linuxswp.img als /dev/loop1 einzurichten.

#!/bin/sh

echo INITRD: Versuche /dev/hda1 als msdos zu mounten

if /bin/mount -n -t msdos /dev/hda1 /mnt; then

   echo INITRD: Mounted OK
   /bin/losetup /dev/loop0 /mnt/linux/linuxdsk.img
   /bin/losetup /dev/loop1 /mnt/linux/linuxswp.img
   exit 0

else

   echo INITRD: Mounten fehlgeschlagen
   exit 1

fi

Das erste Loop-Device /dev/loop0 wird die Root-Partition und das zweite /dev/loop1 wird der Auslagerungsbereich (Swap-Partition).

Wenn Sie hinterher als gewöhnlicher User ohne Root-Rechte auf die DOS-Partition schreiben möchten, dann sollten Sie stattdessen das folgende Kommando verwenden:

mount -n -t msdos /dev/hda1 /mnt -o uid=0,gid=0,umask=000,quiet

Es leitet alle Zugriffe auf die DOS-Partition um und setzt die passenden Zugriffsrechte für die Dateien und Verzeichnisse.

3.4 Die Root-Partition erstellen

Die Root-Partition, die Sie verwenden werden, ist die Datei linuxdsk.img. Sie müssen sie genauso erzeugen wie die Initial-RAM-Disk. Sie muß aber größer sein. Sie können jede beliebige Linux-Distribution darauf installieren.

Der einfachste Weg wird sein, einfach eine existierende Linux-Installation dorthin zu kopieren. Die Alternative ist, ein neues Linux darauf zu installieren.

Angenommen Sie haben das getan, dann gibt es da noch ein paar kleine Änderungen, die Sie vornehmen müssen.

Die Datei /etc/fstab muß die Verweise auf die Root-Partition und die Swap-Partition unter Verwendung der beiden Loop-Devices enthalten, die mit der Initial-RAM-Disk eingerichtet wurden.

/dev/loop0     /      ext2   defaults 1 1
/dev/loop1     swap   swap   defaults 1 1

Das wird dafür sorgen, daß, sobald die richtige Root-Partition verwendet werden soll, diese auch vom Kernel gefunden werden kann. Außerdem kann so auch der Auslagerungsbereich auf die gleiche Weise hinzugefügt werden, wie eine Swap-Partition normalerweise verwendet wird. Sie sollten alle anderen Verweise auf eine Root- oder Swap-Partition entfernen.

Wenn Sie nach dem Start von Linux auch auf die DOS-Partition zugreifen möchten, müssen Sie noch ein paar kleine Änderungen vornehmen.

Erzeugen Sie ein Verzeichnis mit dem Namen /initrd. Dorthin wird die Initial-RAM-Disk gemountet werden, wenn das Loop-Root-Device gemountet ist.

Erstellen Sie einen symbolischen Link mit dem Namen /DOS, der auf /initrd/mnt zeigt, wohin die echte DOS-Partition gemountet wird.

Fügen Sie eine Zeile in die rc-Datei ein, die die Laufwerke mountet. Sie sollte folgendes Kommando ausführen:

mount -f -t msdos /dev/hda1 /initrd/mnt

So wird ein »falsches« Mount-Kommando auf die DOS-Partition angewendet, damit alle Programme wie z.B. df wissen, daß die DOS-Partition gemountet wurde und wo sie zu finden ist. Wenn Sie in der Datei /linuxrc andere Optionen verwendet haben, sollten Sie sie selbstverständlich auch hier verwenden.

Es ist nicht notwendig, einen Linux-Kernel auf dieser Root-Partition zu haben, weil er bereits vorher geladen wurde. Sofern Sie Kernel-Module verwenden, kopieren Sie diese wie gewohnt auf das Laufwerk.

3.5 Die Swap-Partition erstellen

Das Laufwerk, das Sie verwenden werden, ist die Datei linuxswp.img. Die Swap-Partition ist sehr einfach zu erstellen. Erzeugen Sie eine leere Datei, wie beim Erstellen der Initial-RAM-Disk und starten Sie

mkswap linuxswp.img
um sie zu initialisieren.

Die Größe des Auslagerungsbereiches ist davon abhängig, was Sie mit dem installierten System machen möchten. Ich empfehle zwischen 8 MB und der Größe des RAM-Speichers, den Sie in ihrem Rechner haben.

3.6 Das DOS-Verzeichnis erstellen

Die Dateien, die Sie verwenden wollen, müssen auf die DOS-Partition verschoben werden.

Die Dateien, die im DOS-Verzeichnis mit dem Namen C:\LINUX gebraucht werden, sind die folgenden:

LINUXDSK.IMG

Die Image-Datei die zur Root-Partition wird.

LINUXSWP.IMG

Der Auslagerungsbereich (Swap-Partition).

3.7 Eine Boot-Diskette erstellen

Die verwendete Diskette ist eine normale bootfähige DOS-Diskette

Unter DOS wird sie mit dem Befehl

format a: /s
erstellt.

Auf dieser Diskette müssen Sie eine Datei mit dem Namen AUTOEXEC.BAT erstellen. Außerdem müssen Sie den Kernel, eine gepackte Initial-RAM-Disk und LOADLIN.EXE auf die Diskette kopieren.

AUTOEXEC.BAT

Die bei DOS automatisch gestartete Batch-Datei.

LOADLIN.EXE

Das Programm LOADLIN.EXE

ZIMAGE

Der Linux-Kernel

INITRDGZ.IMG

Das Image der gepackten Intitial-RAM-Disk.

Die Datei AUTOEXEC.BAT sollte nur eine einzelne Zeile enthalten:

\loadlin \zImage initrd=\initrdgz.img root=/dev/loop0 ro

Darin wird der zu ladende Kernel angeben, die Intitial-RAM-Disk und die Root-Partition, nachdem die Initial-RAM-Disk ihre Arbeit beendet hat. Außerdem wird festgelegt, daß die Root-Partition nur für lesenden Zugriff gemountet wird.


Inhalt