Autor Thema: Eigener mehrstufiger Bootloader  (Gelesen 7125 mal)

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« am: 09. September 2012, 11:24 »
Als erstes möchte ich sagen, ja ich will einen eigenen Bootloader schreiben (bzw. habe dies ohnehin schon gemacht) und nicht GRUB und Co nutzen.

Da ich jetzt endlich wieder etwas mehr Zeit habe und mich mal wieder mit OSDev beschäftigen kann, wollte ich meinen Kernel (und dann auch das gesamte OS) auf andere Architekturen portieren. Da mit dem Raspberry Pi auch eine sehr gute Möglichkeit dafür zur Verfügung steht, habe ich mit der ARM-Archiktektur angefangen.

Bevor ich den Kernel portieren kann, muss dieser erstmal geladen werden können (und bei mir auch noch zusätzlich Programme). Nein ich will die Programme nicht in eine initrd packen (warum das eher unschön ist, sollte sich weiter unten ergeben).

Problem, vorallem auch auf der ARM Architektur, ist es, dass es keine einheitliche Platform, für die man programmieren kann, gibt. Jedes Board ist im Endeffekt wieder eine andere Platform, selbst wenn mir ein flexibler Bootloader zur Verfügung stehen sollte. Es ist von uboot, über Openfirmware (mein momentaner Favorit), fastboot bis bald EFI alles mögliche vorhanden.

Dann kommt noch hinzu, dass es keine, mir bekannte, Möglichkeit gibt, zur Laufzeit die vorhandene Hardware herauszufinden und vorallem auch wo im Adressbereich sie sich befindet. Also muss es auf jeden Fall auf der ARM-Architektur immer was Board-spezifisches geben.

Dazu kam mir dann, mal wieder (wie einige jetzt denken werden ;) ), hoch komplizierte Idee.

Ich möchte meinen Bootloader in mehrere Stages aufteilen (bisher nix neues):
  • Stage 1 (optional, wenn wir auf dem PC, die Firmware keine Dateien laden kann) -> Bootsektor, lädt Stage 2 und 3
  • Stage 1.5 (optinal, nur wenn benötigt) -> lädt Stage 2 und 3
  • Stage 2 -> hardware-dependent Teil, stellt ein HAL für die jeweilige Platform zur Verfügung
  • Stage 3 -> hardware-independent Teil, nutzt HAL und lädt Kernel und Programme
Soweit nix neues, aber ich möchte es nun so umsetzen, dass Stage 2 und 3, 2 voneinander unabhängige Dateien sind.

Der "boot"-Ordner von meinem System könnte für die x86-Architektur z.B. so aussehen:

/boot
    osloader
    /stage2
        bios
        efi
        openfirmware

Mit EFI habe ich mich noch nicht weiter beschäftigt, aber Openfirmware z.B. kann Dateien von unterstützten Dateisystemen laden. Problem ist hier das BIOS, denn dort habe ich nur 512byte (bzw. genug wenn ich direkt von CD boote) zur Verfügung. Der Bootsector müsste nun aber die beiden Dateien "/boot/stage2/bios" und "/boot/osloader" laden, dass das nicht geht ist mir klar. Also war mein erster (und bisher leider einziger) Gedanke, ich brauche eine Stage 1.5. Der Bootsektor würde also entweder ein paar mehr Sektoren laden, keine Ahnung wo ich die abzwacken soll oder (was zwar gehen würde, aber unschön wäre) ich müsste noch eine Datei z.B. "stage_1_5_bios" laden und die lädt dann die anderen beiden Dateien.

Problem bei dieser zusätzlichen Datei wäre, wo soll diese gespeichert werden. Um so flexibel wie möglich zu sein, müsste sie in "/", was aber nicht so schön in eine aufgeräumte Ordnerstruktur passen würde. Eine andere Möglichkeit wäre, im Bootsektor einen direkten Verweis auf z.B. den FAT-Dateieintrag zu speichern. Da sehe ich aber das Problem, was passiert beim Defragmentieren? Der FAT-Dateieintrag könnte ja an eine andere Position verschoben werden und dann findet der Bootsektor den Eintrag nicht mehr. Ich weiß auch nicht wie es mit anderen Dateisystemen ist, könnte es da ein ähnliches Problem geben?

Meine Frage also, wie könnte man obiges Problem sinnvoll lösen?

[Jetzt sollte man nur weiterlesen wenn man das Konzept interessant findet oder darüber diskutieren möchte, hat nämlich nix mehr mit dem obigen Problem zu tun]

Warum eigentlich so kompliziert? Mein Problem ist einfach, dass ich nicht meinen kompletten Bootloader für jedes ARM-Board anpassen wollte. Als ich mich dann aber mal näher mit der Doku zum Raspberry Pi auseinander gesetzt habe, viel mir auf, dass sich das mit dem bisherigen Konzept nicht machen lässt. Deswegen jetzt mehrere Stufen.

Um einfach mal zu verdeutlichen wie das ganze dann für die ARM-Architektur aussehen könnte:

/boot
    osloader
    /stage2
        bcm2835
        tegra2
        openfirmware

Bei openfirmware bin ich mir auch nicht ganz 100%ig sicher, denn ich weiß dass es möglich ist, so einiges über die Hardware herauszufinden und auch bestimmte Funktionen (ähnlich wie beim BIOS) nutzen zu können, aber ob ich auch direkt herausfinde welcher UART verwendet wird und wo dieser hingemappt ist, keine Ahnung. Kann also gut sein, dass ich auch für Boards mit openfirmware eine spezialisierte Stage2 haben muss.

