paging at boot works now!!!!
This commit is contained in:
39
linker.ld
39
linker.ld
@@ -1,30 +1,25 @@
|
|||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
|
KERNEL_VIRT_BASE = 0xC0000000;
|
||||||
|
KERNEL_PHYS_BASE = 0x00100000;
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = ALIGN(8);
|
. = KERNEL_VIRT_BASE;
|
||||||
.boot : {
|
|
||||||
KEEP(*(.multiboot))
|
.text : AT(KERNEL_PHYS_BASE) {
|
||||||
|
*(.text)
|
||||||
}
|
}
|
||||||
. = 1M; /* Load kernel at 1MB */
|
|
||||||
|
|
||||||
.text BLOCK(4K) : ALIGN(4K)
|
.rodata : AT(KERNEL_PHYS_BASE + (ADDR(.rodata) - KERNEL_VIRT_BASE)) {
|
||||||
{
|
*(.rodata)
|
||||||
*(.text)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.rodata BLOCK(4K) : ALIGN(4K)
|
.data : AT(KERNEL_PHYS_BASE + (ADDR(.data) - KERNEL_VIRT_BASE)) {
|
||||||
{
|
*(.data)
|
||||||
*(.rodata)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.data BLOCK(4K) : ALIGN(4K)
|
.bss : AT(KERNEL_PHYS_BASE + (ADDR(.bss) - KERNEL_VIRT_BASE)) {
|
||||||
{
|
*(COMMON)
|
||||||
*(.data)
|
*(.bss)
|
||||||
}
|
}
|
||||||
|
|
||||||
.bss BLOCK(4K) : ALIGN(4K)
|
|
||||||
{
|
|
||||||
*(COMMON)
|
|
||||||
*(.bss)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ gdt_end:
|
|||||||
|
|
||||||
gdt_descriptor:
|
gdt_descriptor:
|
||||||
dw gdt_end - gdt_start - 1
|
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
|
CODE_SEG equ gdt_code - gdt_start
|
||||||
DATA_SEG equ gdt_data - 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
|
; constants for multiboot
|
||||||
MAGIC equ 0xE85250D6
|
MAGIC equ 0xE85250D6
|
||||||
ARCH equ 0 ; 0 for i386, 4 for MIPS
|
ARCH equ 0 ; 0 for i386, 4 for MIPS
|
||||||
HDRLEN equ 24 ; Total length: 4 fields + end tag
|
HDRLEN equ 24 ; Total length: 4 fields + end tag
|
||||||
CHECKSUM equ -(MAGIC + ARCH + HDRLEN)
|
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
|
section .multiboot_header
|
||||||
align 8
|
align 8
|
||||||
@@ -25,6 +34,16 @@ stack_bottom:
|
|||||||
resb 16384 ; 16 KiB is reserved for stack
|
resb 16384 ; 16 KiB is reserved for stack
|
||||||
stack_top:
|
stack_top:
|
||||||
|
|
||||||
|
align 4096
|
||||||
|
PAG_mainPD:
|
||||||
|
resd 1024
|
||||||
|
align 4096
|
||||||
|
PAG_identityPT:
|
||||||
|
resd 1024
|
||||||
|
align 4096
|
||||||
|
PAG_kernelPT:
|
||||||
|
resd 1024
|
||||||
|
|
||||||
section .rodata
|
section .rodata
|
||||||
%include "src/bootload/GDT.asm"
|
%include "src/bootload/GDT.asm"
|
||||||
|
|
||||||
@@ -32,24 +51,12 @@ section .text ; entrypoint for bootloader
|
|||||||
[BITS 32]
|
[BITS 32]
|
||||||
global _start:function (_start.end - _start)
|
global _start:function (_start.end - _start)
|
||||||
_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
|
cli
|
||||||
lgdt [gdt_descriptor]
|
lgdt [gdt_descriptor + KERNEL_OFFSET]
|
||||||
jmp CODE_SEG:.final ; if I get problems, check this line here, future me!
|
jmp CODE_SEG:.final + KERNEL_OFFSET ; if I get problems, check this line here, future me!
|
||||||
.final:
|
.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 AX, DATA_SEG ; data segment selectors
|
||||||
mov DS, AX
|
mov DS, AX
|
||||||
mov ES, AX
|
mov ES, AX
|
||||||
@@ -57,8 +64,53 @@ _start:
|
|||||||
mov GS, AX
|
mov GS, AX
|
||||||
mov SS, AX
|
mov SS, AX
|
||||||
|
|
||||||
push ecx ; magic number
|
mov ecx, 1024 ; 1024 * 4KB = 4MB
|
||||||
push ebx ; info structure
|
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
|
extern kernel_main
|
||||||
call kernel_main
|
call kernel_main
|
||||||
add esp, 8 ; remove arguments
|
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");
|
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: ");
|
kputstr("Entering Graphics mode: ");
|
||||||
VGA_switch(VGA_values);
|
VGA_switch(VGA_values);
|
||||||
|
*(uint8_t*)0xA0000 = 1;
|
||||||
kputstr("OK\n");
|
kputstr("OK\n");
|
||||||
|
|
||||||
VGA_clear((VGA_pixel){0xFF,0xFF,0xFF});
|
VGA_clear((VGA_pixel){0xFF,0xFF,0xFF});
|
||||||
@@ -56,6 +50,13 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
|
|||||||
}
|
}
|
||||||
kputstr("OK\n");
|
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: ");
|
kputstr("Setting up IRQs: ");
|
||||||
for (uint8_t i=0;i<16;i++) {
|
for (uint8_t i=0;i<16;i++) {
|
||||||
idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E);
|
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);
|
IRQ_registerhandler(0x00, &tick);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (1) {}
|
while (1) {}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user