# Een aantal basisutility's

## Analyse

In het vorige hoofdstuk leek het wellicht of we niet zo veel bewerkstelligden. Er werd veel energie gestoken in het opnieuw ontwerpen van de rootdisk, maar de functionaliteit bleef in feite hetzelfde als in de initiële prototypefase. De rootdisk doet nog steeds niet zo veel. Maar we brachten veelbetekenende verbeteringen aan wanneer het aankomt op ruimtebesparingen. In deze fase zullen we die extra ruimte nuttig gebruiken en beginnen de rootdisk met zoveel utility's vol te proppen als erop passen.

De eerste twee rootdisks die we samenstelden hadden alleen interne shell-opdrachten zoals `echo` en `pwd`. Voor deze fase zou het prettig zijn om een aantal van de algemeen gebruikte externe opdrachten zoals `cat`, `ls`, `mkdir`, `rm` en dergelijke op de rootdisk te hebben. Dit in gedachten houdend kunnen we de doelen voor deze fase als volgt definiëren:

- Behoud alle functionaliteit van de vorige rootdisk.

- Voeg een aantal algemeen in gebruik zijnde externe opdrachten toe.

## Ontwerp

### Bepalen van de benodigde opdrachten

De eerste vraag die wellicht opkomt is, "Hoe weten we welke opdrachten nodig zijn?" Het is mogelijk gewoon met `cat` en `ls` te beginnen en dan andere opdrachten te installeren wanneer we erachter komen dat we ze nodig hebben. Maar dit is verschrikkelijk inefficiënt. We hebben een plan of een blauwdruk nodig om vanuit te werken. Hiervoor kunnen we ons wenden tot de Filesystem Hierarchy Standard (FHS) beschikbaar vanaf http://www.pathname.com/fhs/. De FHS dicteert welke opdrachten aanwezig zouden moeten zijn op een GNU/Linux systeem en waar ze in de directorystructuur zouden moeten worden geplaatst.

### Lokaliseren van broncode

De volgende logische vraag is, "Nu we weten wat we nodig hebben, waar halen we de broncode vandaan?" Het antwoord op deze vraag kan worden gevonden door het Internet te doorzoeken. Er zijn verscheidene goede Internetbronnen in omloop die ons kunnen helpen in onze speurtocht naar broncode. Een goede plek om te beginnen te zoeken is de Linux Software Map (LSM) op Ibiblio. Ibiblio's LSM zoekpagina is te vinden door te navigeren naar http://www.ibiblio.org/pub/linux. Door als trefwoorden de namen van opdrachten te gebruiken, zouden we in staat moeten zijn met de naam en lokatie van het corresponderende broncodepackage aan te komen.

### De invloed van de FHS

Laten we eens kijken naar de vereisten van de FHS voor de `/bin` directory. De eerste paar opdrachten in de lijst zijn `cat`, `chgrp`, `chmod` & `chown`. Na deze trefwoorden te hebben gebruikt in een LSM zoekactie komen we tot de ontdekking dat we het GNU textutils package nodig hebben voor cat en het GNU fileutils package voor `chmod`, `chrp` & `chown`. In feite komen aardig wat opdrachten in `/bin` uit GNU fileutils. Dus een goede manier om het probleem aan te pakken betreffende het op zoek gaan naar de broncode zou kunnen zijn de opdrachten per package te groeperen, zoals hieronder wordt getoond.

- De BASH shell -- `echo`, `false`, `pwd`, `sh`, `true`

- GNU textutils -- `cat`

- GNU fileutils -- `chgrp`, `chmod`, `chown`, `cp`, `dd`, `df`, `ln`, `ls`, `mkdir`, `mknod`, `mv`, `rm`, `rmdir`, `sync`

- GNU sh-utils -- `date`, `hostname`, `stty`, `su`, `uname`

Deze vier packages bevatten niet alle opdrachten in de `/bin` directory, maar ze vertegenwoordigen er meer dan 70% van. Dat zou voldoende moeten zijn voor het bewerkstelligen van ons doel in het toevoegen van een aantal van de algemeen in gebruik zijnde externe opdrachten. We kunnen ons in latere fasen van het project altijd nog bezig houden met de resterende opdrachten.

## Constructie

In plaats van het direct kopiëren van de bestanden naar de ramdisk, kunnen we het makkelijker maken door een fasegebied op te zetten. Het fasegebied zal ons ruimte geven om te werken zonder ons druk te hoeven maken over de ruimtebeperkingen van de ramdisk. Het zal ook voorzien in een manier om ons werk op te slaan en het makkelijker maken om de rootdisk in latere fasen van het project uit te breiden.

De faseprocedure werkt als volgt:

1. Maak een directorystructuur aan gedefinieerd in de FHS.

2. Kopieer de bestanden vanaf de rootdisk uit fase 2.

3. Bouw de vier nieuwe packages vanuit de broncode.

4. Installeer de bestanden naar de correcte FHS directory's.

