1 Punkte von GN⁺ 2025-01-10 | 1 Kommentare | Auf WhatsApp teilen
  • SerenityOS lief vor allem unter QEMU gut, doch auf einem echten Notebook traten schon beim Booten, Debugging und Storage-Zugriff nacheinander Blockaden auf, die Lücken in der Hardware-Unterstützung sichtbar machten
  • Testgerät war ein Dell 3100 Chromebook mit Intel Celeron N4020, 4 GB DDR4, 32 GB eMMC und einem 1366×768-TN-Display; das erhoffte Closed-Case-Debugging auf Cr50-Basis schlug auf diesem Board fehl
  • Nachdem der Cr50-Weg versperrt war, wurde ein RP2040-basierter Pi Pico intern eingebaut und direkt mit UART und SPI-Flash verbunden, um mit CircuitPython und serprog ein provisorisches Debugging- und Flashing-Gerät namens PicoCCD zu bauen
  • Frühe Boot-Logs ließen sich nur schwer direkt über den MMIO-16550-UART hinter PCI ausgeben; stattdessen wurde der von der ChromeOS-EC protokollierte IO-Port 0x80 als langsamer provisorischer Ausgabekanal genutzt
  • Die eMMC-Unterstützung erreichte nach Problemen mit Unterschieden bei der SD/MMC-Initialisierung, fehlender SDHCI-Stromsteuerung und deaktivierten SD-spezifischen Befehlen teilweise sogar eine grafische Sitzung, doch Performance, Stabilität und Patch-Bereinigung stehen noch aus

Dell 3100 Chromebook als Ziel für echte Hardware

  • Beim Versuch, sich stärker in SerenityOS einzubringen, fiel als erste Schwäche auf: Es läuft unter QEMU, aber die Unterstützung für echte Hardware ist unzureichend
  • An der UEFI-Unterstützung arbeitete spholz bereits, daher wurde sie nicht angefasst; für diese Arbeit reichte es, wenn der Kernel des master-Branches in einer TianoCore-UEFI-Laufzeitumgebung per GRUB bootete
  • Das Debugging eines OS auf derselben Hardware wie der Haupt-Entwicklungsmaschine sollte vermieden werden, und als Ziel diente relativ aktuelle Hardware, die man tatsächlich täglich nutzen könnte
  • Auf Allegro wurde nach einem günstigen Chromebook gesucht, dabei wurde ein Dell 3100 für 95 PLN, etwa 25 EUR, gekauft
    • Intel Celeron N4020, 2 Kerne, kein Hyper-Threading
    • 4 GB DDR4
    • 32 GB Onboard-eMMC
    • 1366×768-TN-Display, angetrieben von einer UHD600-IGP
    • 2× USB-A, 2× USB-C, 3,5-mm-Klinke
    • Eine Tastatur, die sich besser anfühlte als die in Dells höherwertigen Business-Notebooks
  • Dieses Gerät wird im Folgenden als octopus bezeichnet

Erwartungen an Cr50-basiertes Debugging und das Scheitern

  • Ein wichtiger Grund für die Wahl eines Chromebooks war, dass der Cr50-Sicherheitschip bzw. Embedded Controller nützliche Funktionen für Closed-Case-Debugging bereitstellt
  • Fast alle Chromebooks seit 2018 können über ein SuzyQ-Kabel einen USB-C-Port fürs Debugging nutzen, und Cr50 stellt normalerweise drei ttyUSB-Geräte bereit
    • Interne Cr50-Konsole
    • AP-Konsole, also der serielle Port des Chromebooks
    • cros_ec-Konsole, also der Embedded Controller
  • Ziel war es, auf die serielle Konsole zugreifen zu können, ohne das Notebook offen mit heraushängenden Kabeln zu betreiben; zusammen mit Tastaturemulation und Steuerung des Energiezustands über cros_ec schien sogar eine einfache KVM-Form möglich
  • Auf dem tatsächlichen octopus funktionierte Cr50 CCD nicht
    • Ein neues SuzyQ-Kabel wurde gebaut und die Lötstellen mit einem anderen Chromebook überprüft, dennoch schlug es fehl
    • octopus war eines der wenigen Notebooks, bei denen CCD nicht funktioniert, weil Dell einige Widerstände auf dem Board nicht bestückt hat
    • Einige berichteten von eingeschränktem Erfolg bei einer bestimmten Port-Ausrichtung und angeschlossenem Ladegerät, doch auf diesem Gerät funktionierte es überhaupt nicht
  • Später gefundene Informationen deuteten darauf hin, dass die fehlenden Widerstände nicht die USB-Bridge selbst, sondern nur das SPI-Flashing betreffen sollten; der genaue Grund, warum Cr50-Debugging gar nicht funktionierte, bleibt daher unklar

