[????] BUILD 0.1.1.??? DATE 9/0?/2011 AT ?:?? ??
==================================================== Mainly changed: Tasking + Implemented multitasking
This commit is contained in:
@ -173,7 +173,7 @@ void _CommandMemPrintMemmap()
|
||||
blocks = n - old;
|
||||
used = 0;
|
||||
for (; old < n; old++)
|
||||
used += (MemPhGetFrame(old) != 0);
|
||||
used += (MemPhGetBlock (old) != 0);
|
||||
|
||||
if (used <= blocks / 5) c = ' ';
|
||||
else if (used > 4 * blocks / 5) c = 219;
|
||||
|
@ -55,7 +55,7 @@ Point ConsoleGetCursor()
|
||||
return ConsoleCursor;
|
||||
}
|
||||
|
||||
extern void ConsoleSetCursor(Point p)
|
||||
void ConsoleSetCursor(Point p)
|
||||
{
|
||||
ConsoleCursor = p;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ void DriversInstall()
|
||||
DriversInstall_Clock();
|
||||
|
||||
// Install fdc
|
||||
IrqInstallHandler(6, FloppyIrqHandler);
|
||||
FloppyInitialize();
|
||||
Error ("Floppy", "Floppy driver is currently disabled.\n");
|
||||
//IrqInstallHandler(6, FloppyIrqHandler);
|
||||
//FloppyInitialize();
|
||||
}
|
||||
|
@ -180,13 +180,16 @@ void luxInitrdInstall (MultibootInfo* info)
|
||||
VfsInstallFs(&fs);
|
||||
|
||||
// Check for multiboot info flags to see if any modules are loaded
|
||||
if ((info->Flags & 8) == 0) return;
|
||||
if ((info->Flags & 8) == 0) {
|
||||
Error("Initrd", "No boot modules found!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through each module and if it is an initrd image, mount it
|
||||
MultibootModule* modules = (MultibootModule*) info->ModulesAddress;
|
||||
|
||||
for (i = 0; i < info->ModulesCount; i++)
|
||||
if ((*(uint32*) modules[i].ModuleStart) == LUXMAGIC)
|
||||
if (*((uint32*) modules[i].ModuleStart) == LUXMAGIC)
|
||||
{
|
||||
// Mount the device
|
||||
Log("Initrd", "Found initrd image at 0x%x.\n", modules[i].ModuleStart);
|
||||
@ -196,4 +199,7 @@ void luxInitrdInstall (MultibootInfo* info)
|
||||
mp->FsData[0] = modules[i].ModuleStart;
|
||||
mp->FsData[1] = modules[i].ModuleEnd;
|
||||
}
|
||||
else {
|
||||
Log("Initrd", "Found module @ 0x%x, but not initrd image.\n", modules[i].ModuleStart);
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ void HalInitialize()
|
||||
KeyboardInstallB(); Log("HAL", "%#[2/2]\n", ColorLightGreen);
|
||||
|
||||
// Install mouse driver
|
||||
MouseInstall(); Log("HAL", "Installed mouse driver\n");
|
||||
//MouseInstall(); Log("HAL", "Installed mouse driver\n");
|
||||
|
||||
// Install VFS
|
||||
VfsInstall();
|
||||
|
@ -228,6 +228,10 @@ DirectoryEntry* VfsReadDirectory (FILE* handle, uint32 index)
|
||||
if (!handle) return NULL;
|
||||
MountPoint* mp = &(mpArray[handle->DeviceId]);
|
||||
|
||||
// Don't try to read files as directories
|
||||
if ((handle->Flags & 0x7) == FileFile) return NULL;
|
||||
|
||||
// Ask FS to make the read
|
||||
if (!fsArray[mp->FsId].ReadDirectory) return NULL;
|
||||
return fsArray[mp->FsId].ReadDirectory(mp, handle, index);
|
||||
}
|
||||
|
@ -33,8 +33,6 @@ enum PageFlags
|
||||
PageFrame = 0xFFFFF000
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
Page Pages[1024];
|
||||
} PageTable;
|
||||
@ -48,25 +46,28 @@ typedef struct {
|
||||
extern PageDirectory* CurrentDirectory;
|
||||
extern PageDirectory* KernelDirectory;
|
||||
|
||||
extern void PagingInitialize(uint32 SystemMemory);
|
||||
extern void PagingSwitchPageDirectory (PageDirectory* dir);
|
||||
extern Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir);
|
||||
|
||||
extern void PagingEnable ();
|
||||
extern void PagingDisable ();
|
||||
extern void PagingSwitchDirectory (PageDirectory* dir);
|
||||
extern void PagingFlushTlb ();
|
||||
extern void PagingInitialize (uint32* kernelEnd);
|
||||
extern void PagingMapPage (uint32 phys, uint32 virt, uint32 flags, PageDirectory* pd);
|
||||
extern void PagingUnmapPage (uint32 virt, PageDirectory* pd);
|
||||
extern uint32 PagingGetPhysical (uint32 virt, PageDirectory* pd);
|
||||
|
||||
/***************************************************
|
||||
* Physical memory manager *
|
||||
***************************************************/
|
||||
extern uint32 TotalFrames;
|
||||
extern uint32 TotalBlocks;
|
||||
extern uint32 TotalMemory;
|
||||
extern uint32 UsedFrames;
|
||||
extern uint32 UsedBlocks;
|
||||
|
||||
void MemPhInitialize(uint32 SystemMemoryKb);
|
||||
extern void MemPhSetFrame (uint32 frame, uint8 value);
|
||||
uint32 MemPhGetFrame (uint32 frame);
|
||||
uint32 MemPhFindFreeFrame();
|
||||
void MemPhAllocFrame(Page* page, uint8 isKernel, uint8 isWriteable);
|
||||
void MemPhFreeFrame(Page* page);
|
||||
void MemPhReserveFrames (uint32 address, uint32 length);
|
||||
extern void MemPhInitialize (uint32 SystemMemoryKb);
|
||||
extern void MemPhSetBlock (uint32 Block, uint8 value);
|
||||
extern uint32 MemPhGetBlock (uint32 Block);
|
||||
extern uint32 MemPhAllocateBlock ();
|
||||
extern void MemPhFreeBlock (uint32 addr);
|
||||
extern void MemPhReserveBlocks (uint32 address, uint32 length);
|
||||
|
||||
|
||||
/***************************************************
|
||||
@ -82,12 +83,12 @@ typedef struct
|
||||
|
||||
extern MemHeap* KernelHeap;
|
||||
|
||||
extern uint32 MemHeapFindSmallestHole (uint32 size, uint8 page_align, MemHeap* heap);
|
||||
extern int32 MemHeapCompare (uint32 a, uint32 b);
|
||||
extern MemHeap* MemHeapCreate(uint32 start, uint32 end, uint32 max, uint8 flags);
|
||||
extern void MemHeapExpand(uint32 newsz, MemHeap* heap, PageDirectory* pd);
|
||||
extern uint32 MemHeapContract(uint32 newsz, MemHeap* heap, PageDirectory* pd);
|
||||
extern uint32 MemHeapAlloc (uint32 size, uint8 isPageAligned, MemHeap* heap, PageDirectory* pd);
|
||||
extern void MemHeapFree (uint32 address, MemHeap* heap, PageDirectory* pd);
|
||||
extern uint32 MemHeapFindSmallestHole (uint32 size, uint8 page_align, MemHeap* heap);
|
||||
extern int32 MemHeapCompare (uint32 a, uint32 b);
|
||||
extern MemHeap* MemHeapCreate (uint32 start, uint32 end, uint32 max, uint8 flags);
|
||||
extern uint32 MemHeapExpand (uint32 newsz, MemHeap* heap, PageDirectory* pd);
|
||||
extern uint32 MemHeapContract (uint32 newsz, MemHeap* heap, PageDirectory* pd);
|
||||
extern uint32 MemHeapAlloc (uint32 size, uint8 isPageAligned, MemHeap* heap, PageDirectory* pd);
|
||||
extern void MemHeapFree (uint32 address, MemHeap* heap, PageDirectory* pd);
|
||||
|
||||
#endif /* MEMORY_ADD_H_ */
|
||||
|
@ -32,7 +32,7 @@
|
||||
// Memory manager
|
||||
#define KERNEL_HEAP_START 0xC0000000
|
||||
#define KERNEL_HEAP_INITIAL_SIZE 0x100000
|
||||
#define KERNEL_HEAP_END (KERNEL_HEAP_START + KERNEL_HEAP_INITIAL_SIZE)
|
||||
#define KERNEL_HEAP_END (KERNEL_HEAP_START + KERNEL_HEAP_INITIAL_SIZE)
|
||||
|
||||
|
||||
#endif /* SETTINGS_H_ */
|
||||
|
@ -1 +1 @@
|
||||
#define OS_BUILD "0.1.0.601"
|
||||
#define OS_BUILD "0.1.0.629"
|
||||
|
@ -28,8 +28,7 @@ uint32 _malloc_init2 (uint32 size, uint8 page_aligned, uint32* phys)
|
||||
|
||||
if (phys)
|
||||
{
|
||||
Page *pg = PagingGetPage(ret, 0, KernelDirectory);
|
||||
*phys = (*pg & PageFrame) + (ret & 0xFFF);
|
||||
*phys = PagingGetPhysical(ret, KernelDirectory) + (ret & 0xFFF);
|
||||
|
||||
Log("Mem","%#Allocated %u bytes (%spage aligned) at address 0x%x (phys=%x).\n", ColorLightMagenta, size, ((page_aligned) ? "" : "not "), ret, *phys);
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
#include <memory-add.h>
|
||||
// MemoryGetFree(), MemoryGetTotal(), MemoryGet blah blah...
|
||||
|
||||
// Returns total physical memory in bytes
|
||||
uint32 MemoryGetTotal()
|
||||
@ -17,13 +16,13 @@ uint32 MemoryGetTotal()
|
||||
// Returns total free physical memory in bytes
|
||||
uint32 MemoryGetFree()
|
||||
{
|
||||
return (TotalFrames - UsedFrames) * 0x4;
|
||||
return (TotalBlocks - UsedBlocks) * 0x4;
|
||||
}
|
||||
|
||||
// Total used physical memory in bytes
|
||||
uint32 MemoryGetUsed()
|
||||
{
|
||||
return UsedFrames * 0x4;
|
||||
return UsedBlocks * 0x4;
|
||||
}
|
||||
|
||||
// Same as above functions, but in frames
|
||||
@ -34,15 +33,15 @@ uint32 MemoryGetFrameSize()
|
||||
|
||||
uint32 MemoryGetFramesTotal()
|
||||
{
|
||||
return TotalFrames;
|
||||
return TotalBlocks;
|
||||
}
|
||||
|
||||
uint32 MemoryGetFramesUsed()
|
||||
{
|
||||
return UsedFrames;
|
||||
return UsedBlocks;
|
||||
}
|
||||
|
||||
uint32 MemoryGetFramesFree()
|
||||
{
|
||||
return (TotalFrames - UsedFrames);
|
||||
}
|
||||
return (TotalBlocks - UsedBlocks);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "../../drivers/cmos/cmos.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
uint32 mem_kernel_end = 0;
|
||||
uint8 mem_initialized = 0;
|
||||
|
||||
@ -42,7 +41,7 @@ void _memory_reserve_system(MultibootInfo* info)
|
||||
while ((uint32)location < (info->MemoryMapAddress + info->MemoryMapLength))
|
||||
{
|
||||
if (location->Type > 1)
|
||||
MemPhReserveFrames((uint32)location->Address, (uint32)location->Length);
|
||||
MemPhReserveBlocks((uint32)location->Address, (uint32)location->Length);
|
||||
|
||||
location = (MultibootMemoryMapEntry*) ((uint32)location + location->Size + sizeof(uint32));
|
||||
}
|
||||
@ -53,29 +52,35 @@ void _memory_reserve_system(MultibootInfo* info)
|
||||
Error("Mem", "%#Missing %#memory map%# info from bootloader.\n", ColorLightRed, ColorWhite, ColorLightRed);
|
||||
|
||||
// Standard memory hole at 15mb
|
||||
MemPhReserveFrames(0x00F00000, 0x00100000);
|
||||
MemPhReserveBlocks(0x00F00000, 0x00100000);
|
||||
}
|
||||
|
||||
// Standard reserved memory areas
|
||||
MemPhReserveFrames(0x0, 0x400 + 256); // Real mode IVT, BDA
|
||||
MemPhReserveFrames(0x1000, 0x2400); // DMA buffer
|
||||
MemPhReserveFrames(0x9FC00, 385*1024); // EBDA, Video memory, ROM area
|
||||
}
|
||||
|
||||
|
||||
void MemoryInitialize (MultibootInfo* info)
|
||||
{
|
||||
// Get total system memory
|
||||
uint32 totalSystemMemory = _memory_get_total_mem(info);
|
||||
|
||||
// Initialize physical & virtual memory managers
|
||||
uint32 end = mem_kernel_end + 0x80000;
|
||||
MemPhInitialize(totalSystemMemory);
|
||||
PagingInitialize(0x200000);
|
||||
PagingInitialize(&end);
|
||||
|
||||
// Reserve physical blocks
|
||||
_memory_reserve_system(info);
|
||||
|
||||
uint32 i;
|
||||
// Allocate some space for the kernel heap
|
||||
for (i = KERNEL_HEAP_START; i <= KERNEL_HEAP_END; i += 0x1000)
|
||||
PagingMapPage(MemPhAllocateBlock(), i, PageWriteable, KernelDirectory);
|
||||
|
||||
// Create the kernel heap
|
||||
KernelHeap = MemHeapCreate(KERNEL_HEAP_START, KERNEL_HEAP_START
|
||||
+ KERNEL_HEAP_INITIAL_SIZE, 0xCFFFF000, 3); // is kernel, writeable
|
||||
|
||||
Log("Mem", "Done initializing memory!");
|
||||
Log("Mem", "Done initializing memory!\n");
|
||||
|
||||
mem_initialized = 2;
|
||||
}
|
||||
@ -84,5 +89,5 @@ void MemoryTempInitialize (uint32 kernel_end)
|
||||
{
|
||||
mem_initialized = 1;
|
||||
mem_kernel_end = kernel_end;
|
||||
Log("Mem", "Initialized temporary memory manager, allocating from %#0x%x.\n", kernel_end);
|
||||
Log("Mem", "Initialized temporary memory manager, allocating from %#0x%x.\n", ColorWhite, mem_kernel_end);
|
||||
}
|
||||
|
@ -26,29 +26,22 @@ start:
|
||||
|
||||
mov ecx, eax
|
||||
|
||||
; lgdt [trickgdt]
|
||||
; mov ax, 0x10;
|
||||
; mov ds, ax
|
||||
; mov es, ax
|
||||
; mov fs, ax
|
||||
; mov gs, ax
|
||||
; mov ss, ax
|
||||
|
||||
; jmp 0x08:HigherHalf ; NOTE: Must be absolute jump!
|
||||
|
||||
HigherHalf:
|
||||
|
||||
; Verify booted with multiboot compliant bootloader
|
||||
; setup initial stack
|
||||
mov esp, stack+STACKSIZE
|
||||
|
||||
; Verify booted with multiboot compliant bootloader
|
||||
cmp ecx, 0x2BADB002
|
||||
jne .bad
|
||||
|
||||
push esp
|
||||
push ebx
|
||||
|
||||
extern k_main
|
||||
call k_main
|
||||
|
||||
cli
|
||||
hlt
|
||||
|
||||
; Show error message, and halt system
|
||||
.bad:
|
||||
|
||||
@ -72,27 +65,8 @@ HigherHalf:
|
||||
ErrorString db 0xA, "%#! Fatal error: Not booted with multiboot compliant bootloader (e.g. GRUB).", 0x0
|
||||
ErrorColor db 0x0C
|
||||
|
||||
|
||||
|
||||
; tells the assembler to include this data in the '.setup' section
|
||||
section .setup
|
||||
|
||||
trickgdt:
|
||||
dw gdt_end - gdt - 1 ; size of the GDT
|
||||
dd gdt ; linear address of GDT
|
||||
|
||||
gdt:
|
||||
dd 0, 0 ; null gate
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x40 ; code selector 0x08: base 0x40000000, limit 0xFFFFFFFF, type 0x9A, granularity 0xCF
|
||||
db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x40 ; data selector 0x10: base 0x40000000, limit 0xFFFFFFFF, type 0x92, granularity 0xCF
|
||||
|
||||
gdt_end:
|
||||
|
||||
|
||||
|
||||
|
||||
; stack
|
||||
section .bss
|
||||
align 32
|
||||
stack:
|
||||
resb STACKSIZE ; This reserves 64KBytes of memory here
|
||||
resb STACKSIZE ; This reserves memory for stack
|
||||
|
@ -6,9 +6,6 @@
|
||||
#define MEMHEAP_INDEX_SIZE 0x20000
|
||||
#define MEMHEAP_MINIM_SIZE 0x70000
|
||||
|
||||
#define FlagsKernel 1
|
||||
#define FlagsWriteable 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 Magic;
|
||||
@ -98,30 +95,31 @@ MemHeap* MemHeapCreate(uint32 start, uint32 end, uint32 max, uint8 flags)
|
||||
}
|
||||
|
||||
|
||||
void MemHeapExpand(uint32 newsz, MemHeap* heap, PageDirectory* pd)
|
||||
uint32 MemHeapExpand(uint32 newsz, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
if (newsz <= heap->EndAddress - heap->StartAddress) return;
|
||||
if (newsz <= heap->EndAddress - heap->StartAddress) return heap->EndAddress - heap->StartAddress;
|
||||
|
||||
if (newsz & 0xfff) newsz = (newsz & 0xfffff000) + 0x1000;
|
||||
if (newsz + heap->StartAddress >= heap->MaxAddress) return;
|
||||
if (newsz + heap->StartAddress >= heap->MaxAddress) return heap->EndAddress - heap->StartAddress;
|
||||
|
||||
uint32 i;
|
||||
for (i = heap->EndAddress - heap->StartAddress; i < heap->StartAddress + newsz; i+=0x1000)
|
||||
MemPhAllocFrame(PagingGetPage(i, 1, pd), heap->Flags & FlagsKernel, heap->Flags & FlagsWriteable);
|
||||
for (i = heap->EndAddress; i < heap->StartAddress + newsz; i+=0x1000)
|
||||
PagingMapPage(MemPhAllocateBlock(), i, heap->Flags, pd);
|
||||
|
||||
heap->EndAddress = heap->StartAddress + newsz;
|
||||
return newsz;
|
||||
}
|
||||
|
||||
uint32 MemHeapContract(uint32 newsz, MemHeap* heap, PageDirectory* pd)
|
||||
{
|
||||
if (newsz >= heap->EndAddress - heap->StartAddress) return 0;
|
||||
if (newsz >= heap->EndAddress - heap->StartAddress) return heap->EndAddress - heap->StartAddress;
|
||||
|
||||
if (newsz & 0xfff) newsz = (newsz & 0xfffff000) + 0x1000; // page align
|
||||
newsz = Max(newsz, MEMHEAP_MINIM_SIZE);
|
||||
|
||||
uint32 i;
|
||||
for (i = heap->EndAddress - heap->StartAddress - 0x1000; i > newsz; i-=0x1000)
|
||||
MemPhFreeFrame(PagingGetPage(i, 0, pd));
|
||||
for (i = heap->EndAddress - 0x1000; i > heap->StartAddress + newsz; i-=0x1000)
|
||||
PagingUnmapPage(i, pd);
|
||||
|
||||
heap->EndAddress = heap->StartAddress + newsz;
|
||||
return newsz;
|
||||
|
@ -6,69 +6,123 @@
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*******************************
|
||||
* Data *
|
||||
*******************************/
|
||||
PageDirectory* CurrentDirectory;
|
||||
PageDirectory* KernelDirectory;
|
||||
|
||||
/*******************************
|
||||
* Useful routines *
|
||||
*******************************/
|
||||
void PagingInitialize(uint32 kernel_used)
|
||||
void PagingEnable()
|
||||
{
|
||||
Log("Mem", "Virtual memory manager initialization started. End of kernel = 0x%x\n", kernel_used);
|
||||
PageDirectory* kernelPd = (PageDirectory*) kmalloc_a(sizeof(PageDirectory));
|
||||
memset(kernelPd, 0, sizeof(PageDirectory));
|
||||
|
||||
CurrentDirectory = kernelPd;
|
||||
KernelDirectory = kernelPd;
|
||||
|
||||
uint32 i;
|
||||
for (i = 0; i < kernel_used; i+=0x1000)
|
||||
MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 0, 0);
|
||||
|
||||
Log("Mem", "Identity mapped first 0x%x bytes.\n", kernel_used);
|
||||
|
||||
for (i = KERNEL_HEAP_START; i < KERNEL_HEAP_END; i+=0x1000)
|
||||
MemPhAllocFrame(PagingGetPage(i, 1, kernelPd), 1, 1);
|
||||
|
||||
Log("Mem", "Mapped kernel space.\n");
|
||||
|
||||
PagingSwitchPageDirectory (kernelPd);
|
||||
uint32 tmp;
|
||||
asm volatile ("mov %%cr0, %0" : "=r"(tmp));
|
||||
tmp |= 0x80000000;
|
||||
asm volatile ("mov %0, %%cr0" : : "r"(tmp));
|
||||
}
|
||||
|
||||
void PagingSwitchPageDirectory (PageDirectory* dir)
|
||||
void PagingDisable()
|
||||
{
|
||||
uint32 tmp;
|
||||
asm volatile ("mov %%cr0, %0" : "=r"(tmp));
|
||||
tmp &= 0x7FFFFFFF;
|
||||
asm volatile ("mov %0, %%cr0" : : "r"(tmp));
|
||||
}
|
||||
|
||||
void PagingSwitchDirectory(PageDirectory* dir)
|
||||
{
|
||||
CurrentDirectory = dir;
|
||||
asm volatile ("mov %0, %%cr3":: "r"(&dir->TablesPhysical));
|
||||
|
||||
uint32 cr0;
|
||||
asm volatile ("mov %%cr0, %0": "=r"(cr0));
|
||||
cr0 |= 0x80000000;
|
||||
asm volatile ("mov %0, %%cr0":: "r"(cr0));
|
||||
|
||||
Log("Mem", "Enabled paging.\n");
|
||||
asm volatile ("mov %0, %%cr3" : : "r"(dir->PhysicalAddr));
|
||||
}
|
||||
|
||||
Page* PagingGetPage(uint32 addr, uint8 make, PageDirectory* dir)
|
||||
void PagingFlushTlb ()
|
||||
{
|
||||
addr >>= 12;
|
||||
uint32 tmp;
|
||||
asm volatile ("mov %%cr3, %0" : "=r"(tmp));
|
||||
asm volatile ("mov %0, %%cr3" : : "r" (tmp));
|
||||
}
|
||||
|
||||
uint32 tableIndex = addr >> 10;
|
||||
void PagingInitialize(uint32* kernelEnd)
|
||||
{
|
||||
// Create the kernel page directory
|
||||
PageDirectory* kdir = kmalloc_a(sizeof(PageDirectory));
|
||||
memset(kdir, 0, sizeof(PageDirectory));
|
||||
|
||||
if (dir->Tables[tableIndex])
|
||||
return &dir->Tables[tableIndex]->Pages[addr&0x3ff];
|
||||
KernelDirectory = kdir;
|
||||
|
||||
else if (make)
|
||||
// Set up physical address of PDEs.
|
||||
kdir->PhysicalAddr = (uint32) kdir->TablesPhysical;
|
||||
|
||||
// Identity map the kernel
|
||||
uint32 i = 0;
|
||||
while (i <= *kernelEnd + 1024)
|
||||
{
|
||||
uint32 temp;
|
||||
dir->Tables[tableIndex] = (PageTable*)kmalloc_ap(sizeof(PageTable), &temp);
|
||||
memset (dir->Tables[tableIndex], 0, 0x1000);
|
||||
dir->TablesPhysical[tableIndex] = temp | 0x7;
|
||||
return &dir->Tables[tableIndex]->Pages[addr&0x3ff];
|
||||
PagingMapPage(i, i, PageWriteable, kdir);
|
||||
i += 0x1000;
|
||||
}
|
||||
|
||||
else return 0;
|
||||
// Reserve the identity mapped blocks
|
||||
MemPhReserveBlocks(0x0, *kernelEnd);
|
||||
|
||||
PagingSwitchDirectory(kdir);
|
||||
PagingEnable();
|
||||
}
|
||||
|
||||
void PagingMapPage (uint32 phys, uint32 virt, uint32 flags, PageDirectory* pd)
|
||||
{
|
||||
// Calculate pde and pte
|
||||
uint32 pde = virt >> 22;
|
||||
uint32 pte = (virt >> 12) & 0x3ff;
|
||||
|
||||
phys &= 0xFFFFF000; // Make sure address is page aligned
|
||||
flags &= 0xFFF; // Make sure flags don't overflow
|
||||
|
||||
// See if page table exists
|
||||
if (!pd->Tables[pde])
|
||||
{
|
||||
// No? allocate it
|
||||
uint32 ph;
|
||||
PageTable* pt = kmalloc_ap(sizeof(PageTable), &ph);
|
||||
memset(pt, 0, sizeof(PageTable));
|
||||
|
||||
pd->Tables[pde] = pt;
|
||||
pd->TablesPhysical[pde] = ph | 0x7;
|
||||
}
|
||||
|
||||
// Set up the page
|
||||
pd->Tables[pde]->Pages[pte] = phys | flags | 0x1; // Present, and flags
|
||||
|
||||
// If it is the current directory, flush the tlb to notice the change
|
||||
if (pd == CurrentDirectory) PagingFlushTlb();
|
||||
}
|
||||
|
||||
void PagingUnmapPage (uint32 virt, PageDirectory* pd)
|
||||
{
|
||||
// Calculate pde and pte
|
||||
uint32 pde = virt >> 22;
|
||||
uint32 pte = (virt >> 12) & 0x3ff;
|
||||
|
||||
if (!pd->Tables[pde] || !pd->Tables[pde]->Pages[pte]) return;
|
||||
|
||||
// Get physical address
|
||||
uint32 phys = pd->Tables[pde]->Pages[pte] & PageFrame;
|
||||
|
||||
// Free page
|
||||
pd->Tables[pde]->Pages[pte] = 0;
|
||||
MemPhFreeBlock(phys);
|
||||
|
||||
// If it is the current directory, flush the tlb to notice the change
|
||||
if (pd == CurrentDirectory) PagingFlushTlb();
|
||||
}
|
||||
|
||||
uint32 PagingGetPhysical (uint32 virt, PageDirectory* pd)
|
||||
{
|
||||
// Calculate pde and pte
|
||||
uint32 pde = virt >> 22;
|
||||
uint32 pte = (virt >> 12) & 0x3ff;
|
||||
|
||||
// Not mapped
|
||||
if (!pd->Tables[pde] || !pd->Tables[pde]->Pages[pte]) return NULL;
|
||||
|
||||
return (pd->Tables[pde]->Pages[pte] & PageFrame);
|
||||
}
|
||||
|
@ -6,103 +6,89 @@
|
||||
*/
|
||||
#include <memory-add.h>
|
||||
|
||||
uint32* FrameMap;
|
||||
uint32 TotalFrames;
|
||||
uint32* BlockMap;
|
||||
uint32 TotalBlocks;
|
||||
uint32 TotalMemory;
|
||||
uint32 UsedFrames;
|
||||
uint32 UsedBlocks;
|
||||
|
||||
inline void ConvertIndexToFrame (uint32 index, uint32* address, uint32* offset)
|
||||
inline void ConvertIndexToBlock (uint32 index, uint32* address, uint32* offset)
|
||||
{
|
||||
*address = (index >> 5);
|
||||
*offset = index & 0x1f;
|
||||
}
|
||||
|
||||
inline uint32 ConvertFrameToIndex (uint32 address, uint32 offset)
|
||||
inline uint32 ConvertBlockToIndex (uint32 address, uint32 offset)
|
||||
{
|
||||
return (address<<5) | offset;
|
||||
}
|
||||
|
||||
void MemPhSetFrame (uint32 frame, uint8 value)
|
||||
void MemPhSetBlock (uint32 Block, uint8 value)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
ConvertIndexToBlock(Block, &addr, &off);
|
||||
|
||||
if (value) {
|
||||
if ((FrameMap[addr] & (1<<off)) == 0) UsedFrames++;
|
||||
FrameMap[addr] |= 1<<off;
|
||||
if ((BlockMap[addr] & (1<<off)) == 0) UsedBlocks++;
|
||||
BlockMap[addr] |= 1<<off;
|
||||
}
|
||||
|
||||
else {
|
||||
if (FrameMap[addr] & (1<<off)) UsedFrames--;
|
||||
FrameMap[addr] &= ~(1<<off);
|
||||
if (BlockMap[addr] & (1<<off)) UsedBlocks--;
|
||||
BlockMap[addr] &= ~(1<<off);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 MemPhGetFrame (uint32 frame)
|
||||
uint32 MemPhGetBlock (uint32 Block)
|
||||
{
|
||||
uint32 addr, off;
|
||||
ConvertIndexToFrame(frame, &addr, &off);
|
||||
ConvertIndexToBlock(Block, &addr, &off);
|
||||
|
||||
return FrameMap[addr] & (1<<off);
|
||||
return BlockMap[addr] & (1<<off);
|
||||
}
|
||||
|
||||
uint32 MemPhFindFreeFrame()
|
||||
uint32 MemPhAllocateBlock()
|
||||
{
|
||||
uint32 addr, pos;
|
||||
|
||||
for (addr = 0; addr < TotalFrames >> 5; addr++)
|
||||
if (FrameMap[addr] != 0xffffffff)
|
||||
for (addr = 0; addr < TotalBlocks >> 5; addr++)
|
||||
if (BlockMap[addr] != 0xffffffff)
|
||||
{
|
||||
for (pos = 0; (FrameMap[addr] & (1<<pos)) != 0; pos++) ;
|
||||
for (pos = 0; (BlockMap[addr] & (1<<pos)) != 0; pos++) ;
|
||||
|
||||
return ConvertFrameToIndex(addr, pos);
|
||||
uint32 index = ConvertBlockToIndex(addr, pos);
|
||||
MemPhSetBlock(index, 1);
|
||||
|
||||
// Return address
|
||||
return (index<<12);
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
void MemPhAllocFrame(Page* page, uint8 isKernel, uint8 isWriteable)
|
||||
void MemPhFreeBlock(uint32 addr)
|
||||
{
|
||||
if ((*page & PageFrame) != 0) return;
|
||||
uint32 Block = addr >> 12;
|
||||
if (!Block) return;
|
||||
|
||||
uint32 free = MemPhFindFreeFrame();
|
||||
if (free == 0xffffffff) {
|
||||
Panic("Mem", "%#Failed allocation free=0x%x page=0x%x\n", ColorRed, free, *page);
|
||||
return;
|
||||
}
|
||||
|
||||
MemPhSetFrame(free, 1);
|
||||
*page |= PagePresent;
|
||||
*page |= (isKernel) ? 0 : PageUser;
|
||||
*page |= (isWriteable) ? PageWriteable : 0;
|
||||
*page |= (free<<12) & PageFrame;
|
||||
}
|
||||
|
||||
void MemPhFreeFrame(Page* page)
|
||||
{
|
||||
uint32 frame = *page & PageFrame;
|
||||
if (!frame) return;
|
||||
|
||||
MemPhSetFrame(frame, 0);
|
||||
*page &= ~PageFrame;
|
||||
MemPhSetBlock(Block, 0);
|
||||
}
|
||||
|
||||
void MemPhInitialize(uint32 SystemMemoryKb)
|
||||
{
|
||||
TotalFrames = SystemMemoryKb >> 2;
|
||||
TotalBlocks = SystemMemoryKb >> 2;
|
||||
TotalMemory = SystemMemoryKb;
|
||||
|
||||
FrameMap = (uint32*) kmalloc(sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
memset(FrameMap, 0, sizeof(uint32) * (1 + (TotalFrames>>5)));
|
||||
BlockMap = (uint32*) kmalloc(sizeof(uint32) * (1 + (TotalBlocks>>5)));
|
||||
memset(BlockMap, 0, sizeof(uint32) * (1 + (TotalBlocks>>5)));
|
||||
Log("Mem", "%#Started physical memory manager ok!, found %ukb\n", ColorLightGreen, SystemMemoryKb);
|
||||
}
|
||||
|
||||
void MemPhReserveFrames (uint32 address, uint32 length)
|
||||
void MemPhReserveBlocks (uint32 address, uint32 length)
|
||||
{
|
||||
address >>= 12;
|
||||
length = (length>>12) + ((length & 0xfff) > 0);
|
||||
uint32 end = address + length;
|
||||
|
||||
for (; address < end ; address++)
|
||||
MemPhSetFrame(address, 1);
|
||||
MemPhSetBlock(address, 1);
|
||||
}
|
||||
|
Reference in New Issue
Block a user