= NAT-Router =

Ich möchte einen NAT-Router auf einem embedded Board haben. Dazu sind wir folgendermassen vorgegangen: Als erstes habe ich ein neues Linux-System in einem chroot-Jail erzeugt und dieses nach meinen Vorstellungewn angepasst:

  # cd MeinProjektVerzeichnis
  # debootstrap lenny router
  
Jetzt haben wir ein hübsches Basis-Debian (lenny-Distribution), das in dem Unterverzeichnis "natrouter" erzeugt wurde.
  
  # chroot router
  # mount proc /proc -t proc
  
Wir betreten das Verzeichnis mit "chroot", was dazu führt, daß wir uns (fast) wie in einem neuen, eigenen Linux-System fühlen. Natürlich arbeiten wir immer noch auf dem originalen System, daher empfehle ich nach Abschluss der ganzen Aktion einen Reboot des ganzen Systems. Das proc-System mounte ich, weil das chroot-System dadurch etwas "echter" wirkt, was bei der Installation weiterer Pakete ansonsten zu Fehlern führen kann.
  
  # aptitude install locales
  # dpkg-reconfigure locales
  # aptitude install joe less ssh
  # aptitude install shorewall ntpdate
  # aptitude install grub
  # aptitude install linux-image-2.6.26-486

Das sind ein paar Pakete, die immer bzw. speziell für unseren Router sinnvoll sind. Arbeitet man auf einem deutsch konfigurierten Muttersystem, sollte man "locales" als erstes installieren und konfigurieren, um Warnings bei den weiteren Paketinstallationen zu vermeiden.

  # umount /proc
  # exit

Jetzt habe ich das chroot-System wieder ordentlich verlassen und schreibe das Verzeichnis dann auf die CF-Karte.

  # cfdisk /dev/sdc
  
Ich erzeuge eine einzige, grosse Partition mit Filesystemtyp "Linux ext3". Diese mache ich z.B. 512 MB gross. Indem ich nicht die ganze Platte benutze, stelle ich sicher, daß das Image später auch auf verschieden grosse CF-Karten kopiert werden kann.

  # mke2fs -j /dev/sdc1
  # mount /dev/sdc1 /mnt
  # cp -a router /mnt

Jetzt installiere ich den grub-Bootloader (näheres siehe LinuxOhneBildschirm):

  # chroot router
  # cp -r /usr/lib/grub/i386-pc /boot/grub
  # exit
  # grub
  grub> device (hd0) /dev/sdb
  grub> root (hd0,0)
  grub> setup (hd0)
  grub> quit

Einige Kleinigkeiten zur Konfiguration innerhalb des chroot sind noch empfehlenswert. Auf LinuxOhneBildschirm ist ein Beispiel, wie man die inittab anpasst. Dazu empfehle ich noch folgendes:

  # echo "router" >/etc/hostname

Dabei kommt in die /etc/inittab folgende Zeile. Die restlichen Terminalzeilen kann man auskommentieren (siehe LinuxOHneBildschirm).

T0:2345:respawn:/sbin/getty -L ttyS0 38400 vt100



Im laufenden System sollte man übrigens Datum und Uhrzeit richtig gesetzt haben:

  # date 030715212009       (bedeutet 7.3.09, 15:21)
  # hwclock --systohc


Jetzt haben wir ein funktionierendes System, das wir bereits produktiv einsetzen können.

== bootcd ==

Mit dem Debian-Paket "bootcd" können wir dieses System nun für ein embedded board noch etwas besser anpassen. Dazu installieren wir bootcd im Master-System, konfigurieren "/etc/bootcd/bootcdwrite.conf" (langsam und mit nachdenken) und starten "bootcdwrite". Die Besonderheit bei einem embedded System ist, daß man von der ersten Partition statt von einer Floppy bootet. Bei unserem System konnte man leider auch nicht direkt vom CD-Image booten (wurde vom embedded-BIOS nicht unterstützt). Dazu benutzen wir den grub-Bootblock (wie oben installiert), kopieren das "/boot"-Verzeichnis des Masters auf die erste Partition der Festplatte/CF-Karte und tragen in der "grub/menu.lst" in der Kernel-Zeile die zweite Partition als Bootdevice für den Kernel ein. Auf diese zweite Partition kopieren wir dann das CD-Image, das bootcd erzeugt hat.

== bootcd ==

Zweiter Anlauf im Juni 2010 - jetzt nochmal ausführlicher:

Vorher sollte noch folgendes innerhalb des chroots installiert werden:

  aptitude install grub
  