Die Idee ist es dann, dass Stage2 die Hardware initialisiert und einen HAL für Stage3 zur Verfügung stellt. Dabei kann Stage2 im einfachen binär-Format vorliegen (z.B. beim BIOS nötig) oder als ELF-Datei (für Bootloader wie uboot oder auch GRUB). Stage3 ist dann auf jeden Fall im ELF-Format (es sei denn mir kann noch jemand, ein einfacheres, weniger komplexes, Dateiformat nennen, wo ich die Datei an einer beliebigen Stelle ausführen kann und nur die Symbole auflösen muss, welches auch noch von aktuellen GCC-Versionen unterstützt wird?), damit es an einer beliebigen, von Stage2 festgelegten, Stelle ausgeführt werden kann.

Von Stage2 werden dann auch ein paar nötige hardware-dependent Sachen an Stage3 weitergegeben (z.B. Memory-Map und eindeutiger Name des Boards/derPlatform). Denn Stage3 muss dann auch eine Board-/Platformspezifische Konfigurationsdatei laden, in dem die zu ladenden Programme (was auch Treiber sein können bzw. müssen) stehen. Bei dieser Sache bin ich mir auch noch nicht ganz sicher ob ich das über eine Konfigurationsdatei mache oder ob die zu ladenden Programme nicht direkt in Stage2 gespeichert werden und Stage3 dann zur Verfügung gestellt werden. So wäre ich nicht ganz so flexibel, aber es wäre weniger aufwendig. Das einzige was nämlich in so einer Datei stehen würde, wäre der zu ladende Kernel (für den Fall es könnte mehrere Versionen geben, was ich im Moment nicht plane) und viel wichtige, die zu ladenden Programme und Treiber, damit das OS von sich aus die restlichen Treiber und Programme laden kann.

Am Beispiel des x86er, bräuchte ich z.B. einen IDE-, einen AHCI, einen USB1-3, einen ATAPI usw. -Treiber und noch mind. der Device- und Storage-Server. Für die x86er Architektur würde sich wahrscheinlich eine Datei anbieten, damit man die Treiber auswechseln bzw erweitern kann. Auf den ARM-Boards ist das eher unnötigt, da es sich um SOCs handelt, wo es keine austauschbare Hardware gibt.

Was also machen?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 09. September 2012, 12:54 »
Also war mein erster (und bisher leider einziger) Gedanke, ich brauche eine Stage 1.5. Der Bootsektor würde also entweder ein paar mehr Sektoren laden, keine Ahnung wo ich die abzwacken soll oder (was zwar gehen würde, aber unschön wäre) ich müsste noch eine Datei z.B. "stage_1_5_bios" laden und die lädt dann die anderen beiden Dateien.
GRUB packt seine stage1.5 doch in den Platz zwischen MBR und Anfang der ersten Partition. Traditionell wären das also zusätzliche 31 kB, neuerdings eher ein knappes MB. Geht aber natürlich nur, wenn dir die komplette Platte gehört, in einem Partitionsbootsektor klappt das offensichtlich nicht. Da könntest du dich entscheiden, eine eigene Partition für diese Zusatzsektoren herzunehmen, oder ein FS zu benutzen, das dir erlaubt, ein paar Sektoren am Anfang abzuzwacken (FAT hat das ja zum Beispiel).

Ansonsten musst du eben entscheiden ob Blocklisten in ein Dateisystem rein ein akzeptables Risiko sind. Ich glaube, Lilo hat das so gemacht. Geht dann halt ab und zu kaputt, wenn man nicht aufpasst. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 09. September 2012, 13:04 »
Hallo,

Als erstes möchte ich sagen, ja ich will einen eigenen Bootloader schreiben (bzw. habe dies ohnehin schon gemacht) und nicht GRUB und Co nutzen.
Womit wir wieder bei der Sinnfrage wären. :-)

Für die ARM-Architektur geben dir Flattened Device Trees (FTDs) eine Möglichkeit, zur Laufzeit die vorhandene Hardware zu ermitteln. Die sind boardspezifisch und werden vom Hersteller mit dem Bootloader mitgeliefert und beim Start dem Kernel bereitgestellt, entweder als binäre Datenstruktur oder in einem menschenlesbaren Format.

FTDs solltest du nutzen, statt dir eine eigene /boot/device.hints (siehe FreeBSD) einfallen zu lassen. Linux unterstützt sie bereits seit längerem und sie geben dem Hersteller eine Möglichkeit, die Portierung von Linux auf die Boards zu vereinfachen. Auch Linux möchte irgendwann einen "unified ARM kernel" wie für x86 haben! Siehe für den ARM-Port vor, dass man FTDs auch statisch in den Kernel einkompilieren kann und du hast das Bootloader-Problem gelöst. ;-)

Für mich klingt dein Problem nach "mein Kernel braucht aber Module". Gute Bootloader (EFI, GRUB, Syslinux, Openfirmware) können das bereits. Warum du sie ablehnst, kann ich nicht nachvollziehen. Die meisten embedded-Bootloader (u-boot, RedBoot, aber auch LILO) können nur ein Modul, die initrd, laden. Dafür schenken sie dir FTDs. Der Rest (BIOS, boot.nb0) ist zu primitiv, also musst du bootloader- und hardwarespezifische Erweiterungen schreiben.

Deine Verzeichnisstruktur ist overkill, denn sie setzt voraus, dass auch ein Dateisystem verwendet wird. Das ist bei Flash nicht zwingend gegeben, normalerweise hast du dort den Kernel und die Initrd in zwei getrennten, fixen Bereichen im Flash sitzen und der Bootloader kopiert diese 1:1 in den RAM und springt hin.

Warum eigentlich so kompliziert? Mein Problem ist einfach, dass ich nicht meinen kompletten Bootloader für jedes ARM-Board anpassen wollte.
Dann nimm doch den Bootloader, der schon angepasst ist. ;-) Auf ARM habe ich übrigens bisher nur u-boot, RedBoot und boot.nb0 angetroffen, Openfirmware kenne ich nur von Sun SPARC...

