Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Hauke am 04. April 2006, 12:56
-
Ich hab mir das Tutorial "C-Kernel" durchgelesen und nach einigen Problemen beim Linken im Forum gefunden, dass die kernel.c falsch sein soll und umgeändert.
void main()
{
int i;
char Text[] = "Welcome to Protected Mode";
char *VideoMem = (char*)0xA8000;
for(i = 0; Text[i] != 0; i++)
{
VideoMem[i] = Text[i];
VideoMem[++i] = 7;
}
}
Aber ich bekomme immer noch eine Fehlermeldung
CKernel.obj:kernel.c:(.text+0x2c): undefined reference to `_memcpy'
Aber ich weis nicht genau was der Linker damit meint.
Hier noch mal meine link.txt:
OUTPUT_FORMAT("binary")
INPUT(kernel32.obj ckernel.obj)
ENTRY(start)
SECTIONS
{
.text 0x200 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(1);
}
.data : {
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(1);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(1);
}
end = .; _end = .; __end = .;
}
-
Scheinbar wird die Funktion memcpy verwendet. Vielleicht durch irgendeinen Optimierungsversuch des Compilers. Du könntest z.B. einfach mal eine memcpy-Funktion hinzufügen:
void memcpy(void *dest, const void *src, int n);
void main()
{
int i;
char Text[] = "Welcome to Protected Mode";
char *VideoMem = (char*)0xA8000;
for(i = 0; Text[i] != 0; i++)
{
VideoMem[i] = Text[i];
VideoMem[++i] = 7;
}
}
void memcpy(void *dest, const void *src, int n)
{
int i;
for (i = 0;i <= n;i++)
{
dest = (void*)src;
dest++;
src++;
}
}
-
Der String ist in der .rdata Section und wird deswegen auf den Stack kopiert.
Besser:
char * Text = "Welcome to Protected Mode";
-
Heißt es nicht .rodata?
-
Also bei mir nicht. Kann aber sein, dass das wieder so ein Ding ist, was bei Linux und Windows unterschiedlich ist. (Zumindest deutet Google das so an.)
-
Also mit dem Linken funktioniert jetzt, aber es stürzt beim echten PC immer ab und bei Bochs bleibt es stehen. Ich hab auch schon verschiedene Varianten ausprobiert z. B. nur
return; (return 0;)
aber es funktioniert irgendwie nicht. :?:
-
du musst doch auch gar nicht mehr aus der main-funktion raus. für den anfang reicht es, wenn du am ende eine endlosschleife machst. zum beispiel while(true);
-
Es funktioniert immer noch nicht. Auf dem Bildschirm wird nichts angezeigt und ich weis nicht warum und warum der PC abstürzt oder bei Bochs stehen bleibt. Hier vielleicht noch mal der Kernel32, der die Mainfunktion aufruft:
[Bits 32]
extern _main
global start
start:
call _main
stop:
jmp stop
Vielleicht weis jemand woran es lieben kann.
-
Wenn ich mich nicht irre ist der Video-Speicher An 0xb8000 und nicht an 0xa8000 !
Also sollte es nicht
char *VideoMem = (char*)0xA8000;
heissen, sondern
char *VideoMem = (char*)0xB8000;
mfG Toni Kaufmann
-
Das ist zwar richtig, aber der der Kernel ist aber an der Adresse 0x10000. Das steht auch so im Tutorial und ich hab schon beide Varianten ausprobiert, weil ich mir nicht so sicher war. Und beide Funktionieren auch nicht.
-
Funktioniert es denn, wenn du die ausgabe noch im asm-teil machst ?
z.B mit:
[Bits 32]
global start
start:
mov BYTE [0xb8000], 'A'
mov BYTE [0xb8001], 0x0f
jmp $
-
Die Ausgabe im ASM Teil funktioniert noch, aber der Aufruf der Main Funktion nicht.
Und wenn ich die Main Funktion durchlaufen lasse und danach in ASM Bildschiermausgabe mache. Wird bei Bochs das "A" ausgegeben (das andere aber nicht) und der echte PC stützt ab. :?:
-
Mich verwirrt noch das .text 0x200 im linker-file, wenn doch der Kernel an 0x1000 ist. Ist aber auch möglich, dass ich einen Denkfehler mache.