PicoCCD mit einem Pi Pico

  • Nachdem der Cr50-Weg versperrt war, wurde geprüft, ob in den freien Raum im Gerät ein gewöhnliches Pi Pico-Board passt; es passte problemlos hinein
  • Schaltpläne ähnlicher Notebooks wurden herangezogen, aber es gab keinen exakt zu octopus passenden Schaltplan
    • Ein großer Debug-Port auf dem Board bezog sich auf Intel-JTAG und Testpunkte und passte nicht zum Ziel
    • Ein anderer war Google Servo, doch Google hat mehrere Debug-Probes unter dem Namen Servo veröffentlicht und die Dokumentation ist begrenzt, was die Suche erschwerte
    • Als relevante Dokumentation diente die Servo-Dokumentation
  • Mit dem UART-Applet von Glasgow und aktivierter Frequenzdetektion wurden verdächtige UART-TX-Pads direkt sondiert, während Linux wiederholt auf /dev/ttyS1 ausgab
    • Das TX-Pad war in wenigen Minuten gefunden
    • RX war schwieriger, weil aktives Senden nötig ist und das Berühren der falschen Leitung das Board zurücksetzen kann; tatsächlich kam es zweimal zu Resets
    • Danach wurden auch die RX/TX-Pins für die EC in etwa 10 Minuten gefunden
  • Die angelöteten Kabel wurden mit UV-härtendem Epoxid fixiert, und über sechs Monate gab es keine Verbindungsprobleme
  • Auch die SPI-Peripherie des RP2040 wurde genutzt: Sechs Leitungen wurden an den Flash-Chip gelötet, die Leiterbahn zum Write-Protect-Pin wurde durchtrennt und mit GND verbunden, um Schreibzugriff ohne Cr50-Freigabe zu erhalten
  • Als Software fiel die Wahl auf CircuitPython
    • Denn Skripte und Daten lassen sich per USB-Massenspeicher übertragen
    • Das Bridging von UART auf ein cdc_acm-USB-Gerät war einfach
    • Da auch SPI-Flash angebunden war, wurde außerdem eine Flashing-Funktion benötigt
  • Als übliches Open-Source-Tool für EEPROM- und SPI-Flashing kam flashrom zum Einsatz, und serprog, das SPI über UART proxyt, passte zum Zweck
    • Es gab zwar die C-Implementierung pico-serprog von stacksmashing, doch dass der Pico bei jedem BIOS-Flash neu geflasht werden müsste, passte nicht
    • Stattdessen wurde serprog in CircuitPython implementiert, mit viel Bezug auf das Glasgow-serprog-Applet
  • Der resultierende Code wurde als schnell zusammengebautes Closed-Case-Debugging-Setup PicoCCD gebündelt; das Repository liegt unter PicoCCD auf Forgejo
  • WeirdTreeThing schrieb für einen ähnlichen Zweck ebenfalls RP2040-C-Code; auch seine PicoCCD-Version existiert

