Autor Thema: Problem bei Physikalischer Speicherverwaltung (Bitmap)  (Gelesen 38163 mal)

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #40 am: 23. November 2014, 20:02 »
Zitat
Wie lautet der Fehlercode?
Der Fehlercode also die Nummer des Interrupts "cpu->intr" ist 13 was meiner Belegung nach einem General Protection Fault entspricht.
Der Fehlercode ist in cpu->error.

Zitat
Gerade weil es an so vielem liegen kann, ist der komplette Quelltext hilfreich. An dem geposteten Code kann ich nichts falsches entdecken.
dann werde ich mal schauen ob ich mein projekt irgendwie auf github bekomme...
sollte ja nicht so schwer sein... aber eigtl sollte ja nur der code den ich gepostet habe für mein problem releavant sein... oder? kann es daran liegen dass meine physische Speicherverwaltung nicht richtig funktioniert und die pmm_alloc() Funktion nicht funktioniert?
Das wäre eine Möglichkeit von mindestens 1596.
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #41 am: 23. November 2014, 20:10 »
oh ok d.h. es gibt viele Möglichkeiten ^^ ich werde gleich mal den Fehlercode heraussuchen und posten.


s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #42 am: 23. November 2014, 21:52 »
ok der Fehlercode ist 258 (dezimal) und die auftretende Exception meines Wissens nach ein General Protection Fault.

Schonmal Danke für Eure Hilfe

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #43 am: 23. November 2014, 22:33 »
Bei den Fehlercodes ist die Betrachung in Hexadezimal am sinnvollsten. Der Wert ist also 0x102. Das setzt sich aus zwei Teilen zusammen: Die unteren 3 Bits geben an, wo der Fehler aufgetreten ist (IDT oder GDT), und die restlichen Bits geben den Eintrag an. (Siehe auch Kapitel 6.13 in Volume 3 der Manuals.) Die 2 heißt IDT und 0x100 ist die Adresse des 32. Eintrags (0x100 / 8 = 32), also des Timer IRQs. Das heißt deine IDT wird vermutlich überschrieben, unerreichbar gemacht (Paging) oder verschoben (LIDT), bevor der nächste Timerinterrupt auftritt. Außerdem ist das Aufrufen aus dem Userspace (int 0x20) nicht erlaubt. Glaube das gibt auch diesen Fault.
« Letzte Änderung: 23. November 2014, 22:41 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #44 am: 24. November 2014, 18:27 »
oh ok ich hab meinen Fehler entdeckt ich habe versucht aus einer Funktion heraus (Userspace) den Timerinterrupt auszulösen.. hab das jetzt entfernt und statt irgendeiner exception oder irgendwelchen fehlercodes startet er jetzt einfach neu. Das allerdings erst ab dem 2. Task also vermutlich ist auch wieder der Taskswitch oder der Timerinterrupt schuld.

Das bedeutet, solang ich mit init_task() nur einen Task initialisiere, gibt er meine A's unendlich lang auf dem Bildschirm aus und alles funktioniert wie gewollt, aber ab dem 2. Task -> Neustart..


s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #45 am: 24. November 2014, 20:04 »
also ich hab jetzt mal in meine task.c in die schedule Funktion, ein


  // Prozessorzustand des neuen Tasks zurueckgeben
  if(current_task != NULL) {
    cpu = current_task->cpu_state;
  }

  return cpu;


eingefügt um zu überprüfen ob der Task == NULL ist also noch uninitialisiert, d.h. die schedule Funktion zu früh aufgerufen wurde...

Das hat zwar den Neustart Fehler beseitigt, allerdings bekomme ich jetzt einen General Protection Fault, mit dem Fehlercode: 1364 (dezimal). Wenn ich das richtig interpretiere liegt mein Fehler also in der GDT, oder? wie genau finde ich den Deskriptor raus an dem es konkret liegt?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #46 am: 24. November 2014, 20:12 »
Die Deskriptornummer steht ab Bit 3 im Fehlercode, Bits 0, 1 und 2 sind Flags, die dir sagen, in welcher Tabelle und so. Kapitel 6.13 ("Error Code") in meiner Fassung des Intel-Manuals erklärt das.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #47 am: 24. November 2014, 20:20 »
ja ich denke das hab ich verstanden, ich versuche das grad rauszufinden komme aber nicht so recht klar, also mein Fehlercode entspricht in Binärformat: 10101010100

d.h. da Bit 2 gesetzt ist liegt es laut Intel Manual an der GDT.

Doch bei der Berechnung der Nummer des Deskriptors komme ich irgendwie nicht ganz klar: Binär: 10101010 also Hexadezimal: 0xAA also Dezimal: 170

170 / 8 (weil ein Eintrag 8 Bytes) ergibt eine Kommazahl?!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #48 am: 24. November 2014, 20:25 »
Das ist kein Byte-Offset (und auch kein Selektor), sondern direkt die Nummer des Deskriptors.

Dass der GDT-Eintrag 170 nicht existiert, überrascht uns vermutlich beide nicht. Deine nächste Aufgabe wäre herauszufinden, aus welchem Grund dein Code versucht, diesen Deskriptor zu benutzen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #49 am: 24. November 2014, 20:32 »
gute frage, die ich vermutlich auf echter hardware ohne debugging nicht beantworten kann.. aber ich denke mal dass bei dem Aufruf meines TSS irgendwas schiefgeht.. werd das mal überprüfen…
danke schonmal..

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #50 am: 24. November 2014, 20:44 »
Hier mal meine gdt.c falls man da irgendwas rauslesen kann..

// Source Code Fileor GDT Header File

#include "gdt.h"
#define GDT_ENTRIES 6

#define GDT_FLAG_DATASEG 0x02
#define GDT_FLAG_CODESEG 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


static unsigned long long gdt[GDT_ENTRIES];
static unsigned long tss[32] = { 0, 0, 0x10 };

void set_tss_entry(int x, unsigned long val)
{
 tss[x] = val;
}

static 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(void)
{

struct {
    unsigned short 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, %fs;"
  "mov %ax, %gs;"
  "mov %ax, %ss;"
  "ljmp $0x8, $.1;"
  ".1:;"
);

}

void init_gdt(void)
{
    set_entry(0, 0, 0, 0);
    set_entry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT |
        GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
    set_entry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT |
        GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
    set_entry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT |
        GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
    set_entry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT |
        GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
    set_entry(5, (unsigned long) tss, sizeof(tss), GDT_FLAG_TSS | GDT_FLAG_PRESENT | GDT_FLAG_RING3);

    load_gdt();

    // Taskregister neu laden
    asm volatile("ltr %%ax" : : "a" (5 << 3));

}

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #51 am: 24. November 2014, 20:49 »
Ich hätte noch zwei, drei Theorien einzuwerfen: Vielleicht schaust du gerade auf den falschen Wert (etwas das gar nicht der Error Code ist), oder deine Ausgabefunktion ist fehlerhaft. Und der Klassiker kaputter Stack ist auch immer dabei.
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #52 am: 24. November 2014, 20:54 »
also die Ausgabefunktion ist mit kputn genauso wie im Tutorial 1:1 übernommen… d.h. ich gebe direkt mit

kputn(cpu->error, 10); // Basis 10, also decimal

den Error Code aus…
sollte also nicht das Problem sein…

Wie genau erkenne ich einen kaputten Stack? und was kann ich dagegen tun?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #53 am: 24. November 2014, 21:01 »
Den könntest du erkennen, indem du schaust, ob die anderen Werte auf dem Stack plausibel sind.
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #54 am: 24. November 2014, 21:03 »
ok, also soll ich quasi die register auslesen.. nur weiß ich ja nicht welche werte in den registern normalerweise stehen sollten ^^

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #55 am: 24. November 2014, 21:08 »
In EIP sollte ein Wert stehen, der auf deinen Code zeigt, in ESP sollte eine Adresse stehen, die auf einen der dir bekannten Stacks liegt. Du legst die ja mit pmm_alloc an, bzw. die sind direkt im Kernel. In den Segmentregistern sollten gültige Werte stehen.
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #56 am: 24. November 2014, 21:21 »
also gut jetz spielt mein Kernel endgültig verrükct.. bin mit meinem Latein am Ende...

Jetz wollte ich debugging Ausgaben mit kputs und kputn einbauen.. -> Neustart (vermutlich Triple Fault)

Kommentiere ich die Debuggingausgaben aus, also genau die selbe situation wie vorher tritt statt eines GPF nun eine Invalid Opcode Exception mit Fehlercode: 0 auf...

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #57 am: 24. November 2014, 22:04 »
In solchen Fällen ist es sinnvoll zu schauen, was überhaupt noch funktioniert.
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #58 am: 24. November 2014, 23:12 »
Naja solange weniger als 2 Tasks laufen, also kein Taskswitch stattfindet geht alles..GDT einwandfrei, IDT einwandfrei, Testausgaben mit kputs und kputn auch.

Hmm komisch..

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #59 am: 25. November 2014, 12:22 »
Mal ne Frage wieso ist deine TSS in der GDT im Ring 3  eingetragen? Muss die nicht im Ring 0 sein?
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

 

Einloggen