Cítili jste někdy nostalgii nad starými operačními systémy? Já popravdě nijak zvlášť. Ano, cítím velký respekt k osobnostem jako je Ken Thompson, Dennis Ritchie nebo Gary Killdal, ale provozovat Unix poplatný začátku 70. let, nebo CP/M ze stejné doby mě – samo o sobě – neláká. Co však naopak lákavým shledávám, je provozovat tzv. "distraction-free" environment, tj. prostředí, ve kterém se můžete opravdu soustředit na jednu konkrétní úlohu aniž by vaše pozornost byla štěpena "tisícem a jednou" notifikací z tisíci a jedné další aplikace. A k tomu už se staré operační systémy dobře hodit mohou. Ostatně, jak by tomu také mohlo být jinak – v případě DOSu – na jednoúlohovém operačním systému? 😉

Následující text se zaměřuje na to, jak provozovat DOS-like operační systém v roce 2024 pod Fedora Linuxem. Už padlo, co bylo první z motivací pro takový krok; další (a zde už naopak určitou nostalgii cítím) jsou některé programovací jazyky z doby, kdy jsem je poznal před více než dvaceti lety (tj. ve stavu a podobě poplatné době před čtyřiceti a více lety). Konkrétně např. klasické K&R C. Kompilátory, jako je OpenWatcom, jsou open source a zároveň dostupné ve verzích právě i pro systémy, jako je některá z inkarnací DOS-like operačních systémů. A v duchu klasického "last but not least", mě láká i možnost pustit si staré hry včetně klasiky v podobě DOOMu. Suma sumárum, nic až tak dramatického.

Jaký DOS a na čem?

Z předchozího vyplynulo, že bych rád provozoval nějakou formu DOSu (ano, stále jste na serveru věnovanému Fedoře, nemějte obavy). Už od roku 1994 existuje projekt FreeDOS, jehož cílem je vytvoření DOS-like operačního systému maximálně kompatibilního s MS-DOSem (pro kontext, právě v roce 1994 bylo oznámeno, že Microsoft už nebude MS-DOS dále vyvíjet). FreeDOS je navíc open source, dodnes má kolem sebe relativně malou, ale sympatickou komunitu v čele s Jimem Hallem, který je původním autorem FreeDOSu (v roce 1994 PD-DOS aka "public domain" DOS). Ano existují i jiné známé (a pod Linuxem provozovatelné) projekty, jako je DOSBox, ale zde se již nejedná o plnohodnotný operační systém se vším všudy. (Což ale rozhodně neznamená, že bych ho jakkoliv zatracoval, naopak!)

Takže, na čem vůbec dnes lze provozovat FreeDOS? Sice lze říci, že počítač, který má v sobě – řekněme – nějaké CPU à la 486 se dá za rozumný peníz sehnat snad vždy, ale taková volba má i své nevýhody ve formě archaických rozhraní a nutnosti provozovat věci typu disketová mechanika. Bylo by fajn provozovat naše "distraction-free" prostředí, ale zároveň si zachovat alespoň některé výdobytky současné doby ve formě snadného sdílení dat a podobně. Co tedy současný hardware? Rychle narazíme jak na problém (vcelku logicky) v podobě chybějících ovladačů, tak na holý fakt, že soudobé počítače jsou EFI-only, často zcela bez legacy BIOSu – a to je něco, přes co (opět logicky) u DOSu nejede vlak.

"V" jako virtualizace a "E" jako emulace

Jsou přesně tím typem řešení, ke kterému se nakonec dostaneme. Protože se pohybujeme pod Fedorou (a obecně pod Linuxem), patrně nejpřímočařejší – a zároveň i výkonově komfortní – cestou, jak virtualizovat nějaký operační systém, bude za použití KVM. Pro pohodlné provozování FreeDOSu je zároveň více než vhodné prověřit, že zvolený nástroj bude schopen emulovat ve FreeDOSu podporovaný hardware. A pokud se řekne emulátor, opět není nutné chodit daleko, ve Fedoře jde o známé QEMU (Quick EMUlator). Ten má zároveň tu příjemnou vlastnost, že dovede pracovat s akcelerací přes KVM (výkonový propad bez jejího použití je naprosto zásadní). Samozřejmě není striktně nutné použít přímo QEMU, ale nějakou nadstavbu nad ním postavenou (libvirt) a spolu s tím některý z dostupných GUI nástrojů jako jsou gnome-boxes nebo virt-manager. Toto řešení si dále rozebereme, ale není jediné možné.

