fixing up paging issues
This commit is contained in:
@@ -4,18 +4,38 @@
|
|||||||
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
|
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
|
||||||
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
|
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
|
||||||
|
|
||||||
.section .multiboot
|
.section .multiboot, "a"
|
||||||
.align 4
|
.align 4
|
||||||
.long MAGIC
|
.long MAGIC
|
||||||
.long FLAGS
|
.long FLAGS
|
||||||
.long CHECKSUM
|
.long CHECKSUM
|
||||||
|
|
||||||
.section .bss
|
.section .text
|
||||||
.align 4096
|
.global _start
|
||||||
boot_page_directory:
|
_start:
|
||||||
.skip 4096
|
cli
|
||||||
boot_page_table1:
|
|
||||||
.skip 4096
|
mov $(page_directory - 0xC0000000), %ecx
|
||||||
|
|
||||||
|
mov %cr4, %edx
|
||||||
|
or $0x00000010, %edx
|
||||||
|
mov %edx, %cr4
|
||||||
|
|
||||||
|
mov %ecx, %cr3
|
||||||
|
|
||||||
|
mov %cr0, %edx
|
||||||
|
or $0x80000000, %edx
|
||||||
|
mov %edx, %cr0
|
||||||
|
|
||||||
|
lea higher, %ecx
|
||||||
|
jmp *%ecx
|
||||||
|
higher:
|
||||||
|
mov $stack_top, %esp
|
||||||
|
push %ebx
|
||||||
|
push %eax
|
||||||
|
call kmain
|
||||||
|
loop:
|
||||||
|
jmp loop
|
||||||
|
|
||||||
.section .bss
|
.section .bss
|
||||||
.align 16
|
.align 16
|
||||||
@@ -23,13 +43,11 @@ stack_bottom:
|
|||||||
.skip 16384 # 16 KiB
|
.skip 16384 # 16 KiB
|
||||||
stack_top:
|
stack_top:
|
||||||
|
|
||||||
.section .text
|
.section .data, "a"
|
||||||
.global _start
|
.align 4096
|
||||||
_start:
|
.global page_directory
|
||||||
cli
|
page_directory:
|
||||||
mov $stack_top, %esp
|
.long 0x00000083
|
||||||
push %ebx
|
.skip 3068
|
||||||
push %eax
|
.long 0x00000083
|
||||||
call kmain
|
.skip 1020
|
||||||
loop:
|
|
||||||
jmp loop
|
|
||||||
@@ -18,6 +18,9 @@ extern void enable_interrupts();
|
|||||||
|
|
||||||
void* page = NULL;
|
void* page = NULL;
|
||||||
|
|
||||||
|
extern char __kernel_start;
|
||||||
|
extern char __kernel_end;
|
||||||
|
|
||||||
void kmain(uint32_t magic, multiboot_info* mbi) {
|
void kmain(uint32_t magic, multiboot_info* mbi) {
|
||||||
extern print_stream_t vga_print_stream;
|
extern print_stream_t vga_print_stream;
|
||||||
extern print_stream_t* kout;
|
extern print_stream_t* kout;
|
||||||
@@ -49,16 +52,19 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_mm((void*)mbi->mmap_addr, mbi->mmap_length);
|
init_pmm((void*)mbi->mmap_addr, mbi->mmap_length);
|
||||||
uint32_t mem_size = total_free_memory();
|
uint32_t mem_size = total_free_memory();
|
||||||
kprintf("Total available memory: %d MB\n", mem_size / 1024 / 1024);
|
kprintf("Total available memory: %d MB\n", mem_size / 1024 / 1024);
|
||||||
|
|
||||||
init_paging();
|
kprintf("__kernel_start: 0x%x\n", &__kernel_start);
|
||||||
enable_paging();
|
kprintf("__kernel_end: 0x%x\n", &__kernel_end);
|
||||||
kprintf("Paging enabled\n");
|
extern uint32_t page_directory[1024];
|
||||||
|
kprintf("page directory: 0x%x\n", &page_directory);
|
||||||
|
uint32_t size = (&__kernel_end - &__kernel_start) / 1024;
|
||||||
|
kprintf("kernel size: %dKB\n", size);
|
||||||
|
|
||||||
// enable_interrupts();
|
init_page_tables();
|
||||||
// kprintf("Interrupts enabled\n");
|
kprintf("Page tables reloaded");
|
||||||
|
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,35 @@
|
|||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
|
KERNEL_VMA = 0xC0000000;
|
||||||
|
KERNEL_LMA = 0x00200000;
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0xC0100000;
|
. = KERNEL_VMA + KERNEL_LMA;
|
||||||
__kernel_start = .;
|
__kernel_start = .;
|
||||||
|
.text : AT(ADDR(.text) - KERNEL_VMA)
|
||||||
.text BLOCK(4K) : ALIGN(4K)
|
|
||||||
{
|
{
|
||||||
*(.multiboot)
|
*(.multiboot)
|
||||||
*(.text)
|
*(.text*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.rodata BLOCK(4K) : ALIGN(4K)
|
.rodata : AT(ADDR(.rodata) - KERNEL_VMA)
|
||||||
{
|
{
|
||||||
*(.rodata)
|
*(.rodata*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.data BLOCK(4K) : ALIGN(4K)
|
.data : AT(ADDR(.data) - KERNEL_VMA)
|
||||||
{
|
{
|
||||||
*(.data)
|
*(.data*)
|
||||||
}
|
}
|
||||||
|
|
||||||
.bss BLOCK(4K) : ALIGN(4K)
|
.bss : AT(ADDR(.bss) - KERNEL_VMA)
|
||||||
{
|
{
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss*)
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
*(.bss)
|
__bss_end = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
__kernel_end = .;
|
__kernel_end = .;
|
||||||
}
|
}
|
||||||
@@ -13,8 +13,6 @@ static uint32_t max_address = 0;
|
|||||||
static uint32_t total_available_memory = 0;
|
static uint32_t total_available_memory = 0;
|
||||||
static uint8_t memory_bitmap[BITMAP_SIZE];
|
static uint8_t memory_bitmap[BITMAP_SIZE];
|
||||||
|
|
||||||
uint32_t* page_directory;
|
|
||||||
|
|
||||||
static void mark_free(uint32_t addr) {
|
static void mark_free(uint32_t addr) {
|
||||||
uint32_t page_index = addr / PAGE_SIZE;
|
uint32_t page_index = addr / PAGE_SIZE;
|
||||||
uint32_t byte_index = page_index / 8;
|
uint32_t byte_index = page_index / 8;
|
||||||
@@ -56,8 +54,10 @@ static void parse_multiboot_mmap(void* base, uint32_t limit) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t kernel_phys_start = (uint32_t)&__kernel_start - 0xC0000000;
|
||||||
|
uint32_t kernel_phys_end = (uint32_t)&__kernel_end - 0xC0000000;
|
||||||
for (uint32_t addr = usable_start; addr < usable_end; addr += 4096) {
|
for (uint32_t addr = usable_start; addr < usable_end; addr += 4096) {
|
||||||
if (addr <= (uint32_t)&__kernel_end && addr >= (uint32_t)&__kernel_start) {
|
if (addr <= (uint32_t)&kernel_phys_end && addr >= (uint32_t)&kernel_phys_start) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ static void parse_multiboot_mmap(void* base, uint32_t limit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_mm(void* mmap_base, uint32_t mmap_limit) {
|
void init_pmm(void* mmap_base, uint32_t mmap_limit) {
|
||||||
for (int i = 0; i < BITMAP_SIZE; i++) {
|
for (int i = 0; i < BITMAP_SIZE; i++) {
|
||||||
memory_bitmap[i] = 0xFF;
|
memory_bitmap[i] = 0xFF;
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,8 @@ uint32_t total_free_memory() {
|
|||||||
return total_available_memory;
|
return total_available_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* alloc_page() {
|
// this returns the virtual address of the physical page allocated
|
||||||
|
void* alloc_phys_page() {
|
||||||
for (uint32_t i = 0; i < BITMAP_SIZE; i++) {
|
for (uint32_t i = 0; i < BITMAP_SIZE; i++) {
|
||||||
uint8_t b = memory_bitmap[i];
|
uint8_t b = memory_bitmap[i];
|
||||||
if (b == 0xFF) {
|
if (b == 0xFF) {
|
||||||
@@ -103,7 +104,7 @@ void* alloc_page() {
|
|||||||
if ((b & (1 << bit)) == 0) {
|
if ((b & (1 << bit)) == 0) {
|
||||||
uint32_t page_addr = (i * 8 + bit) * PAGE_SIZE;
|
uint32_t page_addr = (i * 8 + bit) * PAGE_SIZE;
|
||||||
mark_used(page_addr);
|
mark_used(page_addr);
|
||||||
return (void*)page_addr;
|
return (void*)(page_addr + 0xC0000000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,22 +112,19 @@ void* alloc_page() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_page(void* addr) {
|
void free_phys_page(void* addr) {
|
||||||
mark_free((uint32_t)addr);
|
mark_free((uint32_t)addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_paging() {
|
extern uint32_t page_directory[1024];
|
||||||
page_directory = alloc_page();
|
extern void flush_tlb();
|
||||||
|
extern void disable_pae();
|
||||||
|
void init_page_tables() {
|
||||||
|
uint32_t* kernel_table = alloc_phys_page();
|
||||||
for (int i = 0; i < 1024; i++) {
|
for (int i = 0; i < 1024; i++) {
|
||||||
page_directory[i] = 0x0;
|
kernel_table[i] = (i * PAGE_SIZE) | 0x3;
|
||||||
}
|
}
|
||||||
|
uint32_t* phys_table = kernel_table - 0xC000000;
|
||||||
uint32_t* page_table = alloc_page();
|
page_directory[768] = (uint32_t)(phys_table) | 0x3;
|
||||||
page_directory[0] = (uint32_t)(page_table) | 0x3;
|
flush_tlb();
|
||||||
for (int i = 0; i < 1024; i++) {
|
|
||||||
page_table[i] = (i * PAGE_SIZE) | 0x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void load_page_directory(uint32_t* pd);
|
|
||||||
load_page_directory(page_directory);
|
|
||||||
}
|
}
|
||||||
@@ -7,13 +7,12 @@ typedef struct __attribute__((packed)) {
|
|||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
} mem_page_t;
|
} mem_page_t;
|
||||||
|
|
||||||
void init_mm(void* mmap_base, uint32_t mmap_limit);
|
void init_pmm(void* mmap_base, uint32_t mmap_limit);
|
||||||
uint32_t total_free_memory();
|
uint32_t total_free_memory();
|
||||||
|
|
||||||
void* alloc_page();
|
void* alloc_page();
|
||||||
void free_page(void* addr);
|
void free_page(void* addr);
|
||||||
|
|
||||||
void init_paging();
|
void init_page_tables();
|
||||||
void enable_paging();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,21 +1,11 @@
|
|||||||
.code32
|
.code32
|
||||||
.global load_page_directory
|
.global flush_tlb
|
||||||
load_page_directory:
|
flush_tlb:
|
||||||
push %ebp
|
mov %cr3, %eax
|
||||||
mov %esp, %ebp
|
|
||||||
|
|
||||||
mov 8(%ebp), %eax
|
|
||||||
mov %eax, %cr3
|
mov %eax, %cr3
|
||||||
|
|
||||||
leave
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.global enable_paging
|
.global disable_pae
|
||||||
enable_paging:
|
disable_pae:
|
||||||
mov %eax, %cr0
|
|
||||||
orl $0x80000000, %eax
|
|
||||||
mov %cr0, %eax
|
|
||||||
jmp 1f
|
|
||||||
1:
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
2
makefile
2
makefile
@@ -16,7 +16,7 @@ LDFLAGS := -T kernel/linker.ld
|
|||||||
|
|
||||||
all: $(OSNAME).iso
|
all: $(OSNAME).iso
|
||||||
|
|
||||||
$(OSNAME).bin: $(OBJECTS)
|
$(OSNAME).bin: $(OBJECTS) kernel/linker.ld
|
||||||
$(LD) $(LDFLAGS) -o $@ $(OBJECTS)
|
$(LD) $(LDFLAGS) -o $@ $(OBJECTS)
|
||||||
|
|
||||||
$(OSNAME).iso: $(OSNAME).bin grub.cfg
|
$(OSNAME).iso: $(OSNAME).bin grub.cfg
|
||||||
|
|||||||
Reference in New Issue
Block a user