paging at boot works now!!!!
This commit is contained in:
23
linker.ld
23
linker.ld
@@ -1,29 +1,24 @@
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS {
|
||||
. = ALIGN(8);
|
||||
.boot : {
|
||||
KEEP(*(.multiboot))
|
||||
}
|
||||
. = 1M; /* Load kernel at 1MB */
|
||||
KERNEL_VIRT_BASE = 0xC0000000;
|
||||
KERNEL_PHYS_BASE = 0x00100000;
|
||||
|
||||
.text BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
SECTIONS {
|
||||
. = KERNEL_VIRT_BASE;
|
||||
|
||||
.text : AT(KERNEL_PHYS_BASE) {
|
||||
*(.text)
|
||||
}
|
||||
|
||||
.rodata BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
.rodata : AT(KERNEL_PHYS_BASE + (ADDR(.rodata) - KERNEL_VIRT_BASE)) {
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
.data : AT(KERNEL_PHYS_BASE + (ADDR(.data) - KERNEL_VIRT_BASE)) {
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
.bss : AT(KERNEL_PHYS_BASE + (ADDR(.bss) - KERNEL_VIRT_BASE)) {
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ gdt_end:
|
||||
|
||||
gdt_descriptor:
|
||||
dw gdt_end - gdt_start - 1
|
||||
dd gdt_start
|
||||
dd gdt_start - 0xC0000000 + 0x00100000 ; paging, thank me later.
|
||||
|
||||
CODE_SEG equ gdt_code - gdt_start
|
||||
DATA_SEG equ gdt_data - gdt_start
|
||||
@@ -1,8 +1,17 @@
|
||||
; TODO:
|
||||
; load GDT [x]
|
||||
; enter long m. [x]
|
||||
; enable paging [x]
|
||||
; fix damn grub parameter passing [x]
|
||||
|
||||
; constants for multiboot
|
||||
MAGIC equ 0xE85250D6
|
||||
ARCH equ 0 ; 0 for i386, 4 for MIPS
|
||||
HDRLEN equ 24 ; Total length: 4 fields + end tag
|
||||
CHECKSUM equ -(MAGIC + ARCH + HDRLEN)
|
||||
KERNEL_VIRT_BASE equ 0xC0000000
|
||||
KERNEL_PHYS_BASE equ 0x00100000
|
||||
KERNEL_OFFSET equ (-KERNEL_VIRT_BASE)+KERNEL_PHYS_BASE
|
||||
|
||||
section .multiboot_header
|
||||
align 8
|
||||
@@ -25,6 +34,16 @@ stack_bottom:
|
||||
resb 16384 ; 16 KiB is reserved for stack
|
||||
stack_top:
|
||||
|
||||
align 4096
|
||||
PAG_mainPD:
|
||||
resd 1024
|
||||
align 4096
|
||||
PAG_identityPT:
|
||||
resd 1024
|
||||
align 4096
|
||||
PAG_kernelPT:
|
||||
resd 1024
|
||||
|
||||
section .rodata
|
||||
%include "src/bootload/GDT.asm"
|
||||
|
||||
@@ -32,24 +51,12 @@ section .text ; entrypoint for bootloader
|
||||
[BITS 32]
|
||||
global _start:function (_start.end - _start)
|
||||
_start:
|
||||
; To set up a stack, we set the esp register to point to the top of our
|
||||
; stack (as it grows downwards on x86 systems). This is necessarily done
|
||||
; in assembly as languages such as C cannot function without a stack.
|
||||
mov esp, stack_top
|
||||
mov ebp, esp
|
||||
|
||||
mov ecx, eax ; move multiboot magic number to ecx
|
||||
|
||||
; TODO:
|
||||
; load GDT [x]
|
||||
; enter long m. [ ]
|
||||
; init FPU [ ]
|
||||
|
||||
; load GDT
|
||||
cli
|
||||
lgdt [gdt_descriptor]
|
||||
jmp CODE_SEG:.final ; if I get problems, check this line here, future me!
|
||||
lgdt [gdt_descriptor + KERNEL_OFFSET]
|
||||
jmp CODE_SEG:.final + KERNEL_OFFSET ; if I get problems, check this line here, future me!
|
||||
.final:
|
||||
mov edx, eax ; we need the boot shit from grub still
|
||||
; so now eax -> edx and ebx -> ebx
|
||||
mov AX, DATA_SEG ; data segment selectors
|
||||
mov DS, AX
|
||||
mov ES, AX
|
||||
@@ -57,8 +64,53 @@ _start:
|
||||
mov GS, AX
|
||||
mov SS, AX
|
||||
|
||||
push ecx ; magic number
|
||||
push ebx ; info structure
|
||||
mov ecx, 1024 ; 1024 * 4KB = 4MB
|
||||
mov edi, PAG_identityPT + KERNEL_OFFSET
|
||||
mov eax, 0
|
||||
|
||||
.fill_identity:
|
||||
mov [edi], eax
|
||||
or dword [edi], 0x3
|
||||
add eax, 0x1000
|
||||
add edi, 4
|
||||
loop .fill_identity
|
||||
|
||||
mov ecx, 1024
|
||||
mov edi, PAG_kernelPT + KERNEL_OFFSET
|
||||
mov eax, KERNEL_PHYS_BASE
|
||||
|
||||
.fill_kernel:
|
||||
mov [edi], eax
|
||||
or dword [edi], 0x3
|
||||
add eax, 0x1000
|
||||
add edi, 4
|
||||
loop .fill_kernel
|
||||
|
||||
; identity PT = entry 0
|
||||
mov eax, PAG_identityPT + KERNEL_OFFSET
|
||||
or eax, 0x3
|
||||
mov [PAG_mainPD + KERNEL_OFFSET + 0*4], eax
|
||||
|
||||
; kernel PT = entry 768
|
||||
mov eax, PAG_kernelPT + KERNEL_OFFSET
|
||||
or eax, 0x3
|
||||
mov [PAG_mainPD + KERNEL_OFFSET + 768*4], eax
|
||||
|
||||
mov eax, PAG_mainPD + KERNEL_OFFSET
|
||||
mov cr3, eax
|
||||
mov eax, cr0
|
||||
or eax, 0x80000000
|
||||
mov cr0, eax
|
||||
|
||||
jmp .pagingfinished
|
||||
.pagingfinished
|
||||
; fix stack once again and since we need to keep the contents, we just add an offset
|
||||
mov esp, stack_top
|
||||
mov ebp, stack_bottom
|
||||
|
||||
push edx
|
||||
push ebx
|
||||
|
||||
extern kernel_main
|
||||
call kernel_main
|
||||
add esp, 8 ; remove arguments
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "stddef.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
typedef uint32_t PAG_PT_entry_t;
|
||||
typedef PAG_PT_entry_t PAG_PT_t[1024];
|
||||
typedef PAG_PT_t PAG_PD_t[1024];
|
||||
|
||||
extern PAG_PD_t PAG_mainPD;
|
||||
|
||||
|
||||
@@ -32,15 +32,9 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
|
||||
|
||||
kputstr("Hello JPOS, World!\n");
|
||||
|
||||
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
|
||||
kputstr("Invalid magic from bootloader.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
kputstr("Got past magic check.\n");
|
||||
|
||||
kputstr("Entering Graphics mode: ");
|
||||
VGA_switch(VGA_values);
|
||||
*(uint8_t*)0xA0000 = 1;
|
||||
kputstr("OK\n");
|
||||
|
||||
VGA_clear((VGA_pixel){0xFF,0xFF,0xFF});
|
||||
@@ -56,6 +50,13 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
|
||||
}
|
||||
kputstr("OK\n");
|
||||
|
||||
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
|
||||
kputstr("Invalid magic from bootloader.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
kputstr("Got past magic check.\n");
|
||||
|
||||
kputstr("Setting up IRQs: ");
|
||||
for (uint8_t i=0;i<16;i++) {
|
||||
idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E);
|
||||
@@ -86,7 +87,5 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
|
||||
|
||||
IRQ_registerhandler(0x00, &tick);
|
||||
|
||||
|
||||
|
||||
while (1) {}
|
||||
}
|
||||
Reference in New Issue
Block a user