Divided the kernel into seperate distinct phases

The first stage after GRUB will be Pre-Kernel. This stage will organize the
information we receive from the bootloader. (in our case that will be grub)

The second stage is for now called early_main. The program will at this
point already be running in virtual higher-half / higher-quarter address space.
The goal of the second stage is to set up the kernel in such a way that we are
ready to jump in to usermode.

The third stage is for now called kernel_main. This stage will jump us into
usermode and load the startup programs.

- Added a GRUB entry for tests
- Started writing the pre-kernel stage
- Removed knowledge of multiboot from early_main
- Edited the linkerscript to link variables in pre-kernel to
	lower address space. ( from 1MB and up)
This commit is contained in:
Nigel Barink 2022-08-22 21:16:34 +02:00
parent 0f0fc9f252
commit 5051b8903c
16 changed files with 206 additions and 253 deletions

View File

@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc
CPP = ${HOME}/opt/cross/bin/i686-elf-g++
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 $(BUILD_DIR)/launcher.o
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 $(BUILD_DIR)/prekernel.o
SRC_DIR = source
BUILD_DIR = build
@ -30,7 +30,7 @@ clean_iso:
iso: clean_iso clean build
mkdir -p root/boot/grub
cp build/myos.bin root/boot/myos.bin
cp src/grub.cfg root/boot/grub/grub.cfg
cp source/grub.cfg root/boot/grub/grub.cfg
grub-mkrescue -o build/barinkOS.iso root
run: all
@ -58,13 +58,13 @@ $(BUILD_DIR)/kterm.o:
$(CPP) -c $(SRC_DIR)/kernel/Terminal/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/boot.o:
$(AS) $(SRC_DIR)/kernel/KernelLauncher/boot.s -o $(BUILD_DIR)/boot.o
$(AS) $(SRC_DIR)/kernel/Boot/boot.s -o $(BUILD_DIR)/boot.o
$(BUILD_DIR)/crti.o:
$(AS) $(SRC_DIR)/kernel/KernelLauncher/crti.s -o $(BUILD_DIR)/crti.o
$(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o
$(BUILD_DIR)/crtn.o:
$(AS) $(SRC_DIR)/kernel/KernelLauncher/crtn.s -o $(BUILD_DIR)/crtn.o
$(AS) $(SRC_DIR)/kernel/crtn.s -o $(BUILD_DIR)/crtn.o
$(BUILD_DIR)/io.o:
$(CPP) -c $(SRC_DIR)/kernel/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti
@ -104,5 +104,5 @@ $(BUILD_DIR)/memory.o:
$(BUILD_DIR)/paging.o:
$(CPP) -c $(SRC_DIR)/kernel/Memory/VirtualMemoryManager.cpp -o $(BUILD_DIR)/paging.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/launcher.o:
$(CPP) -c $(SRC_DIR)/kernel/KernelLauncher/launcher.cpp -o $(BUILD_DIR)/launcher.o $(CFLAGS) -fno-exceptions -fno-rtti
$(BUILD_DIR)/prekernel.o:
$(CPP) -c $(SRC_DIR)/kernel/PreKernel/prekernel.cpp -o $(BUILD_DIR)/prekernel.o $(CFLAGS) -fno-exceptions -fno-rtti

View File

@ -1,3 +1,9 @@
menuentry "BarinkOS" {
multiboot /boot/myos.bin
}
menuentry "BarinkOS Tests" {
multiboot /boot/myos.bin
}

View File

@ -43,6 +43,14 @@ multiboot_page_table:
.global _start
.type _start, @function
_start:
/* push the pointer to the Multiboot information structure*/
pushl %ebx
/* push the magic value */
pushl %eax
call testLauncher
# Get physical address of the boot_page_table
movl $(boot_page_table - 0xC0000000), %edi
# Map address 0
@ -112,11 +120,7 @@ isPaging:
pushl $0
popf
/* push the pointer to the Multiboot information structure*/
pushl %ebx
/* push the magic value */
pushl %eax
call early_main
@ -129,11 +133,11 @@ isPaging:
jmp 1b
.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"
.include "./source/kernel/Memory/GDT/gdt.s"
.include "./source/kernel/irs_table.s"
.include "./source/kernel/irq_table.s"
.include "./source/kernel/Interrupts/idt/idt.s"
.include "./source/kernel/Memory/paging.s"
.include "./source/kernel/cpu.s"

View File

@ -1,91 +0,0 @@
#pragma once
#include "../multiboot.h"
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
#define __VERBOSE__
#include "../Terminal/kterm.h"
void CheckMBT ( multiboot_info_t* mbt ){
/* Set MBI to the addresss of the multiboot information structure*/
multiboot_info_t * mbi = (multiboot_info_t *) mbt;
#ifdef __VERBOSE__
/* Print out the flags */
printf("flags = 0x%x\n", (unsigned) mbi->flags);
#endif
/* Are mem_* valid? */
if ( CHECK_FLAG(mbi->flags,0)){
// Do nothing
}
/* is boot device valid ? */
if (CHECK_FLAG (mbi->flags, 1))
{
#ifdef __VERBOSE__
printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device);
#endif
}
/* is the command line passed? */
if (CHECK_FLAG ( mbi->flags,2))
{
#ifdef __VERBOSE__
printf("cmdline = %s\n", (char *) (mbi->cmdline + 0xC0000000));
#endif
}
/* Are mods_* valid? */
if(CHECK_FLAG ( mbi->flags, 3)){
multiboot_module_t *mod;
uint32_t i;
#ifdef __VERBOSE__
printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr);
for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline);
}
#endif
}
/* Bits 4 and 5 are mutually exclusive! */
if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5))
{
#ifdef __VERBOSE__
printf("Both bits 4 and 5 are set.\n");
#endif
return;
}
/* Is the symbol table of a.out valid? */
if (CHECK_FLAG(mbi->flags, 4)){
multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
#ifdef __VERBOSE__
printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n",
(unsigned) multiboot_aout_sym->tabsize,
(unsigned) multiboot_aout_sym->strsize,
(unsigned) multiboot_aout_sym->addr);
#endif
}
/* Is the section header table of ELF valid? */
if (CHECK_FLAG(mbi->flags, 5)){
multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
#ifdef __VERBOSE__
printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n",
(unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size,
(unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx);
#endif
}
/* Draw diagonal blue line */
if (CHECK_FLAG (mbt->flags, 12)){
#ifdef __VERBOSE__
printf("Can draw!\n");
#endif
}
}