Existuje minimálně několik dalších cest, jak provozovat FreeDOS emulovaně, u několika se krátce se pozastavím:

  1. PCem, emulátor, který se nachází přímo v repozitářích Fedory. Má jednoduché, ale sympatické GUI. Ve výchozím stavu emuluje procesor 8088 používaný v původním IBM PC (na kterém FreeDOS na IBM 5150 prokazatelně provozovat lze) a lze nakonfigurovat i množství dalšího emulovaného hardware. Na určitý okruh použití jistě postačí.
  2. 86box (nezaměňovat s box86), jde o fork PCemu, dostupný jako copr repozitář. Samotná aplikace je licencovaná pod GNU GPL, ale pro plnohodnotné použití jsou nezbytné tzv. "ROM dumps", díky kterým je možné emulovat doslova gigantické množství historického hardware. Licenčně se však jedná o problematické řešení.
  3. dosemu2, uvádím ho zde proto, že i když jde rámcově o obdobné řešení jako u DOSBoxu (takže zde není použit FreeDOS jako takový), umožňuje alespoň přímočaře používat FreeDOSové userspace aplikace. I tento emulátor je dostupný jako copr repozitář. (Pro pořádek: původní dosemu je k dispozici v repozitáři rpmfusion-free.)

Podstatná věc je, že celou dobu se bavíme o virtualizaci (a emulaci) operačního systému, který je 16bitový a navržený a zkompilovaný pro architekturu x86. Pokud bychom chtěli provozovat FreeDOS na počítači, jako je některé z Raspberry Pi, je třeba mít na zřeteli, že se jedná o ARM a použít KVM pro provoz VM s FreeDOSem nebude možné. Můj pokus s Raspberry Pi 3, Fedorou a FreeDOSem ve VM vytvořeném přes QEMU ukázal (a nejen můj), že to není z hlediska výkonu dobré řešení (byť netvrdím, že je to nemožné – s novějšími generacemi Raspberry Pi může být situace lepší).

Atomic Pi s Fedorou a QEMU

Protože myšlenka provozu FreeDOSu na "něčem, jako je Raspbery Pi, ale s x86 CPU" mě lákala skoro od začátku, začal jsem se poohlížet o potřebném hardware. A opravdu, takových projektů několik existuje (nebo existovalo). Ve výsledku jsem zakoupil Atomic Pi, který kromě vzdáleně podobné velikosti s Raspberry Pi nemá s malinou mnoho společného a je vlastně zajímavé spíš tím, o jak běžný hardware (s obyčejným – ale zase s VT-x, takže i KVM podporujícím – CPU Intel Atom x5-Z8350 a obyčejným UEFI od AMI) se jedná. Běžný, ve Fedoře podporovaný, ale i zabugovaný (působící např. že se myš zasekává při dosažení levého okraje obrazovky, byť je pravdou, že workaround alespoň pro X server existuje).

Hostitel pro provoz QEMU s akcelerací pomocí KVM jsem tedy měl. V kombinaci s pár DC-DC měniči, trochou balsy, 10" LCD a nějakým tím pájením z toho vznikl malý jednoúčelový počítač. Software jsem zvolil tak minimalistický, jak to jen šlo. Fedora v minimální instalaci (nakonec doplněná o dnf groupinstall "Podpora hardware" – po minutách nechápavého civění na obrazovku s otázkou, proč se WiFi adaptér od Intelu nechce probrat k životu) s login manažerem ly pro správný look & feel a správcem oken i3 (použil bych sway, ale kvůli bugu výše jsem se uchýlil k řešení na X serveru, tedy s i3). Po přihlášení do systému se pak automaticky nahodí virtuální stroj s FreeDOSem.

QEMU krok za krokem

Nehledě na to, na jakém x86 železe se rozhodnete FreeDOS pod QEMU na Fedoře provozovat, je nutné (resp. vhodné v případě KVM) splnit několik základních prerekvizit.

1) Ověřte, že váš procesor podporuje KVM (pozor, podpora virtualizace může být deaktivovaná v UEFI/BIOSu):

cat /proc/cpuinfo | egrep "vmx|svm"    # jde-li o Intel, nebo AMD

2) A zda má načtený příslušný jaderný modul:

lsmod | grep kvm

3) Nainstalujte QEMU a pár základních utilit včetně nástroje pro manipulaci s virtuálními image:

sudo dnf in qemu-kvm qemu-img libguestfs -y 

4) Připravte si virtuální disk pro instalaci FreeDOSu:

qemu-img create -f qcow2 dos.qcow2 1G

Formát QCOW2 je příjemnou volbou, protože reálně vzniklý soubor zabírá pouze takové množství místa, jaké zrovna využíváte. Zároveň zvolená velikost 1 GB je postačující pro všechna myslitelná využití FreeDOSu, která mě napadají.

5) Stáhněte si LiveCD FreeDOSU, rozbalte archiv, a v adresáři obsahujícím FD13LIVE.iso nabootujte VM:

