Autor Thema: C Kernel Main Funktion funktioniert nicht.  (Gelesen 14977 mal)

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« am: 18. January 2007, 12:57 »
 Ich hab schon die Datein so programmiert, wie im Tutorial „C Kernel starten“, jedoch wird der Text nicht ausgegeben, aufrufen und zurückspringen tut er wohl, und in der Main Funktion ist er scheinbar auch. Nur auf den Bildschierm schreibt er nur ein

int main()
{
    char *Text = "Welcome to Protected Mode";
    char *VideoMem = (char*)0xB8000;
    while(*Text)
    {
        *VideoMem = *Text;
        *VideoMem++;
        *VideoMem = 7;
        *VideoMem++;
        *Text++;
    }
    return(0);
}

Und muss „*VideoMem++;“ nicht „VideoMem++;“ sein (wie die beiden anderen auch), die Adresse muss doch Höher werden und nicht der Wert an der Adresse, so würde das vielleicht eine Sinn machen, aber wenn ich es umändere ist das gleiche wie vorher. Ich weis nicht wo der Fehler ist. :?

Termite

  • Beiträge: 239
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 18. January 2007, 13:16 »
Pointer sollte man schon beherschen.

int main()
{
    char *Text = "Welcome to Protected Mode";
    char *VideoMem = (char*)0xB8000;
    while(*Text)
    {
        *VideoMem = *Text;
        VideoMem++;
        *VideoMem = 7;
        VideoMem++;
        Text++;
    }
    return(0);
}

du legst char pointer an. mit dem * kannst du auf den inhalt zugreifen, auf den der pointer verweist. mit VidoeMem++ erhöst du den Pointer. mit *VideoMem++ erhöst du nur den inhalt auf den der pointer zeigt.

gruss

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #2 am: 18. January 2007, 13:23 »
termite, operator precedence sollte man schon beherrschen ;) Der Code tut so schon. Trotzallem ist der dereferenzierungsoperator hier überflüssig, aber er verändert nichts am ergebnis, da das post ++ vor dem * ausgeführt wird.

Hab kurz den code in meinen kernel eingebaut und der tut wie er soll. Aber im Tutorial Subforum gibts auch einen thread zu diesem Tutorial, da das iirc einige Fehler hatte.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 18. January 2007, 13:46 »
Wo ist den das Tutorial Subforum? :?

Termite

  • Beiträge: 239
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 18. January 2007, 14:01 »
Wieder was gelernt.

zumindest ist es überflüssig, und es verwirrt beim lesen und verstehen des Cods.


int main()
{
    char *Text = "Welcome to Protected Mode";
    char *VideoMem = (char*)0xB8000;
    while(*Text)
    {
        *VideoMem++ = *Text;
        *VideoMem++ = 7;
        Text++;
    }
    return(0);
}

das währe ja somit auch richtig und würde genau das tun was wir wollen. Nur ob man das auch einfach verstehen kann.


http://lowlevel.brainsware.org/forum/index.php?board=7.0

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 18. January 2007, 14:25 »
So ich habs. Dem einen Zeiger muss noch die Adreese zuaddiert werden wo der Kernel ist. Bei mit 0x10000
const int Adresse = 0x10000;
int main()
{
char *Text = "Welcome to Protected Mode"+Adresse; 
char *VideoMem = (char*)0xB8000; 

while(*Text) 

    *VideoMem++ = *Text;
    *VideoMem++ = 7;
    Text++;


return(0);
}
Danke für die Hilfe :-)

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 18. January 2007, 14:54 »
Ich hab doch noch eine Frage, wie kann man assembler Befehle bei diesem Compiler benutzen. Normalerweise ist das ja
(mir sind der Int und der out & in Befehle am wichtigsten)
asm{
xor eax,eax
xor ebx,ebx
};
Nur er mag das nicht. Was muss man da einstellen, oder wie geht das?

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 18. January 2007, 15:08 »
hi,
ich arbeite zwar kaum mit C, aber soweit ich weiss nutzen viele C Compiler nicht die Intel Asm Syntax sondern eine andere AT&T Sytntax oder wie die heißt.

Grüsse,
Stefan

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 18. January 2007, 15:32 »
OK wenn das stimmt, wie ist aber der Befehl dafür, dass er weis das asm Code kommt und wo gibt es eine liste aller Befehle? Oder der wichtigsten.  :?

Neo3

  • Beiträge: 39
    • Profil anzeigen
    • GlobalNetzone
Gespeichert
« Antwort #9 am: 18. January 2007, 16:17 »
Hallo Hauke