Auf den ARM-Boards ist das eher unnötigt, da es sich um SOCs handelt, wo es keine austauschbare Hardware gibt.
Zumindest u-boot unterstützt USB und kann auch davon booten... und schon hast du austauschbare Hardware. :-)

taljeth: GRUB und LILO benutzen Blocklisten in ein Dateisystem hinein, GRUB aber nur für stage2 (die sich seltener ändert und daher seltener kaputtgeht).

Gruß,
Svenska

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 09. September 2012, 13:38 »
Stimmt, GRUB 1 benutzt natürlich auch Blocklisten für stage2, außer wenn man eine stage1.5 benutzt. Ob GRUB 2 das immer noch kann, weiß ich nicht, aber meines Wissens ist da der normale Weg, dass man einen FS-Treiber fest in die core.img reinbaut, die der stage1.5 entspricht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 09. September 2012, 13:39 »
Zitat von: taljeth
GRUB packt seine stage1.5 doch in den Platz zwischen MBR und Anfang der ersten Partition. Traditionell wären das also zusätzliche 31 kB, neuerdings eher ein knappes MB. Geht aber natürlich nur, wenn dir die komplette Platte gehört, in einem Partitionsbootsektor klappt das offensichtlich nicht. Da könntest du dich entscheiden, eine eigene Partition für diese Zusatzsektoren herzunehmen, oder ein FS zu benutzen, das dir erlaubt, ein paar Sektoren am Anfang abzuzwacken (FAT hat das ja zum Beispiel).
Das mit den Zusatzsektoren bei FAT wusste ich so noch gar nicht, aber birgt auch wieder das Problem, ich kann dann wahrscheinlich nicht einfach in eine schon vorhandene Partition installieren. Ziel wäre es, so wenig wie möglich an den schon vorhandenen Sachen zu ändern, sprich "einfach" nur den Bootsektor ändern, die Dateien an die richtige Stelle kopieren und gut ist. Muss ich mir mal genauer angucken und durch den Kopf gehen lassen.

Zitat von: svenska
Für die ARM-Architektur geben dir Flattened Device Trees (FTDs) eine Möglichkeit, zur Laufzeit die vorhandene Hardware zu ermitteln. Die sind boardspezifisch und werden vom Hersteller mit dem Bootloader mitgeliefert und beim Start dem Kernel bereitgestellt, entweder als binäre Datenstruktur oder in einem menschenlesbaren Format.
Gilt für welche Boards und was ist mit den Boards die das nicht haben? Ich habe hier halt nen Raspberry Pi, der hat es nicht und nen AC100 (Tegra 2) und ich möchte meinen da gibts das auch nicht. Mein drittes ARM-Board (weiß gerade nicht die Bezeichnung) hat das definitiv nicht, da schon älter.

Das ist also nur eine zusätzliche Option und nicht die ultimative Lösung ;)

Zitat von: svenska
Für mich klingt dein Problem nach "mein Kernel braucht aber Module". Gute Bootloader (EFI, GRUB, Syslinux, Openfirmware) können das bereits. Warum du sie ablehnst, kann ich nicht nachvollziehen.
Weil jeder Bootloader das anders umsetzt und ich dann ja doch wieder für jeden Bootloader eine extra Stage schreiben muss. Zumal dann für jeden Bootloader wieder eine andere Config-Datei angepasst werden muss.

Ok, obiges muss ich so oder so machen, aber ich habe einen Punkt ab dem das dann alles einheitlich ist und das will ich versuchen zu erreichen.

Zitat von: svenska
Deine Verzeichnisstruktur ist overkill, denn sie setzt voraus, dass auch ein Dateisystem verwendet wird. Das ist bei Flash nicht zwingend gegeben, normalerweise hast du dort den Kernel und die Initrd in zwei getrennten, fixen Bereichen im Flash sitzen und der Bootloader kopiert diese 1:1 in den RAM und springt hin.
Ist kein unüberwindbares Problem. In dem Fall wäre es dann ähnlich wie beim BIOS, man bräuchte ne Stage1, welche Stage2 und 3 lädt. Zumal das Problem ja ohnehin vorhanden ist. Da würde ich dann liebe an die Stelle nen vernünftigen Bootloader (z.B. openfirmware und selbst uboot dürfte da noch gehen) und die können dann ja wieder aus einem Dateisystem laden.

Zitat von: svenska
Dann nimm doch den Bootloader, der schon angepasst ist.
Eigentlich wollte ich mir die Diskussion ja ersparen, aber egal ;) Die Bootloader bieten aber halt nicht das was ich bräuchte und ich müsste so oder so noch eine eigene Stage da drüber packen.

Zitat von: svenska
GRUB und LILO benutzen Blocklisten in ein Dateisystem hinein, GRUB aber nur für stage2 (die sich seltener ändert und daher seltener kaputtgeht).
Naja, seltener ist immer noch zu oft ;) Ich weiß halt nicht wie das bei extfs aussieht, also ob es da sowas wie defragmentieren (als Bsp.) gibt, weil da könnte genau das Problem auftreten und das will ich, wenn es irgendwie geht, halt vermeiden.

Zitat von: taljeth
Stimmt, GRUB 1 benutzt natürlich auch Blocklisten für stage2, außer wenn man eine stage1.5 benutzt. Ob GRUB 2 das immer noch kann, weiß ich nicht, aber meines Wissens ist da der normale Weg, dass man einen FS-Treiber fest in die core.img reinbaut, die einer kombinierten stage1 und stage1.5 entspricht.
Also wurde das Problem auch schon mal so ähnlich von anderen gelöst, interessant.

