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:
@@ -1,4 +1,6 @@
|
||||
#include "pageallocator.h"
|
||||
#include "mmgr.h"
|
||||
#include "allocator.h"
|
||||
#include "types/status.h"
|
||||
|
||||
physaddr_t reserve_page(struct page_stack_t *stack)
|
||||
@@ -15,12 +17,25 @@ physaddr_t reserve_page(struct page_stack_t *stack)
|
||||
|
||||
int free_page(struct page_stack_t *stack, physaddr_t location)
|
||||
{
|
||||
void *new_limit;
|
||||
if(stack->stack_pointer > stack->limit_pointer)
|
||||
{
|
||||
stack->stack_pointer--;
|
||||
*stack->stack_pointer = location;
|
||||
return S_OK;
|
||||
}
|
||||
else if((new_limit = allocate_from_top(page_size)) != NULL)
|
||||
{
|
||||
switch(map_page(stack, new_limit, location, PAGE_RW))
|
||||
{
|
||||
case S_OUT_OF_MEMORY:
|
||||
return S_OUT_OF_MEMORY;
|
||||
case S_OUT_OF_BOUNDS:
|
||||
return S_OUT_OF_BOUNDS;
|
||||
case S_OK:
|
||||
stack->limit_pointer = new_limit;
|
||||
}
|
||||
}
|
||||
return S_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -29,7 +44,7 @@ size_t free_page_count(struct page_stack_t *stack)
|
||||
return stack->base_pointer - stack->stack_pointer;
|
||||
}
|
||||
|
||||
int initialize_page_stack(struct page_stack_t *stack, struct memory_map_t *map, size_t page_size)
|
||||
int initialize_page_stack(struct page_stack_t *stack, struct memory_map_t *map)
|
||||
{
|
||||
stack->total_pages = 0;
|
||||
for(int i = 0; i < map->size; i++)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user