Autor Thema: uint64_t/uint16_t Probelm  (Gelesen 4026 mal)

iksnagreb

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« am: 24. July 2012, 09:19 »
Ich habe die GDT wie im Wiki eingerichtet:

http://www.lowlevel.eu/wiki/Global_Descriptor_Table

Es funktioniert bei mir jedoch nur, wenn ich für uint64_t den long long Datentyp verwende und für uint16_t den short Datentyp.

Der Compiler gibt mir sonst aus:
gdt.h:14:1: Fehler: unbekannter Typname: »uint64_t«
gdt.h:39:6: Fehler: unbekannter Typname: »uint16_t«

Warum ist das so?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 24. July 2012, 09:27 »
Weil uint64_t kein eingebauter Datentyp ist, sondern normal per typedef in der stdint.h bereitgestellt wird. Die musst du erstens haben (entweder die mitgelieferte von einem Crosscompiler für dein OS oder eine selbstgeschriebene) und zweiten natürlich auch #includen, damit du die Typen benutzen kannst.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

iksnagreb

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 24. July 2012, 09:30 »
Vielen Dank für die schnelle Antwort.

Ist es den möglich  mit long long und short weiter zu machen, oder gibt es da irgend welche Probleme?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 24. July 2012, 10:00 »
Probleme kriegst du eventuell dann, wenn du auf einen anderen Compiler umsteigst, der short oder long long anders definiert. Praktisch wird das nicht vorkommen, ist also vor allem eine Stilfrage. uint64_t ist einfach viel expliziter als long long.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 09. November 2012, 18:48 »
Ich hätte da auch mal ne Frage  :-D

Um unint64_t und so benutzen zu können, muss man stdint.h inkludieren und deswegen logischerweise das -nostdinc im Makefile entfernen, damit das auch geht.
Könnte es deswegen Probleme geben, wenn irgendwelche Codefetzen aus den Includes mit in den Kernel kommen? Ich meine das das im Tutorial irgendwo erwähnt wurde.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 09. November 2012, 19:52 »
Hallo,

du solltest aufpassen, dass der vom Compiler erzeugte Code nicht die FPU oder andere Coprozessoren benutzt, aber floating-point im Kernel will man sowieso nicht. Ansonsten muss der Compiler ja Code bereitstellen, wenn die CPU gewisse Operationen nicht in Hardware kann - die sind aber unabhängig von der Umgebung.

Gruß,
Svenska

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 09. November 2012, 20:30 »
Der Parameter -ffreestanding sollte dafür sorgen, dass der Compiler nicht davon ausgeht, dass eine Library zur Verfügung steht. Mit den Headern in der Freestanding-Umgebung solltest du keine Probleme bekommen. Hier stehen die Header, die dir dann zur Verfügung stehen: http://gcc.gnu.org/onlinedocs/gcc/Standards.html
Dieser Text wird unter jedem Beitrag angezeigt.

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 10. November 2012, 14:32 »
Der Parameter -ffreestanding sollte dafür sorgen, dass der Compiler nicht davon ausgeht, dass eine Library zur Verfügung steht. Mit den Headern in der Freestanding-Umgebung solltest du keine Probleme bekommen. Hier stehen die Header, die dir dann zur Verfügung stehen: http://gcc.gnu.org/onlinedocs/gcc/Standards.html

Danke für den Tipp. :)

Ich bin irgendwie gerade unsicher, ob ich das mit der GDT jetzt richtig gemacht habe... Im Wiki steht ja, dass alles richtig ist, wenn der Kernel danach noch funktioniert. Das tut er bei mir, allerdings auch, wenn ich irgendwas in der GDT Funktion ändere. Kann da vielleicht einer kurz drüber gucken?  :-)
#include <stdint.h>
#include "includes.h"

#define GDT_FLAG_DATASEGM 0x02
#define GDT_FLAG_CODESEGM 0x0a
#define GDT_FLAG_TSS 0x09

#define GDT_FLAG_SEGMENT 0x10
#define GDT_FLAG_RING0 0x00
#define GDT_FLAG_RING3 0x60
#define GDT_FLAG_PRESENT 0x80

#define GDT_FLAG_4K_GRAN 0x800
#define GDT_FLAG_32_BIT 0x400

#define GDT_ENTRIES 0x5

static uint64_t gdt[GDT_ENTRIES];

void init_gdt() 
{
  set_entry(0, 0, 0, 0);
  set_entry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEGM | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
  set_entry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEGM | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
  set_entry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEGM | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
  set_entry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEGM | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
 
  load_gdt();
}

void set_entry(int i, unsigned int base, unsigned int limit, int flags)
{
  gdt[i] = limit & 0xffffLL;
  gdt[i] |= (base & 0xffffffLL) << 16;
  gdt[i] |= (flags & 0xffLL) << 40;
  gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
  gdt[i] |= ((flags >> 8) & 0xffLL) << 52;
  gdt[i] |= ((base >> 24) &  0xffLL) << 56;
}


void load_gdt()
{
  struct {
    uint16_t limit;
    void * pointer;
  } __attribute__((packed)) gdtp = {
    .limit = GDT_ENTRIES * 8 - 1,
    .pointer = gdt,
  };
  asm volatile("lgdt %0" : : "m" (gdtp));
 
  asm volatile(
"mov $0x10, %ax;"
"mov %ax, %ds;"
"mov %ax, %es;"
     "mov %ax, %ss;"
     "ljmp $0x8, $.1;"
     ".1:"
);
}

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 10. November 2012, 15:15 »
Ich bin irgendwie gerade unsicher, ob ich das mit der GDT jetzt richtig gemacht habe... Im Wiki steht ja, dass alles richtig ist, wenn der Kernel danach noch funktioniert.

Was genau änderst denn du?

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 10. November 2012, 15:41 »
Jetzt scheint es richtig zu funktionieren.  :roll:^^

Vorher konnte ich eigentlich alle Werte ändern. Jetzt wird die CPU resettet.
Trotzdem danke. :-)

 

Einloggen