Wo liegt dann eigentlich diese stage1.5?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 09. September 2012, 14:00 »
Wo liegt dann eigentlich diese stage1.5?
Du solltest aufmerksamer lesen. ;)

Das war das mit dem Platz zwischen MBR und dem Start der ersten Partition.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 09. September 2012, 14:14 »
Zitat von: taljeth
Du solltest aufmerksamer lesen.

Das war das mit dem Platz zwischen MBR und dem Start der ersten Partition.
Ich hatte das schon gelesen, aber irgendwie hatte ich es in Erinnerung, dass die als Datei irgendwo liegt.

Zur Not, muss ich halt doch eine Datei in "/" ablegen und diese als stage1.5 nutzen, würde dann ja mit zum Bootsektor gehören und ist eine Lösung mit der ich mich anfreunden könnte.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 09. September 2012, 15:36 »
Zitat von: svenska
FTDs solltest du nutzen, statt dir eine eigene /boot/device.hints (siehe FreeBSD) einfallen zu lassen.
Genau das werde ich auch versuchen zu machen :)

Damit lässt sich Platform und Architektur unabhängig, die vorhandene Hardware definieren. So ist alles nach der Stage3 gleich und muss nicht für eine andere Platform/Architektur angepasst werden.

Da kommt aber noch ganz schön Arbeit auf mich zu ;)


kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 09. September 2012, 16:00 »
Ich hatte das schon gelesen, aber irgendwie hatte ich es in Erinnerung, dass die als Datei irgendwo liegt.
GRUB 1 installiert die verfügbaren stage1.5 schon nach /boot/grub, genauso wie auch stage1 dort landet, aber in beiden Fällen ist das keine Datei, die beim Booten wirklich benutzt wird.

Zitat
Zur Not, muss ich halt doch eine Datei in "/" ablegen und diese als stage1.5 nutzen, würde dann ja mit zum Bootsektor gehören und ist eine Lösung mit der ich mich anfreunden könnte.
Was meinst du mit "würde mit zum Bootsektor gehören"? Ist nicht alles, was im FS liegt, außerhalb des Bootsektors?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 09. September 2012, 16:27 »
Zitat von: taljeth
Was meinst du mit "würde mit zum Bootsektor gehören"? Ist nicht alles, was im FS liegt, außerhalb des Bootsektors?
Naja, einmal von der Lage des Source-Code´s her und Stage1 und 1.5 bilden zusammen ja eine Einheit, z.B. wenn Stage1 für´s BIOS und FAT12 geschrieben ist, dann ist es Stage1.5 auch. Daher gehört das für mich "zusammen", wenn man die Stage1.5 dann auch im Dateisystem sehen kann. Dazu fällt mir ein, gibt es eigentlich bei anderen Dateisystemen auch sowas wie versteckt/hidden als Ordner- und Dateiattribut?

Zu der ganzen Thematik fällt mir noch ein, bei FAT32 gibt es doch sowieso mehr als nur den eigentlichen Bootsektor, da müsste das wahrscheinlich nicht mal so sein.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 10. September 2012, 00:24 »
Hallo,

Zitat von: svenska
... Flattened Device Trees (FTDs) ...
Gilt für welche Boards und was ist mit den Boards die das nicht haben?
Also meine Seagate Dockstar hat das, wenn ich mich recht entsinne. Mein Toradex T20 hat es definitiv. Möglicherweise hat es auch mein Allnet 6500. (Die Geräte sind weit weg, daher kann ich das gerade nicht nachprüfen.) Sicher ist, dass FTDs die Zukunft sind.

Zu den Boards, die das nicht haben, zitiere ich mich selbst:
Zitat
Siehe für den ARM-Port vor, dass man FTDs auch statisch in den Kernel einkompilieren kann und du hast das Bootloader-Problem gelöst.

Zitat von: svenska
Für mich klingt dein Problem nach "mein Kernel braucht aber Module". Gute Bootloader können das bereits.
Weil jeder Bootloader das anders umsetzt und ich dann ja doch wieder für jeden Bootloader eine extra Stage schreiben muss. Zumal dann für jeden Bootloader wieder eine andere Config-Datei angepasst werden muss.
Es gibt aber weniger verschiedene Bootloader als Plattformen. Wenn du für u-boot und GRUB dein OS angepasst hast, hast du bereits 80% des Notwendigen erschlagen. So brauchst du ohnehin für jede Plattform einen eigenen Bootloader.

Da würde ich dann liebe an die Stelle nen vernünftigen Bootloader (z.B. openfirmware und selbst uboot dürfte da noch gehen) und die können dann ja wieder aus einem Dateisystem laden.
Dein Bootloader soll u-boot starten? ;-)

Zitat von: svenska
Dann nimm doch den Bootloader, der schon angepasst ist.
Eigentlich wollte ich mir die Diskussion ja ersparen, aber egal ;) Die Bootloader bieten aber halt nicht das was ich bräuchte und ich müsste so oder so noch eine eigene Stage da drüber packen.
Dann bau doch lieber eine bootloader-spezifische stage2, die
- bei guten Bootloadern (Kernel+Module) den Speicher so umbaut, wie dein Kernel das will
- bei normalen Bootloadern (Kernel+Initrd) die Module aus einer initrd in den Speicher so entpackt, wie dein Kernel das will
- bei dummen Bootloadern (BIOS) die Module von einem Speicher lädt und so in den Speicher packt, wie dein Kernel das will

Fertig. Da brauchst du nicht groß Layer schaufeln. Für x86 ist Multiboot ein geeigneter Standard, für ARM wären es FTDs (plus deine Modulliste, aber die kann ja statisch in den stage2 einkompiliert sein).