View File

@ -1,28 +0,0 @@
#include <stdint.h>
#include <stddef.h>
void put_char(char ch, size_t x, size_t y ){
*((uint16_t*)0xb8000+(y * 80 + x)) = ch | ((7 | 0 << 4) << 8);
}
void write_ln(char* s, size_t length, size_t x , size_t y)
{
// Because read only data is linked at a virtual address we'll need to convert
// the string adddres from virtual to phys.
s = s - 0xC0000000;
size_t column , row;
column = x;
row = y;
for(int i = 0; i < length ; i ++)
{
put_char(s[i] , column,row );
column ++;
}
}
extern "C" void testLauncher () {
write_ln("hello", 5 ,0,0);
}

View File

@ -1,6 +1,6 @@
#include "MBI_MMap.h"
/*
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt) {
printf("mmap_addr = 0x%x, mmap_length = 0x%x\n", (unsigned) mbt->mmap_addr , (unsigned) mbt->mmap_length );
@ -23,13 +23,13 @@ void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt) {
}
*/
/**
* @brief Debug Verbose functions
*
* @param mmap
*/
/*
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap) {
printf(
"size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n",
@ -41,3 +41,4 @@ void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap) {
(unsigned) mmap->type
);
}
*/

View File

@ -1,16 +1,18 @@
#pragma once
#include <stddef.h>
#include "../../multiboot.h"
//#include "../../multiboot.h"
#include "../memoryinfo.h"
void initialise_available_regions(uint32_t memoryMapAddr, uint32_t memoryMapLastAddr, uint32_t* memoryBitMap, int* used_blocks);
/*
void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt);
*/
/**
* @brief Debug Verbose Functions
*
* @param mmap
*/
/*
void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap);
*/

View File

@ -0,0 +1,28 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
extern "C" const uint32_t kernel_begin;
extern "C" const uint32_t kernel_end;
struct BootInfoBlock {
bool MapIsInvalid;
uint32_t bootDeviceID ;
uint32_t GrubModuleCount;
bool ValidSymbolTable;
uint32_t SymbolTableAddr;
uint32_t SymbolTabSize;
uint32_t SymbolStrSize;
bool ValidELFHeader;
bool EnabledVBE;
bool PhysicalMemoryMapAvailable;
};
// Put the BootInfoBlock 1MB above the kernel.
const uint32_t BootInfoBlock_pptr = kernel_end - 0xC0000000 + 0x1000;

View File