Zuerst mal müste man wissen was du für eine Compiler nutzt da Inline Assembler auf den genutzten Compiler ankommt, das selbe ist bei dem Befehl der ASM ausfürt, schreib mal welchen Compiler du nutzt dann kann man dir weiter helfen.

Freundlich Grüsse
Neo3
Mit grosser Kraft folgt grosse Verantwortung.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 18. January 2007, 16:27 »
Der gcc Compiler von GNU Version 2.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 18. January 2007, 16:33 »
Ich gehe mal nicht davon aus, daß du einen gcc 2.x hast, der ist nämlich mittlerweile so gut wie antik. Aber angenommen, das mit gcc ist richtig:
asm(
  "xor %eax, %eax\n" // Register haben Prozentzeichen
  "mov $42, %eax\n" // Konstanten mit Dollarzeichen. NB: Zielregister kommt als zweites!
  "mov $0x42, %eax\n" // Hexzahlen mit 0x wie in C üblich
);
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 18. January 2007, 16:45 »
Klapp super :-). Eine frage noch bei „in und out“ bei in ist das zweite ja wohl as Ziel „in $0x64, %al\n“ und bei Out? Wie ist das da?
Und wie kann ich C variablen mit asm kombinieren?
Int o; //z. B.
o = 20;
asm(
“mov o,%eax\n“);
« Letzte Änderung: 18. January 2007, 16:56 von Hauke »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 18. January 2007, 19:11 »
So, habe das jetzt mal richtig gemacht... Guckst du hier: http://lowlevel.brainsware.org/wiki/index.php/Inline-Assembler_mit_GCC. Verbesserungsvorschläge usw. sind natürlich willkommen. Ich glaube, im Moment ist das alles noch etwas sehr knapp (und auch nicht ganz vollständig). Falls du also nicht alles verstehen solltest, ist das also keine Schande für dich, sondern nur ein Anhaltspunkt, daß du mir Feedback geben solltest. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Termite

  • Beiträge: 239
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 18. January 2007, 22:30 »
Halo noch mal

du hast gesagt, dein kernel kopiert den code an die addresse 0x10000. wenn du diese dazuadierst dann funktioniert es.

hast du mal versucht, funktionen aufzurufen? Ich hab die vermutung, das du beim linking ein problem hast. dein code ist auf die Addresse 0x00000 gelinkt , und daher wird auch diese addressen verwendet. Das problem selber ist noch nicht gelöst. Bei jeder weiteren verwendung eines pointers, must du korrekturrechnugen einbauen.

beim linker sollte man das mit angeben können, was die startadresse sein soll. beim ARMLinker ging das auch über scader fils.

gruss

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 18. January 2007, 22:38 »
Zumindest vorläufig sollte es ld -Ttext=0x100000 tun.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 19. January 2007, 14:21 »
Ich kann ja mal die txt zeigen, welche Ld aufruft. Ich weis die meisten Befehl für den Liker nicht deswegen könnte es sein das da ein oder mehrere Fehler ist oder sind. Damit meine ich besonders (.text  0x200) aber als ich das nach .text  0x10000 funktionierte es aber nicht. Und Funktionen lassen sich richtig aufrufen.  :?

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 = .;
}

Und dann noch eine Frage was ist hier dran Falsch:  :?
char inp(char Port)
{
char Daten;
asm("inb %0,%1":"=a"(Daten):"d"(Port));
return Daten;
}

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 19. January 2007, 15:43 »
Damit meine ich besonders (.text  0x200) aber als ich das nach .text  0x10000 funktionierte es aber nicht.
Ich weiß nicht, ob du den Fehler nur hier beim Posten gemacht hast, aber 0x100000 sollte es sein, mit einer Null mehr, oder?

Zitat
Und dann noch eine Frage was ist hier dran Falsch:  :?
char inp(char Port)
{
char Daten;
asm("inb %0,%1":"=a"(Daten):"d"(Port));
return Daten;
}
%0 ist Daten, %1 ist Port. Und in AT&T-Syntax immer Quelle zuerst. Damit hätte ich dann inb %1, %0 gesagt.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 19. January 2007, 16:06 »
Ja oben hab ich eine null zu viel. Und die Funktion geht immer noch nicht Fehlermeldung:
E:\djgpp\tem\ccHDZZXh.s: Assembler messages:
E:\djgpp\tem\ccHDZZXh.s:54: Error: suffix or operands invalid for ‚in’


kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 19. January 2007, 17:31 »
Die Portnummer muß ein Word sein (also dx). Weil dein Parameter aber als char deklariert ist, versucht gcc aber inb dl, al zu schreiben, was dem Assembler nicht so gefällt. Wenn du unsigned short Port als Parameter nimmst, sollte das funktionieren.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen