Forum: Projekte & Code POSIX Multitasking Betriebssystem für ARM7 Prozessoren


von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hier möchte ich mal ein kleines Projekt vorstellen, das seit längerem 
bei mir in der "Schublade" liegt. Habe vor ca. 2 Jahren damit angefangen 
und es vor ca. 1 Jahr pausiert (mangels Zeit oder so). Werde vermutlich 
demnächst daran weiterarbeiten.

Es handelt sich um ein (mangels Features noch nicht wirklich sinnvoll 
benutzbares) Multitasking Betriebssystem für ARM7 Prozessoren (ohne MMU) 
mit POSIX-API (jedoch natürlich nicht vollständig).

Es hat doch recht viele Features deswegen, so denke ich, ist es für den 
Ein oder Anderen sicher einen Blick wert.

An Prozessoren unterstützt es den LPC2478, entwickelt habe ich es unter 
dem in http://gsg-elektronik.de/?id=64 vorgestelltem Board, auf dem es 
unverändert läuft.
Ich habe stets großen Wert darauf gelegt, dass es sich ohne viel Aufwand 
auf andere Systeme der ARM7 Architektur portieren lässt (dabei kann ich 
auch gerne behilflich sein).

Es besteht aus einem Kernel, der im Flash der CPU sitzt, oder zumindest 
direkt vom Bootloader ausgeführt wird, und Userspace-Programmen, die auf 
einer ext2-formatierten SD Karte sind (als ELF) und vom Kernel 
ausgeführt werden.

An Userspace-Programmen sind bisher nur /bin/sh (eine sehr rudimentäre 
Shell, damit der Benutzer (z.B. über die UART) sagen kann, was er will), 
/bin/top (ein Programm um Prozesslisten und weitere Informationen vom 
Scheduler abzurufen), und /sbin/init (das wie in POSIX definiert einige 
Userspace-seitige Initialisierungen übernimmt und eine Shell ausführt).

Die libc implementiert nicht wenige Funktionen für Userspace Programme, 
die ich nun aufliste. Nicht in POSIX spezifizierte sind in Klammern.
fcntl: open
poll: poll
sched: sched_yield, (sched_info, sched_list)
signal: kill, sigaction, raise, signal
stdio: fclose, fopen, fread, fwrite, putchar, fputs, puts, perror, 
printf, sprintf, fprintf, vfprintf, vsprintf
stdlib: atexit, exit, _Exit, malloc, calloc, free, realloc, (alloca), 
abort, qsort, strtol, atoi
string: memcpy, memmove, memset, strchr, strcmp, strcpy, strdup, strlen, 
strncmp, strerror
unistd: _exit, fork, execve, close, read, write, getpid, getppid, setsid
sys/mman: mmap, munmap
sys/wait: waitpid, wait
(teils jedoch eher unvollständige Implementationen, nicht selten 
aufgrund Limitierungen des Kernels)

Eher eine Vielfalt an interessanten Features bietet dagegen der Kernel:
- Bei Absturz eines Programms Anzeige der GPRs, eines Function Call 
Stacktrace, bei Userspace-Programmen inklusive Symbolnamen
- Triviale Sicherheitsfeatures wie z.B. Überprüfen von 
Userspace-Pointern bei Syscalls, Nullen frischer Userspace Pages, ...
- Support des Hardware Watchdog Timer um System automatisch neu zu 
booten falls es abstürzt
- MMC/SD-Treiber (jedoch Software-MCI, über GPIOs direkt oder SPI)
- UART (als Konsole)
- Im Kernel einkompiliertes Dateisystem (damals zum Testen entwickelt, 
bevor Unterstützung für SD-Karten vorhanden war)
- IBM PC Partitionstabelle im MBR
- Dateisysteme ext2 und minix
- VFS unterstützt "Baum" an Mounts (so wie z.B. bei Linux), z.B. kann 
/mnt auf anderes Dateisystem verweißen als das Komplement von /mnt im 
root-Verzeichnis
- Effiziente APIs im Kernel zum einfachen Hinzufügen neuer 
Dateisystemtreiber, Gerätetreiber, etc.
- ELF Unterstützung inkl. Symboltable, Anpassung der GOT (Zwangsweise, 
da das Multitasking-Prinzip sonst nicht umsetzbar wäre)
- Falls vorhanden, können LEDs genutzt werden, um CPU-Auslastung (und 
weiteres) anzuzeigen
- Speicherverwaltung die mehrere Speicherareale nutzen kann (um sowohl 
internen als auch externen Speicher zu nutzen)
- Scheduler, der einiges an Statistik sammelt (Ausführungszeiten, somit 
CPU-Auslastung; Load Averages); einen Algorithmus für kurze 
Interrupt-Response-Zeiten hat; POSIX-poll() Funktionen für effizientes 
Warten; Unterstützung für Signale
- Session/Terminal-Unterstützung (jedoch eher rudimentär)

Das Multitasking ist wegen der fehlenden MMU nicht effizient exakt nach 
POSIX implementierbar, jedoch hinreichend für eigentlich alle 
Anwendungen.
fork() legt, natürlich, keinen neuen Address-Space an (geht ja nicht). 
Der alte Address-Space wird also beibehalten, solange bis mit execve() 
ein neues Programm für diesen Prozess ausgeführt wird. fork() legt also 
eher eine Art Thread an, als einen Prozess (Eigentlich etwas zwischen 
Thread und Prozess, da z.B. Filedescriptors geklont werden). Das ist das 
genutzte Prinzip des Multitaskings.

Es fehlt sämtliches an Dokumentation, schwer zu "bedienen" dürfte es 
dennoch nicht sein. In misc/ befindet sich ein Skript um eine 
ARM-Toolchain zu erstellen. Das ist eigentlich alles was man braucht um 
es zu kompilieren.
Zum Kompilieren des Kernels muss man zumindest die sys/conf anpassen, 
dann "make buildkernel" ausführen.
Die libc sowie die Userspace-Programme sind mit "make buildworld" zu 
kompilieren. "make installworld" kopiert sie in ein Verzeichnis, dessen 
Inhalt man direkt in das root-Dateisystem für das Betriebssystem 
kopieren kann (also auf die SD-Karte).

Vielleicht bringt es ja was. Für Fragen und Ähnliches bin ich gerne da.

Gruß,
Euer Alex

von Kurti (Gast)


Lesenswert?

Für wen oder was hast du das geschrieben?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.