5. Strip de binary's om ruimte te besparen.

6. Controleer op library afhankelijkheden.

7. Kopieer de gehele directorystructuur naar de ramdisk.

8. Comprimeer de ramdisk en schrijf het weg naar diskette.

### Maak een fasegebied aan

    bash# mkdir ~/fase
    bash# cd ~/fase
    bash# mkdir bin boot dev etc home lib mnt opt proc root sbin tmp usr var
    bash# mkdir var/log var/run

### Kopieer de inhoud van de rootdisk uit fase 2

    bash# dd if=~/phase2-image.gz | gunzip -c > /dev/ram7
    bash# mount /dev/ram7 /mnt
    bash# cp -dpR /mnt/* ~/fase
    bash# umount /dev/ram7
    bash# rmdir ~/fase/lost+found

### Installeer "cat" uit GNU Textutils

    bash# cd /usr/src/textutils-2.1
    bash# ./configure --host=i386-pc-linux-gnu
    bash# make
    bash# cd src
    bash# cp cat ~/fase/bin

### Installeer de binary's uit GNU fileutils

    bash# cd /usr/src/fileutils-4.1
    bash# ./configure --host=i386-pc-linux-gnu
    bash# make
    bash# cd src
    bash# cp chgrp chmod chown cp dd df ln ls ~/fase/bin
    bash# cp mkdir mkfifo mknod mv rm rmdir sync ~/fase/bin

### Installeer binary's uit sh-utils

    bash# cd /usr/src/sh-utils-2.0
    bash# ./configure --host=i386-pc-linux-gnu
    bash# make
    bash# cd src
    bash# cp date hostname stty su uname ~/fase/bin

### Kopieer aanvullende library's

    bash# ldd ~/fase/bin/cat
    bash# ldd ~/fase/bin/ls
    bash# ldd ~/fase/bin/su
    bash# ls ~/fase/lib
    bash# cp /lib/librt.so.1 ~/fase/lib
    bash# cp /lib/libpthread.so.0 ~/fase/lib
    bash# cp /lib/libcrypt.so.1 ~/fase/lib

### Strip binary's en libary's

    bash# strip ~/fase/bin/*
    bash# strip --strip-unneeded ~/fase/lib/*

### Maak een gecomprimeerd rootdiskimage aan

    bash# cd /
    bash# dd if=/dev/zero of=/dev/ram7 bs=1k count=4096
    bash# mke2fs -m0 /dev/ram7
    bash# mount /dev/ram7 /mnt
    bash# cp -dpR ~/fase/* /mnt
    bash# umount /dev/ram7
    bash# dd if=/dev/ram7 of=~/phase3-image bs=1k
    bash# gzip -9 ~/phase3-image

### Schrijf het rootdiskimage naar diskette

Doe de diskette met het label "root disk" in het station fd0.

    bash# dd if=~/phase3-image.gz of=/dev/fd0 bs=1k

## Implementatie

We zullen voor de werking van een aantal opdrachten een read-write bestandssysteem nodig hebben. Het normale functioneren van de kernel is root read-only te mounten, maar we kunnen dit wijzigen met behulp van een kerneloptie. Door aan LILO rw door te geven voor init=/bin/sh zullen we een read-write root bestandssysteem krijgen.

### Systeemstart

Volg de volgende stappen voor het activeren van het systeem.

- Boot de PC met behulp van de LILO bootdisk.

- Typ achter de LILO prompt `bootdisk rw init=/bin/sh` en druk op Enter.

- Doe de recent aangemaakte rootdisk in het diskettestation wanneer dit wordt aangegeven.

De terminalweergave zal er ongeveer uitzien zoals in het volgende voorbeeld.

    boot: bootdisk rw init=/bin/sh
    Loading bootdisk
    Uncompressing Linux... Ok, booting kernel.
    ..
    .. [diverse kernelmeldingen]
    ..
    VFS: Insert root floppy to be loaded into RAM disk and press ENTER
    RAMDISK: Compressed image found at block 0
    VFS: Mounted root (ext2 filesystem).
    Freeing unused kernel memory: 178k freed
    # _

### Nieuwe opdrachten testen

Probeer een aantal nieuwe opdrachten te gebruiken nu het systeem beschikbaar en werkend is.

    bash# uname -a
    bash# ls /etc
    bash# echo "PocketLinux" > /etc/hostname
    bash# hostname $(cat /etc/hostname)
    bash# uname -n
    bash# mkdir /home/stuff
    bash# cd /home/stuff

Als alles goed gaat dan zouden de opdrachten `cat`, `ls` en `hostname` nu moeten werken. Zelfs `mkdir` zou nu moeten werken aangezien het root bestandssysteem read-write is gemount. Aangezien we gebruik maken van een ramdisk zullen alle wijzigingen die we aanbrengen verloren gaan zodra de PC wordt gereset.

### Systeem afsluiten

Verwijder de diskette uit fd0 en herstart het systeem met CTRL-ALT-DELETE.