Implement Allocator. Add virtual page map. Fix PageMap class.
This commit is contained in:
parent
f2e09e98a7
commit
e6e156e255
@ -33,7 +33,7 @@ void memset(uint8_t* base, uint32_t count, uint8_t to) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mark_unavailble(uint32_t address, uint32_t size) {
|
void mark_unavailble(uint32_t address, uint32_t size, uint8_t* buffer) {
|
||||||
// This function takes an address and length and marks the corresponding pages as unavailable.
|
// This function takes an address and length and marks the corresponding pages as unavailable.
|
||||||
address -= address % 4096;
|
address -= address % 4096;
|
||||||
if (size % 4096)
|
if (size % 4096)
|
||||||
@ -43,7 +43,7 @@ void mark_unavailble(uint32_t address, uint32_t size) {
|
|||||||
size /= 4096;
|
size /= 4096;
|
||||||
|
|
||||||
for (int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) {
|
||||||
unset_bit(address + i, bitmap);
|
unset_bit(address + i, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_unavailble(bitmap, 0x20000);
|
mark_unavailble(bitmap, 0x20000, bitmap);
|
||||||
|
|
||||||
// Page Directory
|
// Page Directory
|
||||||
PDE* kernel_page_directory = bitmap + 0x20000;
|
PDE* kernel_page_directory = bitmap + 0x20000;
|
||||||
@ -140,22 +140,39 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark unavailable bitmap to 0x522000
|
// Mark unavailable bitmap to 0x522000
|
||||||
mark_unavailble(bitmap, 0x4000000);
|
mark_unavailble(bitmap, 0x4000000, bitmap);
|
||||||
|
|
||||||
// Now we want to map some stuff.
|
// Now we want to map some stuff.
|
||||||
// But first, we should load the kernel somewhere
|
// But first, we should load the kernel somewhere
|
||||||
|
|
||||||
uint8_t* kernel_location = 0x522000; // Just load it at 0x522000 for now
|
|
||||||
mark_unavailble(0x522000, 32768); // Just treat the kernel as not growing beyong 32k for now.
|
|
||||||
|
|
||||||
map_many_4k_phys_to_virt(0x522000, 0xc0000000, kernel_page_directory, kernel_page_tables, 8); // Map 8 pages from 0x522000 to 0xc0000000;
|
|
||||||
|
uint8_t* kernel_location = 0x542000; // Just load it at 0x522000 for now
|
||||||
|
mark_unavailble(kernel_location, 32768, bitmap); // Just treat the kernel as not growing beyong 32k for now.
|
||||||
|
|
||||||
|
map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 8); // Map 8 pages from 0x522000 to 0xc0000000;
|
||||||
map_4k_phys_to_virt((uint32_t)kernel_page_directory, 0xc0100000, kernel_page_directory, kernel_page_tables); // Map the page directory to 0xc0100000
|
map_4k_phys_to_virt((uint32_t)kernel_page_directory, 0xc0100000, kernel_page_directory, kernel_page_tables); // Map the page directory to 0xc0100000
|
||||||
map_many_4k_phys_to_virt(0x121000, 0xc0101000, kernel_page_directory, kernel_page_tables, 1024); // Map 1024 pages from 0x121000 to 0xc0101000
|
map_many_4k_phys_to_virt(0x121000, 0xc0101000, kernel_page_directory, kernel_page_tables, 1024); // Map 1024 pages from 0x121000 to 0xc0101000
|
||||||
map_4k_phys_to_virt(0xb8000, 0xc0501000, kernel_page_directory, kernel_page_tables); // Map 0xb8000 (video) to 0xc0501000
|
map_4k_phys_to_virt(0xb8000, 0xc0501000, kernel_page_directory, kernel_page_tables); // Map 0xb8000 (video) to 0xc0501000
|
||||||
map_4k_phys_to_virt(0x521000, 0xc0502000, kernel_page_directory, kernel_page_tables); // Map the PTE** data, we'll need to convert the pointers to point at kernel space at some point.
|
map_4k_phys_to_virt(0x521000, 0xc0502000, kernel_page_directory, kernel_page_tables); // Map the PTE** data, we'll need to convert the pointers to point at kernel space at some point.
|
||||||
|
|
||||||
|
uint8_t* vm_bitmap = 0x522000;
|
||||||
|
|
||||||
|
memset(vm_bitmap, 0x20000, 0xff);
|
||||||
|
|
||||||
|
mark_unavailble(0xc0000000, 0x8000, vm_bitmap);
|
||||||
|
mark_unavailble(0xc0100000, 0x1000, vm_bitmap);
|
||||||
|
mark_unavailble(0xc0101000, 0x400000, vm_bitmap);
|
||||||
|
mark_unavailble(0xc0501000, 0x1000, vm_bitmap);
|
||||||
|
mark_unavailble(0xc0502000, 0x1000, vm_bitmap);
|
||||||
|
mark_unavailble(0xc0600000, 0x20000, vm_bitmap);
|
||||||
|
mark_unavailble(0xc0620000, 0x20000, vm_bitmap);
|
||||||
|
mark_unavailble(0x8a000, 0x6000, vm_bitmap);
|
||||||
|
|
||||||
// Map the bitmap
|
// Map the bitmap
|
||||||
map_many_4k_phys_to_virt(0x100000, 0xc0600000, kernel_page_directory, kernel_page_tables, 32);
|
map_many_4k_phys_to_virt(0x100000, 0xc0600000, kernel_page_directory, kernel_page_tables, 32);
|
||||||
|
// Map the virtual memory bitmap
|
||||||
|
map_many_4k_phys_to_virt(0x522000, 0xc0620000, kernel_page_directory, kernel_page_tables, 32);
|
||||||
|
|
||||||
map_4k_phys_to_virt(0x8000, 0x8000, kernel_page_directory, kernel_page_tables);
|
map_4k_phys_to_virt(0x8000, 0x8000, kernel_page_directory, kernel_page_tables);
|
||||||
map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 6);
|
map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 6);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[BITS 32]
|
[BITS 32]
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
call main
|
jmp main
|
||||||
|
|
||||||
extern main
|
extern main
|
@ -15,9 +15,16 @@ int main() {
|
|||||||
|
|
||||||
PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000);
|
PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000);
|
||||||
kernel_pd.select();
|
kernel_pd.select();
|
||||||
kernel_pd.map(0x0, 0x400000);
|
|
||||||
kernel_pd.unmap(0x8000);
|
kernel_pd.unmap(0x8000);
|
||||||
|
|
||||||
|
PageMap phys_pm(0xc0600000);
|
||||||
|
PageMap virt_pm(0xc0620000);
|
||||||
|
|
||||||
|
Allocator kernel_allocator = Allocator(&kernel_pd, &phys_pm, &virt_pm, 0xd0000000);
|
||||||
|
|
||||||
|
void* alloc = kernel_allocator.allocate(4096);
|
||||||
|
void* alloc2 = kernel_allocator.allocate(4096);
|
||||||
|
|
||||||
init_idt();
|
init_idt();
|
||||||
init_term();
|
init_term();
|
||||||
|
|
||||||
@ -25,6 +32,8 @@ int main() {
|
|||||||
|
|
||||||
printf("KERNEL OK!\n");
|
printf("KERNEL OK!\n");
|
||||||
|
|
||||||
|
printf("Alloc: %x\nAlloc2: %x\n", alloc, alloc2);
|
||||||
|
|
||||||
init_keyboard();
|
init_keyboard();
|
||||||
|
|
||||||
enable_idt();
|
enable_idt();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "screenstuff.h"
|
||||||
|
|
||||||
void memset(uint8_t* address, uint32_t count, uint8_t value) {
|
void memset(uint8_t* address, uint32_t count, uint8_t value) {
|
||||||
for (int i=0; i<count; i++)
|
for (int i=0; i<count; i++)
|
||||||
@ -10,6 +11,10 @@ void memcpy(uint8_t* src, uint8_t* dst, uint32_t count) {
|
|||||||
dst[i] = src[i];
|
dst[i] = src[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageMap::PageMap(uint32_t map) {
|
||||||
|
this->pagemap = (uint8_t*)map;
|
||||||
|
}
|
||||||
|
|
||||||
void PageMap::set_bit(uint32_t index) {
|
void PageMap::set_bit(uint32_t index) {
|
||||||
uint32_t offset = index % 8;
|
uint32_t offset = index % 8;
|
||||||
uint32_t i = index / 8;
|
uint32_t i = index / 8;
|
||||||
@ -50,7 +55,7 @@ void PageMap::mark_available(uint32_t address, uint32_t count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PageMap::available(uint32_t address) {
|
bool PageMap::available(uint32_t address) {
|
||||||
return bit_set(address >> 4096);
|
return bit_set(address >> 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t PageMap::find_next_available_from(uint32_t address) {
|
uint32_t PageMap::find_next_available_from(uint32_t address) {
|
||||||
@ -64,7 +69,7 @@ uint32_t PageMap::find_next_available_from(uint32_t address, uint32_t count) {
|
|||||||
while (!available(address)) address += 4096;
|
while (!available(address)) address += 4096;
|
||||||
|
|
||||||
for (int a=address, i=0; i<count; i++, a+=4096)
|
for (int a=address, i=0; i<count; i++, a+=4096)
|
||||||
if (!available(address))
|
if (!available(a))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
@ -162,22 +167,27 @@ void PageDirectory::select() {
|
|||||||
|
|
||||||
PageMap* Allocator::phys;
|
PageMap* Allocator::phys;
|
||||||
|
|
||||||
Allocator::Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt) {
|
Allocator::Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base) {
|
||||||
PD = page_directory;
|
this->PD = page_directory;
|
||||||
phys = phys;
|
this->phys = phys;
|
||||||
virt = virt;
|
this->virt = virt;
|
||||||
|
|
||||||
remaining = 0;
|
this->virt_alloc_base = virt_alloc_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Allocator::allocate() {
|
void* Allocator::allocate(uint32_t size) {
|
||||||
uint32_t phys_addr = phys->find_next_available_from(0);
|
uint32_t count = (size + (4096%size)) / 4096;
|
||||||
uint32_t virt_addr = virt->find_next_available_from(virt_alloc_base);
|
|
||||||
|
|
||||||
phys->mark_unavailable(phys_addr);
|
uint32_t virt_addr = virt->find_next_available_from(this->virt_alloc_base, count);
|
||||||
virt->mark_unavailable(virt_addr);
|
this->virt->mark_unavailable(virt_addr, count);
|
||||||
|
|
||||||
PD->map(phys, virt);
|
for (int i=0; i<count; i++) {
|
||||||
|
uint32_t phys_addr = this->phys->find_next_available_from(0);
|
||||||
|
this->phys->mark_unavailable(phys_addr);
|
||||||
|
this->PD->map(phys_addr, virt_addr + 4096 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return virt_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Allocator::deallocate(uint32_t virt_addr) {
|
void Allocator::deallocate(uint32_t virt_addr) {
|
||||||
|
@ -11,7 +11,7 @@ void memcpy(uint8_t* src, uint8_t* dst, uint32_t count);
|
|||||||
|
|
||||||
class __attribute__((packed)) PageMap {
|
class __attribute__((packed)) PageMap {
|
||||||
private:
|
private:
|
||||||
uint8_t pagemap[1024^2 / 8];
|
uint8_t* pagemap;
|
||||||
|
|
||||||
void set_bit(uint32_t index);
|
void set_bit(uint32_t index);
|
||||||
void unset_bit(uint32_t index);
|
void unset_bit(uint32_t index);
|
||||||
@ -19,7 +19,7 @@ private:
|
|||||||
bool bit_set(uint32_t index);
|
bool bit_set(uint32_t index);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageMap(uint8_t* map);
|
PageMap(uint32_t map);
|
||||||
|
|
||||||
void mark_unavailable(uint32_t address);
|
void mark_unavailable(uint32_t address);
|
||||||
void mark_unavailable(uint32_t address, uint32_t count);
|
void mark_unavailable(uint32_t address, uint32_t count);
|
||||||
@ -73,16 +73,16 @@ protected:
|
|||||||
|
|
||||||
PageDirectory* PD;
|
PageDirectory* PD;
|
||||||
|
|
||||||
uint32_t current_alloc_address;
|
|
||||||
uint32_t remaining;
|
|
||||||
|
|
||||||
uint32_t virt_alloc_base;
|
uint32_t virt_alloc_base;
|
||||||
public:
|
public:
|
||||||
Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt);
|
Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
|
||||||
virtual void* allocate();
|
virtual void* allocate(uint32_t size);
|
||||||
virtual void deallocate(uint32_t virt_addr);
|
virtual void deallocate(uint32_t virt_addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void* operator new (uint32_t size, Allocator* allocator);
|
||||||
|
void operator delete (void* ptr, Allocator* allocator);
|
||||||
|
|
||||||
class Process : protected Allocator {
|
class Process : protected Allocator {
|
||||||
private:
|
private:
|
||||||
uint32_t PID;
|
uint32_t PID;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user