Compare commits
4 Commits
83bcac7a16
...
1b41a3e9cf
Author | SHA1 | Date | |
---|---|---|---|
1b41a3e9cf | |||
c886669d56 | |||
d96cb73995 | |||
847f2b4f4c |
@ -199,8 +199,8 @@ static IDTEntry idt[256];
|
||||
|
||||
struct IDTR
|
||||
{
|
||||
uint16_t limit;
|
||||
uint64_t offset;
|
||||
u16 limit;
|
||||
u64 offset;
|
||||
} __attribute__((packed));
|
||||
|
||||
static void idt_add_handler(short num, void* handler, u8 type_attr)
|
||||
|
@ -196,7 +196,7 @@ namespace MMU
|
||||
auto& l4 = l4_entry(virt);
|
||||
if (!l4.present)
|
||||
{
|
||||
u64 addr = TRY(MemoryManager::alloc_physical_page());
|
||||
u64 addr = TRY(MemoryManager::alloc_frame());
|
||||
l4.present = true;
|
||||
l4.set_address(addr);
|
||||
memset(l3_table(virt), 0, PAGE_SIZE);
|
||||
@ -208,7 +208,7 @@ namespace MMU
|
||||
auto& l3 = l3_entry(virt);
|
||||
if (!l3.present)
|
||||
{
|
||||
u64 addr = TRY(MemoryManager::alloc_physical_page());
|
||||
u64 addr = TRY(MemoryManager::alloc_frame());
|
||||
l3.present = true;
|
||||
l3.set_address(addr);
|
||||
memset(l2_table(virt), 0, PAGE_SIZE);
|
||||
@ -222,7 +222,7 @@ namespace MMU
|
||||
auto& l2 = l2_entry(virt);
|
||||
if (!l2.present)
|
||||
{
|
||||
u64 addr = TRY(MemoryManager::alloc_physical_page());
|
||||
u64 addr = TRY(MemoryManager::alloc_frame());
|
||||
l2.present = true;
|
||||
l2.set_address(addr);
|
||||
memset(l1_table(virt), 0, PAGE_SIZE);
|
||||
|
@ -8,9 +8,9 @@ const usize ARCH_TIMER_FREQ = 10;
|
||||
|
||||
void Timer::arch_init()
|
||||
{
|
||||
constexpr u16 divisor = (uint16_t)(base_frequency / (ARCH_TIMER_FREQ * 1000));
|
||||
constexpr u16 divisor = (u16)(base_frequency / (ARCH_TIMER_FREQ * 1000));
|
||||
static_assert(divisor >= 100);
|
||||
IO::outb(PIT_CHANNEL_0, (uint8_t)(divisor & 0xFF));
|
||||
IO::outb(PIT_CHANNEL_0, (u8)(divisor & 0xFF));
|
||||
IO::outb(0x80, 0); // short delay
|
||||
IO::outb(PIT_CHANNEL_0, (uint8_t)((divisor & 0xFF00) >> 8));
|
||||
IO::outb(PIT_CHANNEL_0, (u8)((divisor & 0xFF00) >> 8));
|
||||
}
|
@ -29,7 +29,7 @@ extern "C" [[noreturn]] void _start()
|
||||
|
||||
Serial::printf("Mapping address 0x%lx\n", address);
|
||||
|
||||
u64 physical = MemoryManager::alloc_physical_page().release_value();
|
||||
u64 physical = MemoryManager::alloc_frame().release_value();
|
||||
|
||||
Serial::printf("Allocated physical frame %#lx\n", physical);
|
||||
|
||||
|
@ -33,20 +33,24 @@ static bool page_bitmap_read(u64 index)
|
||||
|
||||
static void page_bitmap_set(u64 index, bool value)
|
||||
{
|
||||
uint64_t byteIndex = index / 8;
|
||||
uint8_t bitIndexer = 0b10000000 >> (index % 8);
|
||||
page_virtual_bitmap_addr[byteIndex] &= (uint8_t)(~bitIndexer);
|
||||
if (value) { page_virtual_bitmap_addr[byteIndex] |= bitIndexer; }
|
||||
u64 byte_index = index / 8;
|
||||
u8 mask = 0b10000000 >> (index % 8);
|
||||
page_virtual_bitmap_addr[byte_index] &= (u8)(~mask);
|
||||
if (value) { page_virtual_bitmap_addr[byte_index] |= mask; }
|
||||
}
|
||||
|
||||
#define CHECK_PAGE_ALIGNED(address) check(is_aligned(address, ARCH_PAGE_SIZE))
|
||||
|
||||
namespace MemoryManager
|
||||
{
|
||||
Result<void> protect_kernel_sections()
|
||||
{
|
||||
u64 rodata_pages = get_blocks_from_size((u64)(end_of_kernel_rodata - start_of_kernel_rodata), ARCH_PAGE_SIZE);
|
||||
const u64 rodata_size = (u64)(end_of_kernel_rodata - start_of_kernel_rodata);
|
||||
const u64 rodata_pages = get_blocks_from_size(rodata_size, ARCH_PAGE_SIZE);
|
||||
TRY(remap((u64)start_of_kernel_rodata, rodata_pages, MMU::NoExecute));
|
||||
|
||||
u64 data_pages = get_blocks_from_size((u64)(end_of_kernel_data - start_of_kernel_data), ARCH_PAGE_SIZE);
|
||||
const u64 data_size = (u64)(end_of_kernel_data - start_of_kernel_data);
|
||||
const u64 data_pages = get_blocks_from_size(data_size, ARCH_PAGE_SIZE);
|
||||
TRY(remap((u64)start_of_kernel_data, data_pages, MMU::NoExecute | MMU::ReadWrite));
|
||||
|
||||
return {};
|
||||
@ -61,7 +65,7 @@ namespace MemoryManager
|
||||
|
||||
// walk the memory map
|
||||
MMapEnt* ptr = &bootboot.mmap;
|
||||
uint64_t mmap_entries = (bootboot.size - 128) / 16;
|
||||
u64 mmap_entries = (bootboot.size - 128) / 16;
|
||||
for (u64 i = 0; i < mmap_entries; i++)
|
||||
{
|
||||
u64 size = MMapEnt_Size(ptr);
|
||||
@ -92,22 +96,19 @@ namespace MemoryManager
|
||||
memset(page_bitmap_addr, 0xFF, page_bitmap_size);
|
||||
|
||||
ptr = &bootboot.mmap;
|
||||
for (uint64_t i = 0; i < mmap_entries; i++)
|
||||
for (u64 i = 0; i < mmap_entries; i++)
|
||||
{
|
||||
uint64_t index = MMapEnt_Ptr(ptr) / ARCH_PAGE_SIZE;
|
||||
u64 index = MMapEnt_Ptr(ptr) / ARCH_PAGE_SIZE;
|
||||
if (!MMapEnt_IsFree(ptr)) { reserved_mem += MMapEnt_Size(ptr); }
|
||||
else
|
||||
{
|
||||
free_mem += MMapEnt_Size(ptr);
|
||||
for (uint64_t j = 0; j < (MMapEnt_Size(ptr) / ARCH_PAGE_SIZE); j++)
|
||||
{
|
||||
page_bitmap_set(index + j, false);
|
||||
}
|
||||
for (u64 j = 0; j < (MMapEnt_Size(ptr) / ARCH_PAGE_SIZE); j++) { page_bitmap_set(index + j, false); }
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
lock_pages((u64)page_bitmap_addr, page_bitmap_size / ARCH_PAGE_SIZE + 1);
|
||||
lock_frames((u64)page_bitmap_addr, page_bitmap_size / ARCH_PAGE_SIZE + 1);
|
||||
}
|
||||
|
||||
void init()
|
||||
@ -116,21 +117,21 @@ namespace MemoryManager
|
||||
MMU::setup_initial_page_directory();
|
||||
}
|
||||
|
||||
void lock_page(u64 page)
|
||||
void lock_frame(u64 frame)
|
||||
{
|
||||
uint64_t index = ((uint64_t)page) / ARCH_PAGE_SIZE;
|
||||
const u64 index = ((u64)frame) / ARCH_PAGE_SIZE;
|
||||
if (page_bitmap_read(index)) return;
|
||||
page_bitmap_set(index, true);
|
||||
used_mem += ARCH_PAGE_SIZE;
|
||||
free_mem -= ARCH_PAGE_SIZE;
|
||||
}
|
||||
|
||||
void lock_pages(u64 pages, u64 count)
|
||||
void lock_frames(u64 frames, u64 count)
|
||||
{
|
||||
for (u64 index = 0; index < count; index++) { lock_page(pages + (index * ARCH_PAGE_SIZE)); }
|
||||
for (u64 index = 0; index < count; index++) { lock_frame(frames + (index * ARCH_PAGE_SIZE)); }
|
||||
}
|
||||
|
||||
Result<u64> alloc_physical_page()
|
||||
Result<u64> alloc_frame()
|
||||
{
|
||||
for (u64 index = start_index; index < (page_bitmap_size * 8); index++)
|
||||
{
|
||||
@ -145,9 +146,9 @@ namespace MemoryManager
|
||||
return err; // FIXME: ENOMEM.
|
||||
}
|
||||
|
||||
Result<void> free_physical_page(u64 page)
|
||||
Result<void> free_frame(u64 frame)
|
||||
{
|
||||
u64 index = page / ARCH_PAGE_SIZE;
|
||||
const u64 index = frame / ARCH_PAGE_SIZE;
|
||||
if (index > (page_bitmap_size * 8)) return err;
|
||||
if (!page_bitmap_read(index)) return err;
|
||||
page_bitmap_set(index, false);
|
||||
@ -159,7 +160,7 @@ namespace MemoryManager
|
||||
|
||||
Result<void> remap(u64 address, usize count, int flags)
|
||||
{
|
||||
check(is_aligned(address, ARCH_PAGE_SIZE));
|
||||
CHECK_PAGE_ALIGNED(address);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
@ -170,6 +171,62 @@ namespace MemoryManager
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> map(u64 virt, u64 phys, usize count, int flags)
|
||||
{
|
||||
CHECK_PAGE_ALIGNED(virt);
|
||||
CHECK_PAGE_ALIGNED(phys);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
TRY(MMU::map(virt, phys, flags));
|
||||
virt += ARCH_PAGE_SIZE;
|
||||
phys += ARCH_PAGE_SIZE;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<u64> alloc_at(u64 virt, usize count, int flags)
|
||||
{
|
||||
CHECK_PAGE_ALIGNED(virt);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
u64 frame = TRY(alloc_frame());
|
||||
TRY(MMU::map(virt, frame, flags));
|
||||
virt += ARCH_PAGE_SIZE;
|
||||
}
|
||||
|
||||
return virt;
|
||||
}
|
||||
|
||||
Result<void> unmap_owned(u64 virt, usize count)
|
||||
{
|
||||
CHECK_PAGE_ALIGNED(virt);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
u64 frame = TRY(MMU::unmap(virt));
|
||||
TRY(free_frame(frame));
|
||||
virt += ARCH_PAGE_SIZE;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> unmap_weak(u64 virt, usize count)
|
||||
{
|
||||
CHECK_PAGE_ALIGNED(virt);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
TRY(MMU::unmap(virt));
|
||||
virt += ARCH_PAGE_SIZE;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> remap_unaligned(u64 address, usize count, int flags)
|
||||
{
|
||||
if (!is_aligned(address, ARCH_PAGE_SIZE)) count++;
|
||||
|
@ -8,11 +8,11 @@ namespace MemoryManager
|
||||
|
||||
Result<void> protect_kernel_sections();
|
||||
|
||||
Result<u64> alloc_physical_page();
|
||||
Result<void> free_physical_page(u64 page);
|
||||
Result<u64> alloc_frame();
|
||||
Result<void> free_frame(u64 frame);
|
||||
|
||||
void lock_page(u64 page);
|
||||
void lock_pages(u64 pages, u64 count);
|
||||
void lock_frame(u64 frame);
|
||||
void lock_frames(u64 frames, u64 count);
|
||||
|
||||
Result<void> remap(u64 address, usize count, int flags);
|
||||
Result<void> remap_unaligned(u64 address, usize count, int flags);
|
||||
@ -20,6 +20,13 @@ namespace MemoryManager
|
||||
bool validate_readable_page(u64 address);
|
||||
bool validate_writable_page(u64 address);
|
||||
|
||||
Result<void> map(u64 virt, u64 phys, usize count, int flags);
|
||||
|
||||
Result<u64> alloc_at(u64 virt, usize count, int flags);
|
||||
|
||||
Result<void> unmap_owned(u64 virt, usize count);
|
||||
Result<void> unmap_weak(u64 virt, usize count);
|
||||
|
||||
u64 free();
|
||||
u64 used();
|
||||
u64 reserved();
|
||||
|
Loading…
Reference in New Issue
Block a user