Aufgrund eines Bugs (glauben wir?!?) ist es nötig, im chroot-System diesen Befehl auszuführen:

  mkdir /mnt/floppy

und eine Zeile im bootcdflopcp-Skript auf der Hauptmaschine unter
 
  /usr/share/bootcd/bootcdflopcp
  
zu ändern. 

  FLOPPY=/dev/hda1
  
Da wir mit einer initrd arbeiten, installieren wir noch ein passendes Hilfspaket (machen wir das nicht, weist 
bootcdwrite uns darauf hin). Natürlich brauchen wir auch mkisofs, um das CD-Image zu erzeugen. Folgendes muss also im Basissystem installiert werden:

  aptitude install bootcd-mkinitramfs
  aptitude install mkisofs

Ich habe folgende Einstellungen in der Datei ''/etc/bootcd/bootcdwrite.conf'' geändert (und alles andere gelassen):

  SRCDISK=/lenny_dist
  
  CDDEV="auto /dev/hda2"
  FLOPPY_RUNTIME_DEV=/dev/hda1
  BOOTFLOPPY=no
  FASTBOOT=no
  

Nun zum Bootvorgang. Unser embedded Board kann nicht von einem ISO-Image booten. Ginge das, würde man das Image auf die CF-Karte schreiben und fertig... So machen wir das anders. Unsere CF-Karte bekommt zwei Partitionen: hda1 ()oder sda1 oder sdc1 oder wasauchimmer Dein CF-Karten-Lesegerät für ein Device zugeordnet hat) ist klein und enthält später den Bootkernel, die initrd sowie die Konfiguration. Diese PArtition ist z.B. 100MB groß (es reicht aber auchviel weniger). Die zweite Partition hda2 kann beliebig gross sein und enthält das ISO-Image. Wir formatieren die erste Partition mit

  mke2fs /dev/sdx1

Dann mountet man die erste Partition und kopiert das boot-Verzeichnis dort hinein. Grub besteht aus zwei Teilen (Stages). Da wir aus dem chroot keinen Zugang auf die zukünftige boot-Platte haben, kann man es leider nicht direkt mit dem Debian-typischen Befehl "grub-install" installieren. Wir kopieren die zweite Stufe deshalb von Hand nach /boot/grub.

  mount /dev/sdx1 /mnt/
  # dann innerhalb des changeroots:
  cp -r /usr/lib/grub/i386-pc /boot/grub
  # dann wieder außerhalb des changeroots
  cp -a /chroot-debian/boot /mnt
  umount /mnt

Jetzt wollen wir die erste Stufe installieren. Am leichtesten ist es, wenn das grub-Paket auf dem Basissystem und das im chroot die gleiche Version hat. Dann installieren wir wie oben angegeben die erste Stufe aus dem Basissystem heraus (da, wo /dev/sdx steht, tragen wir wieder den Wert unseres Cardreaders ein). ''(Siehe LinuxOhneBildschirm zur genaueren Erklärung.)''

  # grub
  grub> device (hd0) /dev/sdx
  grub> root (hd0,0)
  grub> setup (hd0)
  grub> quit

Jetzt konfigurieren wir die zweite grub-Stufe, indem wir die folgende Datei einrichten:

  mount /dev/sdx1 /mnt/
  joe /mnt/boot/grub/menu.lst
  
In diese Datei kommt jetzt dieser Inhalt (siehe LinuxOhneBildschirm):

  # -TB-
  # Erste serielle Schnittstelle mit 38400 bps einrichten
  serial --unit=0 --speed=38400
  # und diese als Terminal benutzen
  terminal serial
  #
  default 0
  timeout         1
  #
  title           Debian GNU/Linux, kernel 2.6.26-2-486
  root            (hd0,0)
  kernel          /boot/vmlinuz-2.6.26-2-486 root=/dev/hda2 ro console=ttyS0,38400n8   reboot=bios
  initrd          /boot/initrd.img-2.6.26-2-486
  #
  title           Debian GNU/Linux, kernel 2.6.26-2-486 (single-user mode)
  root            (hd0,0)
  kernel          /boot/vmlinuz-2.6.26-2-486 root=/dev/hda2 ro console=ttyS0,38400n8 reboot=bios single
  initrd          /boot/initrd.img-2.6.26-2-486
  

Als letztes kopieren wir das frisch mit '''bootcdwrite''' erzeugte Image in die zweite Partition:

  dd if=/var/spool/bootcd/cdimage.iso of=/dev/sdx2

Hat man in Zukunft etwas am Image verändert, so braucht man nur diesen letzten Schritt zu wiederholen.