2 Punkte von GN⁺ 2024-12-06 | 1 Kommentare | Auf WhatsApp teilen
  • Banan-OS ist ein in C++ geschriebenes Hobby-Betriebssystem und unterstützt derzeit die Architekturen x86_64 und i686
  • Der Funktionsumfang umfasst Ring3-User-Space, SMP, einen Netzwerk-Stack, ELF-Laden und dynamisches Linken, Copy-on-Write-Speicher sowie eine grundlegende grafische Umgebung
  • Unterstützt werden bei Treibern und Systemfunktionen NVMe- und ATA-Datenträger, NICs der Reihen E1000/E1000E und RTL, PS2- und USB-Eingabe, die Dateisysteme Ext2 und FAT, GRUB sowie ein eigener BIOS-Bootloader
  • TCP ist als teilweise implementiert und fehlerhaft gekennzeichnet; SSL, virtio-Geräte, einige USB-Controller, die Dateisysteme Sys und 9P sowie ein eigener UEFI-Bootloader sind noch nicht implementiert
  • Das Bauen erfolgt hauptsächlich über das Skript ./bos; nach dem Erstellen der Toolchain sind QEMU- und Bochs-Starts, Kernel- und Image-Builds sowie die Auswahl von Architektur-, Bootloader-, UEFI- und initrd-Optionen möglich

Überblick über Banan-OS

  • Banan-OS ist ein in C++ geschriebenes Hobby-Betriebssystem
  • Derzeit unterstützte Architekturen sind x86_64 und i686
  • Eine Live-Demo ist unter bananymous.com/banan-os verfügbar
  • Um DOOM auszuführen, muss man mit dem Befehl start-gui in die GUI-Umgebung wechseln und dann im GUI-Terminal doom starten

Wichtige implementierte Funktionen

  • Allgemeine Funktionen
    • Ring3-User-Space

      • SMP, also Multiprocessing
      • linearer Framebuffer auf Basis von VESA und GOP
      • Netzwerk-Stack
      • Laden von ELF-Executables
      • partieller AML-Interpreter
      • grundlegende grafische Umgebung
      • Terminal-Emulator
      • Statusleiste
      • Programmstarter
      • „Anständige Apps“ sind noch nicht implementiert
      • ELF Dynamic Linking
      • Copy-on-Write-Speicher
      • File Mapping ist implementiert
      • anonyme Mappings sind nicht implementiert

Unterstützung für Treiber, Netzwerk und Dateisysteme

  • Treiber
    • Unterstützt NVMe-Datenträger sowie ATA-IDE-/SATA-Datenträger
    • Unterstützt E1000-, E1000E- und RTL8111/8168/8211/8411-NICs
    • PS2-Tastaturen unterstützen alle Scancode-Sets, PS2-Mäuse werden ebenfalls unterstützt
    • USB unterstützt xHCI, Tastaturen, Mäuse, Massenspeicher und Hubs
    • EHCI, OHCI, UHCI sowie virtio-Netzwerk- und Speichergeräte sind nicht implementiert
  • Netzwerk
    • Unterstützt ARP, ICMP, IPv4 und UDP
    • TCP ist teilweise implementiert und fehlerhaft

      • Unix-Domain-Sockets werden unterstützt
      • SSL ist nicht implementiert
      • Dateisysteme
      • Unterstützt virtuelles Dateisystem, Ext2, FAT12/16/32, Dev, Ram und Proc
      • Sys und 9P sind nicht implementiert
      • Bootloader
      • Unterstützt GRUB und einen eigenen BIOS-Bootloader
      • Ein eigener UEFI-Bootloader ist noch nicht implementiert

Codestruktur

  • Jede Hauptkomponente und Bibliothek hat ein eigenes Unterverzeichnis wie kernel, userspace oder libc
  • Jedes Verzeichnis enthält ein include-Verzeichnis mit allen Header-Dateien der Komponente
  • Alle Header werden über absolute Pfade eingebunden

