Eigenes OS?
-
Vielleicht stehe ich heute auf der Leitung. Ich benötige für kernel.asm das aout-Format (verkraftet beim Linken 16/32 bit gemischt) wegen des Linkers! Also ganz sachlich:
So klappt es bestens:
nasmw -O32 -f bin boot.asm -o boot.bin nasmw -O32 -f aout kernel.asm -o kernel.o nasmw -O32 -f aout isr.asm -o isr.o nasmw -O32 -f aout process.asm -o process.o nasmw -O32 -f aout flush.asm -o flush.o gcc -Wall -O -c ckernel.c -o ckernel.o ... gcc -Wall -O -c syscall.c -o syscall.o ld -T kernel.ld kernel.o ... syscall.o -o ckernel.bin -Map kernel.map cmd /c copy /b boot.bin + ckernel.bin MyOS
Nachteil: Modernere Linker kennen kein aout (UNIX assembler out) mehr, wenn ich das richtig verstanden habe.
Versuch 1: nasmw -O32 -f coff kernel.asm -o kernel.o
nasmw -O32 -f coff kernel.asm -o kernel.o
kernel.asm:21: error: COFF format does not support non-32-bit relocations
kernel.asm:26: error: COFF format does not support non-32-bit relocations
kernel.asm:55: error: COFF format does not support non-32-bit relocations
make.exe: *** [all] Error 1Hier streikt nasm(w) wegen 16 bit relocations.
Versuch 2: nasmw -O32 -f elf kernel.asm -o kernel.o
kernel.o: file not recognized: File format not recognized
make.exe: *** [all] Error 1Diesmal will der Linker nicht.
Damit hänge ich irgendwie am aout-Format fest.
Vielleicht hilft da ein cross-compiler:
- http://wiki.osdev.org/GCC_Cross-Compiler
- http://lowlevel.brainsware.org/wiki/index.php/Cross-Compiler
Kennt sich da jemand genau aus? Bin leider (noch) kein Compiler-Experte.
Übrigens ist abc.w hier auch mit mingw gescheitert:
http://www.c-plusplus.net/forum/viewtopic-var-p-is-1687893.htmlIch habe das mit mingw (ist in code::blocks enthalten) noch mal probiert:
C:\Programme\CodeBlocks\MinGW\bin\ld: cannot perform PE operations on non PE output file 'ckernel.bin'.
Hmmm, siehe unten!
Kennt sich da jemand genau aus? Offensichtlich lösen die Cross-Compiler dieses Problem.
daher bin ich bei meinem DJGPP (gcc 3.1, ld 2.13) und aout geblieben, habe aber das Gefühl, das man da einen Schritt vorwärts kommen sollte.
Kann mir jemand die Hintergründe, warum man diesen Cross-Compiler bauen muss, mal erklären. Da hat sich doch gegen "früher" etwas verschlechtert, denn ich arbeite doch mit dem DJGPP und dem aout-Format sehr gut! Das Problem ist der Wechsel von aout nach elf.
-
Erhard Henkes schrieb:
So klappt es bestens:
nasmw -O32 -f bin boot.asm -o boot.bin nasmw -O32 -f aout kernel.asm -o kernel.o nasmw -O32 -f aout isr.asm -o isr.o nasmw -O32 -f aout process.asm -o process.o nasmw -O32 -f aout flush.asm -o flush.o gcc -Wall -O -c ckernel.c -o ckernel.o ... gcc -Wall -O -c syscall.c -o syscall.o ld -T kernel.ld kernel.o ... syscall.o -o ckernel.bin -Map kernel.map cmd /c copy /b boot.bin + ckernel.bin MyOS
ok, du kannst nasm- und gcc-output zusammenlinken, also ist doch alles gut. ich sehe jedenfalls keinen grund, die tools zu wechseln (ein solcher wäre für mich z.b. ein ernsthafter bug des gcc oder nasm).
btw, aber wenn du unbedingt wechseln willst, kannste das auch zu einem beliebigen späteren zeitpunkt tun. ist also nix, was die weiterentwicklung deines OS grossartig beeinflussen würde.
-
Hallo!
Super Topic und Themenwahl!
Ich habe ein kleines Problem! Wenn meine Kernel.bin (ASM + C-Kernel) keine Größe hat, die ohne Rest durch 512 Bytes teilbar ist, dann erhalte Ich einen Triple Fault!
Anfangs habe Ich per "times ??? db 0" die Datei richtig vergrößert, jedoch ist dies bei JEDER Änderung des Kernels notwendig!
Kennt jemand eine Lösung, um dies zu umgehen oder wenigstens das Ergebnis des Linkens auf eine Größe von ?.00 KB zu bringen?Gruß
ChrisPS: Ich arbeite mit Windoof Vista und habe DJGPP, wie überall angepriesen installiert und in Gebrauch!
-
Erhard Henkes schrieb:
Ich benötige für kernel.asm das aout-Format (verkraftet beim Linken 16/32 bit gemischt) wegen des Linkers!
Der [BITS 16]-Code in der kernel.asm passt noch in die boot.asm. Dann stünde in der kernel.asm i.e. nur noch folgendes:
[BITS 32] [extern _main] mov ax, 0x10 mov ds, ax ; data descriptor --> data, stack and extra segment mov ss, ax mov es, ax xor eax, eax ; null desriptor --> FS and GS mov fs, ax mov gs, ax mov esp, 0x200000 ; set stack below 2 MB limit call _main ; ->-> C-Kernel (...)
Damit wäre das Linker-Problem vom Tisch. Falls du ernsthaft GRUB in Erwägung ziehst, könntest du konsequenterweise die erste Hälfte von Teil 1 des Tutorials ersatzlos streichen. Das wäre schade.
-
Der [BITS 16]-Code in der kernel.asm passt noch in die boot.asm.
Ja, die Idee hatte ich gestern auch, nachdem der Code da jetzt relativ kurz ist.
Falls du ernsthaft GRUB in Erwägung ziehst, könntest du konsequenterweise die erste Hälfte von Teil 1 des Tutorials ersatzlos streichen. Das wäre schade.
Ja, das stimmt. Mir gefällt dieser Weg ohne GRUB und Windows auch sehr gut, vor allem, weil alle es anders machen. GRUB ist eben sehr komfortabel. Dafür ist man im Endeffekt an Linux und diesen Bootloader gebunden. Vielleicht schaffen wir es gemeinsam, den Bootloader bzw. kernel.asm (da ist ja Platz, da keine 512 Byte-Grenze mehr vorhanden) den Anforderungen entsprechend zu gestalten und GRUB zu umgehen.
-
@+gjm+: hast Du die Trennung bereits praktisch durchgeführt?
Ich habe mal versuchsweise getrennt, stürzt aber noch beim Kernel laden ab.
Ansonsten müsste ich nochmal step-by-step versuchsweise den Code in kleineren Häppchen von kernel.asm nach boot.asm schleppen.
Dann könnte man nämlich mal coff testen.Nachfolgender Code klappt (s.u.).
-
Einen Fehler habe ich step-by-step gefunden:
cli ; clear interrupts lgdt [gdtr] ; load GDT via GDTR (defined in file "gtd.inc") jmp 0x8:PM ; http://www.nasm.us/doc/nasmdo10.html#section-10.1
muss im 16-bit-Teil stehen.
Das macht mir noch ein Problem. So sieht es momentan aus (läuft!):
boot.asm
..kernel.asm
..Frage: wie werde ich den 16 bit Teil in kernel.asm noch los? Ich springe ja vom bootloader nach 0x8000 (Kernelstart).
-
Erhard Henkes schrieb:
Frage: wie werde ich den 16 bit Teil in kernel.asm noch los? Ich springe ja vom bootloader nach 0x8000 (Kernelstart).
Ganz einfach: Im Bootloader in den Protected Mode schalten (lgdt und cr0 laden), und dann mit jmp 0x08:0x8000 in den Kernel springen (d.h. im Bootloader ist auch kein 32 Bit Teil). Im Kernel kannst du dann direkt mit 32 Bit Code anfangen, und musst die Segmentregister erstmal laden. Danach solltest du dann nochmal eine GDT im Kernel laden, falls der Bootloader irgendwann überschrieben wird.
-
Der boot.asm muß somit nur folgendes hinzugefügt werden:
(...) .A20_done: cli lgdt [gdtr] mov eax, cr0 or eax, 1 mov cr0, eax ; jmp 0x8000 jmp 0x8:0x8000 ; Ist zwar ein 16-bit-FAR-Jmp, allerdings ; wird hier CS mit "index" 8 der GDT geladen (da in PM). ; Deshalb wird der Code ab Sprungziel von der CPU ; als 'BITS 32' interpretiert (s. CODE_Desc in der gdt.inc). (...) %include 'gdt.inc' ; <- Achtung : die gdt.inc ist nun hier und nicht mehr in der kernel.asm. times 510-($-$$) hlt db 0x55 db 0xAA
Nun sollte nur noch in der boot.asm "BITS 16"-Code sein.
-
Danke! Hat gut funktioniert. Der boot sector ist immer noch halb leer, hat also noch Luft für notwendige Ergänzungen.
kernel.asm stellt sich nun wie folgt dar (ich lade GDT dort auf Anraten nochmals, ist das so im Code richtig umgesetzt?):
[Bits 32] [global KernelStart] KernelStart: mov ax, 0x10 mov ds, ax ; data descriptor --> data, stack and extra segment mov ss, ax mov es, ax xor eax, eax ; null desriptor --> FS and GS mov fs, ax mov gs, ax mov esp, 0x200000 ; set stack below 2 MB limit lgdt [gdtr] ; load GDT via GDTR (defined in file "gtd.inc") [extern _main] ; entry point in ckernel.c call _main ; ->-> C-Kernel jmp $ ;;;;;;;;;;;; ; Includes ; ;;;;;;;;;;;; %include "gdt.inc"
Die 16/32-Bit-Trennung ist damit gelungen, endlich. Ein kleiner Meilenstein.
Nun geht auch folgendes:
nasmw -O32 -f bin boot.asm -o boot.bin nasmw -O32 -f coff kernel.asm -o kernel.o
Aber hier gibt es noch ein kleines Problem, auch noch mit KernelStart:
C:\DJGPP\bin/ld.exe: warning: cannot find entry symbol KernelStart; defaulting to 00008000 <--- Wieso dies?
ckernel.o(.text+0x1f8):ckernel.c: undefined reference to\_file\_data_end' ckernel.o(.text+0x1fd):ckernel.c: undefined reference to
_file_data_start'
ckernel.o(.text+0x215):ckernel.c: undefined reference to\_file\_data_end' ckernel.o(.text+0x21a):ckernel.c: undefined reference to
_file_data_start'
ckernel.o(.text+0x220):ckernel.c: undefined reference to\_file\_data_start' gdt.o(.text+0xf6):gdt.c: undefined reference to
_gdt_flush'
gdt.o(.text+0xfb):gdt.c: undefined reference to\_tss\_flush' idt.o(.text+0x70):idt.c: undefined reference to
_idt_flush'
isrs.o(.text+0xe):isrs.c: undefined reference to_isr0' isrs.o(.text+0x21):isrs.c: undefined reference to
_isr1'
...
isrs.o(.text+0x29e):isrs.c: undefined reference to_isr127' irq.o(.text+0xc5):irq.c: undefined reference to
_irq0'
...
irq.o(.text+0x1f7):irq.c: undefined reference to_irq15' paging.o(.text+0x522):paging.c: undefined reference to
_copy_page_physical'
task.o(.text+0x23b):task.c: undefined reference to\_irq\_tail' task.o(.text+0x3c1):task.c: undefined reference to
_irq_tail'
task.o(.text+0x7f2):task.c: undefined reference to `_read_eip'
make.exe: *** [all] Error 1Ich möchte die Syntax mit dem führenden Unterstrich in C behalten. Tipp?
-
ich lade GDT dort auf Anraten nochmals, ...
Das macht hier keinen Sinn weil gelten würde : "alte GDT == neue GDT". Ausserdem müssten dann die Segmentregister erst wieder mit den Deskriptoren der "neuen" GDT initialisiert werden bevor sie "Wirkung" zeigen.
C:\DJGPP\bin/ld.exe: warning: cannot find entry symbol KernelStart; defaulting to 00008000 <--- Wieso dies?
Das Symbol (Label ?) "KernelStart" ist nirgendwo in der kernel.asm definiert.
-
ich lade GDT dort auf Anraten nochmals, ...
Das macht hier keinen Sinn weil gelten würde : "alte GDT == neue GDT". Ausserdem müssten dann die Segmentregister erst wieder mit den Deskriptoren der "neuen" GDT initialisiert werden bevor sie "Wirkung" zeigen.Also wieder weg.
Der Bereich unter 08:0x8000 wird später nicht beschrieben.Das Symbol (Label ?) "KernelStart" ist nirgendwo in der kernel.asm definiert.
Mit aout war/ist das kein Problem. Braucht coff das anders? Habe da noch nichts gefunden.
kernel.asm:
[Bits 32] [global KernelStart] KernelStart: mov ax, 0x10 mov ds, ax ; data descriptor --> data, stack and extra segment mov ss, ax mov es, ax xor eax, eax ; null desriptor --> FS and GS mov fs, ax mov gs, ax mov esp, 0x200000 ; set stack below 2 MB limit [extern _main] ; entry point in ckernel.c call _main ; ->-> C-Kernel jmp $
Das war doch vorher auch nicht anders (da hatte ich nur RealMode).
Warum ist COFF so seltsam?
-
Ganz schön zickenhaft der ld. Probiere mal folgendes in der kernel.asm:
[BITS 32] section .text ; <- jawohl lieber ld, "KernelStart" ist nun auch in der section .text :) [global KernelStart] KernelStart: mov ax, 0x10 (...)
-
Hat wirklich geholfen. Warum schluckt der ld das beim aout-Format und motzt erst beim COFF-Format. Merkwürdiges Verhalten. Man lernt nie aus.
Hilft auch gegen das Ignorieren der C-Funktionen.
Offenbar weiß der Linker beim COFF nicht, wo das Programm anfängt?!
Damit sind wir zumindest den Schritt aout --> coff gegangen.
nasmw -O32 -f coff kernel.asm -o kernel.o nasmw -O32 -f coff isr.asm -o isr.o nasmw -O32 -f coff process.asm -o process.o nasmw -O32 -f coff flush.asm -o flush.o
Vielleicht hilft es bei der Benutzung von Linkern höherer Versionen, die bisher mit aout Probleme hatten.
-
Wenn wir schon bei so grausamen Themen sind. Ich wollte mal mein opulentes makefile umstellen auf eine variable Darstellung (vor allem, damit man compiler leicht tauschen kann). Hier klappt aber die Umsetzung c --> o und asm --> coff noch nicht, wenn ich das richtig sehe:
# Makefile for PrettyOS SOURCES= kernel.o \ ckernel.o \ isr.o \ video.o \ flush.o \ gdt.o \ idt.o \ isrs.o \ irq.o \ util.o \ math.o \ timer.o \ keyboard.o \ process.o \ ordered_array.o \ paging.o \ kheap.o \ descriptor_tables.o \ task.o \ fs.o \ initrd.o \ syscall.o CFLAGS= -Wall \ -O LDFLAGS= -T kernel.ld -Map kernel.map ASFLAGS= -fcoff CC=gcc NASM=nasmw AS=as all: nasmw -f bin file_data.asm -o file_data.dat nasmw -O32 -f bin boot.asm -o boot.bin make -s link make -s image link: ld $(LDFLAGS) -o ckernel.bin $(SOURCES) image: cmd /c copy /b boot.bin + ckernel.bin MyOS cmd /c rename MyOS MyOS.bin del MyOS partcopy MyOS.bin 0 7000 -f0 .s.o: $(NASM) $(ASFLAGS) $< .c.o: $(CC) -c $(CFLAGS) -o $@ $< .a.o: $(AS) $(ASFLAGS) -o $<
G:\OSDev\Test\49>make
nasmw -f bin file_data.asm -o file_data.dat
nasmw -O32 -f bin boot.asm -o boot.bin
make -s link
C:\DJGPP\bin/ld.exe: cannot open kernel.o: No such file or directory (ENOENT)
make.exe[1]: *** [link] Error 1
make.exe: *** [all] Error 2Offensichtlich baut er keine xxx.o aus den xxx.c. und kein coff aus asm.
Wo ist der Hauptfehler? Baue so was sonst nie selbst.
-
Kann ich nicht folgen. Eine "kernel.o" existiert doch, generiert via
nasmw -O32 -f coff kernel.asm -o kernel.o
?
-
nasmw -O32 -f coff kernel.asm -o kernel.o
Nein ich wollte das aktuelle makefile komplett durch dieses ersetzen.
habe folgendes noch geändert:
.asm.o: $(NASM) $(ASFLAGS) $<
Da stand vorher s.o.:
G:\OSDev\Test\49>make
nasmw -f bin file_data.asm -o file_data.dat
nasmw -O32 -f bin boot.asm -o boot.bin
make -s link
C:\DJGPP\bin/ld.exe: cannot open ckernel.o: No such file or directory (ENOENT)
make.exe[1]: *** [link] Error 1
make.exe: *** [all] Error 2Ich sehe aber kein kernel.o im Verzeichnis.
Wenn ich das -s(ilent) weg nehme:
G:\OSDev\Test\49>make
nasmw -f bin file_data.asm -o file_data.dat
nasmw -O32 -f bin boot.asm -o boot.bin
make link
make.exe[1]: Entering directoryg:/OSDev/Test/49' ld -T kernel.ld -Map kernel.map -o ckernel.bin kernel.o ckernel.o isr.o video.o flush.o gdt.o idt.o isrs.o irq.o util.o math.o timer.o keyboard.o process.o orde red\_array.o paging.o kheap.o descriptor\_tables.o task.o fs.o initrd.o syscall.o C:\\DJGPP\\bin/ld.exe: cannot open ckernel.o: No such file or directory (ENOENT) make.exe[1]: *** [link] Error 1 make.exe[1]: Leaving directory
g:/OSDev/Test/49'
make.exe: *** [all] Error 2
-
+gjm+ schrieb:
ich lade GDT dort auf Anraten nochmals, ...
Das macht hier keinen Sinn weil gelten würde : "alte GDT == neue GDT". Ausserdem müssten dann die Segmentregister erst wieder mit den Deskriptoren der "neuen" GDT initialisiert werden bevor sie "Wirkung" zeigen.
Der Zweck ist wie gesagt Problemen vorzubeugen, wenn der Bootsektor überschrieben wird, weil die GDT beim LGDT nicht in die CPU geladen wird. Wenn die GDT, die sich außerhalb des Kernels befindet, überschrieben wird, weil die Speicherverwaltung den Bereich, wo der Bootsektor war, als freien Speicher empfinden, knallt es beim Nachladen der Segmentregister.
Das Laden der Segmentregister ist nicht zwingend notwendig, sofern alte und neue GDT den selben Inhalt haben. (Und wenn die Segmentregister nicht aus Versehen mit alten Selektoren geladen werden, ist es auch kein Problem eine neue GDT anzulegen.)
Aber wenn Erhard die guten 32 KByte RAM da unten verrotten lassen will, soll mir recht sein. Hat er ja schließlich für bezahlt. ^^
Erhard Henkes schrieb:
Ich sehe aber kein kernel.o im Verzeichnis.
Weil du kein Target abhängig von den $(SOURCES) gemacht hast. Make weiß nicht, dass die Objektdateien vorher gebaut werden müssen, weil du es ihm nicht gesagt hast.
-
Ich dachte, dieses
.c.o: $(CC) -c $(CFLAGS) -o $@ $<
kümmert sich bereits darum. Wenn das nur faul rum hängt, fliegt's raus.
.c.o sei auch obsolet, habe ich irgendwo gelesen. Dieses $@ $< finde ich auch irgendwie unlesbaren Mist.Die sechs Assemblerzeilen schreibe ich nun lieber fix rein, nur mit Variable für Format und Flags.
TARGET des Link-Vorgangs ist für mich ckernel.bin, oder?
So wird brav kompiliert, ich kann den Compiler und die Flags zumindest variabel austauschen und verstehe das makefile noch bestens. Das doppelte Aufführen der Dateinamen muss allerdings noch weg, aber unbedingt leserlich und klar nach vollziehbar.
# Makefile for PrettyOS ASFLAGS= -O32 -f coff TARGET= ckernel.bin OBJ= kernel.o ckernel.o isr.o video.o flush.o gdt.o \ idt.o isrs.o irq.o util.o math.o timer.o keyboard.o \ process.o ordered_array.o paging.o kheap.o descriptor_tables.o \ task.o fs.o initrd.o syscall.o LDFLAGS= -T kernel.ld -Map kernel.map LD= ld CFLAGS= -Wall -O CC= gcc all: nasmw -f bin file_data.asm -o file_data.dat nasmw -O32 -f bin boot.asm -o boot.bin nasmw $(ASFLAGS) kernel.asm -o kernel.o nasmw $(ASFLAGS) isr.asm -o isr.o nasmw $(ASFLAGS) process.asm -o process.o nasmw $(ASFLAGS) flush.asm -o flush.o make compile make link make image compile: $(CC) $(CFLAGS) -c ckernel.c -o ckernel.o $(CC) $(CFLAGS) -c video.c -o video.o -O1 $(CC) $(CFLAGS) -c math.c -o math.o -O1 $(CC) -O -c util.c -o util.o -O1 $(CC) $(CFLAGS) -c gdt.c -o gdt.o $(CC) $(CFLAGS) -c idt.c -o idt.o $(CC) $(CFLAGS) -c isrs.c -o isrs.o $(CC) $(CFLAGS) -c irq.c -o irq.o $(CC) $(CFLAGS) -c timer.c -o timer.o $(CC) $(CFLAGS) -c keyboard.c -o keyboard.o $(CC) $(CFLAGS) -c ordered_array.c -o ordered_array.o $(CC) $(CFLAGS) -c paging.c -o paging.o $(CC) $(CFLAGS) -c kheap.c -o kheap.o $(CC) $(CFLAGS) -c descriptor_tables.c -o descriptor_tables.o $(CC) $(CFLAGS) -c task.c -o task.o $(CC) $(CFLAGS) -c fs.c -o fs.o $(CC) $(CFLAGS) -c initrd.c -o initrd.o $(CC) $(CFLAGS) -c syscall.c -o syscall.o link: $(LD) $(LDFLAGS) -o $(TARGET) $(OBJ) image: cmd /c copy /b boot.bin + ckernel.bin MyOS del *.coff del *.o del *.bin cmd /c rename MyOS MyOS.bin del MyOS partcopy MyOS.bin 0 7000 -f0
Wie kann ich diesen Teil mit "compile:" allgemein ablaufen lassen analog dem Linker-Befehl? Da die o alle aus c kommen, sollte das gehen.
Sollte man die o (OBJECTS) oder die c (SOURCES, wie unten stehend) auflisten? Ich habe das mit den obj-Dateien bevorzugt, also den Linker-Vorgang in den Mittelpunkt gerückt, weil ja auch obj-Dateien von NASM zu verarbeiten sind.
Bei makefiles stehe ich immer grundsätzlich auf dem Schlauch, weil jedes Vorbild anders aussieht und die Tutorials absolut nix taugen, weil diese keine klare Linie vorgeben. Vielleicht gibt es auch einfach keine.
So in etwa findet man es z.B. (Bsp. mit C++, mit diesem obsolet-Stil .cpp.o, den Linker finde ich dort z.B. nicht, Compile- und Link-Vorgang verquickt, irgendwie viel unverständliches Zeugs, die letzte Zeile habe ich ja oben gerade gekillt, weil sie noch nicht gearbeitet hat, lag da nur so rum, ich habe sie aber verstanden trotz wildcards):
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=helloall: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): (CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@Am schlimmsten finde ich so etwas "SOURCES:.cpp=.o" mit diesem Doppelpunkt.
Vielleicht kann mir da jemand auf die Sprünge helfen. Ich finde es gut, wenn Compile- und Link-Vorgang getrennt dargestellt werden, weil dies bei einem OS wichtig ist.So etwas wie
$(CC) $(CFLAGS) -c $(SOURCES) -o $(OBJECTS)
wäre gut verständlich. Dann müsste man aber die c-Dateien noch allgemein als Sources angeben. Habe dies probiert, hat aber nicht geklappt. Vielleicht kann jemand meine Idee doch noch zum Laufen bringen:# Makefile for PrettyOS
# Assemble
ASFLAGS= -O32 -f coff# Compile
SOURCES= ???.c
CFLAGS= -Wall -O
CC= gcc# Link
OBJ= kernel.o ckernel.o isr.o video.o flush.o gdt.o \
idt.o isrs.o irq.o util.o math.o timer.o keyboard.o \
process.o ordered_array.o paging.o kheap.o descriptor_tables.o \
task.o fs.o initrd.o syscall.o
TARGET= ckernel.bin
LDFLAGS= -T kernel.ld -Map kernel.map
LD= ldall:
nasmw -f bin file_data.asm -o file_data.dat
nasmw -O32 -f bin boot.asm -o boot.bin
nasmw $(ASFLAGS) kernel.asm -o kernel.o
nasmw $(ASFLAGS) isr.asm -o isr.o
nasmw $(ASFLAGS) process.asm -o process.o
nasmw $(ASFLAGS) flush.asm -o flush.o
make compile
make link
make imagecompile:
??? #Idee: $(CC) $(CFLAGS) -c $(SOURCES) -o $(OBJECTS)link:
$(LD) $(LDFLAGS) -o $(TARGET) $(OBJ)image:
cmd /c copy /b boot.bin + ckernel.bin MyOS
del *.o
del *.bin
cmd /c rename MyOS MyOS.bin
partcopy MyOS.bin 0 7000 -f0c.o.:
$(CC) -c $(CFLAGS) -o $@ $<
-
Aber wenn Erhard die guten 32 KByte RAM da unten verrotten lassen will, soll mir recht sein. Hat er ja schließlich für bezahlt. ^^
Ja, aber man muss ja auch andere denken. Der Speicher bis 0x00008000 sollte nach dem Boot-Vorgang schon wieder genutzt werden können, aber irgendwo muss das GDT ja dann liegen, z.B. nach dem Kernel-Ende:
Das gute PrettyOS hat das ja alles schon im C-Kernel eingebaut, wenn ich das richtig sehe, und das wird in main() nach Bildschirmlöschen und Begrüßen umgehend installiert:
flush.asm (siehe lgdt [...] )
..Dieses gdt_flush wird mittels gdt_install in main() aufgerufen:
..int main() { k_clear_screen(); printformat("Welcome to PrettyOS ... \n"); // GDT, IDT, ISRS, IRQ, timer, keyboard, paging, interrupts, multitasking gdt_install(); //... }
Ist das so o.k.? Die GDT sitzt dann bei der Adresse &gdt. Ich habe zur Kontrolle ein printformat eingebaut:
Welcome to PrettyOS ...
gdt: 0000D480hDen Verschwendungsvorwurf kann ich so nicht auf mir sitzen lassen.