# Ruimte besparen

## Analyse

Eén van de keerzijden in de prototype fase van het project was dat de disketteset niet zo heel erg bruikbaar was. De enige opdrachten die hier werkten waren de interne opdrachten van de BASH-shell. We zouden onze rootdisk kunnen verbeteren door opdrachten als `cat`, `ls`, `mv`, `rm`, enzovoort te installeren. Helaas hebben we maar weinig ruimte. Op de huidige rootdisk staan geen gedeelde library's, dus elk utility zou net als de BASH-shell statisch moeten worden gelinkt. Veel grote binary's in combinatie met een statische shell zouden al snel de weinige 1.44M beschikbare diskruimte overschrijden. Dus ons hoofddoel in deze fase is maximaal te besparen op de ruimte op de rootdisk en de weg te banen voor uitgebreidere functionaliteit in de volgende fase.

## Ontwerp

Kijk nog eens in de Bootdisk-HOWTO en merk op hoeveel utility's op een 1.44M diskette kunnen worden geperst. Er zijn drie dingen die dit mogelijk maken. Eén is het gebruik van gedeelde library's. De tweede zijn de gestripte library's en de derde is het gebruik van een gecomprimeerd bestandssysteem. We kunnen deze technieken allemaal gebruiken om ruimte op onze rootdisk te besparen.

### Gedeelde library's

Als eerste zullen we de BASH-shell opnieuw moeten bouwen om gebruik te kunnen maken van gedeelde library's. Dit keer zullen we het zonder de optie `--enable-static-link` configureren. Zodra BASH eenmaal opnieuw is gecompileerd, zullen we uit moeten zoeken met welke library's het is gelinkt en deze library's op moeten nemen op de rootdisk. De opdracht `ldd` maakt deze taak makkelijk. Door het op de opdrachtregel typen van `ldd bash` krijgen we een lijst te zien met alle gedeelde library's waar BASH gebruik van maakt. Zolang deze library's allen naar de rootdisk worden gekopieerd, zou de nieuw gecompileerde BASH prima moeten werken.

### Gestripte binary's

Vervolgens zouden we binary's kunnen strippen die naar de rootdisk worden gekopieerd. De manpage van `strip` beschrijft niet veel meer over wat het doet dan het "strip verwerpt alle symbolen uit de objectbestanden." Het lijkt of het verwijderen van delen uit een binary het als onbruikbaar achterlaat, maar dit is niet het geval. De reden dat het werkt, komt doordat een groot aantal van deze verworpen symbolen wordt gebruikt voor het opsporen van programmeerfouten. Ondanks dat deze debugging symbolen zeer behulpzaam zijn voor programmeurs die er ter verbetering van de code mee werken, doen ze voor de gemiddelde gebruiker niet veel meer dan het innemen van meer diskruimte. En aangezien ruimte op een diskette een toegift is, kunnen we beslist maar beter zoveel mogelijk symbolen uit BASH en andere binaire bestanden verwijderen voordat we ze naar de ramdisk kopiëren.

Het proces bestaande uit het strippen van bestanden om ruimte te besparen, werkt ok voor gedeelde library-bestanden. Maar bij het strippen van library's is het van belang gebruik te maken van de optie `--strip-unneeded` ter voorkoming dat ze beschadigd raken. Met `--strip-unneeded` neemt de bestandsomvang af, maar blijven de symbolen nodig voor het veranderen van het geheugenadres intact wat bij gedeelde library's voor de juiste werking nodig is.

### Gecomprimeerd bestandssysteem

Als laatste kunnen we het probleem aanpakken hoe we een gecomprimeerd root bestandssysteem bouwen. In de Bootdisk-HOWTO worden drie manieren aanbevolen voor het construeren van een gecomprimeerd root bestandssysteem met behulp van een ramdisk, een vrije harddiskpartitie of een loopbackdevice. Bij dit project zullen we ons concentreren op het gebruik van de ramdisk benadering. Het lijkt logisch dat als het root bestandssysteem vanaf een ramdisk gaat worden uitgevoerd, het net zo goed ook op een ramdisk kan worden gebouwd. We hoeven slechts een second extended bestandssysteem op een ramdisk device aan te maken, het te mounten en er bestanden naar te kopiëren. Zodra het bestandssysteem is voorzien van alle bestanden die op de rootdisk nodig zijn, umounten we het eenvoudigweg, comprimeren het en schrijven het weg naar diskette.