@ -0,0 +1,93 @@
#include <stdint.h>
#include <stddef.h>
#include "multiboot.h"
#include "bootstructure.h"
#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit)))
extern "C" void testLauncher ( unsigned long magic, multiboot_info_t* mbi) {
// Create the bootInfoBlock at its location
BootInfoBlock* BIB = (BootInfoBlock*) BootInfoBlock_pptr;
/*
* Check Multiboot magic number
*/
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
{
BIB->MapIsInvalid = true;
return;
} else{
BIB->MapIsInvalid = false;
}
/* is boot device valid ? */
if (CHECK_FLAG (mbi->flags, 1))
{
BIB->bootDeviceID = mbi->boot_device;
}
/* Are mods_* valid? */
if(CHECK_FLAG ( mbi->flags, 3)){
multiboot_module_t *mod;
uint32_t i;
BIB->GrubModuleCount = mbi->mods_count;
for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){
}
}
/* Is the symbol table of a.out valid? */
if (CHECK_FLAG(mbi->flags, 4))
{
BIB->ValidSymbolTable = true;
multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);
} else{
BIB->ValidSymbolTable = false;
}
/* Is the section header table of ELF valid? */
if (CHECK_FLAG(mbi->flags, 5))
{
BIB->ValidELFHeader = true;
multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);
}else{
BIB->ValidELFHeader = false;
}
/*
If we got a memory map from our bootloader we
should be parsing it to find out the memory regions available.
*/
if (CHECK_FLAG(mbi->flags, 6))
{
BIB->PhysicalMemoryMapAvailable = true;
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) (mbi->mmap_addr) ;
for (; (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
} else{
}
}
} else{
BIB->PhysicalMemoryMapAvailable = false;
}
/* Draw diagonal blue line */
if (CHECK_FLAG (mbi->flags, 12)){
BIB->EnabledVBE = true;
} else{
BIB->EnabledVBE;
}
}

View File