Build und Ausführung

  • Unter Ubuntu 22.04 werden über apt die Pakete build-essential, git, ninja-build, texinfo, bison, flex, libgmp-dev, libmpfr-dev, libmpc-dev, parted, qemu-system-x86, cpu-checker benötigt
  • In einer pacman-Umgebung werden base-devel, git, wget, cmake, ninja, parted, qemu-system-x86 benötigt
  • Die Toolchain für das Betriebssystem wird einmalig mit ./bos toolchain gebaut
    • Da dabei binutils und gcc kompiliert werden, kann das längere Zeit dauern
  • Das Builden und Ausführen des OS selbst erfolgt mit dem Befehl ./bos
    • ./bos qemu
    • ./bos qemu-nographic
    • ./bos qemu-debug
    • ./bos bochs
  • Es ist auch möglich, nur den Kernel oder nur das Disk-Image zu bauen
    • ./bos kernel
    • ./bos image
  • Zum Erstellen und Ändern von Disk-Images sind Root-Rechte erforderlich

Build-Optionen und Image-Verwaltung

  • Für Builds auf einer anderen Architektur muss die Umgebungsvariable BANAN_ARCH gesetzt werden
    • Beispiel: BANAN_ARCH=i686
  • Zum Wechseln des Bootloaders muss die Umgebungsvariable BANAN_BOOTLOADER gesetzt werden
    • Unterstützte Werte sind BANAN und GRUB
  • Für den Start im UEFI-Modus muss BANAN_UEFI_BOOT=1 gesetzt werden
    • OVMF_PATH muss ebenfalls auf den korrekten OVMF-Pfad gesetzt werden; der Standardwert ist /usr/share/ovmf/x64/OVMF.fd
  • Um ein initrd-Image ohne physisches Root-Dateisystem zu erstellen, muss BANAN_INITRD=1 gesetzt werden
    • Das kann beim Testen auf Hardware mit nicht unterstützten USB-Controllern verwendet werden
  • Wenn das Disk-Image beschädigt ist oder ein neues Image erstellt werden soll, kann man build/banan-os.img löschen oder ./bos image-full ausführen
  • Ein Shell-Completion-Skript für zsh wird ebenfalls bereitgestellt
    • Die Datei _script/shell-completion/zsh/_bos kann nach /usr/share/zsh/site-functions/ kopiert werden, oder _script/shell-completion/zsh wird in der .zshrc zu fpath hinzugefügt

Wie man beiträgt

  • Das Upstream-Projekt wird nicht auf GitHub, sondern unter https://git.bananymous.com/Bananymous/banan-os gehostet
  • GitHub-PRs können ebenfalls gesendet werden, aber der Maintainer muss den Diff herunterladen und manuell anwenden
  • Es ist auch möglich, einen Account auf dem separaten Git-Server zu erhalten; dafür sollte man per E-Mail oder Discord Kontakt aufnehmen
  • Für neue Funktionen wird bevorzugt, zuerst den Maintainer zu kontaktieren
    • Da es sich um ein Lernprojekt handelt, kann ein PR für eine Funktion, die der Maintainer selbst umsetzen wollte, ohne vorherige Absprache geschlossen werden
    • Bugfixes sind immer willkommen
  • Commit-Messages müssen in der ersten Zeile das Format Subject: Description haben
    • Subject bezeichnet den geänderten Bereich, etwa Kernel, Shell oder BuildSystem
    • Die erste Zeile muss innerhalb von 72 Zeichen bleiben
    • Der Hauptteil sollte die Änderungen und deren Gründe zusätzlich erläutern
  • Alle Commits müssen die in .pre-commit-config.yaml definierten pre-commit hooks bestehen

