Basic Launch of Higher half kernel
We now can launch the kernel at 0xC0000000 (or 3 GiB mark) with paging enabled. A lot of early main is currently not executed to keep debugging as simple as possible during the initial testing of higher half kernel loading. A lot of the implementation is straight from wiki.osdev.org/Higher_Half_x86_Bare_Bones. Thanks to all the folks who keep that wiki updated, its really resourceful.
This commit is contained in:
parent
bbfea39c23
commit
7d6c823d79
9
Makefile
9
Makefile
@ -3,7 +3,7 @@ EMULATOR = qemu-system-i386
|
||||
AS = ${HOME}/opt/cross/bin/i686-elf-as
|
||||
CC = ${HOME}/opt/cross/bin/i686-elf-gcc
|
||||
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
|
||||
CFLAGS = -ffreestanding -O2 -Wall -Wextra
|
||||
CFLAGS = -ffreestanding -Og -ggdb -Wall -Wextra
|
||||
|
||||
OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/paging.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o
|
||||
|
||||
@ -34,11 +34,14 @@ iso: clean_iso clean build
|
||||
grub-mkrescue -o build/barinkOS.iso root
|
||||
|
||||
run: all
|
||||
$(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo
|
||||
$(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo
|
||||
|
||||
debug: all
|
||||
$(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -s -d int
|
||||
|
||||
build_kernel: $(OBJ_LINK_LIST)
|
||||
$(CC) -T $(SRC_DIR)/kernel//linker.ld -o $(BUILD_DIR)/myos.bin \
|
||||
-ffreestanding -O2 -nostdlib $(OBJ_LINK_LIST) -lgcc
|
||||
-ffreestanding -ggdb -Og -nostdlib $(OBJ_LINK_LIST) -lgcc
|
||||
|
||||
build_x86_64:
|
||||
$(AS) $(SRC_DIR)/cgc/x86_64/crti.s -o $(BUILD_DIR)/crti_64.o
|
||||
|
@ -7,30 +7,104 @@
|
||||
.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */
|
||||
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
|
||||
|
||||
.section .multiboot
|
||||
.section .multiboot.data, "aw"
|
||||
.align 4
|
||||
.long MAGIC
|
||||
.long FLAGS
|
||||
.long CHECKSUM
|
||||
|
||||
|
||||
.section .bss
|
||||
.align 16
|
||||
/*
|
||||
* Allocate initial stack
|
||||
*/
|
||||
.section .bootstrap_stack, "aw", @nobits
|
||||
stack_bottom:
|
||||
.skip 16384 # 16 KiB
|
||||
stack_top:
|
||||
|
||||
.section .text
|
||||
.include "./src/kernel/Memory/GDT/gdt.s"
|
||||
.include "./src/kernel/irs_table.s"
|
||||
.include "./src/kernel/irq_table.s"
|
||||
.include "./src/kernel/Interrupts/idt/idt.s"
|
||||
.include "./src/kernel/Memory/paging.s"
|
||||
.include "./src/kernel/cpu.s"
|
||||
|
||||
/*
|
||||
* Preallocate a couple pages to get us bootstrapped
|
||||
* Being carefull to not use any address the bootloader might
|
||||
* be using for its multiboot structures
|
||||
*/
|
||||
.section .bss, "aw", @nobits
|
||||
.align 4096
|
||||
boot_page_directory:
|
||||
.skip 4096
|
||||
boot_page_table:
|
||||
.skip 4096
|
||||
# More page tables may be required
|
||||
|
||||
# Entry point
|
||||
.section .multiboot.text, "a"
|
||||
.global _start
|
||||
.type _start, @function
|
||||
.type _start, @function
|
||||
_start:
|
||||
# Get physical address of the boot_page_table
|
||||
movl $(boot_page_table - 0xC0000000), %edi
|
||||
# Map address 0
|
||||
movl $0, %esi
|
||||
# Map 1023 pages the 1024th being the VGA text buffer
|
||||
movl $1023, %ecx
|
||||
|
||||
1: # Map the kernel
|
||||
cmpl $_kernel_start, %esi
|
||||
jl 2f
|
||||
cmpl $(_kernel_end - 0xC0000000), %esi
|
||||
jge 3f
|
||||
|
||||
# Map physical address as "present and writable"
|
||||
movl %esi, %edx
|
||||
orl $0x003, %edx
|
||||
movl %edx, (%edi)
|
||||
|
||||
2: # Size of page is 4096 bytes
|
||||
addl $4096, %esi
|
||||
# Size of entries in boot_page_table is 4 bytes
|
||||
addl $4, %edi
|
||||
# Loop to the next entry if we haven't finished.
|
||||
loop 1b
|
||||
|
||||
3: # Map VGA video memory to 0xC03FF00 as "present, writable"
|
||||
movl $(0x000B8000 | 0x003), boot_page_table - 0xC0000000 + 1023 * 4
|
||||
|
||||
|
||||
# IMPORTANT NOTE FROM WIKI.OSDEV.ORG/HIGHER_HALF_X86_BARE_BONES
|
||||
|
||||
# The page table is used at both page directory entry 0 (virtually from 0x0
|
||||
# to 0x3FFFFF) (thus identity mapping the kernel) and page directory entry
|
||||
# 768 (virtually from 0xC0000000 to 0xC03FFFFF) (thus mapping it in the
|
||||
# higher half). The kernel is identity mapped because enabling paging does
|
||||
# not change the next instruction, which continues to be physical. The CPU
|
||||
# would instead page fault if there was no identity mapping.\
|
||||
|
||||
# Map the page table to both virtual addresss 0x00000000 and 0xC0000000
|
||||
movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0
|
||||
movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
|
||||
|
||||
# Set cr3 to the address of the boot_page_directory
|
||||
movl $(boot_page_directory - 0xC0000000), %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
# Enable paging and the write-protect bit
|
||||
movl %cr0, %ecx
|
||||
orl $0x80010000, %ecx
|
||||
movl %ecx, %cr0
|
||||
|
||||
# Jump to higher half with an absolute jump
|
||||
lea 4f, %ecx
|
||||
jmp *%ecx
|
||||
|
||||
.section .text
|
||||
4:
|
||||
# At this point, paging is fully set up and enabled
|
||||
isPaging:
|
||||
# Unmap the identity mapping as it is now unnecessary
|
||||
movl $0, boot_page_directory + 0
|
||||
|
||||
# Reload cr3 to force tlb flush
|
||||
movl %cr3, %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
/*Setup the stack pointer to point to the beginning of our stack */
|
||||
/* I believe its a high address growing down to lower adress for the stack on x86*/
|
||||
mov $stack_top, %esp
|
||||
@ -44,16 +118,15 @@ _start:
|
||||
|
||||
/* push the magic value */
|
||||
pushl %eax
|
||||
|
||||
call early_main
|
||||
|
||||
call early_main
|
||||
|
||||
mov %cr0, %eax
|
||||
or $1, %eax
|
||||
mov %eax, %cr0
|
||||
mov %eax, %cr0
|
||||
|
||||
|
||||
call kernel_main
|
||||
//call kernel_main
|
||||
|
||||
|
||||
cli
|
||||
@ -61,6 +134,11 @@ _start:
|
||||
jmp 1b
|
||||
|
||||
|
||||
.size _start, . - _start
|
||||
.include "./src/kernel/Memory/GDT/gdt.s"
|
||||
.include "./src/kernel/irs_table.s"
|
||||
.include "./src/kernel/irq_table.s"
|
||||
.include "./src/kernel/Interrupts/idt/idt.s"
|
||||
.include "./src/kernel/Memory/paging.s"
|
||||
.include "./src/kernel/cpu.s"
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@ void kterm_init () {
|
||||
kterm_row = 0;
|
||||
kterm_column = 0;
|
||||
kterm_color = vga_entry_color ( VGA_COLOR_LIGHT_GREY , VGA_COLOR_BLACK);
|
||||
kterm_buffer = (uint16_t*) 0xB8000;
|
||||
kterm_buffer = (uint16_t*) 0xC03FF000;
|
||||
for (size_t y = 0; y < VGA_HEIGHT; y++ ){
|
||||
for( size_t x = 0; x < VGA_WIDTH; x++){
|
||||
const size_t index = y * VGA_WIDTH + x;
|
||||
|
@ -1,11 +1,9 @@
|
||||
#include "kernel.h"
|
||||
|
||||
|
||||
extern "C" void kernel_main (BootInfo* bootinfo) {
|
||||
init_serial();
|
||||
pit_initialise();
|
||||
|
||||
//InitializePaging();
|
||||
//Enable();
|
||||
//pit_initialise();
|
||||
|
||||
startSuperVisorTerminal(bootinfo);
|
||||
}
|
||||
@ -16,8 +14,12 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){
|
||||
* Initialize terminal interface
|
||||
* NOTE: This should be done later on , the magic value should be checked first.
|
||||
*/
|
||||
initGDT();
|
||||
kterm_init();
|
||||
|
||||
init_serial();
|
||||
print_serial("Hello Higher half kernel!");
|
||||
printf("DDDDDDDDDDDDDDDD");
|
||||
return;
|
||||
/**
|
||||
* Check Multiboot magic number
|
||||
* NOTE: Printf call should not be a thing this early on ...
|
||||
@ -31,7 +33,7 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){
|
||||
* Show a little banner for cuteness
|
||||
*/
|
||||
printf("|=== BarinkOS ===|\n");
|
||||
|
||||
printf("Kernel Begin AT(0x%x)", kernel_begin);
|
||||
|
||||
/**
|
||||
* Use the address given as an argument as the pointer
|
||||
@ -107,17 +109,17 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){
|
||||
|
||||
//memAlloc.free_block((void*) memory);
|
||||
//InitializePaging();
|
||||
IdentityMap();
|
||||
Enable();
|
||||
//IdentityMap();
|
||||
//Enable();
|
||||
}
|
||||
|
||||
initGDT();
|
||||
init_idt();
|
||||
//initGDT();
|
||||
//init_idt();
|
||||
// Enable interrupts
|
||||
asm volatile("STI");
|
||||
//asm volatile("STI");
|
||||
|
||||
|
||||
CheckMBT( (multiboot_info_t *) addr);
|
||||
//CheckMBT( (multiboot_info_t *) addr);
|
||||
|
||||
|
||||
kernel_main(&bootinfo);
|
||||
|
@ -1,47 +1,45 @@
|
||||
/* The bootloader will look at this image and start execution at the symbol
|
||||
designated as the entry point. */
|
||||
ENTRY(_start)
|
||||
|
||||
/* Tell where the various sections of the object files will be put in the final
|
||||
kernel image. */
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
|
||||
loaded at by the bootloader. */
|
||||
. = 1M;
|
||||
kernel_begin = .;
|
||||
/* First put the multiboot header, as it is required to be put very early
|
||||
early in the image or the bootloader won't recognize the file format.
|
||||
Next we'll put the .text section. */
|
||||
.text BLOCK(4K) : ALIGN(4K)
|
||||
. = 0x00100000; /* place code at 1MB mark*/
|
||||
|
||||
_kernel_start = .;
|
||||
kernel_begin = .; /* For legacy reasons */
|
||||
|
||||
|
||||
.multiboot.data : {
|
||||
*(.multiboot.data)
|
||||
}
|
||||
|
||||
.multiboot.text : {
|
||||
*(multiboot.text)
|
||||
}
|
||||
|
||||
. += 0xC0000000; /* Addresses in the following code need to be above the 3Gb mark */
|
||||
|
||||
|
||||
.text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000)
|
||||
{
|
||||
*(.multiboot)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
/* Read-only data. */
|
||||
.rodata BLOCK(4K) : ALIGN(4K)
|
||||
.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
/* Read-write data (initialized) */
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
.data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
|
||||
/* Read-write data (uninitialized) and stack */
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
.bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
*(.bootstrap_stack)
|
||||
}
|
||||
|
||||
/* The compiler may produce other sections, by default it will put them in
|
||||
a segment with the same name. Simply add stuff here as needed. */
|
||||
|
||||
kernel_end = .;
|
||||
_kernel_end = .;
|
||||
kernel_end = .; /* For legacy reasons */
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user