Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Themen - Sapphire

Seiten: [1]
1
Lowlevel-Coding / Paging Fehler: Bit 31 in cr0
« am: 22. June 2008, 21:44 »
Hallo nachdem mir hier schon so schnell mit meiner memalloc Funktion geholfen wurde, habe ich wieder ein Problem an dem ich schon einige Zeit sitze.

Situation:
Ich lege erst ein PageDirectory und 2 PageTables an. Die erste Table mappt die ersten 4 MB Virtuellen Speicher auch in die ersten 4 MB der Physischen Speichers, und die 2te Mappt den Speicherbereich bei genau 3GB an 0xB8000 wo sich ja der Video speicher befindet.
Anschließend setze ich das Bit 31 in cr0 um Paging zu aktivieren.
Wenn ich jetz ganz normal auf die Adresse 0xB8000 zugreife geht alles gut nur wenn ich auf 0xC0000000 (3GB) zugreife bekomme ich eine Exception.

Problem:
Obwohl ich Bit 31 gesetzt habe ist es nicht gesetzt  :-P wenn mein Interrupt Handler aufgerufen wird. Ich denke das er mir das Bit garnicht richtig setzt.

Frage:
Ist mein Code falsch (Code folgt unten) oder gibt es Fälle wo er das Bit einfach nicht setzten kann / bzw löscht der Prozessor das Bit 31 bei einer Exception automatisch ?
Wer net wenn mir da jemand Auskunft geben könnt.

Code:
Definition
struct Paging_PageDirectory
{
  unsigned int PageTableAdress[1024];
};

struct Paging_PageTable
{
  unsigned int PhysPageAdress[1024];
};

/*
Aktiviert Paging.
*/
void Paging_Enable( void );
/*
Deaktiviert Paging.
*/
void Paging_Disable( void );
/*
Ändert das aktive PageDirectory und
gibt die Adresse des Alten zurück
*/
void Paging_SwapDirectory( struct Paging_PageDirectory* Directory);
/*
Gibt das aktive PageDirectory zurück.
*/
struct Paging_PageDirectory* Paging_GetActivDirectoy( void );
/*
Erstellt ein PageDirectory an übergeben Adresse.
*/
struct Paging_PageDirectory* Paging_CreatePageDirectory( void* Adress);
/*
Fügt einen Eintrag im Angebeben PageDirectory hinzu und
erstellt eine PageTable an angebener Adresse.
*/
struct Paging_PageTable* Paging_AddPageDirectoryEntry(unsigned short Entry,void* PageTableAdress,struct Paging_PageDirectory* PagingDirectory);
/*
Gibt einen Eintrag aus einem PageDirectory zurück.
*/
struct Paging_PageTable* Paging_GetPageTable(struct Paging_PageDirectory* Directory,unsigned short Entry);
/*
Fügt einen Eintrag in eine PageTable hinzu.
*/
void Paging_AddPageTableEntry(struct Paging_PageDirectory* Directory,unsigned short DirectoryEntry,unsigned short TableEntry,void* PhysAdress);


Assembler Code
;C: void Paging_Enable( void );
_Paging_Enable:
  push eax
  mov eax,cr0   ;cr0 in eax laden
or eax,0x80000000  ;Bit Nr. 31 setzen
mov cr0,eax   ;eax in cr0 schreiben
pop eax
ret           ;zurück

;C: void Paging_Disable( void );
_Paging_Disable:
  push eax
  mov eax,cr0   ;cr0 in eax laden
  xor eax,10000000000000000000000000000000b  ;Bit Nr. 31 löschen
  mov cr0,eax   ;eax in cr0 schreiben
  pop eax
  ret
 
;C: void Paging_SwapDirectory( unsigned int DirectoryAdress );
_Paging_SwapDirectory: ; 1 Parameter: Adresse des neuen PageDirectory
 push ebp 
 mov ebp, esp 
 push eax

 mov eax, [ebp+8] ;Adresse nach eax lesen
 mov cr3, eax

 pop eax
 mov esp, ebp 
 pop ebp 
 ret
 
;C: unsigned int Paging_GetActivDirectoy( void );
_Paging_GetActivDirectory:
  mov eax,cr3 ;cr3 in eax laden
  ret         ;zurück (eax = Adresse)

C Code
/*
Erstellt ein PageDirectory an übergeben Adresse.
*/
struct Paging_PageDirectory* Paging_CreatePageDirectory( void* Adress)
{
  //Überprüfen ob gültige Adress
  if((((unsigned int)Adress)&0xFFFFF000)!=((unsigned int)Adress))
  {
    KMSG("Invalid Page DIrectory Adress\n\r");
    //1 Sekunde warten
    timer_waitticks(100);
  }
  // 
  memset(Adress,0x00,4096);
  return (struct Paging_PageDirectory*)Adress;
};