1 Kommentare

 
GN⁺ 2024-12-06
Meinungen auf Hacker News
  • Wirklich cool, und der Name gefällt mir auch. Ich frage mich, was von dem, was du bisher implementiert hast, der schwierigste Teil war, und ob es zwischendurch ernsthafte Hindernisse gab.

    • Es gab nichts übermäßig Schwieriges, aber wenn ich etwas nennen müsste, wären es wohl der AML-Interpreter oder der USB-Stack.
      Der AML-Interpreter war schwierig, weil die ACPI-Spezifikation so furchtbar chaotisch geschrieben ist; USB war anstrengend, weil die Spezifikation sehr umfangreich ist und viele Querverweise enthält.
      Große Hindernisse gab es keine, aber bei manchen Features habe ich erst aufgegeben und bin ein oder zwei Monate später wieder darauf zurückgekommen.
    • Anfangs habe ich es als „banyan tree“ gelesen und erst durch die ASCII-Art gemerkt, dass es eine Bananen-Anspielung ist.
  • Wirklich cool. Besonders beeindruckend ist, dass du den USB-Treiber von Grund auf implementiert hast. Nebenbei: Ich habe versucht, es mit cat doom1.wad kaputtzumachen.

    • Danke. Für Daten, die an die TTY geschrieben werden, gibt es kaum Serialisierung, daher kann es kaputtgehen, wenn man ihr beliebige Binärdaten füttert :D
  • Bei der Ankündigung eines neuen Betriebssystem-Kernels gibt es einen Satz, der traditionell enthalten sein muss, aber in dieser Ankündigung fehlt er.

    • Du meinst sicher: „Das ist ein Hobbyprojekt und wird nicht groß und professionell wie GNU sein“, oder?
  • Cool. Mich würde interessieren, wie viele Stunden pro Woche du ungefähr in dieses Projekt steckst. Der Arbeitsaufwand wirkt beträchtlich.
    In deinem Profil steht, dass du Student bist; heißt das, du studierst an einer Uni? Falls ja, hast du dieses OS auch direkt im Rahmen deines Studiums behandelt?

    • Ja, ich bin Student. Ich habe das Projekt einem Professor gezeigt und konnte dadurch einige Kurse wie Betriebssysteme oder Nebenläufigkeit „überspringen“.
      Ansonsten ist dieses Projekt nicht direkt Teil meines Studiums. Allerdings habe ich durch das Projekt auch einen Teilzeitjob im Embedded-Bereich der Uni bekommen.
      Wie viel Zeit ich investiere, hängt wirklich davon ab, was im Leben gerade los ist. In manchen Monaten waren es insgesamt nur 5 Stunden, in manchen Wochen fast 40 Stunden.
  • Ein cooles Projekt. Als Name für einen Fork wäre PlatanOS auch nicht schlecht.

    • PlátanOS, mit Betonung auf der ersten Silbe, fände ich gut.
  • Sehr schön, und es sieht nach viel Arbeit aus. Mich würde interessieren, welche Herausforderung dir besonders in Erinnerung geblieben ist.

    • Die größte Herausforderung war vermutlich, große Spezifikationen zu lesen. So etwas hatte ich vorher nie richtig gemacht, daher hat es eine Weile gedauert, mich daran zu gewöhnen.
  • Großartig. Mich würde interessieren, wie du entwickelst. Läuft es in einer VM oder auf echter Hardware? Wie sieht der Ablauf aus, wenn du dich hinsetzt und mit der Arbeit beginnst?
    Du musst dabei viel gelernt haben; mich würde auch interessieren, wie du Notizen machst oder die Entwicklung nachverfolgst. Oder ist das OS selbst so etwas wie ein lebendes Entwicklungstagebuch?

    • Etwa 95 % der Tests mache ich in einer VM. Das ist viel schneller und viel bequemer. Trotzdem teste ich auch regelmäßig auf echter Hardware.
      Es ist immer toll zu sehen, wie es auf echtem Bare Metal läuft, und Bare Metal ist nicht so nachsichtig wie eine VM.
      Normalerweise entscheide ich mich für ein Feature, das ich hinzufügen möchte, überfliege grob die relevanten Spezifikationen und schaue mir manchmal auch an, wie bestehende Betriebssysteme damit umgehen. Dann baue ich mir im Kopf ein Modell davon, was das System braucht, und schreibe den Code so, wie er mir in dem Moment einfällt.
      Ich habe die wirklich schlechte Angewohnheit, keine Dokumentation oder Notizen zu schreiben. Im Grunde behalte ich alles im Kopf und vergesse es später, wenn ich die Information brauche. Für Komplexeres zeichne ich manchmal Diagramme und schreibe Notizen, aber die bewahre ich fast nur lokal auf.
  • Mich würde interessieren, wo man bei Treibern wie NVMe, ATA oder Realtek-NICs überhaupt anfängt. Bei Maus und Tastatur weiß ich, dass sie den Standard HID verwenden, aber haben andere Geräte auch ähnliche Standardprotokolle?
    Ist das der Grund, warum Linux in den meisten Fällen eine „Treiberinstallation“ vermeiden kann? Und wenn es Standard-Geräte-APIs gibt, warum durchläuft Windows dann jedes Mal einen Treiberinstallationsprozess, wenn man etwas anschließt?

    • Im Grunde sind die Protokolle für fast alle gängigen Geräte standardisiert. Allerdings gibt es auch Geräte, bei denen der Hersteller einen Treiber bereitstellen muss.
      Für alle Geräte, für die ich Treiber geschrieben habe, waren die Spezifikationen frei verfügbar. NVMe findet man zum Beispiel unter https://nvmexpress.org/specifications.
      Wie Linux oder Windows Treiber genau handhaben, weiß ich nicht gut. Beim Kompilieren des Linux-Kernels legt man fest, welche Treiber in den Kernel aufgenommen werden und welche als Module bleiben. Übliche Treiber werden normalerweise zusammen mit dem Kernel gebaut, sodass man sie später kaum installieren muss; man lädt einfach das Treibermodul.
      Außerdem gibt es Geräte, die mit einem generischen Treiber funktionieren, mit einem spezifischen Treiber aber mehr Funktionen bieten. Zum Beispiel LED-Einstellungen bei einer Gaming-Maus. Windows installiert vermutlich solche optionalen Treiber.
  • Ein sehr cooles Nebenprojekt. Hast du Tipps für Leute, die etwas Ähnliches versuchen wollen, etwa wo man anfangen sollte oder welche Referenzen gut sind?

    • Im Grunde dasselbe, was andere schon gesagt haben. Es lohnt sich, https://wiki.osdev.org/Getting_Started zu lesen, und wenn man sich entscheidet, ein Betriebssystem zu entwickeln, sollte man im Hinterkopf behalten, dass es sehr viel Zeit kostet.
    • Für praktisches Wissen eignet sich das OSDev Wiki, für die Theorie Bücher über Betriebssystemdesign und Rechnerarchitektur.
    • Für Rust gibt es https://os.phil-opp.com/, für allgemeine Betriebssystementwicklung https://github.com/tuhdo/os01. Außerdem sollte man Operating Systems: Three Easy Pieces unbedingt lesen.
  • Hervorragend. Mit dieser Funktionsausstattung hätte ich nicht gerechnet. Planst du, künftig noch mehr Software zu portieren?

    • Ich habe vor, mehr zu portieren. Im Basis-OS möchte ich keinen Third-Party-Code haben, aber Ports sind eine sehr gute Möglichkeit, Dinge auszuführen, die ich noch nicht selbst geschrieben habe.
      Lokal habe ich noch ein paar Ports, die noch nicht funktionieren. git, binutils, gcc und make kompilieren alle, werfen aber seltsame Fehler. Vermutlich liegt es an Bugs in meiner libc oder bei den Systemaufrufen.