Boot-Logs von SerenityOS gewinnen

  • Zum Debugging wurde Alpine Linux installiert und grundlegende Utilities eingerichtet, um extern gebaute SerenityOS-Kernel auf das Gerät zu bringen
  • Später wuchs das Setup zu einer Struktur mit automatischem Download von Artefakten von der Build-Maschine, Entpacken und Überschreiben des Kernels sowie einem GRUB-Eintrag, der ein User-Space-.tar entpackt
  • Die Iterationszeit von einer Änderung bis zum Test betrug zum Zeitpunkt des Schreibens etwa 20 Sekunden, was für Bare-Metal-Hacking ziemlich gut war
  • Der erste GRUB-Booteintrag war im Grunde multiboot /Kernel serial_debug, doch weder Bildschirm noch serieller Port gaben etwas aus
  • Für das Problem mit der Bildschirmausgabe wurde die Methode gefunden, insmod all_video zum GRUB-Booteintrag hinzuzufügen; allein löste das Problem zwar nicht, aber es war die richtige Richtung
  • Das Fehlen serieller Ausgabe war das größere Problem
    • coreboot-Logs kamen noch bis wenige Sekunden zuvor herein
    • Der UART dieses Geräts war kein traditioneller port-mapped 16550, sondern ein MMIO-basierter 16550A
    • In den Linux-Logs erschienen ttyS0 und ttyS1 als 16550A an MMIO-Adressen
    • In lspci erschien der Intel Celeron/Pentium Silver Processor Serial IO UART Host Controller als PCI-Gerät

16550-UART und Umweg über Port 0x80

  • Traditionell wurden externe Geräte des IBM-PC auf dem x86-CPU-Port-I/O abgebildet und mit Befehlen wie outb und inb angesprochen
  • Viele Geräte wechselten später zu MMIO, doch serielle Ports blieben oft bei der alten Methode, weil hohe Konkurrenz um Geschwindigkeit dort weniger wichtig ist; dadurch blieben sie als Debug-Ports nützlich
  • In einer typischen Umgebung kann man etwa outb 0x3f8, 0x41 schreiben und auf der Gegenseite ein A empfangen; auch die Initialisierung ist kurz und in kleinen Projekten leicht umzusetzen
  • Der UART von octopus war jedoch ein MMIO-Gerät hinter PCI, und so früh im SerenityOS-Bootvorgang konnte man PCI-Initialisierung kaum voraussetzen
    • SerenityOS hat zwar eine PCI-Bus-Implementierung, doch der Bootzeitpunkt war zu früh
    • Auch das vorhandene PCISerialDevice war noch nie in einem MMIO-Kontext verwendet worden
    • Diesen Treiber ohne Debug-Ausgabe zu schreiben, war nicht ideal
  • Der Embedded Controller von ChromeOS-Geräten protokolliert alle Schreibzugriffe auf IO-Port 0x80
    • Dieser Port wird traditionell für POST-Statusmeldungen genutzt
    • Die 7-Segment-Bootcode-Anzeigen auf Mainboards arbeiten, indem sie Port 80 dekodieren
  • Die Hypothese wurde unter Linux mit einem Skript getestet, das Bytes nach /dev/port schreibt, und diese Bytes waren in der cros_ec-Konsole lesbar
  • Rund um Kernel/Arch/init.cpp, den Einstiegspunkt von SerenityOS, wurden Zeilen wie IO::out8(0x80, 1); eingefügt, um die aktuelle Ausführungsposition zu verfolgen; so wurde der Absturz bis zu Memory::MemoryManager::initialize(0); eingegrenzt
  • Anschließend wurde versucht, die Adresse der seriellen Schreibroutine von 0x3f8 auf 0x80 zu ändern
    • Anfangs kamen viele Bytes an, aber cros_ec konnte sie nicht zuverlässig weiterleiten, wodurch Overflows entstanden
    • Später wurde sogar die Log-Ausgabe von cros_ec selbst beschädigt
    • Anders als ein echter serieller Chip besitzt sie keinen großen Puffer
  • Als Umgehung wurden zwischen den Schreibvorgängen viele nop-basierte Wait States eingefügt
    • Wenn alle Bootmeldungen ausgegeben wurden, verlängerte sich der Bootvorgang von einigen Sekunden auf mehrere Minuten
    • Für Bare-Metal-Debugging wurde das dennoch als akzeptabler Preis gesehen
  • Um cros_ec-Logzeilen automatisch zu parsen und als ASCII zu dekodieren, wurde ein Bash-Einzeiler aus picocom, watch, grep, sed, cut und xxd verwendet