Ich weiß halt nicht wie das bei extfs aussieht, also ob es da sowas wie defragmentieren gibt, weil da könnte genau das Problem auftreten und das will ich, wenn es irgendwie geht, halt vermeiden.
ext2 kennt "immutable" als Dateiflag. Damit ist es nicht verschiebbar. Lässt sich mit root-Rechten natürlich entfernen. :-P

Zitat von: svenska
FTDs solltest du nutzen, statt dir eine eigene /boot/device.hints (siehe FreeBSD) einfallen zu lassen.
Genau das werde ich auch versuchen zu machen :)
FreeBSD kann neuerdings übrigens auch FTDs.

Ein Hauptnachteil von FreeBSD für mich ist übrigens dieses ganze loader-Gedöns. "Mal eben schnell" ein FreeBSD übers Netzwerk starten ist nicht, wenn man nicht gerade zufällig die CD rumliegen hat und sich dann eine FreeBSD-spezifische PXE-Umgebung (mit TFTP und NFS) aufzieht. Der NetBSD-Kernel unterstützt immerhin Multiboot, wenn auch nur begrenzt (ohne ddb und ohne Module).

Naja, ich hab halt gerne einen Bootloader (bei mir extlinux) für alles. Verwaltet sich einfach schöner.

Gruß,
Svenska

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 10. September 2012, 07:02 »
Zu den Boards, die das nicht haben, zitiere ich mich selbst:
Zitat
Siehe für den ARM-Port vor, dass man FTDs auch statisch in den Kernel einkompilieren kann und du hast das Bootloader-Problem gelöst.
Dann habe ich aber entweder nen Kernel, der unnötig groß ist (zumal ich das im Kernel gar nicht brauche) oder wieder einen Kernel pro Board, das keinen FTD hat. Also packe ich es in die sowieso boardspezifische Loaderstufe.

Zitat von: svenska
Für mich klingt dein Problem nach "mein Kernel braucht aber Module". Gute Bootloader können das bereits.
Weil jeder Bootloader das anders umsetzt und ich dann ja doch wieder für jeden Bootloader eine extra Stage schreiben muss. Zumal dann für jeden Bootloader wieder eine andere Config-Datei angepasst werden muss.
Es gibt aber weniger verschiedene Bootloader als Plattformen. Wenn du für u-boot und GRUB dein OS angepasst hast, hast du bereits 80% des Notwendigen erschlagen. So brauchst du ohnehin für jede Plattform einen eigenen Bootloader.
Jap, in gewisser Weise brauche ich das sowieso. Was mir am Wochenende einfach klar geworden ist, auf der ARM-Architektur kann ich noch nicht mal einfach so die UART benutzen, weil das auch wieder boardspezifisch ist. Mal wird eine ARM kompatible UART genutzt, mal eine die 16550 ähnlich ist und mal eine die noch anders funktioniert (nur mal als ein Bsp).

Da würde ich dann liebe an die Stelle nen vernünftigen Bootloader (z.B. openfirmware und selbst uboot dürfte da noch gehen) und die können dann ja wieder aus einem Dateisystem laden.
Dein Bootloader soll u-boot starten? ;-)
Da hast du mich falsch verstanden, ich möchte dass dann uboot meinen Bootloader startet.

Zitat von: svenska
Dann nimm doch den Bootloader, der schon angepasst ist.
Eigentlich wollte ich mir die Diskussion ja ersparen, aber egal ;) Die Bootloader bieten aber halt nicht das was ich bräuchte und ich müsste so oder so noch eine eigene Stage da drüber packen.
Dann bau doch lieber eine bootloader-spezifische stage2, die
- bei guten Bootloadern (Kernel+Module) den Speicher so umbaut, wie dein Kernel das will
- bei normalen Bootloadern (Kernel+Initrd) die Module aus einer initrd in den Speicher so entpackt, wie dein Kernel das will
- bei dummen Bootloadern (BIOS) die Module von einem Speicher lädt und so in den Speicher packt, wie dein Kernel das will

Fertig. Da brauchst du nicht groß Layer schaufeln. Für x86 ist Multiboot ein geeigneter Standard, für ARM wären es FTDs (plus deine Modulliste, aber die kann ja statisch in den stage2 einkompiliert sein).
Also eine initrd will ich auf keinen Fall haben, nicht so wie Linux sie hat. Damit fallen schonmal die Bootloader weg, welche nur Kernel+initrd laden können. Dann kommt hinzu, dass es nicht nur darum geht, dass ich die Module dann so umbauen müsste wie ich das für richtige halte, sondern das ich im Falle von z.B. GRUB, auch noch andere Sachen machen muss und dazu gehört dann der Zugriff aufs BIOS. Der Plan ist zwar, eventuell auch nen "Loader" für GRUB mal zu haben, aber das liegt noch in sehr weiter Ferne.

Zumal, wie gesagt, dann noch das Problem der Config-Dateien dazu kommt, ich habe mir einfach als Ziel gesetzt, dass das bei mir einheitlich sein soll und das heißt also, dass ich nicht will das man einmal an einer GRUB oder sonstwas für nem Bootloader Config-Datei rumspielen muss, sondern an der Config-Datei von meinem Bootloader.

Ich weiß halt nicht wie das bei extfs aussieht, also ob es da sowas wie defragmentieren gibt, weil da könnte genau das Problem auftreten und das will ich, wenn es irgendwie geht, halt vermeiden.
ext2 kennt "immutable" als Dateiflag. Damit ist es nicht verschiebbar. Lässt sich mit root-Rechten natürlich entfernen. :-P
Also genauso "sicher" wie vorher auch. Es und nach Murphy wird es auch schief gehen ;)