@ -22,6 +22,7 @@ void kterm_init () {
kterm_column = 0;
kterm_color = vga_entry_color ( VGA_COLOR_LIGHT_GREY , VGA_COLOR_BLACK);
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;
@ -31,7 +32,6 @@ void kterm_init () {
}
}
void kterm_resetcolor(){
kterm_color = vga_entry_color ( VGA_COLOR_LIGHT_GREY , VGA_COLOR_BLACK);
}
@ -42,9 +42,7 @@ void kterm_setcolor(uint8_t color){
void kterm_putat (char c, uint8_t color, size_t x, size_t y ) {
const size_t index = y * VGA_WIDTH + x;
kterm_buffer[index] = vga_entry(c, color);
}
void enable_cursor (uint8_t start_cursor , uint8_t end_cursor ){

View File

@ -1,15 +1,13 @@
#include "kernel.h"
extern "C" void early_main(unsigned long magic, unsigned long addr){
// Convert MBI address to higher quarter kernel space
addr += KERNEL_BASE_ADDR;
/**
extern "C" void early_main()
{
/*
* 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!\n");
@ -17,110 +15,38 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){
// Enable interrupts
asm volatile("STI");
printf("DEBUG:\n Magic: 0x%x\n MBT_addr: 0x%x\n", magic, addr);
/**
* Check Multiboot magic number
* NOTE: Printf call should not be a thing this early on ...
*/
if (magic != MULTIBOOT_BOOTLOADER_MAGIC){
printf("Invalid magic number: 0x%x\n", magic);
return;
}
/**
/*
* Show a little banner for cuteness
*/
printf("|=== BarinkOS ===|\n");
/**
* Use the address given as an argument as the pointer
* to a Multiboot information structure.
*/
multiboot_info_t* mbt = (multiboot_info_t*) (addr );
/**
* Construct our own bootInfo structure
*/
BootInfo bootinfo = {};
/*
If we got a memory map from our bootloader we
should be parsing it to find out the memory regions available.
*/
if (CHECK_FLAG(mbt->flags, 6))
{
/*
Setup Physical memory managment
*/
MemoryInfo meminfo = {};
bootinfo.memory = &meminfo;
///mapMultibootMemoryMap(bootinfo.memory , mbt);
printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory );
BootInfoBlock* BootInfo = (BootInfoBlock*) ( BootInfoBlock_pptr + 0xC0000000 );
/*
PhysicalMemory memAlloc = PhysicalMemory{};
memAlloc.setup(bootinfo.memory );
*/
printf("Bootloader information:\n");
if( BootInfo->ValidELFHeader )
{
printf("- Valid ELF Header is available!\n");
}
// TODO: FIX physical allocator
/*
Mark already in use sections
*/
// Mark kernel memory as used
printf("Kernel Begin Pointer: 0x%x, Kernel end pointer: 0x%x\n", &kernel_begin , &kernel_end );
multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) (mbt->mmap_addr + KERNEL_BASE_ADDR) ;
if(BootInfo->EnabledVBE)
{
printf("- VBE graphics mode is available!\n");
}
for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){
if(BootInfo->ValidSymbolTable)
{
printf("- Valid Symbol Table available at 0x%x.\n Tab Size: %d, str Size: %d\n", BootInfo->SymbolTableAddr, BootInfo->SymbolTabSize, BootInfo->SymbolStrSize);
}
if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){
} else{
printf("allocate region: 0x%x, size : 0x%x bytes\n", (unsigned) mmap->addr,(unsigned) mmap->len );
// memAlloc.allocate_region((unsigned)mmap->addr , (unsigned)mmap->len);
}
}
printf("allocate region: 0x%x, size : 0x%x bytes\n", &kernel_begin, &kernel_end - &kernel_begin );
//memAlloc.allocate_region(kernel_end, kernel_end - kernel_begin);
// test alloc_block
/*
uint8_t* memory = (uint8_t*) memAlloc.allocate_block();
printf("Got a new pointer: 0x%x\n", memory);
uint8_t* memory2 = (uint8_t*) memAlloc.allocate_block();
printf("Got a new pointer: 0x%x\n", memory2);
memAlloc.free_block((void*) memory);
uint8_t* newBlockPlse = (uint8_t*) memAlloc.allocate_block();
*/
//memAlloc.free_block((void*) memory);
//InitializePaging();
//IdentityMap();
//Enable();
} else{
printf("memory flag not set!");
if(BootInfo->PhysicalMemoryMapAvailable)
{
printf("- Physical Memory Map available!\n");
}
CheckMBT( (multiboot_info_t *) addr);
asm volatile("mov %cr0, %eax ");
asm volatile("or $1, %eax");
asm volatile("mov %eax, %cr0");
kernel_main(&bootinfo);
kernel_main();
}
@ -151,9 +77,28 @@ void map_multiboot_info_structure(unsigned long addr){
asm("movl %cr3, %ecx;" "movl %ecx, %cr3" );
}
extern "C" void kernel_main (BootInfo* bootinfo) {
void PhysicalMemoryAllocatorTest(){
#ifdef UNIT_TESTS
// test alloc_block
uint8_t* memory = (uint8_t*) memAlloc.allocate_block();
printf("Got a new pointer: 0x%x\n", memory);
uint8_t* memory2 = (uint8_t*) memAlloc.allocate_block();
printf("Got a new pointer: 0x%x\n", memory2);
memAlloc.free_block((void*) memory);
uint8_t* newBlockPlse = (uint8_t*) memAlloc.allocate_block();
#endif
}
extern "C" void kernel_main () {
pit_initialise();
// Create a dummy BootInfo object
// TODO: This should be done properly or the dependency should
// be removed from the SuperVisorTerminal.
BootInfo* bootinfo = {};
startSuperVisorTerminal(bootinfo);
}

View File

@ -3,19 +3,16 @@ extern "C"
{
#include "Lib/string.h"
}
#include "definitions.h"
#include "Drivers/VGA/VBE.h"
#include "Terminal/kterm.h"
#include "multiboot.h"
#include "bootinfo.h"
#include "Memory/PhysicalMemoryManager.h"
#include "Memory/memoryinfo.h"
#include "Memory/VirtualMemoryManager.h"
#include "KernelLauncher/bootcheck.h"
#include "Memory/GDT/gdtc.h"
#include "Interrupts/idt/idt.h"
@ -27,17 +24,15 @@ extern "C"
#include "time.h"
#include "SuperVisorTerminal/superVisorTerminal.h"
#include "PreKernel/bootstructure.h"
#define CHECK_FLAG(flag, bit) ( flag & (1 << bit ))
#define PANIC(message) {return;}
void map_multiboot_info_structure(unsigned long addr);
extern "C" void kernel_main (BootInfo* bootinfo);
extern "C" void kernel_main ();
extern "C" const void* kernel_begin;
extern "C" const void* kernel_end;
extern "C" uint32_t boot_page_directory;
extern "C" uint32_t multiboot_page_table;

View File

@ -16,7 +16,7 @@ SECTIONS
.multiboot.text : {
*(multiboot.text)
*launcher.o(.text)
*prekernel.o(.text)
}
. += 0xC0000000; /* Addresses in the following code need to be above the 3Gb mark */