Framebuffer und erste Grafikausgabe

  • Nachdem Boot-Logs verfügbar waren, wurde einige Tage lang die Codebasis direkt gelesen, um das Problem zu verstehen; am Ende wurde jedoch die Community um Hilfe gebeten
  • spholz wies auf den damals offenen SerenityOS PR #24435 hin, und mit diesem Branch gebaut funktionierte der generic framebuffer
  • Auf dem Bildschirm erschien ein Ergebnis, das zwar wie ein Erfolg aussah, obwohl die Arbeit fehlgeschlagen war; anschließend traten die Storage-Probleme deutlicher zutage

eMMC und Probleme bei der SD/MMC-Initialisierung

  • Der bestehende Absturz in StorageManagement folgte darauf, dass die Initialisierung des SD Host Controllers fehlschlug und die Controller-Liste leer blieb
    • In den Logs standen PCI: Failed to initialize SD Host Controller und ASSERTION FAILED: !m_controllers.is_empty()
    • In der Folge kam es in StorageManagement::enumerate_storage_devices() zu einer Kernel Panic
  • In octopus steckt ein 32-GB-eMMC-Chip, und da SerenityOS bereits einige SD-Treiber hatte, schien es so, als müsste nur MMC-Unterstützung ergänzt werden
  • Um SD/MMC-Karten zu nutzen, braucht man grob drei Elemente
    • Host Controller: Auf moderner Hardware meist SDHCI nach Spezifikation der SD Association
    • Den Bus, an den der Host Controller angebunden ist: in diesem Fall PCI
    • Die Protokollimplementierung, mit der Host und Karte kommunizieren
  • Den Crash-Logs nach besaß SerenityOS die ersten beiden Elemente; das verbleibende Problem lag auf der Protokollseite
  • Für SD gibt es eine öffentliche Spezifikation, doch MMC wurde 2007 JEDEC-Standard, und offizieller Zugriff kostet seitdem Geld
  • SD und MMC haben unterschiedliche Initialisierungssequenzen
    • SerenityOS begann damit, CMD0 zu senden und auf eine Antwort zu warten; das sollte sowohl bei SD als auch MMC funktionieren
    • Danach wird CMD8 zur Spannungskonfiguration gesendet, doch MMC unterstützt dies nicht, weshalb ein Fehler auftreten sollte
    • Einige Materialien schlagen vor, die Karte anschließend zurückzusetzen und als MMC zu betrachten
    • Andere Materialien beschreiben einen umfassenderen Ablauf, der anhand der Kombination aus CMD8- und CMD58-Ergebnissen auch SD-Version und Kapazitätstyp unterscheidet
  • Statt alle erweiterten Kompatibilitätsprüfungen zu implementieren, wurden nur grundlegende Prüfungen umgesetzt

