Implement Allocator. Add virtual page map. Fix PageMap class.

This commit is contained in:
Xnoe 2021-10-25 16:29:53 +01:00
parent f2e09e98a7
commit e6e156e255
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
5 changed files with 65 additions and 29 deletions

View File

@ -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);

View File

@ -1,6 +1,6 @@
[BITS 32] [BITS 32]
_start: _start:
call main jmp main
extern main extern main

View File

@ -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();

View File

@ -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) {

View File

@ -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;