Autor Thema: Problem mit Linken  (Gelesen 7373 mal)

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« 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 = .;
}

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 04. April 2006, 13:41 »
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++;
}
}

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 05. April 2006, 00:21 »
Der String ist in der .rdata Section und wird deswegen auf den Stack kopiert.

Besser:
  char * Text = "Welcome to Protected Mode";
Dieser Text wird unter jedem Beitrag angezeigt.

GhostCoder

  • Beiträge: 187
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 05. April 2006, 08:38 »
Heißt es nicht .rodata?
A man, a legend!

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 05. April 2006, 20:22 »
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.)
Dieser Text wird unter jedem Beitrag angezeigt.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 06. April 2006, 16:50 »
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. :?:

nore

  • Beiträge: 76
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 07. April 2006, 14:47 »
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);

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 08. April 2006, 18:05 »
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.

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #8 am: 08. April 2006, 18:46 »
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

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 08. April 2006, 19:31 »
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.

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #10 am: 08. April 2006, 20:32 »
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 $

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 09. April 2006, 17:13 »
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. :?:

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #12 am: 09. April 2006, 18:59 »
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.

 

Einloggen