made the PMM work and a lot faster. Does not like OOM events, seemingly

This commit is contained in:
Morten Delenk 2017-07-20 18:51:52 +01:00
parent 886e585d80
commit bc5bf258a0
12 changed files with 43 additions and 22 deletions

View file

@ -30,6 +30,7 @@ SECTIONS {
}
.bss : {
*(.bss)
*(.bss.*)
*(COMMON)
}
kernel_end = .;

View file

@ -30,6 +30,7 @@ SECTIONS {
}
.bss : {
*(.bss)
*(.bss.*)
*(COMMON)
}
kernel_end = .;

View file

@ -30,6 +30,7 @@ SECTIONS {
}
.bss : {
*(.bss)
*(.bss.*)
*(COMMON)
}
kernel_end = .;

View file

@ -30,6 +30,7 @@ SECTIONS {
}
.bss : {
*(.bss)
*(.bss.*)
*(COMMON)
}
kernel_end = .;

View file

@ -28,5 +28,5 @@ void drivers_init() {
initIDT();
PIC::initPIC(0x20, 0x28);
asm volatile("sti");
asm volatile("int $0");
asm volatile("int $0x20");
}

View file

@ -1,3 +1,3 @@
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/x86_64/pc/include -O2")
SET(PLATFORM_C_FLAGS "-I../../kernel/arch/x86_64/pc/include -O0")
SET(PLATFORM_CXX_FLAGS "${PLATFORM_C_FLAGS}")
SET(PLATFORM_ASM_FLAGS "${PLATFORM_C_FLAGS}")

View file

@ -30,6 +30,7 @@ SECTIONS {
}
.bss : {
*(.bss)
*(.bss.*)
*(COMMON)
}
kernel_end = .;

View file

@ -1,12 +1,25 @@
#include "pmm.hpp"
PMM_MB::PMM_MB(multiboot_info_t *mb_info): PMM(0x1000), mb_info(mb_info) {}
PMM_MB::PMM_MB(multiboot_info_t *mb_info): PMM(0x1000), mb_info(mb_info) {
auto mmap = (multiboot_memory_map_t*)((uintptr_t)(mb_info->mmap_addr));
uint32_t count = mb_info->mmap_length / sizeof(mmap[0]);
for(uint32_t i=0;i<count;i++) {
if(mmap[i].type != MULTIBOOT_MEMORY_AVAILABLE)
continue;
if((phys_t)mmap[i].addr < lowest_page)
lowest_page = (phys_t)mmap[i].addr;
if((phys_t)(mmap[i].addr + mmap[i].len) > highest_page)
highest_page = (phys_t)(mmap[i].addr + mmap[i].len);
}
fill();
}
PMM_MB::~PMM_MB() {}
auto PMM_MB::isFree(phys_t addr) -> bool {
auto mmap = (multiboot_memory_map_t*)((uintptr_t)(mb_info->mmap_addr));
bool free=false;
for(uint32_t i=0;i<mb_info->mmap_length;i++) {
uint32_t count = mb_info->mmap_length / sizeof(mmap[0]);
for(uint32_t i=0;i<count;i++) {
if((mmap[i].addr > addr) || (mmap[i].addr + mmap[i].len < addr))
continue;
if(mmap[i].type != MULTIBOOT_MEMORY_AVAILABLE)

View file

@ -83,7 +83,6 @@ PMM_MMAP::PMM_MMAP(): PMM(0x1000) {
switch(tag.id) {
case 0:
case 1:
case 5:
break; //Ignored for now
case 2: //CPUARCH
if(tag.CPUARCH.value !=
@ -111,10 +110,19 @@ PMM_MMAP::PMM_MMAP(): PMM(0x1000) {
case 4:
bits = tag.BITS.value;
break;
case 5:
if(tag.REGION.permission != PERM::RWX)
break;
if(tag.REGION.start < lowest_page)
lowest_page = tag.REGION.start;
if(tag.REGION.end > highest_page)
highest_page = tag.REGION.end;
break;
default:
for(;;);
}
}
fill();
}
PMM_MMAP::~PMM_MMAP() {}
auto PMM_MMAP::isFree(phys_t addr) -> bool {
@ -125,7 +133,7 @@ auto PMM_MMAP::isFree(phys_t addr) -> bool {
off+=tag.size+2;
if(tag.id != 5)
continue;
if((tag.REGION.start > addr) || (tag.REGION.end < addr))
if((tag.REGION.start > addr) || (tag.REGION.end <= addr))
continue;
if(tag.REGION.permission == PERM::RWX)
return PMM::isFree(addr);

View file

@ -16,7 +16,10 @@ class PMM {
protected:
PMM_ent *head; ///< Head of the linked list
virtual auto isFree(phys_t addr) -> bool; ///< Returns true if the provided page is free to use
auto fill() -> void;
phys_t page_size; ///< Contains the size of a single memory page, in bytes
phys_t lowest_page;
phys_t highest_page;
public:
PMM(phys_t page_size);
virtual ~PMM();

View file

@ -12,5 +12,9 @@ void main() {
drivers_init();
*out << "Hello!\n";
*out << "テスト\n";
while(true) {
out->puti((*pmm, 1));
*out << "\n";
}
for (auto dtor = &start_dtors; dtor != &end_dtors; dtor++) (**dtor)();
}

View file

@ -7,28 +7,16 @@ auto PMM::isFree(phys_t addr) -> bool {
return false;
phys_t start = (phys_t)(&kernel_start);
phys_t end = (phys_t)(&kernel_end);
if((addr >= start) or (addr < end))
if((addr >= start) && (addr < end))
return false;
return true;
}
PMM::PMM(phys_t page_size): page_size(page_size), head(nullptr) {
#ifndef __x86_64__
for(phys_t i=page_size; i; i+=page_size) {
PMM::PMM(phys_t page_size): page_size(page_size), head(nullptr) {}
void PMM::fill() {
for(phys_t i=lowest_page; i<highest_page+1; i+=page_size) {
if(isFree(i))
*this << i;
}
#else
//Find out highest GB
phys_t top=0;
for(phys_t i=page_size; i<1024*1024*1024*1024; i+=1024*1024*1024) {
if(isFree(i))
top=i;
}
for(phys_t i=page_size; i < top; i+=page_size) {
if(isFree(i))
*this << i;
}
#endif
}
PMM::~PMM() {}