/*
Fügt einen Eintrag im Angebeben PageDirectory hinzu und
erstellt eine PageTable an angebener Adresse.
*/
struct Paging_PageTable* Paging_AddPageDirectoryEntry(unsigned short Entry,void* PageTableAdress,struct Paging_PageDirectory* PagingDirectory)
{
    //In Directory Eintragen
    PagingDirectory->PageTableAdress[Entry] = (((unsigned int)PageTableAdress) | 0x007);
    //Paging Table mit 0 füllen
    memset(PageTableAdress,0x00,4096);
    //PageTable zurückgeben
    return (struct Paging_PageTable*)PageTableAdress;
};

/*
Gibt einen Eintrag aus einem PageDirectory zurück.
*/
struct Paging_PageTable* Paging_GetPageTable(struct Paging_PageDirectory* Directory,unsigned short Entry)
{
  return (struct Paging_PageTable*)((Directory->PageTableAdress[Entry]) ^ 0x007);
};

/*
Fügt einen Eintrag in eine PageTable hinzu.
*/
void Paging_AddPageTableEntry(struct Paging_PageDirectory* Directory,unsigned short DirectoryEntry,unsigned short TableEntry,void* PhysAdress)
{
  struct Paging_PageTable* Table = Paging_GetPageTable(Directory,DirectoryEntry);
  Table->PhysPageAdress[TableEntry] = (((unsigned int)PhysAdress) | 0x007);
};

Initialisierung und Test:
struct Paging_PageDirectory* Directory = Paging_CreatePageDirectory(highmem_alloc());
  Paging_AddPageDirectoryEntry(0,highmem_alloc(),Directory);
  Paging_AddPageDirectoryEntry(768,highmem_alloc(),Directory);
  //die Ersten 4 MB
  int i=0;
  unsigned int Phys = 0x00000000;
  for(;i<1024;i++)
  {
    Paging_AddPageTableEntry(Directory,0,i,(void*)Phys);
    Phys += 0x1000;
  };
  //3GB Erste Page
  Paging_AddPageTableEntry(Directory,768,0,(void*)0xB8000);
  Paging_SwapDirectory(Directory);
  Paging_Enable();
  KMSG("Paging Enabled!");
  timer_waitticks(200);
 
  char* Mem = 0xC0000000; //3 GB
  char* String = "Test... Dies ist an die 3 GB Grenze geschrieben!";
  for(i=0;i<strlen(String);i++)
  {
    *Mem = *String;
    Mem++;
    *Mem = KVC_White;
    Mem++;
  }
2
Lowlevel-Coding / memalloc
« am: 14. June 2008, 11:57 »
Hallo erstmal.

Ich sitze grad an einer memalloc Funktion. Habe mir Gedanken gemacht und habe jetzt mal ein paar Fragen dazu.

1) Ich habe mir Überlegt das ich am Anfang jeder neu angeforderten Page eine BitMap platziere. Jedes Bit soll 2 Byte darstellen. So habe ich zwar 1 Byte verschwendet bei Speicherbereichen die ungerade sind, aber es geht pro Page nur 1/16 (256 Bytes) des Speichers drauf.

Frage: Ist es Sinvoll 2 Bytes pro Bit zu benutzen oder sollte ich lieber 1 Byte nehmen, wodurch dann aber schon 1/8 (512 Bytes) für die BitMap belegt sind.
Oder ist das ein ganz falscher Ansatz und es geht platzsparender?

2) memalloc muss sich ja auch die breiets angeforderten Pages speichern. Ich habe mir überlegt das man es dafür z.B. eine Page anfordert und dort erstmal nur die Startadressen der Pages speichern könnte.

Frage: Aber wie soll man dann verfahren wenn die Page voll ist? Wie speichere die nächsten Startadressen ?
Und viel wichtiger: Ist das wiederrum sinnvoll? Oder gibt es auch hier eine bessere / platzsparendere Möglichkeit.

Und noch eine Frage die erstmal nichts mit memalloc zu tuen hat:
3)Was kommt nach dem Speichermanager auf Page basis ?
Erst der Virtual Memory und dann eine Funktion alla memalloc oder umgekehrt.

Ich hoffe ihr könnt mir helfen, hatte bisher nur einen simplen Speichermanager der verkette Listen benutzt hat und hab mir daher um sowas keine gedanken gemacht.

Seiten: [1]

Einloggen