Witam
Pracuję nad Memorry Manager'em dla mojego OS'a.
Napisałem obsługę tablic bitowych, ale za to zatrzymałem się na pagingu.
#include "mm/fm.h"
#include "mm/flags.h"
#include "console.h"
#define PT_START 0x200000 //Adres, w którym zaczynają się PT
#define PT_SIZE 0x1000 //Rozmiar 1 PT
#define PD_ADDR 0x29000 //Adres, w którym znajduje się PD
#define PD_SIZE 0x1000 //Rozmiar PD
#define PAGE_SIZE 0x1000 //Rozmiar 1 strony
long * pagedir = (long *)PD_ADDR;
long freekernelmem = 0x800000; //8 MB
long freeusermem = 0xC0000000; //3 GB
/*****************************************************************************/
/* Funkcja wstawia stronę o adresie wirtualnym vaddr do podanego pd */
/*****************************************************************************/
void put_page( long * pd, long vaddr, long addr, long flags )
{
long pd_entry, pt_entry;
long * pagetable;
pd_entry = vaddr / ( PAGE_SIZE * 1024 ); //Numer PAGE TABLE
pagetable = (long *)pd[pd_entry]; //Wskaźnik na wybrany PT
pt_entry = ( vaddr % ( 1024 * PAGE_SIZE ) ) / PAGE_SIZE; //Numer wpisu w PT
pagetable[pt_entry] = addr | flags; //Ustawienie fizycznego adresu i flag
}
/*****************************************************************************/
/* Funkcja alokująca n stron (strony użytkownika) */
/*****************************************************************************/
void * ualloc_pages( long n )
{
long i;
long retval;
long freeframe;
retval = freeusermem;
for ( i = 0; i < n; i++ ) //Zaalokowanie wybranych stron
{
freeframe = find_free_frame();
put_page( pagedir, freeusermem, ( freeframe * 4096 ), PTE_PRESENT | PTE_WRITE ); //Ustawienie strony
set_frame_status( freeframe, 1 ); //Ustawienie statusu ramki na 1 (zajęta)
freeusermem += 0x1000;
}
return retval;
}
/*****************************************************************************/
/* Funkcja inicjująca MM niskiego poziomu. Inicjuje FM, tworzy tablice */
/* stron, włącza stronnicowanie i wyświetla odpowiedni komunikat ;) */
/*****************************************************************************/
void init_paging( void )
{
printf( "Initializing low-level MM... " );
init_fm(); //Inicjuje Frame Manager'a
long i;
long * pagetable;
for ( i = 0; i < 1024; i++ ) //Tworzy Page Tables
{
pagedir[i] = ( PT_START + ( i * PT_SIZE ) ) | PDE_PRESENT | PDE_WRITE; //Ustawia flagi
}
pagetable = (long *) pagedir[0];
for ( i = 0; i < 1024; i++ ) //Mapuje pierwsze 4 MB
{
pagetable[i] = ( i * 4096 ) | PTE_SUPERVISOR | PTE_PRESENT | PTE_WRITE;
}
pagetable = (long *) pagedir[1];
for ( i = 0; i < 1024; i++ ) //Mapuje następne 4 MB
{
pagetable[i] = ( i * 4096 + 0x400000 ) | PTE_SUPERVISOR | PTE_PRESENT | PTE_WRITE;
}
extern enable_paging();
enable_paging();
printf( "done\n" );
}
Paging inicjuje kodem
GLOBAL enable_paging
enable_paging:
mov eax, 0x29000
mov cr3, eax
mov eax, cr0
;or eax, 0x80000000
or eax, 0x80010000
mov cr0, eax
jmp .enabled
.enabled:
ret
Rezultatem włączenia stronnicowania jest triplefault. Wykłada się przy enable_paging
Ma może ktoś pomysł, jak to naprawić??