Improved kernel memory usage

Moved base linear address to 0xFF800000
Kernel only reserves the page frames it actually needs
Memory for multiboot2 headers is freed
Video memory and APIC registers are dynamically mapped into linear addresses
This commit is contained in:
2021-04-17 03:45:45 -05:00
parent b141582f40
commit 961139df9e
10 changed files with 91 additions and 57 deletions

View File

@@ -1,4 +1,5 @@
#include "mmgr.h"
#include "allocator.h"
#include "apic.h"
#include "msr.h"
#include "stdio.h"
@@ -33,9 +34,9 @@ void apic_enable(struct page_stact_t *page_stack)
);
struct msr_apic_base_t msr;
read_msr(MSR_APIC_BASE, (uint64_t*)&msr);
map_page(page_stack, &_kernel_end, msr.apic_base << 12, PAGE_RW);
apic_registers = (struct apic_registers_t*)allocate_from_bottom(page_size);
map_page(page_stack, apic_registers, msr.apic_base << 12, PAGE_RW);
printf("MSR_APIC_BASE: %016x\n", *((uint32_t*)&msr));
apic_registers = (struct apic_registers_t*)&_kernel_end;
apic_registers->spurious_iv.value = apic_registers->spurious_iv.value | 0x100;
}

View File

@@ -30,7 +30,7 @@
.set tagEntryType, 3
.set tagEntrySize, 12
.set tagEntryAddress, _start - (0xFF900000 - 0x100000)
.set tagEntryAddress, _start - (0xFF800000 - 0x100000)
.set tagModuleAlignType, 6
.set tagModuleAlignSize, 8
@@ -108,19 +108,6 @@ _tempIdentityMap:
.skip 4096
_tempPgTable:
.skip 4096
_bootCmdLine:
.skip 64
.align 64
.global system_info
system_info:
.skip 16
.align 64
.global memory_map
memory_map:
.skip 16 * 16
.section .text
.global _start
@@ -152,13 +139,22 @@ _start:
sub $BASE_DIFF, %eax
push %eax
# Push ending physical address to map
mov (%ebx), %eax
add %ebx, %eax
push %eax
# Push starting physical address to map
mov $PHYSICAL_BASE, %eax
push %eax
# Load physical address of startPaging()
mov $start_paging, %eax
sub $BASE_DIFF, %eax
# Initialize paging
call *%eax
# Jump into mapped kernel binary
lea 1f, %eax
jmp *%eax
@@ -173,7 +169,7 @@ _start:
# Change EBX to point to the virtual address of the multiboot info
# If the new pointer is out-of-bounds, error
add $0xFF800000, %ebx
add $0xFF700000, %ebx
cmp $0xFF800000, %ebx
jl .err
cmp $0xFFC00000, %ebx

View File

@@ -2,7 +2,7 @@ ENTRY(_start)
SECTIONS
{
. = 0xFF900000;
. = 0xFF800000;
VIRTUAL_BASE = .;
PHYSICAL_BASE = 0x100000;
BASE_DIFF = VIRTUAL_BASE - PHYSICAL_BASE;
@@ -34,9 +34,8 @@ SECTIONS
BSS_END = ADDR(.bss) + SIZEOF(.bss) - (VIRTUAL_BASE - PHYSICAL_BASE);
IMAGE_SIZE = ((BSS_END - LOAD_START) + (4096 - ((BSS_END - LOAD_START) % 4096))) / 4096;
_pageMapLocation = 0xFF800000;
_heapLocation = 0xFFB00000;
_heapSize = 0x100000;
_kernelStart = VIRTUAL_BASE;
_kernel_pstart = PHYSICAL_BASE;
_kernel_pend = PHYSICAL_BASE + (4096 * IMAGE_SIZE);
_kernel_start = VIRTUAL_BASE;
_kernel_end = VIRTUAL_BASE + (4096 * IMAGE_SIZE);
}

View File