Zumal, was ist eigentlich das Problem daran, einen eigenen Bootloader zu schreiben, wenn man es für richtig hält? Warum darf es denn unter Linux, so viele verschiedene Bootloader geben und GUIs geben usw.?

Es ist ja nicht so, dass es hier darum geht ein eigenes OS zu schreiben, da macht der Bootloader es dann auch nicht mehr schlimmer ;)

Edit::

Um nochmal was zur Diskussion, eigener Bootloader beizutragen ;)

Zitat von: svenska
Wenn du für u-boot und GRUB dein OS angepasst hast, hast du bereits 80% des Notwendigen erschlagen.
Meinst du damit die installierten Bootloader bzw verwendeten? Weil damit hast du definitv nicht Recht (ich sag nur Verhältnis Windows-/Linuxsysteme)!

Dazu kommt noch, was mache ich mit den restlichen 20%, vorallem auf dem PC. Von dem Bootloader den du verwendest habe ich z.B. auch noch nichts gehört. Da müsste ich also für jeden Bootloader den es auf dem PC gibt meine Stage2 anpassen. Da werde ich ja nie fertig um 100% der Systeme zu unterstützen. Wenn ich aber einen eigenen schreibe, unterstütze ich aber sofort 100% der Systeme.

Das gleiche für ARM, wenn ich nur uboot unterstütze, kann ich die meisten Android-Systeme vergessen (an die ist nunmal am günstigsten ranzukommen), denn da wird fastboot genutzt. Da ich auf ARM eh einen Boardspezifischen Teil brauche, kann ich auch zumindest das Laden von eMMC und SD unterstützen und wenn es dann noch reicht einen Kernel+initrd zu laden, sollte ich auch dort annähernd 100% der vorhandenen Bootloader unterstützen.
« Letzte Änderung: 10. September 2012, 07:53 von FlashBurn »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 10. September 2012, 09:31 »
Dazu kommt noch, was mache ich mit den restlichen 20%, vorallem auf dem PC. Von dem Bootloader den du verwendest habe ich z.B. auch noch nichts gehört. Da müsste ich also für jeden Bootloader den es auf dem PC gibt meine Stage2 anpassen. Da werde ich ja nie fertig um 100% der Systeme zu unterstützen. Wenn ich aber einen eigenen schreibe, unterstütze ich aber sofort 100% der Systeme.
Ich glaube, für den PC hast du keine 20% übrig. Und extlinux (falls du den mit dem unbekannten Bootloader meinst) kriegt auch Multiboot hin, ist also keine zusätzliche Arbeit für dich.

Abgesehen davon ist die Sinnfrage bei einem Bootloader genauso sinnlos wie bei einem OS. Ich rate jedem dringend davon ab, der sich nur irgendwas notdürftig funktionsfähiges zusammenkopieren will, aber wenn man es richtig macht, spricht meines Erachtens nichts dagegen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 10. September 2012, 09:44 »
Zitat von: taljeth
Ich glaube, für den PC hast du keine 20% übrig.
Wie gesagt, reden wir von installiert/verwendet oder von wenn ich GRUB verwenden würde und dann noch die anderen, die vllt installiert sind? Denn auf den meisten System ist außer Windows nix installiert.

Ich habe mit einem eigenen Bootloader einfach mehr Sicherheit (mal davon abgesehen, dass ich das genauso wie das OS aus interesse mache), woran der Fehler liegt und nachher weniger Arbeit.

Zitat von: taljeth
Abgesehen davon ist die Sinnfrage bei einem Bootloader genauso sinnlos wie bei einem OS.
Mein Reden ;)

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 10. September 2012, 11:55 »
Hallo,

Zitat
Siehe für den ARM-Port vor, dass man FTDs auch statisch in den Kernel einkompilieren kann und du hast das Bootloader-Problem gelöst.
Dann habe ich aber entweder nen Kernel, der unnötig groß ist (zumal ich das im Kernel gar nicht brauche) oder wieder einen Kernel pro Board, das keinen FTD hat. Also packe ich es in die sowieso boardspezifische Loaderstufe.
Darum habe ich ja auch gesagt, dass du das in den stage2 tun kannst, der ohnehin plattformspezifisch ist. Der Ansatz ist, auf ARM immer FTDs zu haben, weil die Anzahl der Boards mit FTD steigt. ;-)

Da hast du mich falsch verstanden, ich möchte dass dann uboot meinen Bootloader startet.
Dann würde ich das aber nicht mehr "Bootloader", sondern "OS-Loader" nennen, weil der Bootloader bleibt u-boot. ;-)

Dann bau doch lieber eine bootloader-spezifische stage2, die
- bei guten Bootloadern (Kernel+Module) den Speicher so umbaut, wie dein Kernel das will
- bei normalen Bootloadern (Kernel+Initrd) die Module aus einer initrd in den Speicher so entpackt, wie dein Kernel das will
- bei dummen Bootloadern (BIOS) die Module von einem Speicher lädt und so in den Speicher packt, wie dein Kernel das will
Also eine initrd will ich auf keinen Fall haben, nicht so wie Linux sie hat.
Weil? Du musst ja kein Root-Dateisystem drin haben. Eine verkettete Liste mit Modulen reicht auch - und dann ist es äquivalent zu von GRUB oder deinem OS-Loader geladenen Modulen. Nur halt in einer einzelnen Datei, die bei der Installation vom OS erzeugt wird.

Damit fallen schonmal die Bootloader weg, welche nur Kernel+initrd laden können.
Und damit die meisten vorhandenen.

Dann kommt hinzu, dass es nicht nur darum geht, dass ich die Module dann so umbauen müsste wie ich das für richtige halte, sondern das ich im Falle von z.B. GRUB, auch noch andere Sachen machen muss und dazu gehört dann der Zugriff aufs BIOS.
Hier kann ich dir grad nicht folgen. Was denn zum Beispiel?