qemu-system-i386 --enable-kvm -m 8 \
  -boot order=d \
  -hda dos.qcow2 \
  -cdrom FD13LIVE.iso

Vytvořený VM bude mít vyhrazeno 8 MB RAM, používat akceleraci přes KVM a bude bootovat z CDROMu. Hned v dalším kroku nabootuje instalátor FreeDOSu s vcelku příjemným průvodcem, s jehož pomocí snadno dokončíte instalaci. A to je pro začátek celé, měli byste skončit s funkčním DOSovým systémem.

Instalátor FreeDOSu

Instalátor FreeDOSu

Po dokončení instalace pro přímý boot do FreeDOSu můžete změnit direktivu -boot na order=c, popřípadě ji zcela vypustit (jde o výchozí výchozí chování). Pro korektní vypnutí systému použijte příkazy HALT nebo SHUTDOWN (oba dělají totéž). FreeDOS samozřejmě není case-sensitive, takže lze použít i malá písmena, nicméně ponechme zápis takto pro rozlišení od předchozích příkazů v bashi 🙂

S QEMU mírně do hloubky

Předchozí příkaz pro QEMU je pro základní provoz DOSového systému postačující, ale zároveň spoléháme na výchozí konfiguraci QEMU, která se může v průběhu času změnit. Stejně tak použité argumenty jsou ve většině případů výše pouze zkratkou komplexnějšího zápisu v zájmu snadné čitelnosti a použití. To rozhodně není v žádném případě špatně, pojďme se podívat ale trochu více pod povrch. Po delším experimentování (takovýto zápis např. používá autor FreeDOSu) jsem dospěl pro provoz virtuálních strojů s FreeDOSem k následující konfiguraci (resp. k jejím několika variacím):

GDK_BACKEND=x11 qemu-system-i386 \
    -name FreeDOS \
    -enable-kvm \
    -m 64 \
    -rtc base=localtime \
    -boot order=c \
    -drive format=qcow2,file=dos.qcow2 \
    -cdrom FD13BNS.iso \
    -usbdevice mouse \
    -vga cirrus \
    -display sdl,gl=on,full-screen=on \
    -device sb16,audiodev=snd \
    -device adlib,audiodev=snd \
    -machine pcspk-audiodev=snd \
    -audiodev pipewire,id=snd \
    -device pcnet,netdev=netiface \
    -netdev user,id=netiface \
    -drive format=raw,file=fat:rw:share

Pojďme se podívat na klíčové části. Hned na začátku určitě zaujme nastavení proměnné GDK_BACKEND, striktně vzato to není nutný krok pokud 1) používáte X server místo Waylandu; 2) zároveň jako zvukovou kartu neemulujete Sound Blaster 16; a 3) okno QEMU není dekorované pomocí GTK. Vzhledem k tomu, že bod 1 a 3 odráží výchozí konfiguraci ve Fedoře a bod 2 je něčím, co dost pravděpodobně pod FreeDOSem budete chtít provozovat, můžete narazit na nepříjemný bug ústící v zatuhnutí grafického výstupu v okamžiku inicializace toho zvukového. Klasickým případem, kdy na tento problém narazíte, je bohužel při spuštění hry DOOM. Naštěstí nastavení GDK_BACKEND na hodnotu X11 je jednou z efektivních cest, jak se problému vyhnout.

    -usbdevice mouse \
    -vga cirrus \
    -display sdl,gl=on,full-screen=on \

Nastavení výše definuje myš a grafickou kartu ve FreeDOSu bez problému podporované už ve výchozí konfiguraci. U nastavení direktivy -display se už nabízí více možností, z výkonového hlediska je ideální varianta používající sdl (v případě displayů s poměrem stran 4:3 ale docílíte poněkud paradoxního výstupu – výstup bude vykreslen širokoúhle s černými pruhy nahoře a dole... DOS pro vykreslení textového režimu VGA s 80×25 znaky použije pro každý znak matici 16×9 pixelů, čili 720×400 pixelů. Ty však na tehdejším hardware nebyly čtvercové. Paradoxní je to i proto, že širokoúhlý výstup DOSu na dnešních širokoúhlých monitorech vlastně nijak zvlášť rušivě nepůsobí).

Místo sdl lze nastavit i gtk (vynechte gl=on), dostanete pak okno včetně menu.

    -device sb16,audiodev=snd \
    -device adlib,audiodev=snd \
    -machine pcspk-audiodev=snd \
    -audiodev pipewire,id=snd \

