Ich habe die Baking Pi-Tutorials bereits gefunden , aber sie verwenden nur Assemblersprache . Ich habe die ersten Lektionen verfolgt, aber ich frage mich bereits, wie ich stattdessen C verwenden soll. Ich meine, es gibt einen Grund, warum sie höhere Sprachen erfunden haben. Ich habe versucht, einfach den C-Code in eine object ( .o
) -Datei zu kompilieren
.section .init
.globl _start
_start:
bl main
loop$:
b loop$
zu einer anderen Objektdatei und verknüpfen sie miteinander und so erhalten kernel.img
. Ich habe dann den bereits vorhandenen Kernel durch meinen eigenen ersetzt, aber er führt den C-Code nicht aus. Der C-Code, den ich geschrieben habe, sollte nur die OK-LED einschalten und dann zurückkehren (dann kommt er loop$: b loop$
). Aber die OK-LED blinkt ein paar Mal zufällig und bleibt dann einfach aus. Hier ist mein C-Code:
int main(int argc, char ** argv) {
volatile unsigned *gpioAddr = (volatile unsigned *)0x20200000;
*(gpioAddr + 4) = 1 << 18;
*(gpioAddr + 40) = 1 << 16;
return 0;
}
Wie verwende ich C für die Betriebssystementwicklung auf einem Raspberry Pi?
Ich bezweifle, dass es sich um einen Fehler im Code handelt (obwohl ich nur ein Bastler bin). Ich bin mir bewusst, dass das Einrichten von C kompliziert sein kann, aber ich bin nicht der erste, der dies tut. AFAIK, alle derzeit vorherrschenden Betriebssysteme sind hauptsächlich in C geschrieben, daher muss es einen Artikel geben, der den Prozess erklärt. Ich würde mich auch über eine Liste von Schritten sehr freuen, damit ich diese Schritte googeln und vielleicht eine etwas weniger umfassende Frage stellen kann.
Hinweis: Die ARM-Assembly, die dem obigen C-Code entspricht, funktioniert einwandfrei. Es schaltet die LED ein (nach einigem Blinken). Ich denke (hoffe), dass mein Raspberry Pi in Ordnung ist.
quelle
Antworten:
Ich habe vor Jahren einen sehr einfachen Kernel geschrieben und ihn auf einer 386 ausgeführt. Ich habe seit Jahren keine Bare-Metal-Programmierung mehr durchgeführt, aber im Großen und Ganzen müssen Sie einen Assembler-Code schreiben, der Folgendes bewirkt:
Das Einrichten des Stapels ist einfach - finden Sie einen Speicher, der nicht verwendet wird, und laden Sie die Adresse, in die jemals ein Register als Stapelzeiger verwendet wird.
In Ihrem C-Code müssen Sie OS-Datenstrukturen wie Speicherpools und Thread-Tabellen initialisieren. Sie können keine C-Bibliotheksfunktionen verwenden - Sie müssen das Zeug selbst schreiben.
Wenn Sie ein einfaches Multitasking-Betriebssystem schreiben möchten, müssen Sie einige Assembler-Routinen schreiben, um CPU-Register im Stapel zu speichern und einen anderen Satz von Registerwerten aus dem Stapel eines anderen Threads zu laden. Und Sie müssen eine API schreiben, um verschiedene Threads zu erstellen.
quelle
Ich habe mir Ihren Code nicht genau angesehen, aber Sie scheinen auf dem richtigen Weg zu sein. Stelle sicher das:
_start
Symbol wird in der Tat beim Kompilieren und Verknüpfen Ihrer Assembly-Datei und Ihrer C-Datei verwendet (undmain()
wird stattdessen nicht verwendet).main()
, müssen Sie die C-Aufrufkonvention verwenden:return
Anweisung in C verwendet wird)int main() { ... }
objdump -S main.o
) und sehen Sie sich an, wie sie den Stapel manipuliert.loop$
.Das OSDev-Wiki wird eine sehr nützliche Ressource sein - es befasst sich hauptsächlich mit der x86-Entwicklung, aber die meisten Informationen gelten immer noch für das Himbeer-Pi.
Einige weitere Himbeer-Pi-Osdev-spezifische Ressourcen:
kernel.img
loslegen.kernel.img
ausgeführt wird.quelle
Das Hauptproblem, auf das Sie stoßen könnten, sind die C-Bibliotheken und der Prologcode. Es wird gestartet, bevor Ihr eigener Code ausgeführt wird, und richtet den Stack, den Heap und viele andere hilfreiche Dinge ein. Wenn Sie jedoch versuchen, für Bare Metal zu programmieren, haben Sie kein Betriebssystem unter sich, und Sie sollten es vermeiden, diese Funktionen aufzurufen. Dazu benötigen Sie modifizierte Versionen von C-Bibliotheken und / oder einige globale Symbole, die Sie definieren oder durch Ihre eigenen ersetzen. Dieser Prozess ist ein bisschen kompliziert, deshalb haben sich die Leute von 'Baking Pi' dafür entschieden, Assembly für ihre Tutorials zu verwenden.
quelle
Versuchen Sie dies stattdessen:
http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/
Auch die x86-Erfahrung ist etwas anders. Dies kann auf die allgemeine Bare-Metal-OS-Programmierung von ARM zutreffen. Aber für Pi, tut mir leid, es ist die GPU, die zuerst startet und ziemlich viel vor dem OS (?) Code eingerichtet wird.
quelle
s-matyukevich/raspberry-pi-os
https://github.com/s-matyukevich/raspberry-pi-os
Dieses fantastische Repo erledigt sowohl das C-Bootstraping als auch ziemlich komplexe Themen.
Außerdem wird untersucht, wie der Linux-Kernel vorgeht, und der Linux-Kernel-Code wird mit Anmerkungen versehen.
Schauen Sie sich das erste Tutorial für ein minimalistisches Setup an: https://github.com/s-matyukevich/raspberry-pi-os/tree/43f682d406c8fc08736ca3edd08a1c8e477c72b0/src/lesson01/src
Ich empfehle es sehr.
quelle