Hiervoor moeten we zorgen dat de kernel is geconfigureerd met ondersteuning voor de ramdisk met een standaardomvang van 4.096K. Als de omvang van de ramdisk iets anders is dan 4.096K, dan kan dit worden gecorrigeerd door de regel "ramdisk=4096" toe te voegen aan het `lilo.conf` bestand van het ontwikkelsysteem. De manpage lilo.conf(5) geeft hierover meer informatie.

## Constructie

In deze sectie wordt gebruik gemaakt van ramdisk zeven (`/dev/ram7`) om het rootimage te bouwen. Er is niets bijzonder speciaal aan ramdisk zeven en het is mogelijk een van de andere beschikbare ramdisks te gebruiken op voorwaarde dat ze niet reeds in gebruik zijn.

### Maak een ramdisk aan

    bash# dd if=/dev/zero of=/dev/ram7 bs=1k count=4096
    bash# mke2fs -m0 /dev/ram7
    bash# mount /dev/ram7 /mnt

### Compileer de BASH-shell opnieuw

    bash# cd /usr/src/bash-2.05a
    bash# make distclean
    bash# ./configure --enable-minimal-config --host=i386-pc-linux-gnu
    bash# make
    bash# strip bash

### Stel vast welke library's nodig zijn

    bash# ldd bash

Let op de uitvoer van de opdracht `ldd`. Het zou er ongeveer uit moeten zien als in onderstaand voorbeeld.

    bash# ldd bash
    libdl.so.2=> /lib/libdl.so.2 (0x4001d000)
    libc.so.6=>  /lib/libc.so.6 (0x40020000)
    /lib/ld-linux.so.2=> /lib/ld-linux.so.2 (0x40000000)

### Kopieer BASH en de library's naar de ramdisk

    bash# mkdir /mnt/bin
    bash# cp bash /mnt/bin
    bash# ln -s bash /mnt/bin/sh
    bash# mkdir /mnt/lib

    bash# strip -o /lib/libdl.so.2 /mnt/lib/libdl.so.2
    bash# strip -o /lib/libc.so.6 /mnt/lib/libc.so.6
    bash# strip -o /lib/ld-linux-so.2 /mnt/lib/ld-linux-so.2
    bash# chmod +x /mnt/lib/*

`strip -o` lijkt misschien wel een vreemde manier om library bestanden vanaf het ontwikkelsysteem naar ramdisk te kopiëren. Tijdens het bestandstransport van de bronlokatie naar de doellokatie stript het de symbolen. Het effect hiervan is dat de symbolen uit de library op de ramdisk worden verwijderd, zonder dat de library's op het ontwikkelsysteem worden gewijzigd. Helaas gaan bij het op deze wijze kopiëren van de library's de bestandspermissies verloren, wat de reden is van de opdracht `chmod +x` om de uitvoerbare vlag op alle library's op de rootdisk in te stellen.

### Maak een consoledevice aan

    bash# mkdir /mnt/dev
    bash# mknod /mnt/dev/console c 5 1

### Comprimeer het ramdiskimage

    bash# cd /
    bash# umount /dev/ram7
    bash# sync
    bash# dd if=/dev/ram7 of=~/phase2-image bs=1k
    bash# gzip -9 ~/phase2-image

### Kopieer het gecomprimeerde image naar diskette

Doe de diskette met het label "rootdisk" in het diskettestation fd0.

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

## Implementatie

### Systeemstart

Volg voor het booten de volgende stappen:

- Herstart de PC met behulp van de lilo bootdisk uit het vorige hoofdstuk.

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

- Doe de nieuwe gecomprimeerde rootdisk in het diskettestation wanneer dit wordt aangegeven.

De schermuitvoer zou vergelijkbaar moeten zijn met onderstaand voorbeeld:

    boot: bootdisk 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) read-write.
    Freeing unused kernel memory: 178k freed
    # _

### Verifieer de resultaten

Deze nieuwe rootdisk zou exact hetzelfde moeten functioneren als de rootdisk uit hetzelfde hoofdstuk als de implementatie succesvol was. Het belangrijkste verschil is dat deze gecomprimeerde rootdisk veel meer ruimte heeft om te groeien en we zullen deze extra ruimte nuttig gebruiken in de volgende fase van het project.

### Systeem afsluiten

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