Řádky výše definují běžné zvukové karty počátku devadesátých let, které QEMU dokáže emulovat, jako stvořené pro provoz s FreeDOSem. Díky použití PC speakeru je zápis poněkud zdlouhavější, neboť ten vyžaduje určení zvukového backendu, což je poté nutné udělat i u obou zbývajících zvukových karet. Nicméně zvažte, jestli PC speaker opravdu potřebujete – použije se opravdu výchozí zvukový výstup daného backendu – a není nad hlasité "beep" vystřeleného do nitra lebky při příliš vysoko nastavené hlasitosti 🙂 Osobně se mi tato konfigurace osvědčila jako velmi funkční. Obejdete-li se bez PC Speakeru, lze zapsat i jako oneliner -device sb16 -device adlib.

Pokud potřebujete jinou zvukovou kartu té doby, lze sb16 nahradit např. gus (pro Gravis Ultrasound).

    -device pcnet,netdev=netiface \
    -netdev user,id=netiface \
    -drive format=raw,file=fat:rw:share

Aneb síťování a sdílení. Obojí je s FreeDOSem a QEMU až překvapivě velmi jednoduché. FreeDOS podporuje ve výchozím stavu omezenou množinu síťových karet, prvními dvěma řádky jednu z nich použijeme. Pak už je nutné pouze použít FreeDOSovou aplikaci FDNET pro základní podporu síťování... a vrhnout se na brouzdání. Poslední řádek pak nasdílí adresář na hostitelském systému s názvem share pro hostovaný systém – FreeDOS ho zpřístupní jako disk s dalším dostupným písmenem, v našem příkladě tedy jako disk E: – pozor, na daný adresář se takto vztáhnou limitace souborového systému FAT, myslete na to při pojmenovávání souborů a adresářů. Současně rozhodně nikdy jakkoliv nepřistupujte do adresáře z hostitelského systému v okamžiku, kdy je současně nabootován FreeDOS. A obecně – souborové operace ve FreeDOSu pod QEMU nejsou nejrychlejší.

Protože práce se sdíleným diskem nemusí být vždy úplně pohodlná (a jste odkázání na nástroje poskytované FreeDOSem), lze k celému problému přistoupit i jednoduše obráceně. QCOW2 image lze namountovat v hostitelském OS. Existuje pro to několik cest, patrně nejpohodlnější je to pomocí guestmount:

guestmount -a dos.qcow2 -m /dev/sda1 --rw /mnt/dos

Všechny argumenty samozřejmě upravte s ohledem na konfiguraci vašeho systému.

    -chardev serial,path=/tmp/serial_file,id=serialport \
    -device isa-serial,chardev=serialport \
    -vnc :0 \
    -qmp tcp:localhost:4444,server,wait=off \
    -qmp unix:/tmp/qmp-sock,server=on,wait=off \

Nad rámec původní ukázky pak můžeme emulovat např. i sériový port (vše, co je ve FreeDOSu přesměrováno na COM1, se pak zapíše do souboru /tmp/serial_file na hostiteli, lze tak učinit velmi povědomým zápisem: ECHO ahoj > COM1). Také můžeme umožnit přístup k VM pomocí VNC (výchozí port je 5900, pro 5901 použijte :1 apod.). A celý nový svět se pak skrývá pod direktivou pro QMP (QEMU Machine Protocol), ale to je téma dalece nad rámec tohoto článku, omezím se proto na konstatování, že tato mocná možnost – jak interagovat s běžícím virtuálním strojem – existuje, přičemž poslední dva řádky demonstrují, že tak lze tak učinit pomocí TCP i unixových socketů. Šlo by pokračovat i dál, nicméně už tyto poslední zmíněné direktivy nejsou něčím, co je pro provoz FreeDOSu pod QEMU běžně potřeba.

Závěrem

A to je vše 🙂 Při práci s FreeDOSem mějte na paměti, že je to plnohodnotný DOS se vším, co z toho vyplývá. Souborový systém, který používáte, není žurnálovací, proto silně doporučuji zálohovat data,  plánujete-li ve FreeDOSu uchovávat něco důležitého. Také platí, že kterýkoliv uživatel má přístup kamkoliv do paměti – není nic rychlejšího než odstřelit celý systém kusem špatně napsaného kódu v C – na druhou stranu, opětovné nabootování celého VM s FreeDOSem trvá nižší jednotky sekund... Pokud plánujete použít FreeDOS pro účely hraní starých her, tak (i za použití KVM) bych doporučil použít CPU s alespoň trochu slušným výkonem v singlethreadu (a ne Atom v Atomic Pi).

Mám-li stručně shrnout, pak čistě pro provozování starých her splní účel velmi dobře i DOSBox, ale neužijete si (nebo alespoň já) onen autentický zážitek z DOSu. Zato FreeDOS provozovaný přes QEMU na počítači s Fedorou je příjemná cesta, jak se vrátit do jednodušších časů se vším všudy... Byť vám to dá tu a tam takříkajíc sežrat! 🙂