Vælg en virtuel maskine og kod

Lav dit eget operativsystem, del 2

Når du udvikler operativsystemer, har du brug for løbende at teste det. Det er umuligt at skrive 100 linjers kode og blot tro, at det fungerer. Der er flere subtile ting, der kan gå galt. Det er en god idé at teste løbende, så man finder sine fejl i tide. Det er nemmest at lave manuel testning, dvs. afprøve sit operativsystem med jævne mellemrum og gennemføre forskellige test-scenarier. Du kan downloade mange gode virtuelle maskiner. Find en, der passer til dine behov. Jeg bruger selv Qemu, men har også brugt Bochs i lang tid. Bochs er rimelig nem at komme i gang med og fungerer på både Linux og Windows. Den har en debugger indbygget, hvilket gør den til et kraftfuldt værktøj. Ulempen er, at den kører langsomt, da den simulerer en fysisk computer på et lavt niveau og ikke bruger nogen optimeringstricks. Derfor bruger jeg nu Qemu, som kører væsentligt hurtigere. Den har også mulighed for debugging, men det er ikke lige så nemt at sætte op som i Bochs.

Start allerede nu med at downloade og installere Bochs eller Qemu. Læs starten af deres dokumentation om, hvordan man kommer i gang med at sætte en virtuel maskine op, og hvordan den styres. Jeg plejer at sætte den til at boote fra cd, da det er nemt at lave et cd-image (en iso-fil). Hvis du bruger Windows, skal du hente og installere et par ting, som normalt er tilgængelige på Linux (men Linux-folk, tjek lige efter for en sikkerheds skyld). Download og installer assembleren NASM – The Netwide Assembler. I Windows skal du sørge for at sætte din PATH-systemvariabel til, hvor nasm.exe er placeret. En assembler er forgængeren til compileren. Den tager en tekstfil med en række instruktioner til CPU'en og laver den om til en binær fil. En assembler er simpel, fordi den oversætter instruktionerne en efter en. Den binære fil er blot en anden repræsentation af de instruktioner, du skriver i tekstformat.

Lad os komme i gang. Åbn en simpel teksteditor (brug f.eks. Notepad i Windows) og indtast følgende assembler-program. Gem filen som “kernel.asm”.

bits32

    org0x100000

 

 

    MULTIBOOT_MAGIC    equ0x1BADB002

    MULTIBOOT_FLAGS    equ0x00010000

    MULTIBOOT_CHECKSUM equ -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS)

 

    multiboot_info:

        ; Følgende koder læser Grub for at indlæse vores kerne.

        dd  MULTIBOOT_MAGIC

        dd  MULTIBOOT_FLAGS

        dd  MULTIBOOT_CHECKSUM ; Checksum af ovenstående flags.

        dd  multiboot_info

        dd  multiboot_info

        dd  0

        dd  0

        dd  start   ; Angiver hvor Grub kalder vores kerne.

 

 

 

    start:

 

        ; Her overtager vi kontrollen over computeren fra Grub.

        ; Vi flytter tegn ud til grafikkortets teksthukommelse,

        ; som resulterer i tekst skrevet på skærmen.

 

        movdword[0xB8000], 'H e ' ; <-- Sørg for at fylde ud

        movdword[0xB8004], 'l l ' ; med mellemrum til sidst,

        movdword[0xB8008], 'o   ' ; så der er 4 tegn i alt.

        movdword[0xB800C], 'W o ' ; mellemrummet bliver her

        movdword[0xB8010], 'r l ' ; brugt som en kontrolkode,

        movdword[0xB8014], 'd ! ' ; der giver grøn baggrund.

 

        ; Vi stopper CPU'en ved at få den til at køre i en uendelig løkke.

 

        jmp$

    bits32

    org0x100000

 

 

    MULTIBOOT_MAGIC    equ0x1BADB002

    MULTIBOOT_FLAGS    equ0x00010000

    MULTIBOOT_CHECKSUM equ -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS)

 

 

    multiboot_info:

 

        ; Følgende koder læser Grub for at indlæse vores kerne.

 

        dd  MULTIBOOT_MAGIC

        dd  MULTIBOOT_FLAGS

        dd  MULTIBOOT_CHECKSUM ; Checksum af ovenstående flags.

        dd  multiboot_info

        dd  multiboot_info

        dd  0

        dd  0

        dd  start   ; Angiver hvor Grub kalder vores kerne.

 

 

 

    start:

 

        ; Her overtager vi kontrollen over computeren fra Grub.

        ; Vi flytter tegn ud til grafikkortets teksthukommelse,

        ; som resulterer i tekst skrevet på skærmen.

 

        movdword[0xB8000], 'H e ' ; <-- Sørg for at fylde ud

        movdword[0xB8004], 'l l ' ; med mellemrum til sidst,

        movdword[0xB8008], 'o   ' ; så der er 4 tegn i alt.

        movdword[0xB800C], 'W o ' ; mellemrummet bliver her

        movdword[0xB8010], 'r l ' ; brugt som en kontrolkode,

        movdword[0xB8014], 'd ! ' ; der giver grøn baggrund.

        ; Vi stopper CPU'en ved at få den til at køre i en uendelig løkke.

        jmp$

 