Zumal, wie gesagt, dann noch das Problem der Config-Dateien dazu kommt, ich habe mir einfach als Ziel gesetzt, dass das bei mir einheitlich sein soll und das heißt also, dass ich nicht will das man einmal an einer GRUB oder sonstwas für nem Bootloader Config-Datei rumspielen muss, sondern an der Config-Datei von meinem Bootloader.
Dein Bootloader/OS-Loader muss jetzt aber auch geladen werden. Bei x86 tut das das BIOS, bei ARM der vorhandene Bootloader (hast du oben geschrieben). Um alles einheitlich hinzubekommen, wirfst du dann jede Information weg, die dir der Bootloader geben könnte und nimmst dann eine statische, boardspezifische Konfigurationsdatei, die die gleichen Informationen enthält. Hab ich das jetzt richtig verstanden?

ext2 kennt "immutable" als Dateiflag. Damit ist es nicht verschiebbar. Lässt sich mit root-Rechten natürlich entfernen. :-P
Also genauso "sicher" wie vorher auch. Es und nach Murphy wird es auch schief gehen ;)
Es funktioniert bei Millionen von Rechnern, warum sollte es bei dir nicht der Fall sein? Entweder, du hast deine unverschiebbaren Daten außerhalb des Dateisystems, was den Aufwand in die Höhe treibt - oder du hast sie im Dateisystem, was bei Blocklisten nicht ganz unproblematisch ist. (Und bei ext2 deutlich unproblematischer als bei FAT - wobei DEFRAG Systemdateien ebenfalls in Ruhe lässt.)

Zitat von: svenska
Wenn du für u-boot und GRUB dein OS angepasst hast, hast du bereits 80% des Notwendigen erschlagen.
Meinst du damit die installierten Bootloader bzw verwendeten? Weil damit hast du definitv nicht Recht (ich sag nur Verhältnis Windows-/Linuxsysteme)!
Wieviele Bootloader gibt es denn, die du so in der realen Verbreitung mal gesehen hast?

ARM: Ich kenne RedBoot, boot.nb0 und u-boot, wobei letzterer am weitesten auf interessanten Systemen verbreitet ist. (Ich befürchte, dass du WinCE-Systeme eher nicht als Target betrachtest, sondern eher u-boot drauf portierst und dann weitermachst.)

x86: NTLDR bzw. BOOTLDR können GRUB starten (GRUB4DOS). Das wären die meisten Installationen, wobei Leute, die das als primären Bootloader benutzen, eher nicht deine Zielgruppe sein dürften. GRUB und Syslinux können Multiboot und sind sehr flexibel, was die Quelle des OS angeht. Die BSD-Bootloader können nur ihr eigenes Ding und sind für sonst nichts zu gebrauchen. (Multiboot von BSD läuft über GRUB oder NTLDR/BOOTLDR.)

Dazu kommt noch, was mache ich mit den restlichen 20%, vorallem auf dem PC.
So nenne Er sie mir beim Namen. :-P

Von dem Bootloader den du verwendest habe ich z.B. auch noch nichts gehört.
Syslinux ist eine Suite aus 4 Bootloadern: syslinux für FAT, extlinux für ext2/3/4, pxelinux für Netzwerkboot und isolinux für ISO9660/El-Torito. Letzteres kennst du von nahezu jeder Linux-Installations-CD.

Da müsste ich also für jeden Bootloader den es auf dem PC gibt meine Stage2 anpassen. Da werde ich ja nie fertig um 100% der Systeme zu unterstützen. Wenn ich aber einen eigenen schreibe, unterstütze ich aber sofort 100% der Systeme.
Und vernichtest zuverlässig jede Form von "mehrere Betriebssysteme". Wenn du natürlich den Microsoft-Ansatz "etwas anderes braucht niemand" nimmst, ist das valide. Für ein Hobby-OS solltest du Interoperabilität bereitstellen.

Das gleiche für ARM, wenn ich nur uboot unterstütze, kann ich die meisten Android-Systeme vergessen (an die ist nunmal am günstigsten ranzukommen), denn da wird fastboot genutzt.
Dummerweise sind die Android-Systeme, an die günstig heranzukommen ist, nur per Reverse-Engineering zu analysieren. Zumindest der erste Port sollte auf ein Development-Board geschehen, und dort findest du eigentlich ausschließlich u-boot. Und wer hindert dich eigentlich daran, pro Bootloader (nicht pro Plattform!) eine stage2 zu schreiben, wenn du doch ohnehin für jede Plattform einen Bootloader schreiben willst? ;-)

Da ich auf ARM eh einen Boardspezifischen Teil brauche, kann ich auch zumindest das Laden von eMMC und SD unterstützen und wenn es dann noch reicht einen Kernel+initrd zu laden, sollte ich auch dort annähernd 100% der vorhandenen Bootloader unterstützen.
Also eMMC/SD sind definitiv extrem hardwarespezifisch. Und wenn du oben sämtliche Bootloader, die nur Kernel+Initrd laden können ausschließt, warum sind die dann jetzt hier wieder aktuell?

Nenne dein Teil einfach OS-Loader und lasse es vom garantiert funktionierenden Bootloader der Hardware (BIOS, GRUB, u-boot) laden. ;-)

Übrigens unterstützen alle mir bekannten Bootloader Chainloading, d.h. ein generischer, hardware- und plattformspezifischer stage2 funktioniert mit jedem Bootloader.

Gruß,
Svenska

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 10. September 2012, 12:55 »
Zitat von: svenska
Dann würde ich das aber nicht mehr "Bootloader", sondern "OS-Loader" nennen, weil der Bootloader bleibt u-boot.
Dann ist aber GRUB auch "nur" ein OS-Loader, aber ja mir geht es um einen OS-Loader.