Fehlendes Power-Control-Register und Lösung

  • Der MMC-Initialisierungsablauf sah zusammengefasst so aus
    • Nach dem Reset den Takt auf 400 KHz setzen
    • 1 ms warten und dann weitere 74 Takte abwarten
    • CMD0 senden und auf Antwort warten
    • CMD1 wiederholen, bis Bit 31 der Antwort 1 ist
    • Nach Ende der Schleife den Wert als Operating-Conditions-Register speichern
    • Den SD-Initialisierungsalgorithmus ohne Abfrage SD-spezifischer Register fortsetzen
    • Optional High-Speed-Kompatibilität erkennen und einen von mehreren HS-Modi aktivieren
  • Der Code kam bis ungefähr Schritt 4, danach antwortete die eMMC auf keine Anfrage mehr
  • Nachdem mehrere Tage lang keine Ursache gefunden wurde, begann die eMMC zu antworten, als Code rund um den Controller-Reset entfernt wurde; das Problem wurde auf die Funktion reset_host_controller() eingegrenzt
  • Auffällig an dieser Funktion war, dass im Standard kein Register namens host_configuration zu finden war
    • Der frühere Code hatte mehrere Register willkürlich in zwei host_configuration-Gruppen zusammengefasst
    • Auch die Initialisierung war nicht vollständig abgeschlossen, und die erste Gruppe wurde einfach auf 0 gesetzt
  • In der ersten Gruppe befand sich das Power Control-Register, das den Stromregler der Karte steuert
    • Auf mancher Hardware, einschließlich jeder Implementierung mit eMMC, ist dieses Register nötig, um die Karte selbst einzuschalten
    • Andere Designs, bei denen die Stromschiene direkt mit dem Slot verbunden ist, können diese Einstellung ignorieren
  • Als provisorische Lösung wurde der ursprüngliche Wert von host_configuration_0 übernommen und verwendet
  • Das Kernproblem war, dass versucht wurde, mit der Karte zu kommunizieren, ohne sie eingeschaltet zu haben
  • Danach dauerte es noch einige Stunden, bestimmte nur für SD-Karten gültige Befehle zu finden und zu deaktivieren; mit aussagekräftigeren Debug-Ausgaben des Controllers verlief der Rest der Arbeit vergleichsweise gewöhnlich

Aktueller Stand und offene Arbeiten

  • Letztlich gelang es SerenityOS, sehr langsam eine teilweise beschädigte grafische Sitzung zu starten, die sich aber bald aufhängte
  • Das Problem mit dieser grafischen Sitzung und der Weg, den Framebuffer wieder in Ordnung zu bringen, sollen in einem Folgebeitrag behandelt werden
  • Die gesamte Arbeit war ein Lernprozess über etwa 6 Monate, während nebenbei auch andere Dinge liefen
  • Nächstes Ziel ist es, die Patches aufzuräumen und noch dieses Jahr upstream einzureichen

