Abend zusammen.
Ich bin zur Zeit beim Speichermanager. Der Physikalische funktioniert auch schon, allerdings habe ich jetzt schon seit Wochen Schwierigkeiten mit Paging. Ich habe dieses Tut http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html gelesen, und versucht, auf diesen Anregungen einen Virtuellen Speichermanager zu schreiben. Allerdings endet es immer in einer Reboot Schleife, und zwar, direkt, nach dem, Paging aktiviert wurde. Es gibt keine Pagfault, nichts! Ich habe auch schon die Forensuche bemüht, allerdings habe ich dort nichts gefunden, was mit helfen könnte.
Meine Vermutung ist, dass es entweder am Aufbau meiner Pagetables oder aber beim erstellen dieser liegen muss. Da ich aber nicht weis, ob ich mit dieser Vermutung richtig liege, poste ich hier den ganzen Code, damit ihr mir möglichst gut helfen könnt.
Physikalischer Speichermanager:
Ich bin zur Zeit beim Speichermanager. Der Physikalische funktioniert auch schon, allerdings habe ich jetzt schon seit Wochen Schwierigkeiten mit Paging. Ich habe dieses Tut http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html gelesen, und versucht, auf diesen Anregungen einen Virtuellen Speichermanager zu schreiben. Allerdings endet es immer in einer Reboot Schleife, und zwar, direkt, nach dem, Paging aktiviert wurde. Es gibt keine Pagfault, nichts! Ich habe auch schon die Forensuche bemüht, allerdings habe ich dort nichts gefunden, was mit helfen könnte.
Meine Vermutung ist, dass es entweder am Aufbau meiner Pagetables oder aber beim erstellen dieser liegen muss. Da ich aber nicht weis, ob ich mit dieser Vermutung richtig liege, poste ich hier den ganzen Code, damit ihr mir möglichst gut helfen könnt.
Physikalischer Speichermanager:
Code: [Auswählen]
// Defines
#define PAGESIZE 0x1000
/* Initialize the PMM
* Returnvalue: TRUE if all was ok, FALSE if smth. went wrong
*/
int PMMInit();
/* Alloc a frame
* Arguments: The frame to alloc
* Returnvalue: TRUE if all was ok, FALSE if smth. went wrong
*/
int MallocFrame(const u_long Frame);
/* Free a frame
* Arguments: The frame to free
* Returnvalue: TRUE if all was ok, FALSE if smth. went wrong
*/
int FreeFrame(const u_long Frame);
/* Get the value of a frame
* Arguments: The frame to get
* Returnvalue: The value of the frame
*/
int GetFrame(const u_long Frame);
/* Malloc ram
* Arguments: Size of ram to malloc; Pagealing?; Pointer to the startaddr
* Returnvalue: The addr of the ram
*/
u_long PMM_Malloc(const u_long Size, const int Align, u_long* Phys);
/* Free ram
* Arguments: The start addr of the the ram; Size of the ram
*/
void PMM_Free(const u_long StartAddr, const u_long Size);
/* Initialize the bitmap (bitset)
*/
void InitBitmap();
/* Get the actually placement addr
* Returnvalue: The placement addr
*/
u_long GetPlacementAddr();
/* Get the first free frame in the bitmap (bitset)
* Returnvalue: The first free frame
*/
u_long GetFirstFreeFrame();
// Vars
u_long* Bitmap; // The Bitmap
u_long NFrames; // The number of frames in the bitmap
int IsBitsetCreated; // Is the bitset created?
Code: [Auswählen]
u_long PlacementAddr = (u_long) &kernel_end; // Address of the first free memory
u_long OldPlacementAddr = (u_long) &kernel_end; // The old address of the first free memory
// Create the Bitmap
void CreateBitmap()
{
// Compute the number of frames
NFrames = 0x0;
struct SMbs_MMap_Entry* MMap = (struct SMbs_MMap_Entry*) pMultibootstruct->MMap_addr;
while(MMap < (struct SMbs_MMap_Entry*) pMultibootstruct->MMap_addr + pMultibootstruct->MMap_length)
{
if(MMap->Type == 1)
{
// Vars
u_int64 EndAddr = MMap->Length;
// Save the addr
NFrames = EndAddr;
}
MMap = (struct SMbs_MMap_Entry*) ((u_int32) MMap + MMap->Size + sizeof(u_int32));
}
NFrames = NFrames / PAGESIZE;
//NFrames = (CMOSRead(0x30) | CMOSRead(0x31) << 8) / PAGESIZE;
// Create the bitmap
Bitmap = (u_long*) PMM_Malloc(NFrames / 32, 0, 0);
// Init the bitmap
InitBitmap();
// The bitmap is now created
IsBitsetCreated = TRUE;
}
// Init the PMM
int PMMInit()
{
// Create the Bitmap
CreateBitmap();
return TRUE;
}
// Malloc a frame
int MallocFrame(const u_long Frame)
{
// Set the bit
Bitmap[Frame / 32] |= (1 << Frame % 32);
return TRUE;
}
// Free a frame
int FreeFrame(const u_long Frame)
{
// Delete the bit
Bitmap[Frame / 32] &= ~(1 << Frame % 32);
return TRUE;
}
// Get the value of a frame
int GetFrame(const u_long Frame)
{
// Is the bit set?
return (Bitmap[Frame / 32] & (1 << Frame % 32));
}
// Init the bitmap
void InitBitmap()
{
// Vars
struct SMbs_MMap_Entry* MMap = (struct SMbs_MMap_Entry*) pMultibootstruct->MMap_addr;
// Reset the bitmap
k_memset(Bitmap, 1, NFrames / 32);
// Search the MMap for free memory
while(MMap < (struct SMbs_MMap_Entry*) pMultibootstruct->MMap_addr + pMultibootstruct->MMap_length)
{
// Is the address free?
if(MMap->Type == 1)
{
// Vars
u_int64 Addr = MMap->BaseAddr;
u_int64 EndAddr = MMap->Length;
// The address is free! Mark the bitmap-entry
while(Addr < EndAddr)
{
FreeFrame(Addr / PAGESIZE);
Addr += PAGESIZE;
}
}
MMap = (struct SMbs_MMap_Entry*) ((u_int32) MMap + MMap->Size + sizeof(u_int32));
}
}
// Return the placement addr
u_long GetPlacementAddr()
{
return PlacementAddr;
}
// Return the first free frame
u_long GetFirstFreeFrame()
{
// Vars
u_long Index;
u_long Offset;
// Search for a free frame
for(Index = 0; Index < (NFrames / 32); Index++)
{
for(Offset = 0; Offset < 32; Offset++)
{
if(!(Bitmap[Index] & 1 << Offset))
return Index * 32 + Offset;
}
}
// If nothing was found, return -1
return -1;
}
// Malloc memory
u_long PMM_Malloc(const u_long Size, const int Align, u_long* Phys)
{
// Vars
u_long Addr;
// Page alignt?
if(Align == TRUE && PlacementAddr & 0xFFFFF000)
{
PlacementAddr &= 0xFFFFF000;
PlacementAddr += PAGESIZE;
}
// If Phys, save the start address of the new memory
if(Phys != 0)
*Phys = PlacementAddr;
// Reserv memory
Addr = PlacementAddr;
PlacementAddr += Size;
// If the bitmap is created, mark the bits in the bitset
if(IsBitsetCreated == TRUE)
{
// Temp-Vars
u_long Temp = Addr;
while(Temp < PlacementAddr)
{
MallocFrame(Temp / PAGESIZE);
Temp += PAGESIZE;
}
}
return Addr;
}
// Free memory
void PMM_Free(const u_long StartAddr, const u_long Size)
{
// Vars
u_long Addr = StartAddr;
// Clear the bits in the bitset
while(Addr < StartAddr + Size)
{
FreeFrame(Addr / PAGESIZE);
Addr += PAGESIZE;
}
}
Virtueller Speichermanager:Code: [Auswählen]
// A page
struct SPage
{
u_int32 Present : 1; // Is the page present in the memory?
u_int32 RW : 1; // Read- or Write-able
u_int32 User : 1; // User or supervisor previligs
u_int32 Accessed : 1; // Has the page been accessed since the last refresh?
u_int32 Dirty : 1; // Has the page been changed since the last refresh?
u_int32 Reserved : 7; // Reserved
u_int32 Frame : 20; // Frameaddr in the physical memory
};
// A pagetable
struct SPage_Table
{
struct SPage Pages[1024]; // All pages in the pagetable
};
// Pagediretory
struct SPage_Directory
{
u_int32 TablesPhysical[1024]; // Pointer to the page tables
struct SPage_Table* Tables[1024]; // The page tables
u_int32 PhysicalAddr; // Physicaladdr
};
/* Initalize the VMM
* Returnvalue: TRUE if all was ok, FALSE if smth. went wrong
*/
int VMMInit();
/* Malloc a page
* Arguments: The page to malloc; User?; RW?
* Returnvalue: TRUE if all was ok, FALSE if smth. went wrong
*/
int MallocPage(struct SPage* Page, int User, int RW);
/* Free a page
* Arguments: The page to free
*/
void FreePage(struct SPage* Page);
/* Get the page for an addr
* Arguments:
* Returnvalue: The page for the addr
*/
struct SPage* GetPage(u_long Addr);
// Vars
struct SPage_Directory* PageDirectory; // The page directory
Code: [Auswählen]
// Init the VMM
int VMMInit()
{
// Create a page directory
u_long Phys;
PageDirectory = (struct SPage_Directory*) PMM_Malloc(sizeof(struct SPage_Directory), TRUE, &Phys);
k_memset(PageDirectory, 0, sizeof(struct SPage_Directory));
PageDirectory->PhysicalAddr = Phys;
// Map the memory from physical to virtual
// NOTE: We only map the memory which is actually used!
int Addr = 0;
while(Addr < GetPlacementAddr())
{
MallocPage(GetPage(Addr), FALSE, TRUE);
Addr += PAGESIZE;
}
// Enable paging
asm ("mov %0, %%cr3":: "r"(&PageDirectory->PhysicalAddr));
extern void InitPaging();
InitPaging();
return TRUE;
}
// Malloc a page
int MallocPage(struct SPage* Page, int User, int RW)
{
// Is the page already allocated?
if(Page->Frame != 0)
return FALSE;
// Malloc the page
// Search a free frame
u_long Frame = GetFirstFreeFrame();
// If no Frame free?
if(Frame == -1)
return FALSE;
MallocFrame(Frame * PAGESIZE);
Page->Present = 1;
Page->User = User ? 1 : 0;
Page->RW = RW ? 1 : 0;
Page->Frame = Frame;
return TRUE;
}
// Get a page
struct SPage* GetPage(u_long Addr)
{
// Compute the index of the page table
u_int32 Index = Addr / PAGESIZE / 1024;
// Is the page already existing?
if(PageDirectory->Tables[Index])
{
// Return the page
return &PageDirectory->Tables[Index]->Pages[(Addr / PAGESIZE) % 1024];
}
else
{
// The page is not already existing, create it
u_long Temp;
PageDirectory->Tables[Index] = (struct SPage_Table*) PMM_Malloc(sizeof(struct SPage_Table), TRUE, &Temp);
k_memset(PageDirectory->Tables[Index], 0, PAGESIZE);
PageDirectory->TablesPhysical[Index] = Temp | 0x7;
return &PageDirectory->Tables[Index]->Pages[(Addr / PAGESIZE) % 1024];
}
}
// Free a page
void FreePage(struct SPage* Page)
{
// Free the frame and the page
FreeFrame(Page->Frame);
Page->Frame = 0x0;
}
Ich hoffe, dass mir jemand helfen kann, und bedanke mich schoneinmal für Hilfe im voraus.
Übersicht
Wiki
Hilfe
Suche
Einloggen
Registrieren
Drucken

Gespeichert

Es reicht dir eigentlich anzunehmen, dass in cr3 die Adresse des PD ist, auch wenn in Wirklichkeit in den unteren Bits ein paar Flags sind - aber wenn du nichts spezielles vorhast, bleiben die auf 0.