diff --git a/include/pageallocator.h b/include/pageallocator.h index 5b52d54..3bb71d3 100644 --- a/include/pageallocator.h +++ b/include/pageallocator.h @@ -72,4 +72,4 @@ size_t free_page_count(struct page_stack_t *stack); * @param stack * @param map */ -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); diff --git a/include/stdio.h b/include/stdio.h index 3c086ee..e669124 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -2,6 +2,8 @@ #include +int initialize_screen(); + int putchar(int c); int puts(const char *str); diff --git a/src/pageallocator.c b/src/pageallocator.c index 6289809..51135bf 100644 --- a/src/pageallocator.c +++ b/src/pageallocator.c @@ -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++) diff --git a/src/x86/apic.c b/src/x86/apic.c index 32d6b84..9698e55 100644 --- a/src/x86/apic.c +++ b/src/x86/apic.c @@ -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; } diff --git a/src/x86/entry.S b/src/x86/entry.S index bb4a2ed..24aad6a 100755 --- a/src/x86/entry.S +++ b/src/x86/entry.S @@ -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 diff --git a/src/x86/linker.ld b/src/x86/linker.ld index bf01f37..f13451d 100755 --- a/src/x86/linker.ld +++ b/src/x86/linker.ld @@ -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); } diff --git a/src/x86/mmgr.c b/src/x86/mmgr.c index c4edb6a..572abc2 100644 --- a/src/x86/mmgr.c +++ b/src/x86/mmgr.c @@ -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); diff --git a/src/x86/multiboot2.c b/src/x86/multiboot2.c index c692b5f..c8fff69 100644 --- a/src/x86/multiboot2.c +++ b/src/x86/multiboot2.c @@ -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); diff --git a/src/x86/putc.c b/src/x86/putc.c index 854751f..fad6f72 100644 --- a/src/x86/putc.c +++ b/src/x86/putc.c @@ -1,4 +1,6 @@ #include "stdio.h" +#include "mmgr.h" +#include "allocator.h" #include 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) diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 31fb801..7f8d281 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.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 #include +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;