• Linux startar på Atari Jaguar – spelkonsolen med bara 2 MB minne

    Atari Jaguar blev aldrig den försäljningssuccé som Atari hoppades på. Mer än 30 år senare har den omdiskuterade spelkonsolen ändå lyckats med något oväntat: att starta Linux direkt från en spelkassett.

    Linux har genom åren körts på allt från kraftfulla superdatorer och mobiltelefoner till routrar, mikrovågsugnar och gamla spelkonsoler. Nu har ytterligare en osannolik maskin lagts till på listan.

    Utvecklaren bakom namnet Cakehonolulu har lyckats starta Linux på Atari Jaguar, en spelkonsol som lanserades i Nordamerika i november 1993. Systemet kör en tidig version av Linuxkärnan 7.2 tillsammans med en mycket liten kommandotolk baserad på BusyBox.

    Resultatet är inte någon modern Linuxdator med skrivbord, webbläsare och nätverksanslutning. Det som visas är en enkel textbaserad kommandotolk. Men med tanke på konsolens extrema begränsningar är det ändå en imponerande teknisk bedrift.

    Atari satsade på ”64 bitar”

    När Atari Jaguar presenterades marknadsfördes den som världens första 64-bitars spelkonsol. Påståendet blev omdiskuterat eftersom maskinen egentligen bestod av flera olika processorer och kretsar med olika bitbredder.

    I centrum finns en Motorola 68000-processor, samma processorfamilj som användes i bland annat de första Macintosh-datorerna,Atari ST, Commodore Amiga, Sega Mega Drive och Neo Geo.

    Jaguar innehåller också två specialkretsar som Atari döpte till Tom och Jerry.

    Tom ansvarar främst för grafik, objektbehandling och bildöverföring, medan Jerry bland annat innehåller en digital signalprocessor, timers och funktioner för ljud och seriell kommunikation.

    Trots den påstådda 64-bitarsprestandan blev Atari Jaguar ett kommersiellt misslyckande. Konsolen fick svårt att konkurrera med bland annat Sega Saturn och den första Sony PlayStation. Inte heller tillbehöret Jaguar CD lyckades vända utvecklingen.

    En processor utan minneshantering

    Det första stora hindret för att starta Linux är Jaguars Motorola 68000-processor.

    Processorn saknar en så kallad Memory Management Unit, vanligtvis förkortad MMU. En sådan krets används av moderna operativsystem för att skapa virtuellt minne och hålla olika programs minnesområden åtskilda.

    Det är därför vanligt att säga att Linux kräver en MMU. Det är dock inte helt korrekt.

    Linux innehåller fortfarande stöd för system utan minneshanteringsenhet genom tekniken som ursprungligen utvecklades inom projektet uClinux. För Motorola 68000 kan Linux därför byggas i ett särskilt NOMMU-läge med en enklare och platt minnesmodell.

    Det innebär att programmen arbetar direkt mot datorns fysiska minne utan det skydd och den flexibilitet som virtuellt minne normalt ger.

    Det fungerar, men gör systemet betydligt känsligare för minnesfel och ställer särskilda krav på både program och kompilator.

    Bara 2 MB arbetsminne

    Nästa problem är minnet.

    Atari Jaguar har endast 2 MB RAM. Det är mindre arbetsminne än vad en enda vanlig bild från en modern mobilkamera kan kräva.

    Att kopiera både Linuxkärnan och ett komplett filsystem till arbetsminnet skulle därför snabbt fylla hela minnet.

    Lösningen blev att använda XIP, en förkortning av execute in place. Det betyder att delar av programkoden körs direkt från ROM-minnet i spelkassetten i stället för att först kopieras till RAM.

    Linuxkärnan delades därför upp i två delar.

    De skrivskyddade delarna, bland annat programkod och konstanta data, ligger kvar i spelkassettens ROM-minne. De delar som måste kunna ändras under körningen placeras i konsolens RAM.

    Det handlar bland annat om följande programsektioner:

    • .text innehåller körbar programkod.
    • .rodata innehåller skrivskyddade data.
    • .data innehåller föränderliga data med startvärden.
    • .bss innehåller föränderliga data som nollställs vid start.

    Genom att tala om för Linux var ROM och RAM finns kan kärnan själv hantera de nödvändiga flyttningarna mellan minnesområdena.

    Ljudkretsen blev Linux systemklocka

    Ett operativsystem behöver en regelbunden tidskälla.

    En timer skickar avbrott till processorn med jämna mellanrum och gör det möjligt för Linux att planera när olika processer ska få använda processorn. Utan en fungerande timer kan kärnans schemaläggare inte arbeta korrekt.

    Atari Jaguar saknar den typ av standardtimer som Linux normalt förväntar sig på en dator.

    Utvecklaren använde därför en av de timers som finns i Jerry-kretsen. Dessa var främst avsedda för ljud och signalbehandling men kan även skapa avbrott för Motorola-processorn.

    En krets som ursprungligen hjälpte spelutvecklare att skapa ljud används därmed som systemklocka för Linux.

    Först behövdes någon form av bildskärm

    När Linux anpassas till ny hårdvara måste utvecklaren kunna se kärnans meddelanden. Annars går det inte att veta om systemet har startat, hängt sig eller kraschat.

    I en vanlig dator skickas de första meddelandena ofta genom en seriell port.

    Jerry-kretsen har anslutningar för seriell sändning och mottagning, kallade TXD och RXD. Utvecklaren skrev därför en liten konsoldrivrutin som skickar ut tecken genom dessa anslutningar.

    På så sätt kunde Linux tidiga startmeddelanden läsas från en annan dator.

    Senare skrevs även en enkel konsoldrivrutin för Tom-kretsen. Den gör det möjligt att visa text på en bildskärm när Linux körs på en riktig Atari Jaguar och inte bara i en emulator.

    Kompilatorn skapade förbjudna minnesåtkomster

    När de första försöken gjordes kom inga startmeddelanden alls.

    Problemet visade sig ligga i den korskompilator för Motorola 68000 som följde med Ubuntu. Kompilatorn skapade instruktioner som försökte läsa data från felaktigt justerade minnesadresser.

    Nyare processorer kan ofta hantera sådana åtkomster automatiskt, men den ursprungliga Motorola 68000 kan inte göra det. Resultatet blev att processorn kraschade innan Linux hann skriva något på konsolen.

    Lösningen var att bygga en egen m68k-elf-kompilator särskilt anpassad för den ursprungliga 68000-processorn.

    Ytterligare ett problem var att processorns avbrottsvektorer normalt förväntas ligga vid minnesadress noll. Jaguars kassett-ROM börjar däremot vid adressen 0x80000.

    De nödvändiga vektorerna måste därför kopieras till början av RAM-minnet innan Linux kan hantera avbrott och fel korrekt.

    Efter dessa ändringar började Linux slutligen skriva ut sina startmeddelanden:

    Linux version 7.2.0-rc1+
    uClinux with CPU MC68000
    Flat model support
    

    BusyBox fick bli hela användarmiljön

    Att starta Linuxkärnan är bara halva arbetet. Kärnan måste även kunna starta ett användarprogram, vanligtvis processen init.

    På en vanlig Linuxdistribution startar init-processen flera systemtjänster och förbereder resten av användarmiljön. På Atari Jaguar finns inte minne för något sådant.

    Systemet byggdes därför med Buildroot och BusyBox.

    BusyBox samlar små versioner av många vanliga Unix-kommandon i ett enda program. Samma binärfil kan fungera som exempelvis sh, ls, cat eller echo, beroende på vilket namn den startas med.

    Vanligtvis skapas länkar för alla dessa kommandon. På Jaguar tog även den processen för mycket minne.

    Startskriptet förenklades därför till att direkt köra:

    #!/bin/busybox sh
    
    /bin/busybox sh
    

    Resultatet är en minimal kommandotolk utan något traditionellt Linuxsystem runt omkring.

    Det räcker ändå för att visa att både Linuxkärnan och ett användarprogram kan köras på maskinen.

    Inga vanliga ELF-program

    De flesta moderna Linuxprogram distribueras som ELF-filer. I system utan MMU används i stället ofta det enklare binärformatet FLAT.

    BusyBox byggdes därför som en FLAT-binär med hjälp av Buildroot och verktyget elf2flt.

    Även C-biblioteket behövde anpassas. Systemet använder det resurssnåla biblioteket uClibc, men dess normala minneshanterare behövde bytas mot alternativet malloc-simple.

    Mer avancerade minneshanterare sparar extra information för att kunna göra framtida minnesallokeringar snabbare. På en maskin med bara 2 MB RAM kan själva bokföringen använda en märkbar del av minnet.

    Den enklare minneshanteraren är mindre effektiv men kräver betydligt mindre utrymme.

    Ingen vanlig bootloader

    Datorer använder normalt en bootloader, exempelvis U-Boot eller GRUB, för att förbereda hårdvaran och läsa in operativsystemet.

    På Jaguar skulle en sådan bootloader ta värdefullt utrymme i både ROM och RAM.

    Linuxbilden placeras därför direkt på spelkassetten. När konsolen startar hoppar programmet i princip direkt till den adress där Linuxkärnan finns.

    För riktig hårdvara måste kärnbilden även innehålla Jaguars kassett-header och placeras på rätt fasta adresser i ROM-minnet.

    Den färdiga spelkassetten innehåller därmed Linuxkärnan, det minimala filsystemet och BusyBox.

    Vad kan man använda det till?

    I praktiken inte särskilt mycket.

    Användaren får en liten kommandotolk på en spelkonsol med 2 MB RAM, utan modernt nätverk, grafiskt skrivbord eller vanliga program.

    Ingen kommer sannolikt att ersätta sin vanliga dator med en Atari Jaguar som kör Linux.

    Projektet visar däremot hur anpassningsbar Linuxkärnan fortfarande är. Genom att återanvända ljudtimers, köra kod direkt från en spelkassett och bygga en extremt liten användarmiljö går det att starta Linux på hårdvara som aldrig konstruerades för något operativsystem av detta slag.

    Det är kanske inte praktiskt.

    Men inom retrodatorvärlden är det ofta just det som är poängen: att undersöka hur långt gammal hårdvara kan pressas och lära sig hur datorns mest grundläggande delar faktiskt fungerar.

    Den modifierade Linuxkällkoden har publicerats öppet i projektets GitHub-arkiv.

    https://cakehonolulu.github.io/linux-for-jaguar

    > TEKNISKA DATA: ATARI JAGUAR MED LINUX

    Lanseringsår: 1993

    Huvudprocessor: Motorola 68000

    Processorarkitektur: m68k

    Arbetsminne: 2 MB RAM

    Kassett-ROM: Upp till 6 MB

    ROM-adress: 0x80000

    Specialkretsar: Tom och Jerry

    Linuxkärna: Linux 7.2.0-rc1

    Minnesmodell: NOMMU / uClinux

    Körningsmetod: XIP, Execute In Place

    Användarmiljö: BusyBox och Buildroot

    Binärformat: FLAT, bFLT

    C-bibliotek: uClibc med malloc-simple

    Systemkonsol: Seriell utmatning via Jerry samt bildskärmskonsol via Tom

    Systemtimer: Timer i Jerry-kretsen

    Bootloader: Ingen traditionell bootloader

    Startmetod: Kärnan startas direkt från kassettens ROM

    Resultat: En minimal Linux-kommandotolk

Etikett: spelhistoria

  • Linux startar på Atari Jaguar – spelkonsolen med bara 2 MB minne

    Atari Jaguar blev aldrig den försäljningssuccé som Atari hoppades på. Mer än 30 år senare har den omdiskuterade spelkonsolen ändå lyckats med något oväntat: att starta Linux direkt från en spelkassett. Linux har genom åren körts på allt från kraftfulla superdatorer och mobiltelefoner till routrar, mikrovågsugnar och gamla spelkonsoler. Nu har ytterligare en osannolik maskin…