1 Kommentare

 
GN⁺ 2025-01-10
Hacker-News-Kommentare
  • Ich habe einmal gelesen, dass es bei NetBSD vergleichsweise einfach sei, Treiber an einen eigenen Kernel anzupassen. Vielleicht könnte Serenity einen ähnlichen Weg gehen.
    Für ein junges OS sind Gerätetreiber eine große Hürde.

    • Einer der Grundsätze von Serenity ist, möglichst alles von Grund auf selbst zu bauen. Selbst wenn NetBSD-Treiber leicht anzupassen wären und die Lizenz kompatibel wäre, würden sie daher vermutlich eher eigene Treiber schreiben, statt diesen Weg zu gehen.
    • Bei einem jungen Hobby-OS habe ich mich gefragt, ob es nicht besser wäre, von Anfang an einen beliebten Einplatinencomputer wie den Raspberry Pi ins Ziel zu nehmen.
      Da die Hardware-Konfiguration dort weitgehend feststeht, wird es einfacher, Treiber zu schreiben oder zu übernehmen und das System zu testen.
    • rump kernel/anykernel ist genau so ein Konzept.
      Treiber können mit nur minimaler Basisunterstützung im Userspace ausgeführt werden.
      https://en.wikipedia.org/wiki/Rump_kernel
    • Auf NetBSD kann man sich verlassen. Die libc ist sehr sauber; ich habe sie schon ein paar Mal in verschiedenen Projekten verwendet.
      Bei den Treibern kenne ich mich allerdings nicht so gut aus.
    • Die Lösung besteht darin, ein gutes Hardware-Set auszuwählen, möglichst Geräte, die der Software-Autor selbst verkauft, und dann nur für diese Hardware Treiber zu schreiben.
      So hat Apple es im Grunde von Anfang an gemacht, und es ist der einzige große Erfolg im Bereich Unix-artiger Consumer-Systeme.
      System76 ist fast auch so ein Beispiel, und Frame.work ist ähnlich, legt aber weniger Fokus auf das OS selbst.
  • Dass sie es auf einer Maschine zum Laufen gebracht haben, bei der alle Voraussetzungen ungünstig sind, ist wirklich beeindruckendes Hacking und wirkt wie das Ergebnis enormer Arbeit talentierter Leute.

  • Wenn ich solche Artikel lese, frage ich mich, wie man in die Welt der Treiber und Betriebssysteme einsteigen sollte.
    Das wirkt so komplex, dass ich nicht recht weiß, wo man anfangen soll.

    • Mit moderner Hardware zu kommunizieren ist in der Praxis ziemlich einfach; im Kern geht es darum, Hardware-Speicher zu lesen und zu schreiben.
      Das nennt man Memory-Mapped I/O (MMIO). In normalen Anwendungen geht das nicht, weil der Kernel direkten Zugriff auf Hardware-Speicher verhindert.
      Für den Einstieg braucht man eine Sprache wie Rust/C++/C/Zig, die Maschinencode für die Ziel-CPU erzeugen kann; am besten ohne Runtime oder GC. Wenn Low-Level-Sprachen neu für dich sind, würde ich wegen der vielen Beispiele C empfehlen.
      Außerdem musst du die grundlegende Assemblersprache der Ziel-CPU lernen, und manche Instruktionen stehen möglicherweise nicht als Built-ins in Hochsprachen zur Verfügung.
      Danach schreibst du einen Hello-World-Kernel und lernst dabei, wie die CPU den Kernel startet und wie Ausführungsmodi und Privilegstufen aufgeteilt sind.
      Anschließend konfigurierst du die CPU nach deinen Vorstellungen, unter x86 etwa durch den Wechsel in den Long Mode, um 64-Bit-Instruktionen zu nutzen; meist richtet man in dieser Phase auch virtuellen Speicher ein.
      Wenn du bis hierhin kommst, bekommst du ein Gefühl dafür, wie die CPU mit dem OS zusammenspielt, wie man verfügbare Geräte auflistet und deren Speicheradressen findet. Danach bleiben noch viele Aufgaben wie Dateisysteme und Scheduler.
      Der Unterschied zwischen Software, die auf einem OS läuft, und dem OS-Kernel liegt letztlich im CPU-Modus, in dem der Code gerade ausgeführt wird; mit höchster Berechtigung kann man Instruktionen verwenden, die normalen Apps nicht zur Verfügung stehen.
    • Ich habe mit LDD angefangen. Das Buch ist etwa zehn Jahre alt, aber immer noch relevant.
      Später habe ich in der FreeBSD-Dokumentation echte Schätze gefunden; besonders das FreeBSD Architecture Handbook und das FreeBSD Developers' Handbook könnten hilfreich sein.
      https://lwn.net/Kernel/LDD3/
      https://docs.freebsd.org/en/books/
    • Vor ungefähr 15 Jahren habe ich an der Uni einen Kurs zur OS-Entwicklung besucht und dabei Minix verwendet.
      Minix ist sehr sauber geschrieben, der Kernel umfasst nur etwa 5.000 Zeilen und wird in mehreren Lehrbüchern behandelt.
      Wir haben einen einfachen Server implementiert und auch am Kernel gehackt; weil Minix ein Microkernel ist, funktionieren die meisten Treiber genau auf diese Weise.
      Ich habe die Kursunterlagen im Voraus gelesen und die Vorlesungen kaum besucht, bekam aber trotzdem 8 von 10 Punkten.
      Über NetBSD und SerenityOS habe ich ebenfalls viel Gutes gehört, und Andreas hat einen großen Teil der Entwicklung per Livestream gemacht.
      Wenn man weiß, wo man anfangen soll, wird es tatsächlich einfacher.
    • Ehrlich gesagt besteht der erste Schritt darin, den Zweck der einzelnen Komponenten wie OS, Treiber und Geräte zu verstehen.
      Ein Gerätetreiber stellt zum Beispiel eine Schnittstelle bereit, über die andere Programme auf dem Computer auf ein bestimmtes Gerät zugreifen und es steuern können.
      https://m.youtube.com/watch?v=juGNPLdjLH4 ist ein guter Crashkurs.
      Mit etwas wie Arduino kann man auch ein einfaches USB-Gerät bauen, das Informationen mit dem PC austauscht. Beispiel: https://m.youtube.com/watch?v=yTc2GLXfCOY
      Danach musst du verstehen, was das Subsystem, das dich interessiert, tut und wie du es zum Laufen bringst, und dann Code schreiben. Dazu gehören etwa Speichergeräte oder Grafikgeräte.
      Auch der Raspberry Pi kann ein guter Ausgangspunkt für solche Experimente sein. Beispiel: Writing a bare metal operating system for the raspberry pi https://github.com/babbleberry/rpi4-osdev
    • Dieses Tutorial war wirklich gut:
      https://wiki.osdev.org/Bare_Bones
  • Ich mag das Konzept von SerenityOS und den Ladybird-Browser, daher freue ich mich über solche Fortschritte.

    • Leider haben sich die beiden inzwischen getrennt.
      Ladybird ist nicht nur ein eigenständiges Projekt geworden, sondern betrachtet SerenityOS auch nicht mehr als Zielplattform.
      Ladybird baut die eigene Serenity-Schicht zunehmend ab und ersetzt sie durch Mainstream-Alternativen.
      Als jemand, der hauptsächlich Linux nutzt, freue ich mich darauf, dass Ladybird unter Linux zu einer echten Alternative wird.
      Als SerenityOS-Fan finde ich es aber schade, dass Energie und Innovation, die in Ladybird geflossen sind, aus SerenityOS abwandern.
  • Wenn du Hilfe beim Hacken von Chromebooks brauchst, solltest du auf der chromium-os-dev-Mailingliste fragen.
    Vermutlich kann jemand dabei helfen, CCD zum Laufen zu bringen.
    https://groups.google.com/a/chromium.org/g/chromium-os-dev?p...

  • Auch der Depthcharge-Bootloader unterstützt Netzwerk-Boot über TFTP.
    Man muss ihn selbst bauen und in den SPI flashen, aber für iterative Kernel-Entwicklung ist das ein sehr gutes Feature.
    https://chromium.googlesource.com/chromiumos/platform/depthc...

  • Ich dachte, SerenityOS sei bereits auf echter Hardware gelaufen. Läuft es bisher also noch komplett nur in QEMU?

    • Es stimmt, dass es in der Vergangenheit schon auf echter Hardware ausgeführt wurde.
      Allerdings gab es kaum nennenswerte Treiber, sodass es nur im allereinfachsten Sinn funktionierte, nur auf bestimmter Hardware möglich war und vermutlich nicht besonders gut lief.
      Dieser Versuch zielt darauf ab, es auf mindestens einer realen Hardware-Plattform zuverlässig lauffähig zu machen.
  • Serenity bleibt beeindruckend, auch wenn ich mit der Art der Implementierung nicht immer einverstanden bin.

  • Genau wegen solch furchteinflößender Dinge bin ich hierhergekommen:
    doas dd seek=$((0x$1)) bs=1 count=1 of=/dev/port < <(xxd -p -r <<< "$2")

    • Als Laie frage ich mich wirklich, was dieser Code bedeutet.