Hi,
ich würde gerne meine eigene Linux-Distribution schreiben.
Dabei möchte ich nicht einfach eine existente Distribution modifizieren
oder Linux from Scratch nutzen, sondern Spaß daran haben, etwas zu
programmieren und selbst zu entwickeln.
Eine gut funktionierende Shell (bourne shell / bash) ist schon zu viel
verlangt. Auf jeden Fall soll das OS kein GUI haben, nur Text. Zufrieden
wäre ich schon mit einer simplen Hello World-Ausgabe. Oder lohnt es sich
da, gleich den Kernel selbst zu schreiben?
Und was für Software benötige ich zum Entwickeln eines OS?
Danke im Voraus
Pascal
Pascal schrieb:> Eine gut funktionierende Shell (bourne shell / bash) ist schon zu viel> verlangt. Auf jeden Fall soll das OS kein GUI haben, nur Text
Äh, dir ist bekannt das Linus seinen allerersten Kernel rund um die
existierende GNU Shell geschrieben hat? Eine Shell hat nämlich (fast)
einen kommpletten Satz an Kernel-Schnittstellen eingebaut.
Wenn man sich wenig Arbeit machen will: Schau Dir mal busybox an. Das
ist ein nahezu komplettes Unix mit Linux Kernel Support in einem
kompakten Binary.
Eine darauf aufbauende Distribution wäre z.B. fli4l.de oder OpenWRT.
Als Torvalds mit dem Linux anfing, brauchte man zur Initialisierung des
Prozessors nur ein paar Assemblerzeilen. Bei modernen PC-Prozessoren
kann man den Code zur Initialisierung gar nicht mehr selbst entwickeln.
Wie wäre es mit einem BS für einen 32 Bit Mikrocontroller? Da kannst du
von Anfang an mit IDE und In-Circuit-Debugger arbeiten.
Jim M. schrieb:> Schau Dir mal busybox an
eine interessante Idee...
die busybox befehle kenne ich schon von meinem Android-Handy.. die habe
ich dann in shell scripten genutzt, die beim Booten ausgeführt werden.
Das wird meine erste wahl. Danke!!!!!!!!!!
Noch einer schrieb:> Wie wäre es mit einem BS für einen 32 Bit Mikrocontroller
habe ich bei mir rumzuliegen. Ich finde die Idee nicht schlecht,
wahrscheinlich werde ich das entwickeln.
Es ist schon ein grosser Unterschied, ob man ein eigenes OS schreibt,
oder eine Linux distribution erstellt.
Bei einem eigenen OS muss man sich erst überlegen, für welche Platformen
es sein soll, wofür es sein soll, weilche Algorythmen du verwenden
willst, und welche Schnittstellen du einbauen willst. Das ist sehr
aufwendig, aber durchaus machbar.
Wenn du aber nur eine Linux distribution erstellen willst, ist das viel
einfacher. Zunächst brauchst du eine Libc, diese stellt unter anderem
eine Schnitstelle zwischen Programm und Kernel dar und beinhaltet auch
Dinge wie die ld.so, welche Programme lädt, usw. Bekannte Libcs sind
musl, glibc, uclibc, etc. Der erste Prozess, welcher vom kernel
gestartet wird, ist normalerweise /sbin/init. Man kann dort durchaus ein
standard "Hello World" Program ablegen, wenn man will, und die ausgabe
wird am Bildschirm angezeigt werden. Init oder PID1 hat aber eigentlich
die Aufgabe, auf daemonisierte und zombie Prozesse zu warten, und das
System neu zu starten, und sowie das rc Programm zum starten aller
Services zu starten. Minimale Beispiel init:
https://gist.github.com/rofl0r/6168719
Es ist sinvoll, mit der Funktionsweise von initrd, initramfs, sowie
fundamentalen Linux/Unix Syscalls, bzw. deren C API functionen, bzw. mit
POSIX vertraut zu sein. Schaue dir auch devfs/mdev/vdev/eudev und die
man page von mount(2) und pivot_root(2) an.
Beides zusammen... gibt es so etwas schon?
Ein OS für harte Echtzeitanforderungen auf einem ARM Cortex-M. Für
unkritische Teile zusätzlich die Busybox.
Pascal schrieb:> habe ich bei mir rumzuliegen. Ich finde die Idee nicht schlecht,> wahrscheinlich werde ich das entwickeln.
Es gibt einen ziemlich bedeutenden Schritt von Kernels für Prozessoren
ohne MMU zu solchen mit. Etliche Cortex M implementieren jedoch nicht
einmal die von ARM optional angebotene MPU (Memory Protection Unit), das
effektive Minimum für einen einfachen Kernel mit vom Betriebssystem
getrennten Anwenderprogrammen. MSDOS kam zwar ohne aus, handelte sich
deshalb aber auch den Spottbegriff "glorified bootstrap loader" ein.
Daniel A. schrieb:> Wenn du aber nur eine Linux distribution erstellen willst, ist das viel> einfacher.
was bräuchte ich noch neben dem linux kernel quellcode und wie
kompiliere ich das, um schlussendlich z.B. eine iso zu erhalten? Reicht
zum kompilieren gcc?
Eric B. schrieb:> Erste Anlaufstelle wäre denke ich https://wiki.osdev.org/Main_Page
Habe ich bereits versucht
Die "Babysteps" mit Hello World sind gut nachvollziehbar.
NASM kompiliert auf Linux alles ohne Fehler.
Allerdings habe und hatte ich mein Leben lang nie eine Floppy Disk mit
Magnetscheiben und habe somit versucht die binären daten aus der bin
datei aus dem compiler auf einen USB Stick in die ersten 512 Bytes zu
packen (mit dd)
Wenn ich mit dem BIOS (sowohl mit ausgeschalteter, also beim
ausgewählten Boot Medium bleiben, als auch eingeschalteter
Bootreihenfolge) vom USB Stick boote, kommt nur eine Fehlermeldung:
"Reboot and Select proper Boot device
or Insert Boot Media in selected Boot device and press a key_"
Das stammt nicht aus dem asm code
Und die 1TB Festplatte lässt sich weder mit gparted auf linux mint noch
von gparted live partitionieren, weshalb usb stick nötig ist. Alternativ
hätte ich noch ein usb dvd writer laufwerk von lg
Wäre nett wenn jemand mir helfen könnte
AMD fx 4300 und ASUS am3+ mainboard
Moin,
Pascal schrieb:> was bräuchte ich noch neben dem linux kernel quellcode und wie> kompiliere ich das, um schlussendlich z.B. eine iso zu erhalten? Reicht> zum kompilieren gcc?
Naja, make wirste neben dem gcc noch brauchen und wahrscheinlich noch
das ein oder andere tool, aber eigentlich nix exotisches.
Dann bauste dir einen Kernel moeglichst ohne module, mit angeflanschtem
initramfs, in dem du z.b. mittels gcc ein statisch gelinktes hello-world
gebaut hast. Dem kernel kannste dann z.b. per command-line angeben
"init=/bin/hello", dass er statt einem richtigen init eben dein olles
HelloWorld aufrufen soll.
Diesen Kernel incl. initramfs musste dann halt noch gebootet kriegen,
also brauchste entweder irgendeinen bootloader oder direkt per uefi.
Das wird dir aber alles momentan recht wenig helfen. Mehr wirds helfen,
wenn du dir doch mal z.B. Linux from Scratch anschaust/baust und z.B.
"from powerup to bash prompt".
Gruss
WK
Dergute W. schrieb:> Das wird dir aber alles momentan recht wenig helfen
Doch, das hat es. Sehr sogar
Erstmal noch: jetzt funktioniert das Booten vom usb stick. Der
Bootloader läuft (auch wenn er nur hello world anzeigt ;) )
Jetzt stellt sich mir die folgende Frage:
Wenn ich den Linux Kernel kompiliert habe (mithilfe von gcc und gnu
make), und grub z.B. auf den usb stick soll, der für die Versuche als
Bootmedium verwendet wird: wie packe ich die kompilierte datei auf den
USB-Stick?? Brauche ich dafür ein Tool, muss der Stick vorher auf ext4
oder fat32 formatiert werden?
Mir ist das irgendwie noch ein rätsel als os dev anfänger
Moin,
Pascal schrieb:> Erstmal noch: jetzt funktioniert das Booten vom usb stick. Der> Bootloader läuft (auch wenn er nur hello world anzeigt ;) )
Aha. Welcher Bootloader? Soll er das?
Wie du weiter verfaehrst, haengt von den Faehigkeiten deines Bootloaders
ab. Wenn du ein Linux direkt ausm UEFI starten lassen willst, muss das
von einer FAT Partition aus passieren. Was anderes (ext4 oder sowas)
kann da grad nicht gelesen werden. Dafuer muss aber der Kernel auch
gebaut sein, d.h. die richtigen "X" beim konfigurieren gesetzt worden
sein. Aber es braucht dann nicht unbedingt einen weiteren Bootloader.
Wenn du aber z.B. grub als Bootloader hernimmst, dann kann der eher
irgendein linux-spezifisches Filesystem lesen. Egal wie: Der Bootloader
klaubt sich immer von irgendwoher (von Sektoren einer Pladde, von
Sektoren eines Flashes, ...) einen Kernel zusammen, schreibt den ins RAM
und springt dann "rein". Das muss alles zusammenpassen, sonst gibts
lange Gesichter...
Gruss
WK
Pascal schrieb:> Jetzt stellt sich mir die folgende Frage:> Wenn ich den Linux Kernel kompiliert habe (mithilfe von gcc und gnu> make), und grub z.B. auf den usb stick soll, der für die Versuche als> Bootmedium verwendet wird: wie packe ich die kompilierte datei auf den> USB-Stick?? Brauche ich dafür ein Tool, muss der Stick vorher auf ext4> oder fat32 formatiert werden?
Wie wäre es wenn du erst mal statt mit realer Hardware dein Ganzes
Projekt unter qemu zum laufen bringst, du sparst eine menge Zeit und
Nerven!
Setz dir ein Linux auf falls du es nicht schon hast, setz dir ein paar
Scripte zusammen welche dir dein zeug auf ein Image schreiben und teste
das ganze mit qemu, geht schneller und Schmerz freier. Sollte dann
endlich ein Image den Reifegrad erreicht haben das es genau das macht
was du willst.
Steck dein USBStick an dein Linux vergewisser dich doppelt das richtige
Device zu treffen und nimm dd um das Funktionierende Image an realer
Hardware zu testen.
Außerdem solltest du mal überlegen ob du nicht zu viel auf einmal willst
dein Bootloader kann "Hallo Welt" ausgeben, Glückwunsch, aber bis zum
vollwertigen Bootloader ist es noch ein weiter Weg. Als nächstes
könntest du dein Bootloader so erweitern das er im MBR einer FAT16 leben
kann und vielleicht mehr als 446 Bytes groß sein kann.
Generell macht dir Klar was du willst, ursprünglich wolltest du
Pascal schrieb:> Hi,> ich würde gerne meine eigene Linux-Distribution schreiben.> Dabei möchte ich nicht einfach eine existente Distribution modifizieren> oder Linux from Scratch nutzen, sondern Spaß daran haben, etwas zu
wenn man das jetzt als Layer sieht bootloader -> Kernel -> Userspace,
bist du gerade ziemlich weit weg von denn was du vorhast. Wenn du in der
Ursuppe schwimmen willst ist das fein, das lernt man eine Menge über
Prozessor Architekturen.
Aber dann wäre mein erster versuch nicht ein bootloader für den Linux
Kernel zu schreiben sondern erst mal ein Stück Software das ein kleines
Hallo Welt das nicht in ASM geschrieben wurde zu starten kann.
Wenn dein Ziel aber ein Linux Kernel mit eigenen Userspace ist dann
würde ich mich nicht mit den Bootloader befassen grub/lilo/syslinux/...
nehmen und mit qemu erforschen wie mein Linux einen initprocess bekommt.
Was willst du eigentlich genau machen?
Ja, du kannst einen Bootloader und einen Betriebssystem-Kernel selbst
entwickeln. Gute Informationen für die PC-Plattform dazu gibt es z.B.
unter http://osdev.org oder - auf Deutsch - http://lowlevel.eu.
Du kannst alternativ auch den Linux-Kernel (oder einen anderen Kernel)
benutzen. Das hat den Vorteil, dass du eine funktionierende Umgebung mit
(hoffentlich) funktionierenden Treibern bekommst.
Ich würde dir mal zwei Dinge empfehlen:
- die Tutorialserie unter
http://www.lowlevel.eu/wiki/OS-Dev_f%C3%BCr_Einsteiger
- Linux from Scratch (oder etwas in der Art)
Probiere einfach mal beides aus und entscheide, was dir besser gefällt.
Pascal schrieb:> Daniel A. schrieb:>> Wenn du aber nur eine Linux distribution erstellen willst, ist das viel>> einfacher.>> was bräuchte ich noch neben dem linux kernel quellcode und wie> kompiliere ich das, um schlussendlich z.B. eine iso zu erhalten? Reicht> zum kompilieren gcc?
Ich habe schnell mal ein shellscript erstellt, welches eine fertige ISO
erstellt, welche mit einer /init in einem initramfs welche einige Module
lädt, die CD mounted, und dann die sich darauf befindende /sbin/init
started, die einfach "Hello World!" ausgibt:
https://gist.github.com/Daniel-Abrecht/b745fab790fc6354ce7267e58e91d579
Es funktioniert im moment nur per bios boot und noch nicht per EFI.
Ausserdem ist es nur dafür gedacht zu sehen, was die grundlegenden
nötigen Abläufe beim booten in userspace sind, wie man eine bootbare ISO
erstellt, und welche Module man minimal benötigt (Eigentlich hätte ich
da eine eigene Kernel config erstellen sollen).
Es ist das absolute minimum. Für ernsthafte Projekte empfehle ich im
initramfs einen Device Manager wie vdev oder eudev zu verwenden, um /dev
zu mounten und die Module zu laden, und busybox + ein shellscript alls
/init in der initramfs um das mounten des rootfs usw. zu übernehmen.
Viele Distributionen haben Programme / Scripts um ihre initramfs zu
generieren. Ausserdem habe ich hier musl libc verwendet, aber glibc
könnte je nach Anwendungsfall sinvoller sein. Und eigentlich sollte man
den Compiler für die neue Distro mit der neuen libc nochmal neu
compilieren.
Oh, und hier noch die ISO: https://www.dpa.li/hello_world_distro.iso
Daniel A. schrieb:> Ich habe schnell mal ein shellscript erstellt, welches eine fertige ISO> erstellt, welche mit einer /init in einem initramfs welche einige Module> lädt, die CD mounted, und dann die sich darauf befindende /sbin/init> started, die einfach "Hello World!" ausgibt:> https://gist.github.com/Daniel-Abrecht/b745fab790fc6354ce7267e58e91d579>> Es funktioniert im moment nur per bios boot und noch nicht per EFI.
Kein Problem. Ich nutze noch das gute alte BIOS, USB-Boot wird
unterstützt.
Danke für deine Arbeit!!!
S. R. schrieb:> Was willst du eigentlich genau machen?
Aus Spaß und um Programmiererfahrung ein eigenes Betriebssystem
entwickeln (am besten Linux-basiert)
Erstmal ne textbasierte einfache Shell, dann vielleicht später ein GUI
Spezialisieren kann ich mich ja später noch
Mike B. schrieb:> Da bist du hier auf Mikrocontroller.net goldrichtig!
Super!
Gleich meine nächste Frage:
Wie
- mache ich aus dem Hello World init Prozess mehrere Prozesse
- packe ich Software im Vorhinein (z.B. nano, gcc, nasm,...) in die iso?
Pascal schrieb:> - mache ich aus dem Hello World init Prozess mehrere Prozesse
man fork
> - packe ich Software im Vorhinein (z.B. nano, gcc, nasm,...) in die iso?
man mkisofs
Bevor Du Dir solche Ziele setzt, sollten erstmal die Grundlagen sitzen.
Hmmm schrieb:> Bevor Du Dir solche Ziele setzt, sollten erstmal die Grundlagen sitzen
Du hast Recht
Allerdings ist alles nur schwer für mich verständlich, ich habe zuvor
noch nie die Grundlagen eines OS durchgearbeitet
Pascal schrieb:> Gleich meine nächste Frage:> Wie> - mache ich aus dem Hello World init Prozess mehrere Prozesse
Auf unix systemen nutzt man "fork()" um aus einem 2 identische Prozesse
zu machen. Der rückgabewert von "fork()" gibt dann an, welches der
originalprozess, und welches der child Prozess ist. Den child Prozess
started dann mit "exec" ein anderes Program und überschreibt sich dabei
mit diesem selbst. Eine gute Strategie des Parent Prozesses zu prüfen ob
das funktioniert hat ist, mit "pipe" 2 filedescriptoren zu erstellen,
bei diesen das Cloexec flag zu setzen, und nach dem fork bei beiden den
jeweils anderen Dateidescriptor zu schliessen. Wenn das exec
funktioniert hat sieht der Parent prozess, dass das andere Ende der Pipe
geschlossen wurde, weil der filedescriptor des child prozesses wegen dem
cloexec flag geschlossen wurde. Andernfalls kann der child prozess den
filedescriptor nutzen, um dem parent prozess eine Fehlermeldung zu
übermitteln.
Da das ganze etwas umständlich ist gibt es POSIX funktionen wie system
und popen, die das alles für einen übernehmen. Da man das aber sehr
häufig braucht, verwendet man dazu häufig shell scripte.
> - packe ich Software im Vorhinein (z.B. nano, gcc, nasm,...) in die iso?
Das script erstellt einen Ordner namens my_hello_world_distro. Die
Dateien, die in die ISO verpackt zurden, sind im unterordner "rootfs".
Die iso wird mit mkisofs, bzw. mit genisoimage erstellt, bei der Zeile:
Wenn man die Variablen einsetzt wird daraus jenachdem:
1
genisoimage -r -l -o hello_world_distro.iso -b syslinux/isolinux.bin -c syslinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -A "Hello World Distribution" -input-charset utf-8 rootfs
oder:
1
mkisofs -r -l -o hello_world_distro.iso -b syslinux/isolinux.bin -c syslinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -A "Hello World Distribution" -input-charset utf-8 rootfs
Es ist aber zu beachten, das das init Program mit der musl libc statisch
kompiliert wurde. Man sollte für alle Programme die selbe libc
verwenden. Mein shell script hat dafür den musl-gcc wrapper unter
"./bin/musl/bin/musl-gcc" verwendet. Dieses ruft einfach gcc mit dem
-specs unter "./bin/musl/lib/musl-gcc.specs" auf. Dort steht, wo die
Dateien der libc sind, und gegen welche mit welchen Optionen gelinkt
werden muss. Dies ist aber nicht wirklich ideal.
Wenn man viele andere Programme kompilieren will, sollte man den gcc mit
der neuen libc nochmal neu kompilieren. Dann braucht man den wrapper/das
specs file nichtmehr, kann diesen dann auch von der eigenen Distro aus
verwenden, und läuft auch nicht in andere stolpersteine hinein. Bei
dieser gelegenheit kann man sich auch noch gleich überlegen, ob man
wirklich musl libc verwenden will, oder die weiter verbreitete glibc,
und ob man wirklich gcc nehmen will, oder ob einem clang besser gefällt.
Und dann gibt es noch etwas beim Laden der Programme zu beachten. Das
momentane init program wird statisch gelinkt. Würde man es statdessen
dynamisch linken, müsste man noch die Libraries der Libc in die ISO
packen. Bei musl wäre das einfach die ./bin/musl/lib/libc.so, bei glibc
wäre das unter anderem die ld.so und noch ein paar andere. Diese dienen
bei dynamisch gelinkten Programmen dem laden des Programs selbst. Wenn
das OS ein Program im ELF Format lädt, und es sieht eine Librarie in
dessen .interp section (z.B. ld.so), wird diese Librarie geladen statt
dem Programm, und die Librarie lädt das Programm dann nach. Das ist
vergleichbar mit der shebang Zeile bei Shellscripts (die Zeile mit
"#!/mein/interpreter-program"), bei denen das dort angegebene Program
gestartet wird, und dieses dann das Script lädt. Das script mit
"./scriptname" zu starten ist dann das selbe wie es mit
"/mein/interpreter-program ./scriptname" zu starten. Genauso verhält es
sich bei dynamisch gelinkten Programmen. z.B. wenn ich nachsehe was in
der .interp section meiner /bin/bash steht:
Dann steht dort: "/lib64/ld-linux-x86-64.so.2". Wenn ich also /bin/bash
aufrufe, ist dass das selbe, wie wenn ich "/lib64/ld-linux-x86-64.so.2
/bin/bash" starten würde. (also /lib64/ld-linux-x86-64.so.2 als Program
und /bin/bash als argument).
Wie sollte ich nach dem Hello World Linux vorgehen, um schließlich
irgendwann bei einer selbstgeschriebenen Shell (nur Text) zu landen?
GUI spielt jetzt für mich noch keine wichtige Rolle, wäre später aber
schön.
Ich würde da gerne von
Daniel A. schrieb:> Ich habe schnell mal ein shellscript erstellt, welches eine fertige ISO> erstellt, welche mit einer /init in einem initramfs welche einige Module> lädt, die CD mounted, und dann die sich darauf befindende /sbin/init> started, die einfach "Hello World!" ausgibt:> https://gist.github.com/Daniel-Abrecht/b745fab790fc6354ce7267e58e91d579
diesem Hello World aus weitermachen und mich immer weiter
hineinsteigern, bis eine nutzbare Shell zustande kommt
Make olddefconfig übernimmt die Kernel Konfig des host systems. Der
Kernel und dessen Module mit openssl signiert, wenn das in der Kernel
config eingeschaltet ist. Bei Distributionen die per UEFI Booten können
ist das in der regel der fall. Man könnte es entweder in "make
menuconfig" ausschalten, oder die openssl development files
installieren. Bei debian basierten systemen sind diese glaub ich in den
openssl und libssl-dev Packeten verfügbar.
Für einen init-Prozess gelten ein paar besondere Regeln, weil er ein
besonderer Prozess ist (stirbt ein Prozess mit Kindern, übernimmt der
init-Prozess die Pflege der Waisenkinder). Eine absolut minimale
Implementation gibt es hier: https://gist.github.com/rofl0r/6168719
Das Beispiel kannst du direkt so nehmen, wie es ist. Es tut das, was
nötig ist, und startet ansonsten nur /etc/rc. Dein Hello-World heißt
jetzt also /etc/rc und ist ein ganz normales Linux-Programm.
Pascal schrieb:> Wie sollte ich nach dem Hello World Linux vorgehen, um schließlich> irgendwann bei einer selbstgeschriebenen Shell (nur Text) zu landen?
Indem du dir eine Shell für Linux programmierst. Ob du die nun als
/etc/rc, oder als "./meineshell" startest, spielt keine große Rolle. Wie
du eine Shell programmierst, erfährst du, indem du dich mit der
Programmierung von Linux-Programmen befasst.
Stichwort: Tastatureingaben bekommst du von stdin (kannst du z.B. mit
scanf() lesen), Bildschirmausgaben schreibst du nach stdout (kannst du
z.B. mit printf() machen), und Programme startest du mit einer
Kombination aus fork() und exec(). Der Rest ist Fleißarbeit.
Hm, ich glaub das Projekt ist nicht so sinnig. Der Linux-Kernel macht
schon quasi alles. Ein Hello World auf Basis von Linux ist im
Wesentlichen ein Einzeiler als Init-Prozess ...
Andererseits, wenn man den Linux-Kernel nicht nimmt und die
Hardwareinitialisierung selber macht, ist man auf einer modernen x86-CPU
auch tot, bevor man ein Hello World-Programm hat. Das will man sich
glaube ich wirklich nicht antun.
Ich seh also nicht so wirklich was man jetzt da zwischendrin tun will.
Warum nimmst Du nicht erst einmal CP/M?
Ist ziemlich einfach auf einem AVR oder STM zu implementieren. Ist vor
allem übersichtlicher als Linux.
Wenn Du das am Laufen hast, dann hast Du schon Mal die Grundlagen für
komplexere Systeme.
Warum nicht erstmal mit einem Lehr-Betriebssystem einsteigen, wo alles
"Clean" dokumentiert ist?
Beispielhaft MicroC/OS-II (auch bekannt als "Bildschirmsockel") samt
Buch.
Ist ein prima Einstieg.
Oder "Moderne Betriebssysteme" vom Tanenbaun, aber am besten auf
Englisch. Die deutsche Übersetzung ist rottig.
Meines Erachtens fehlen dir jegliche Grundlagen. Da brauchst du nicht
mit dem Linux Kernel beginnen.
Vielleicht erstmal grundlegende Programmiersprachen (Python) angehen und
die Basics lernen.
labormaus schrieb:> grundlegende Programmiersprachen (Python)
Ich mag Python und es ist schön einfach, aber nicht grundlegend, wenn
man in Richtung "verstehen was im Hintergrund so passiert" gehen will.
Grundlegend ist dafür sowas wie C.
Sven B. schrieb:> labormaus schrieb:>> grundlegende Programmiersprachen (Python)>> Ich mag Python und es ist schön einfach, aber nicht grundlegend, wenn> man in Richtung "verstehen was im Hintergrund so passiert" gehen will.> Grundlegend ist dafür sowas wie C.
Nein. Natürlich kann es nur eins geben, wenn man wirklich die Funktion
eines OS-Kernels verstehen will: Assembler.
Diese C-Fetischisten, aus denen sich die Mehrheit der Kernel-Entwickler
rekrutiert, sind zwar immer bemüht, den Assembler-Anteil so gering wie
möglich zu halten (und möglichst kryptisch entstellt möglichst
unauffindbar zu verstecken), aber auch diese Leute kommen letztlich
nicht drum herum: ganz unten gilt: Asm rules.
Im übrigen ist der sehr unschöne C-Stil des Linux-Kernels genau nur
einer Sache geschuldet: der Effizienz. Das ist eigentlich purer
Assembler, nur mit den Sprachmitteln von C ausgedrückt. Ein anderer
Compiler würde das sofort offenbaren.
Dass nicht schon eine neue Version desselben Compilers sich derart
deutlich bemerkbar macht, liegt einfach nur daran, dass der gcc de facto
Linux-Hure ist. Sprich seine Entwickler bemühen sich natürlich, genau
diesen Effekt möglichst zu verhindern...
Letztlich ist das ein genauso beknacktes Oligopol wie das
sprichwörtliche Wintel-Konglomerat.
Wirklich frei ist man nur in Assembler.
c-hater schrieb:> Diese C-Fetischisten, aus denen sich die Mehrheit der Kernel-Entwickler> rekrutiert, sind zwar immer bemüht, den Assembler-Anteil so gering wie> möglich zu halten
Das will man so. Weil der USB Treiber halt nicht nur auf X86, sondern
auch auf X64 oder ARM laufen soll.
Pascal schrieb:> Gerade bemerkt: Linux-Kernel lässt sich nicht kompilieren!!
Da steht recht deutlich das ihm OpenSSL fehlt. Versteckt sich mitunter
in Paket-Namen wie "libssl-devel".
Das braucht AFAIK nur für signierte Module o.ä, das müsste man
eigentlich mit "make menuconfig" auch abstellen können.
c-hater schrieb:> Wirklich frei ist man nur in Assembler.
Wirklich frei ist man nur, wenn man seine Opcodes mit einer
magnetisierten Nadel in die HDD stanzt. Die ganzen Tools sind nur böser
böser Ballast, die in Wahrheit im Wege stehen.
labormaus schrieb:> Vielleicht erstmal grundlegende Programmiersprachen (Python) angehen und> die Basics lernen.
Programmiersprachen sind für mich erstmal kein Problem, ich bin bereits
mit Java, C, Python, Pascal, VBscript und Batchdateien unter Windows /
Shellscripten unter Linux gut vertraut. Allerdingst möchte ich jetzt am
Betriebssystem selbst programmieren.
Codix schrieb:> Warum nimmst Du nicht erst einmal CP/M?> Ist ziemlich einfach auf einem AVR oder STM zu implementieren. Ist vor> allem übersichtlicher als Linux.> Wenn Du das am Laufen hast, dann hast Du schon Mal die Grundlagen für> komplexere Systeme.
Okay, werde ich mal versuchen. Wäre schon cool auf einem AVR das zu
haben und modifizieren zu können
c-hater schrieb:> Assembler.
Einen Helloworld-Kernel sowie einen, der die Tastatureingaben anzeigt
(als Text, nicht in ASCII-Zahlen) + passenden Bootloader habe ich schon
realisiert. Undzwar in
x86 ASSEMBLER
;)
labormaus schrieb:> Warum nicht erstmal mit einem Lehr-Betriebssystem einsteigen, wo alles> "Clean" dokumentiert ist?
Guter Tipp. Zumindest erstmal ein Buch zum Linux Kernel werde ich mir
kaufen. Ein OS mit leichter verständlichem Kernel werde ich in Betracht
ziehen.
Pascal schrieb:> Eine gut funktionierende Shell (bourne shell / bash) ist schon zu viel> verlangt. Auf jeden Fall soll das OS kein GUI haben, nur Text. Zufrieden> wäre ich schon mit einer simplen Hello World-Ausgabe
Welche Hardware soll unterstütz werden (USB, tty,tcp/ip,
Tastaturlayouts, Schreibrichtung) Welches Filesystem ?
Schau dir mal das ursprüngliche Minix an, alzu kleiner als 12k LOC#s
wird ein Minimalsystem nicht werden.
https://de.wikipedia.org/wiki/Minix_(Betriebssystem)
bitwurschtler schrieb:> Welche Hardware soll unterstütz werden
USB-Stick (egal welches Filesystem, wahrscheinlich FAT)
tty wäre auch ganz gut, aber keine Pflicht
Daniel A. schrieb:> Bei debian basierten systemen sind diese glaub ich in den> openssl und libssl-dev Packeten verfügbar.
openssl hat nicht geholfen, nach Installation von
sudo apt-get install libssl-dev
ging das kompilieren mit
make
!
Thx
Ich habe das jetzt mal abgebrochen. Es wurden nur ein paar Ordner
erstellt, der Linux Kernel entpackt, aber ansonsten in der ganzen Zeit
keine Dateien erstellt!!!!
All das Kompilieren kann eben schon ein paar Stunden dauern, da muss man
eben mal etwas geduldig sein. Man kann ja in der Zwischenzeit auch
andere Dinge machen. Eigentlich hätte ich wohl ein Makefile oder so
statt ein Shellscript schreiben sollen, dann hätte man den build vorgang
wieder fortsetzen können und müsste bei änderungen die letzten par
schritte nicht manuell eingeben.
PS: Falls du es irgendwann doch wieder laufen lässt, syslinux benötigt
beim kompilieren noch das uuid-dev packet.
Daniel A. schrieb:> PS: Falls du es irgendwann doch wieder laufen lässt, syslinux benötigt> beim kompilieren noch das uuid-dev packet.
Danke für den Tipp
Wie kann ich das Hello World durch ein anderes C Programm ersetzen?
Sorry für diese Anfängerfragen
Pascal schrieb:> Wie kann ich das Hello World durch ein anderes C Programm ersetzen?
Zunächst musst du es mit der selben libc & compiler kompilieren. In
diesem fall kann man den musl-gcc wrapper dafür verwenden:
Und die dabei verwendeten Befehle (im C Programm) bleiben wie bei gcc,
wenn ich ein Programm für das aktuell installierte Linux erstelle?
Also z.B. printf("text"); :
Wenn ich es richtig verstanden habe, dann ist
#include <stdio.h> dafür verantwortlich, dass es printf, wie eine
zusätzliche Funktion, gibt, da es die Standard-I/O-Ausgabe (im Terminal)
ermöglicht.
Der Linux-Kernel enthält ja dann stdio, also müsste das möglich sein
Ach ja:
Enthält das OS, das mit dem Shellscript gemacht wird irgendein Programm
außer dem Hello World?
Sonst könnte ich doch mit einer Shell statt dem Hello World es
ermöglichen, Programme zu installieren, und dann bspw. einen Desktop
(GUI) hinzufügen?
Pascal schrieb:> Und die dabei verwendeten Befehle (im C Programm) bleiben wie bei gcc,> wenn ich ein Programm für das aktuell installierte Linux erstelle?> Also z.B. printf("text"); :> Wenn ich es richtig verstanden habe, dann ist> #include <stdio.h> dafür verantwortlich, dass es printf, wie eine> zusätzliche Funktion, gibt, da es die Standard-I/O-Ausgabe (im Terminal)> ermöglicht.>> Der Linux-Kernel enthält ja dann stdio, also müsste das möglich sein
printf ist eine Funktion. Die stdio.h ist ein Header, der von der c
standard library (libc) bereitgestellt wird. Der header enthält nur die
Funktionsdeklaration, etwas in die richtung:
1
int printf(const char*, ...);
Die Libc implementiert die Funktion, bei musl ist diese nach dem
Kompilieren in der Library libc.so vorhanden:
653: 000000000004e637 161 FUNC GLOBAL DEFAULT 7 printf
3
1991: 000000000004e637 161 FUNC GLOBAL DEFAULT 7 printf
Die Libc nutzt die linux kernel syscalls, um diese Funktionen zu
Implementieren. Um text auf FD_STDOUT (standard output file descriptor)
auszugeben, schreibt man diesen in den Filedescriptor (fd) 1. fd 2 ist
FD_STDERR und fd 0 ist FD_STDIN. Um text in einen Filedescriptor zu
schreiben bietet der Linux Kernel den write-syscall. Das kann man mit
strace ganz schön sehen:
1
# ./bin/musl/bin/musl-gcc -static -x c - -o hello <<EOF
2
int printf(const char*, ...);
3
4
int main(){
5
printf("Hello World!\n");
6
}
7
EOF
8
9
# strace ./hello
10
execve("./hello", ["./hello"], [/* 47 vars */]) = 0
> Enthält das OS, das mit dem Shellscript gemacht wird irgendein Programm> außer dem Hello World?
Ja, in der initramfs ist noch ein init program, welches die module im
initramfs lädt, die CD sucht, die CD mountet, und dann die /sbin/init
auf der CD startet. Der quellcode des init Programs in der intramfs
Programms ist unter ./src/initramfs/init.c abgelegt. Der Quellcode des
Hello World init-Program ist unter ./src/init/init.c abgelegt. Die
dateien in der Initramfs sind im Verzeichnis ./initramfs/ abgelegt. Die
initramfs selbst ist unter ./rootfs/boot/initramfs.cpio.gz abgelegt. Sie
kann neu erstellt werden, indem man im Verzeichnis ./initramfs/
folgenden Befehl eingibt:
Wenn man die Module in der initramfs direkt als builtin in den Kernel
einbaut, und beim Starten des Kernels das root device direkt mitgibt
(hier wäre das beim bootloader in der ./rootfs/syslinux/syslinux.cfg),
könnte man die initramfs auch weglassen.
> Sonst könnte ich doch mit einer Shell statt dem Hello World es> ermöglichen, Programme zu installieren, und dann bspw. einen Desktop> (GUI) hinzufügen?
Eine Shell started nur andere Programme. Wenn man gcc und eine Shell
usw. für das Zielsystem neu kompiliert, kann man gcc von der Shell aus
benutzen um weitere Programme zu kompilieren. Das ist natürlich viel
aufwendiger als einen Package Manager zu nehmen. Der Package Manager und
die zur verfügung gestellte Software ist das Herzstück der moderner
linux distributionen, weil es ohne diese extrem aufwendig ist, alle
nötige Software zusammen zu suchen & zu kompilieren.
Meine "Hello World" distribution ist dafür auch nicht wirklich der
richtige Ausgangspunkt, diese ist nur um die grundlegenden Abläufe
aufzuzeigen. Für soetwas wäre dann doch LFS besser geeignet. Noch
einfacher wäre es natürlich, auf existierenden Linux Distributionen
aufzubauen, eine minimale mit debootstrap erstellte devuan/debian
basierte Linux installation ist auch nur ein paar MB gross, aber bietet
bereits alle Software bequem mit einem Packetmanager an.
Daniel A. schrieb:> cp mein_program ./rootfs/sbin/init
Ersetzt das nicht init durch mein_program (also nur den Inhalt)? D.h.
Init besteht hier nur aus Hello World?
Kann nicht sein (die init Datei ist viel größer)
Mit isomaster Init zu ersetzen bzw. an das Ende von init mein_program
heran zu kopieren gelingt nicht, die iso lässt sich nicht booten. Ich
habe die iso noch nicht selbst erstellt (dauert...)
Pascal schrieb:> Einen Helloworld-Kernel sowie einen, der die Tastatureingaben anzeigt> (als Text, nicht in ASCII-Zahlen) + passenden Bootloader habe ich schon> realisiert. Undzwar in>> x86 ASSEMBLER> ;)
Das glaube ich nicht. Du benutzt in diesen deinen Werken ganz sicher das
BIOS bzw. die legacy Emulation des UEFI. Und schon geloosed. Bevor du
auch nur dazu kommst, das 'H' deines "Hello World" aus dem Speicher zu
fischen, ist soviel Code abgelaufen (und ein sehr nennenswerter Anteil
davon ist heutzutage in C verfasst), dass du die Kontrolle bereits
vollkommen verloren hast.
Nur dann, wenn du ein wirklich sehr guter x86-Asm-er bist, könntest du
rausfinden, ob du die Kontrolle noch hast oder nicht.
Folgendes gerade gesehen:
da ich auch Mikrocontroller programmiere, und zufälligerweise ein Si4703
Radiomodul mit i2c-Steuerung habe, hat das meine Aufmerksamkeit geweckt
(siehe Bild).
Da steht, dass Linux einen Treiber für dieses Radiomodul enthält. Wie
kann ich den nutzen? Mein Desktop-PC hat soweit ich weiß keinen
i2c-Bus-Anschluss, ich kenne an meinem PC nur massig USB und intern ist
ein nicht mit Pinout, dafür aber als UART gekennzeichneter serieller
Port, das Gehäuse besitzt aber keinen.
Gibt es sowas wie USB<-->i2c-Wandler?! Oder kann man sowas selbst bauen?
Wäre cool ein FM Radio in einen Desktop PC einzubauen und über Software
zu automatisieren/steuern...
S. R. schrieb:> Ich würde dir mal zwei Dinge empfehlen:> - die Tutorialserie unter> http://www.lowlevel.eu/wiki/OS-Dev_f%C3%BCr_Einsteiger> - Linux from Scratch (oder etwas in der Art)>> Probiere einfach mal beides aus und entscheide, was dir besser gefällt.
Ich wiederhole mich nochmal und schleiche mich dann leise von dannen.
Pascal schrieb:> Daniel A. schrieb:>> cp mein_program ./rootfs/sbin/init>> Ersetzt das nicht init durch mein_program (also nur den Inhalt)? D.h.> Init besteht hier nur aus Hello World?> Kann nicht sein (die init Datei ist viel größer)
Doch, die Datei gibt nur Hello World aus und wartet ein wenig.
Pascal schrieb:> Mit isomaster Init zu ersetzen bzw. an das Ende von init mein_program> heran zu kopieren gelingt nicht, die iso lässt sich nicht booten.
Das kann viele Ursachen haben. Nur mal eine Vermutung, hast du beim
Kompilieren den musl-gcc wrapper verwendet, oder gcc direkt? Und hast du
es statisch (mit -static) gelinkt, oder nicht? Wenn es nicht statisch
gelinkt ist, muss man die benötigten Libraries, wie z.B. die libc.so
oder ld.so noch in die ISO kopieren. Man kann mit ldd nachsehen, welche
das sind. Aber das habe ich ja schon hier schon erwähnt:
Beitrag "Re: Betriebssystem auf Grundlage des Linux-Kernels selbst schreiben"
Daniel A. schrieb:> Doch, die Datei gibt nur Hello World aus und wartet ein wenig
Dann liegt der viele Code wohl an diesem Warte-Befehl...
Welchen verwendest du dafür?
Daniel A. schrieb:> Nur mal eine Vermutung, hast du beim> Kompilieren den musl-gcc wrapper verwendet, oder gcc direkt?
musl-gcc
Daniel A. schrieb:> statisch (mit -static) gelinkt, oder nicht?
statisch gelinkt
Zur Sicherheit mache ich es nochmal
Meine Vermutung isomaster betreffend:
Die iso besteht ja nicht nur aus Dateisystem, sondern auch MBR, anderer
Quellcode,...
vielleicht wurde nur das Dateisystem wieder zurückgepackt in die neue
iso?
Naja, Download jedenfalls fertig. Kompilieren erfolgreich, iso selbst
erstellt (dank deines Skriptes).
Ich versuche mal das was du mir weiter oben beschrieben hast und mache
die iso mit dem Befehl neu. Vielleicht funktioniert das ja so...
Frage geklärt. Ich habe die init.c in ./src/init gefunden.
Ich ändere den Text (nicht im Original, im höher gelegenen Ordner), und
dann ersetze ich die init durch eine mit musl-gcc statisch gelinkt
kompilierte andere init. Dann der iso befehl und das auf den USB Stick
zum Testen. ;)
Seltsam.. Deine Distro hat 36,7MB (iso), damit meine ich
Daniel A. schrieb:> Oh, und hier noch die ISO: https://www.dpa.li/hello_world_distro.iso
, meine hat allerdings nur 21,0MB..
Hattest du da noch nicht das sh script genutzt?
Ich sehe mal nach, ob die überhaupt geht, jedenfalls ist die noch nicht
modifiziert...
S. R. schrieb:> Ich wiederhole mich nochmal und schleiche mich dann leise von dannen.
Von Lowlevel bin ich bereits den Hello World Bootloader und Kernel in
Assembler durchgegangen. Echt cool! in osdev gibt es ja auch den
Unterpunkt GUI, werde ich mir mal irgendwann viel später vornehmen. Mit
Linux zu arbeiten scheint mir allerdings zunächst sinnvoller.
Aber Linux from Scratch verstehe ich irgendwie nicht
Es gibt da ja ein Buch das so heißt. In pdf kostenlos. Habe ich.
Aber wie soll man bitte in Scratch irgendwie Sourcecode verbinden? Da
gibt es doch nur Bilder die man mit den vorgegebenen Befehlen hin und
her bewegbar macht... Wäre nett würde mich jmd. aufklären bevor ich
meine Zeit mit seeeeehr viel lesen nicht verschwende, aber anders
nutze.. Ich habe übermorgen eine 5h Physik-LK Klausur vor mir über
Quantenphysik. nicht dass das ein Problem wäre - 1 garantiert, wenn ich
nicht meine Zeit in anderes investiere
Noch etwas wichtigeres: quemu installiert, allerdings kommt im Terminal
unter dem Befehl qemu ......... immer, dass quemu nicht gefunden wird
es ist aber installiert!
Pascal schrieb:> Seltsam.. Deine Distro hat 36,7MB (iso), damit meine ich>> Daniel A. schrieb:>> Oh, und hier noch die ISO: https://www.dpa.li/hello_world_distro.iso>> , meine hat allerdings nur 21,0MB..
Die kernel config wird mit "make olddefconfig" erstellt. Dabei wird die
Config des hostsystems übernommen. Einige der Module, die bei mir in der
Initramfs sind, sind bei dir scheinbar builtin. Ausserdem scheint dein
Kernel weniger Module zu enthalten als meiner, deshalb ist er kleiner.
Die meisten meiner systeme haben einen custom kernel, in dem die viele
Module builtin sind. In der config für den kernel für die ISO waren
diese bei mir deshalb auch builtin, weil die Config ja übernommen wurde.
Pascal schrieb:> Noch etwas wichtigeres: quemu installiert, allerdings kommt im Terminal> unter dem Befehl qemu ......... immer, dass quemu nicht gefunden wird> es ist aber installiert!
Der Befehl wäre "qemu-system-x86_64". Ich empfehle es mit
"qemu-system-x86_64 -m 2G --drive
media=cdrom,file=hello_world_distro.iso,readonly" zu starten.
Pascal schrieb:> Von Lowlevel bin ich bereits den Hello World Bootloader und> Kernel in Assembler durchgegangen.
Und das Tutorial ist genau dafür gedacht, die Basis für einen real
sinnvollen Kernel zu legen. Egal.
Pascal schrieb:> Aber wie soll man bitte in Scratch irgendwie Sourcecode verbinden? Da> gibt es doch nur Bilder die man mit den vorgegebenen Befehlen hin und> her bewegbar macht...
Ich rede von "Linux From Scratch", das ist diese PDF:
http://www.linuxfromscratch.org/lfs/downloads/stable/LFS-BOOK-8.1.pdf
Das ist eine Anleitung, wie man sich aus den Quelltexten verschiedener
Pakete eine eigene Linux-Distribution zusammenbaut. Wenn du das einmal
gemacht hast, solltest du eine ungefähre Vorstellung davon haben, woraus
so ein "Linux" bestehen kann und wozu man das alles braucht.
Spiel das einmal durch und lerne die Grundlagen. Dann kannst du
anfangen, jedes dieser Teile durch deine eigene Programmierkunst zu
ersetzen, wenn du möchtest.
Du versuchst, ein Betriebssystem zu entwickeln, ohne zu verstehen, wie
ein Betriebssystem funktioniert.
Fig. [making something] by starting from the beginning with the basic ingredients. (*Typically: bake something ~; do something ~; make something ~; Start (something) ~.) We made the cake from scratch, using no prepared ingredients. I didn't have a ladder, so I made one from scratch.
Du hättest ja auch einfach mal kurz reinlesen können, und schauen, was
sich dahinter verbirgt, dann hättest du gleich gesehen, dass das nichts
mit irgendeiner Programmiersprache zu tun hat...
Wenn man "linux scratch" googelt, kommt sogar als erstes der Wikipedia
Artikel der besagt:
1
Linux From Scratch (LFS, „Linux von Grund auf“) ist ein Projekt, das eine Schritt-für-Schritt-Anleitung zur Erstellung eines auf die persönlichen Wünsche angepassten Linux-Betriebssystems von Grund auf aus den Quelltexten anbietet.
Ich habe es soeben geschafft, die minimale init einzubauen!
Daniel A. schrieb:> Minimale Beispiel init:> https://gist.github.com/rofl0r/6168719
Funktioniert prima mit rc (das ehemalige Hello-World-init umbenannt) in
./rootfs/etc/rc
Also bisher startet die init, der allererste Prozess, und der startet
(wie im Sourcecode auf github) rc in etc. Eine Shell besteht ja nicht
nur aus c code sondern macht doch eigentlich nur einen call zu den
einzelnen Binärprogrammen, oder? Vergleichbar mit Android (da habe ich
bisher immmer am OS als superuser rumgespielt, denn man kann ja mit
termux c programme wie nano, vim, make, gcc (clang),... installieren)..
Ich erwarte um die Uhrzeit zwar keine Antworten, probiere aber folgendes
aus:
Die Einzelprogramme mit musl-gcc kompilieren, in den richtigen Ordner
(sbin?) einfügen und ein C Script, das diese ausführt,
schreiben/herunterladen.
Ist das so richtig? Wie installiere ich eine Shell?
2B^!2B schrieb:> Wenn man "linux scratch" googelt, kommt sogar als erstes der Wikipedia> Artikel der besagt:> Linux From Scratch (LFS, „Linux von Grund auf“) ist ein Projekt, das> eine Schritt-für-Schritt-Anleitung zur Erstellung eines auf die> persönlichen Wünsche angepassten Linux-Betriebssystems von Grund auf aus> den Quelltexten anbietet.
Thx. Schade dass ich nichtmal das selbst hingekriegt habe
Die Übersetzungen bei Wikipedia haben wohl doch einen nutzbaren und
sinnvollen Zweck
Ich werde mit Linux from Scratch von Anfang an beginnen. Danke für den
Tipp. Und später ein Buch über den Linux Kernel lesen.
Welche sind am empfehlenswertesten?
labormaus schrieb:> Warum nicht erstmal mit einem Lehr-Betriebssystem einsteigen, wo alles> "Clean" dokumentiert ist?>> Beispielhaft MicroC/OS-II (auch bekannt als "Bildschirmsockel") samt> Buch.> Ist ein prima Einstieg.>> Oder "Moderne Betriebssysteme" vom Tanenbaun, aber am besten auf> Englisch. Die deutsche Übersetzung ist rottig.
Pascal schrieb:> Und später ein Buch über den Linux Kernel lesen.> Welche sind am empfehlenswertesten?
Wie waer's mit was ganz Bizarrem: Die Dokumentation in den Kernelsourcen
selbst? Die kann man tatsaechlich auch lesen. Da gibts direkt ein
Unterverzeichnis Documentation - und man sollt's nicht glauben - da
stehen Dateien drinnen. Mit Texten. Ueber Themen. Und man muss es
garnicht extra kaufen, denn wenn man sofort anruft und gleich bestellt,
gibt's dieses Verzeichnis zu jedem Kernel-Tarball voellig umsonst und
gratis mit dazu. Fast wie der Julienneschneidevorsatz beim Gemuesehobel.
Nur noch besser...
SCNR,
WK
Pascal schrieb:> Ist das so richtig? Wie installiere ich eine Shell?
Das ist eines der frühen Kapitel im Buch "Linux From Scratch".
Dort ist es die bash.
Ich würde dir übrigens die Version mit systemd empfehlen.
Müsste Version 8.1-systemd sein.
Die erspart dir ein paar Schritte und ist zukunftssicherer.