@@ -28,6 +28,34 @@ struct page_table_entry_t *page_tables = (struct page_table_entry_t *)0xFFC00000
struct page_table_entry_t *page_directory = (struct page_table_entry_t *)0xFFFFF000;
int start_paging(physaddr_t start, physaddr_t end, uint32_t *directory, uint32_t *table, uint32_t *identity_table)
{
physaddr_t p = start;
size_t count = 0;
while(p < end)
{
uint32_t table_entry = p + 3;
int index = p / page_size;
table[index - start / page_size] = table_entry;
identity_table[index] = table_entry;
p += page_size;
count++;
}
directory[0] = ((uint32_t)identity_table) + 3;
directory[1022] = ((uint32_t)table) + 3;
directory[1023] = ((uint32_t)directory) + 3;
asm("mov %0, %%cr3"
:
: "r"(directory));
asm("mov %%cr0, %%eax \n"
"or $0x80010000, %%eax \n"
"mov %%eax, %%cr0"
:
:
: "eax");
return count;
}
physaddr_t create_address_space(struct page_stack_t *page_stack)
{
physaddr_t table = reserve_page(page_stack);

View File

@@ -36,10 +36,6 @@ void *read_multiboot_table(struct boot_info_t *boot_info, void *table)
M_UNAVAILABLE);
boot_info->module_count++;
}
else
{
printf("WARNING: Too many modules, must skip one.\n");
}
break;
case MB_BOOT_COMMAND:
strcpy(boot_info->parameters, &((struct multiboot2_string_t*) table)->str);

View File

@@ -1,4 +1,6 @@
#include "stdio.h"
#include "mmgr.h"
#include "allocator.h"
#include <stddef.h>
enum vga_color_t {
@@ -28,12 +30,18 @@ struct cell_t
char bg : 4;
};
struct cell_t *screen = (struct cell_t*)0xFF8B8000;
struct cell_t *screen = (struct cell_t*)NULL;
size_t cursor = 0;
const size_t tab_width = 4;
const size_t line_width = 80;
int initialize_screen()
{
screen = allocate_from_bottom(page_size);
map_page(NULL, screen, 0x000B8000, PAGE_RW);
}
int putchar(int c)
{
switch(c)

View File

@@ -1,5 +1,7 @@
#include "kernel.h"
#include "pageallocator.h"
#include "allocator.h"
#include "mmgr.h"
#include "multiboot2.h"
#include "memorymap.h"
#include "apic.h"
@@ -11,38 +13,18 @@
#include <stdint.h>
#include <stddef.h>
extern int _kernel_pstart;
extern int _kernel_pend;
extern int _kernel_start;
extern int _kernel_end;
struct kernel_t kernel_state;
int start_paging(uint32_t *directory, uint32_t *table, uint32_t *identityTable)
{
for (int i = 0; i < 1024; i++)
{
uint32_t pte = i * 4096 + 3;
table[i] = pte;
identityTable[i] = pte;
}
directory[0] = ((uint32_t)identityTable) + 3;
directory[1022] = ((uint32_t)table) + 3;
directory[1023] = ((uint32_t)directory) + 3;
asm("mov %0, %%cr3"
:
: "r"(directory));
asm("mov %%cr0, %%eax \n"
"or $0x80010000, %%eax \n"
"mov %%eax, %%cr0"
:
:
: "eax");
return 0;
}
int initialize(void *multiboot_info)
{
initialize_gdt();
initialize_idt();
printf("***%s***\n", PACKAGE_STRING);
initialize_allocator(&_kernel_end, (void*)0xFFC00000);
static struct page_stack_t page_stack;
struct memory_region_t map_array[16];
char bootloader_name[64];
@@ -55,12 +37,19 @@ int initialize(void *multiboot_info)
.array = map_array,
.size = 0,
.capacity = 16}};
void *multiboot_end = multiboot_info + *(uint32_t*)multiboot_info;
multiboot_info += 8;
while (multiboot_info != NULL)
{
multiboot_info = read_multiboot_table(&boot_info, multiboot_info);
}
insert_region(&boot_info.map, 0, 1 << 22, M_UNAVAILABLE);
insert_region(&boot_info.map, (physaddr_t)&_kernel_pstart, (physaddr_t)&_kernel_pend, M_UNAVAILABLE);
for(void *p = (void*)&_kernel_end; p < multiboot_end; p += page_size)
{
unmap_page(p);
}
initialize_screen();
printf("***%s***\n", PACKAGE_STRING);
printf("Type\t\tLocation\t\tSize\n");
for (size_t i = 0; i < boot_info.map.size && boot_info.map.array[i].size > 0; i++)
{
@@ -68,8 +57,8 @@ int initialize(void *multiboot_info)
}
page_stack.base_pointer = (physaddr_t*)0xFFC00000;
page_stack.stack_pointer = (physaddr_t*)0xFFC00000;
page_stack.limit_pointer = (physaddr_t*)0xFF900000;
initialize_page_stack(&page_stack, &boot_info.map, 4096);
page_stack.limit_pointer = (physaddr_t*)0xFFC00000;
initialize_page_stack(&page_stack, &boot_info.map);
apic_enable(page_stack);
apic_registers->divide_config.value = APIC_DIVIDE_128;
apic_registers->lvt_timer.vector = ISR_APIC_TIMER;