Nu skal vi lave vores assembler-fil om til en binær fil. Åbn en terminal eller kommandoprompt. Gå til den mappe, hvor kernel.asm ligger, og kør NASM:
    nasm -f bin -o kernel.bin kernel.asm
Hvis alt gik godt, og der ikke kom nogen fejlmeddelelser, så skulle du gerne have en fil, der hedder “kernel.bin”. Opret en ny tekstfil og kald den “menu.lst”. Den indeholder følgende:

    # Dette definerer en indgang i Grub til at starte vores kerne.

 

    title Min foerste kerne

 

    kernel /boot/kernel.bin

Test din kerne

Når de tre filer er på plads, skal vi lave det hele til en iso-fil, som vores virtuelle maskine kan køre. Hvis du bruger Windows, kan du google efter “cdrtools windows” og installere det. Hvis du bruger Linux, har du formentlig allerede pakken installeret. Pakken indeholder et værktøj, der kan lave bootable cd'er. Åbn en terminal eller kommandoprompt og gå til mappen over iso-mappen, som du lige har oprettet. Lav en iso-fil med denne kommando (det er én lang linje):
    mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4
    -boot-info-table -o boot.iso iso
Hvis alt gik godt, skulle du nu have en fil kaldet “boot.iso”. Konfigurer Bochs eller Qemu til at boote fra “boot.iso” (man kan se det som en virtuel cd). Start din virtuelle maskine og se magien udvikle sig. Hvis alt går som forventet, ender du op med noget, der minder om dette skærmbillede:


Tillykke, du har nu lavet din første kerne!

Gør en forskel

Er der et marked for nye operativsystemer på x86-platformen? Det er et godt spørgsmål. Der findes allerede Windows, Mac OS X, Linux, FreeBSD, Syllable og mange andre, så hvad skal vi med et nyt, kan man spørge sig selv. Jeg tror, det er sundt, at der bliver udviklet mange operativsystemer.

  • Du kan præsentere nogle grundlæggende nye ideer for operativsystemer, som andre bagefter kan bruge, f.eks. Linux. Det kan være svært at overbevise Linux-folkene om, at de skal skrive en masse kode, før de har set, at det er smart. På den måde kan du udvikle eksisterende operativsystemer indirekte. 
  •  Hvis der er mange operativsystemer, er der fortsat interesse i standardiseringsarbejde. Det er vigtigt, at der er åbne standarder for de mest grundlæggende enheder i en computer, f.eks. CPU'ens instruktioner. Ellers ødelægger det konkurrencen, og vi ender op med dyre computere. Tværtimod bliver x86-platformen billigere og billigere, fordi der sker en kraftig udvikling og konkurrence. Hvis der kun er et stort operativsystem til en platform, bliver det svært at argumentere for, at man skal lave standarder for den platform. Måske bliver dit lille hobby-operativsystem ikke særlig populært på lang sigt, men det holder udviklingen i gang.
  • Hvis der kommer en kritisk masse af hobby-operativsystemer, vil der måske begynde at ske noget spændende omkring drivere. Som eksempel skal en webcam-producent i dag lave en forskellig driver til Windows, Mac OS X og Linux, hvis webcam'et skal fungere i de tre operativsystemer. Det er dyrt, og nogle producenter vælger kun at lave en driver til Windows. Hvis man i stedet brugte åbne standarder og API'er til at bygge sine drivere, ville det være nemt og billigt at udvikle den til mange systemer. Det kan kun ske, hvis der bliver udviklet kraftfulde driverstandarder og API'er, som fungerer på tværs af platforme. Der er allerede opfundet to standarder, UDI og EDI. Du kan med dit hobby-OS være med til at præge den debat, der er omkring portering af drivers, som måske bliver vigtig i fremtiden. Portering af drivers er vigtig. Se blot på skiftet mellem 32-bit og 64-bit Windows. Der er gået lang tid, før nogle drivers i 64-bit Windows fungerede ordentligt. Årsagen er, at driverproducenterne skulle starte forfra og ikke blot kunne portere de eksisterende drivers. Da man opfandt Windows i sin tid, havde man ikke forestillet sig, at man skulle understøtte 64-bit. At have portable drivers gør det nemmere og billigere at skifte til en ny platform i fremtiden.

 

Alle værktøjer, der er brugt i denne artikel, er open source-software, der nemt kan downloades. Du kan finde links og en zip-fil med eksemplet i denne artikel på følgende side:
http://purl.org/net/bjarke-walling-os-artikel

 


En OS-udviklers værktøjskasse:
● En virtuel maskine, gerne med mulighed for debugging – Bochs, Qemu, Virtual Box, VMware
● En bootloader/boot manager – jeg anbefaler Grub
● En assembler – NASM, Yasm, Gas
● En C-compiler – GCC, MinGW, DJGPP, MS Visual Studio 6 (ikke .NET-udgaven)
● En teksteditor med syntax highligting for assembler, C og andre sprog – f.eks. Notepad2
● Manualer, tonsvis af online manualer – primært Intels Instruction Set Architecture-manualer og andre alt efter, hvilke hardwareenheder du vil snakke med
● En god søgemaskine – Google
● Derudover bør du have:
 Adgang til et online forum, hvor man kan stille spørgsmål – f.eks. osdev.org
 Engelskkundskaber (du skal læse en masse stof på engelsk)
 Tålmodighed og gerne nysgerrighed