Zitat von: svenska
Weil? Du musst ja kein Root-Dateisystem drin haben. Eine verkettete Liste mit Modulen reicht auch - und dann ist es äquivalent zu von GRUB oder deinem OS-Loader geladenen Modulen. Nur halt in einer einzelnen Datei, die bei der Installation vom OS erzeugt wird.
Ist mir aus Nutzersicht zu umständlich, ich müsste also jedes Mal wenn der Nutzer, einen anderen Treiber schon vom OS-Loader mit laden lassen will oder es ein Update gab, das Image neu erstellen und das ist für mich einfach ein no-go. Das ich mir dadurch woanders Schwierigkeiten einhandle ist mir bewusst.

Allerdings ist es das gleiche bei der Sicherheit, entweder du machst es ganz einfach, also keine Sicherheit oder du betreibst Aufwand um Sicherheit zu bekommen.

Zitat von: svenska
Und damit die meisten vorhandenen.
So viel zu deiner weiter unten geforderten Interoperabilität ;) Die Loader sind also alle Unix- bzw. sogar Linux-spezifisch :P

Zitat von: svenska
Hier kann ich dir grad nicht folgen. Was denn zum Beispiel?
Ich gucke im BIOS wegen PCI, weiß nicht wie gut GRUB das mit VESA hinbekommt und nutze es um das Bootlaufwerk genauer zu bestimmen (kann auch noch mehr sein, weiß ich gerade nicht genau).

Zitat von: svenska
Wieviele Bootloader gibt es denn, die du so in der realen Verbreitung mal gesehen hast?
Naja, da liegt doch das "Problem", zu weit über 90% Windows und ansonsten alles mögliche, was derjenige halt gerade mag um sein Linux laden zu lassen.

Zitat von: svenska
So nenne Er sie mir beim Namen.
Das ist ja das Problem, ich kenn sie nicht alle ;) Und gerade auf dem PC/BIOS ist es doch relativ "einfach" einen OS-Loader zu schreiben, genauso wie für Openfirmware.

Zitat von: svenska
Und vernichtest zuverlässig jede Form von "mehrere Betriebssysteme". Wenn du natürlich den Microsoft-Ansatz "etwas anderes braucht niemand" nimmst, ist das valide. Für ein Hobby-OS solltest du Interoperabilität bereitstellen.
Ich glaube da scheitern wir beide an Bootloader oder OS-Loader, weil nur es meinem OS-Loader auf dem PC reicht, dass der Bootsektor geladen wird, heißt das doch nicht das andere OS nicht geladen werden können.

Um es kurz zu machen, ich brauche immer einen Bootloader der meinen OS-Loader lädt (auf dem PC BIOS oder in Zukunft mal EFI).

Zitat von: svenska
Nenne dein Teil einfach OS-Loader und lasse es vom garantiert funktionierenden Bootloader der Hardware (BIOS, GRUB, u-boot) laden.
Wie weiter oben schon gesagt, genau das ist der Fall ;)

Zitat von: svenska
Also eMMC/SD sind definitiv extrem hardwarespezifisch. Und wenn du oben sämtliche Bootloader, die nur Kernel+Initrd laden können ausschließt, warum sind die dann jetzt hier wieder aktuell?
Also ich schließe die Bootloader aus, direkt mein OS zu laden, sie sind dafür da meinen OS-Loader zu laden. Dazu reicht ja kernel+initrd (sprich hardwarespezifischer Teil + allgemeiner Loader-Teil).

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 10. September 2012, 14:00 »
Zitat von: svenska
Und damit die meisten vorhandenen.
So viel zu deiner weiter unten geforderten Interoperabilität ;) Die Loader sind also alle Unix- bzw. sogar Linux-spezifisch :P
tyndur ist kein Unix und ich verbitte mir diese Unterstellung. :P
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 10. September 2012, 14:26 »
Zitat von: svenska
Und damit die meisten vorhandenen.
So viel zu deiner weiter unten geforderten Interoperabilität ;) Die Loader sind also alle Unix- bzw. sogar Linux-spezifisch :P
tyndur ist kein Unix und ich verbitte mir diese Unterstellung. :P
Es geht mir darum, dass die meisten (auf jeden Fall auf ARM) Loader nur kernel+initrd können und das ist sehr wohl Linux-spezifisch ;) Denn da kommt das ja her (bzw. von Unix) und die haben auch nicht auf eine Interoperabilität geachtet :P

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 10. September 2012, 16:59 »
Also ist jeder Bootloader, der nur _ein_ Modul laden kann, Linux-spezifisch. Kann er mehrere, ist er auf ein einziges Betriebssystem zugeschnitten (Ausnahme: Multiboot, was du explizit nicht unterstützen willst) und kann er keine, ist er auch auf ein einziges Betriebssystem zugeschnitten.

Aha.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 10. September 2012, 17:06 »
Zitat von: svenska
Also ist jeder Bootloader, der nur _ein_ Modul laden kann, Linux-spezifisch. Kann er mehrere, ist er auf ein einziges Betriebssystem zugeschnitten (Ausnahme: Multiboot, was du explizit nicht unterstützen willst) und kann er keine, ist er auch auf ein einziges Betriebssystem zugeschnitten.
Die Intention der Ersteller war genau das, Linux zu laden und nicht, wie kann man auch andere OS laden.

Zumal nach der Argumentation auch mein Loader nicht nur auf mein OS zugeschnitten wäre.

Zu Multiboot, ich würde das gerne unterstützen bzw. auf anderen Platformen werde ich das auch machen (sofern vorhanden), aber es ist auf x86 einfach mehr Arbeit für mich.

 

Einloggen