Programm für PrettyOS schreiben - Einsprungpunkt? makefile? .ld?
-
Hallo,
ich hab mal versucht, ein Programm für PrettyOS zu kompilieren und auszuführen. Ich bekomme einen PageFault. Ich habe den selben Code wie für die Hello.elf benutzt.
Ich vermute, das irgendwas mit dem Einsprungpunkt falsch ist.
Mein ld-file (vermutlich falsch, ich weiß nur nicht was):ENTRY(_start) OUTPUT_FORMAT(elf32-i386) OUTPUT_ARCH(i386) SECTIONS { . = 0x1400000; .text : { __code_start = .; *(.text*) } .data : { __data_start = .; *(.data) } .rodata : { __rodata_start = .; *(.rodata) } .bss : { __bss_start = .; *(.bss) *(COMMON) } __end = .; }
mein makefile (vermutlich richtig)
main: test.c userlib.c userlib.h i586-elf-gcc -c userlib.c -std=c99 -march=i386 -mtune=i386 -m32 -fno-pic -Werror -Wall -O -ffreestanding -fleading-underscore -nostdlib -nostdinc -fno-builtin -fno-stack-protector -Iinclude i586-elf-gcc -c test.c -std=c99 -march=i386 -mtune=i386 -m32 -fno-pic -Werror -Wall -O -ffreestanding -fleading-underscore -nostdlib -nostdinc -fno-builtin -fno-stack-protector -Iinclude i586-elf-ld *.o -T user.ld -Map user.map -nostdinc -o test.elf
Ich hätte es ja gerne so gemacht, wie für die Hello.elf, leider hab ich nirgends die entsprechenden Dateien gefunden...
Was mache ich falsch?
mfg
Mr. X
-
Oh sorry, ich habe der Einfachheit einfach program.c gegen hello.c ausgetauscht un dan dessen Stelle kompiliert. Daher gelten die gleichen Bedingungen wie für program.c:
Das Assembler-Programm start.asm muss mitgelinkt werden:
; start.asm [BITS 32] extern __bss_start extern __end extern _main global _start _start: mov esp, 0x600000 ; stackpointer call _main jmp $
Das Linker-Skript user.ld:
ENTRY(_start) OUTPUT_FORMAT(elf32-i386) OUTPUT_ARCH(i386) SECTIONS { . = 0x1400000; .text : { __code_start = .; *(.text*) } .data : { __data_start = .; *(.data) } .rodata : { __rodata_start = .; *(.rodata) } .bss : { __bss_start = .; *(.bss) *(COMMON) } __end = .; }
Im makefile findet sich:
... $(wildcard $(USERDIR)/*) rm -f *.o $(NASM) -O32 -f elf $(USERDIR)/start.asm -I$(USERDIR)/ -o start.o $(CC) $(USERDIR)/*.c -c -I$(USERDIR) -m32 -fno-pic -Werror -Wall -O -ffreestanding -fleading-underscore -nostdlib -nostdinc -fno-builtin $(NASM) -O32 -f elf $(USERDIR)/start.asm -o start.o $(LD) *.o -T $(USERDIR)/user.ld -Map $(USERDIR)/kernel.map -nostdinc -o $(USERDIR)/program.elf rm -f *.o
Am besten nennen wir das Verzeichnis zum Testen von neuen Programmen USERTESTDIR anstelle USERDIR.
Also einfach start.o für den korrekten Einsprung dazu linken.
-
Danke, es funktioniert.
Übrigens, ich habe einen Bug gefunden:
Die Ausgabe eines Programms, z.B. Hello.elf hat folgenden Fehler:
Das erste Zeichen ist nach unten verrutscht, sodass dort steht:ello, Pretty... This piece of... $> H
Zudem ist das laden eines Programms von der Floppy sehr langsam und PrettyOS sucht sehr lange, falsch man einen falschen Namen angegeben hat. Zudem sucht er, selbst wenn nichts eingegeben wurde.
Verwendetes System: Virtual Box. PrettyOS Revision 80
mfg
Mr. X
-
Danke für die Hinweise! Das Laden von Floppy ist bisher leider alles andere als perfekt, aber es läuft. An der Optimierung wird gerade gearbeitet.
EDIT: Ab Revision 81 wird die Leereingabe abgefangen. Der delay von 50 Millisekunden bei Lese-/Schreibvorgängen wurde entfernt.
Kannst Du bitte deine Konfiguration im Unterverzeichnis bei hello.c (o.ä.) und dein funktionierendes makefile für andere hier bitte posten?
-
Das makefile ist nicht repräsentativ. Es ist nicht so kryptisch, wie Euers
Ich hab einfach ein einfaches makefile in einem neuen Verzeichnis angelegt und make.exe und nasmw.exe dahin kopiert.
-
Zeigst Du uns dein Programm?
Vor allem: wie ist es gelaufen? Hat es geklappt?
-
Das makefile ist nicht repräsentativ. Es ist nicht so kryptisch, wie Euers Ich hab einfach ein einfaches makefile in einem neuen Verzeichnis angelegt und make.exe und nasmw.exe dahin kopiert.
Gerade deshalb ist es für Einsteiger sicher interessant.
-
Übrigens, ich habe einen Bug gefunden:
Die Ausgabe eines Programms, z.B. Hello.elf hat folgenden Fehler:
Das erste Zeichen ist nach unten verrutscht, sodass dort steht:
Code:
ello, Pretty...
This piece of...$>
HUrsache aufgespürt:
Nach Reduktion der Systemfrequenz (in timer.c) von 1000 Hz (versuchsweise wie bei Linux) auf 100 Hz läuft die Bildschirmausgabe wieder geordnet. Dies zeigt, dass man die Taskwechsel-Freqenz - ohne Lock der kritischen Abschnitte zwischen den Tasks/Threads - nicht beliebig hoch drehen sollte. Momentan ist das Scheduling noch fest an diese Frequenz gekoppelt.
-
PrettyOS funktioniert bei mir seit Revision 82 oder 81 nicht mehr. Es stürzt nach 1 sek. ab. Der Zug bleibt stehen, die Laufzeitangabe auch. Es nimmt keine Tastatureingaben an. (Eingabezeile ist aber schon da)
Änderungen an der konfiguration der Virtuellen Maschine haben keine Verbesserungen gebracht.Nun aber zum eigentlichen Thema:
Ordner für mein Programm:userlib.h //Der Einfachkeit wegen einfach kopiert userlib.c //Der Einfachkeit wegen einfach kopiert kernel.map //Der Einfachkeit wegen einfach kopiert user.ld //Wie von Erhard Henkes, s.o. start.asm //Wie von Erhard Henkes, s.o. test.c nasmw.exe //Der Einfachkeit wegen einfach kopiert mingw32-make.exe //Der Einfachkeit wegen einfach kopiert makefile build.bat
test.c:
#include "userlib.h" int main() { puts("TEST"); return 0; }
makefile:
main: test.c userlib.c userlib.h nasmw -O32 -f elf start.asm -o start.o i586-elf-gcc -c userlib.c -std=c99 -march=i386 -mtune=i386 -m32 -fno-pic -Werror -Wall -O -ffreestanding -fleading-underscore -nostdlib -nostdinc -fno-builtin -fno-stack-protector -Iinclude i586-elf-gcc -c test.c -std=c99 -march=i386 -mtune=i386 -m32 -fno-pic -Werror -Wall -O -ffreestanding -fleading-underscore -nostdlib -nostdinc -fno-builtin -fno-stack-protector -Iinclude i586-elf-ld *.o -T user.ld -Map user.map -nostdinc -o test.elf
build.bat:
mingw32-make main pause
Nach dem ausführen von build.bat noch die elf-Datei in das Floppy-Image einfügen.
Dann sollte es funktionieren und TEST auf den Bildschírm schreiben.
-
Danke!
-
Analog zu den Funktionen putch und puts sollte es auch getch (schon vorhanden) und gets geben in der userlib
-
PrettyOS funktioniert bei mir seit Revision 82 oder 81 nicht mehr. Es stürzt nach 1 sek. ab. Der Zug bleibt stehen, die Laufzeitangabe auch. Es nimmt keine Tastatureingaben an. (Eingabezeile ist aber schon da)
Änderungen an der konfiguration der Virtuellen Maschine haben keine Verbesserungen gebracht.Danke für den Hinweis!
Bitte teste das auch mit Sun Virtual Box auf das Image. Bei mir läuft das.
qemu verwende ich unter Windows (Version von jidder, low level).Bei Cuervo (unser Cheftester) gibt es seit 81/82 auch Probleme.
Was habe ich geändert?
80 --> 81: diese mehrfachen 50ms-Delays weg, dadurch qemu mit Image sehr schnell (gut für Tests)
81 --> 82: 1000 Hz ---> 100 HzRev. 82 läuft sowohl bei Cuervo als auch bei mir auf realer Hardware.
-
Bitte HELLO.ELF (groß geschrieben) erzeugen wegen:
tools/CreateFloppyImage2 PrettyOS FloppyImage.bin $(STAGE1DIR)/boot.bin $(STAGE2DIR)/BOOT2.BIN $(KERNELDIR)/KERNEL.BIN $(USERTEST)/HELLO.ELF
im makefile
(kann bei Linux Probleme geben, bei MS Windows lief es bisher)
-
Ändert man die Datei "hello.c" in Windows, lässt sich das Projekt auch nicht mehr kompilieren... scheinbar wird die HELLO.ELF gar nicht erst erstellt. Finde auch nichts dahingehend in der makefile.
-
Ich erzeug das Image sowieso manuell, daher war mir das nicht aufgefallen...
-
hallo, rev. 84 liefert die erstellungswerkzeuge (build, makefile, tools, ...) in einem eigenen Unterordner mit. HELLO.ELF muss groß geschrieben werden, damit es in das FloppyImage eingebaut wird.
-
Ich habe nu eine Funktion
char* gets(char* s)
in userlib.h/c eingefügt, aber es klappt leider noch nicht richtig im User-Programm.char* gets(char* s) ///TODO: leads to no success { int i=0; char c; do { c = getch(); putch(c); if(c==8) // Backspace { if(i>0) { s[i]='\0'; } } s[i] = c; i++; } while(c!=10); // Linefeed s[i]='\0'; return s; }
Separat getestet ist alles ok damit.
In der Multitasking-Umgebung von PrettyOS geraten allerdings die Tasks und die Zeichen durcheinander.
-
Hallo!
Habe mir einfach mal ein Programm gebastelt, was einfach nur den Screen löscht. Das compilieren und testen funktioniert wunderbar, bis... naja, bis ich's übertrieben habe... Ich habe dabei das Programm mehrmals hintereinander aufgerufen. Irgendwann (was die Anzahl betrifft nicht reproduzierbar) kam dann ein General Protection Fault...
Hat jemand eine Idee woran das liegen könnte?
#include "userlib.h" int main() { unsigned long* vidmem = (unsigned long*) 0xb8000; unsigned long i=0; while(i<(40*25)) { vidmem[i] = 0x07200720; // white on black, Space (0x20) ++i; }; return 0; }
-
Das ist echt ein interessanter Punkt. So sieht bei mir momentan start.asm aus, das den Start und das Ende von main() der User-Test-Funktion im Verzecihnis user_test_c "umhüllt":
; start.asm [BITS 32] extern __bss_start extern __end extern _main extern _exit extern _test global _start _start: mov esp, 0x600000 ; stackpointer call _main call _test call _exit call _test
... und nach mehrfachem Ausführen gelingt es odch tatsächlich, auch das zweite test() auszuführen. Dann kommt es logischerweise zum Absturz, so wie das Programm aufgebaut ist ohne jmp $ oder hlt!
Mal braucht es nur drei "hello", mal ca. 10:
screenshot: http://www.henkessoft.de/OS_Dev/Bilder/Rev87_mit_gets.PNGWeiß jemand, wie das passieren kann? Hat ja wohl mit dem Multitasking zu schaffen?
-
Nun sieht start.asm so aus:
; start.asm [BITS 32] extern __bss_start extern __end extern _main extern _exit extern _test global _start _start: mov esp, 0x500000 ; stackpointer call _main call _exit call _test jmp $
Man beachte den gegenüber der Shell (dort 0x600000) veränderten Stack-Pointer!