a cow based x86_64 operating system, using limine and stivale2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
6.5 KiB

#include <stddef.h>
#include <stdint.h>
#include <stivale2.h>
#include "memory/gdt.h"
#include "drivers/terminal/video.h"
#include "drivers/terminal/terminal.h"
#include "acpi/acpi.h"
1 year ago
#include "acpi/power.h"
2 years ago
#include "int/apic.h"
#include "int/idt.h"
1 year ago
#include "int/pic.h"
#include "drivers/hpet.h"
1 year ago
#include "drivers/pcie.h"
1 year ago
#include "drivers/ps2kb.h"
#include "memory/physical_allocator.h"
1 year ago
#include "memory/paging.h"
1 year ago
#include "memory/vmap.h"
1 year ago
#include "memory/heap.h"
#include "lib/sprintf.h"
#include "lib/string.h"
#include "lib/logging.h"
#include "lib/common.h"
#include "lib/registers.h"
1 year ago
#include "lib/dump.h"
1 year ago
#define KERNEL_STACK_SIZE 8192
1 year ago
1 year ago
// 8K stack
1 year ago
static uint8_t stack_base[KERNEL_STACK_SIZE] __attribute__((section(".stack"))) __align(16);
1 year ago
#define INITIAL_STACK_PTR ((uintptr_t)(stack_base + KERNEL_STACK_SIZE))
// initial stack pointer
const uintptr_t kernel_stack = INITIAL_STACK_PTR;
static struct stivale2_header_tag_terminal terminal_hdr_tag = {
.tag = {
.identifier = STIVALE2_HEADER_TAG_TERMINAL_ID,
.next = 0
},
.flags = 0
};
1 year ago
static struct stivale2_header_tag_framebuffer framebuffer_hdr_tag = {
// Same as above.
.tag = {
.identifier = STIVALE2_HEADER_TAG_FRAMEBUFFER_ID,
.next = (uint64_t)&terminal_hdr_tag
},
.framebuffer_width = 0,
.framebuffer_height = 0,
2 years ago
.framebuffer_bpp = 32
};
__attribute__((section(".stivale2hdr"), used))
static struct stivale2_header stivale_hdr = {
.entry_point = 0,
1 year ago
.stack = INITIAL_STACK_PTR,
1 year ago
.flags = (1 << 1), // Bit 1: stivale2 gives us high half pointers
.tags = (uintptr_t)&framebuffer_hdr_tag // next tag in the linked list
};
1 year ago
static const void *stivale2_get_tag(const struct stivale2_struct *stivale2_struct,
uint64_t id) {
struct stivale2_tag *current_tag = (void *)stivale2_struct->tags;
1 year ago
// travel the linked list
for (;;) {
1 year ago
// We assert that these are not NULL afterwards, when the terminal
// is successfully initialized
if(current_tag == NULL)
return NULL;
1 year ago
if (current_tag->identifier == id) {
return current_tag;
}
1 year ago
current_tag = (void *)current_tag->next;
}
}
1 year ago
#define PRINT_VAL(v) printf(#v "=%ld\n", (uint64_t)v);
#define PRINT_HEX(v) printf(#v "=%lx\n", (uint64_t)v);
// const char but represents a big string
extern const char _binary_bootmessage_txt;
2 years ago
// print all chars
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
2 years ago
static void debug_terminal() {
char buff[256];
for(int i = 0; i < 256; i++)
buff[i] = i+1;
1 year ago
puts(buff);
2 years ago
}
1 year ago
static void print_fb_infos(struct stivale2_struct_tag_framebuffer* framebuffer_tag) {
PRINT_VAL(framebuffer_tag->framebuffer_width);
PRINT_VAL(framebuffer_tag->framebuffer_height);
PRINT_VAL(framebuffer_tag->framebuffer_pitch);
PRINT_VAL(framebuffer_tag->framebuffer_bpp);
PRINT_HEX(framebuffer_tag->framebuffer_addr);
2 years ago
}
#pragma GCC diagnostic pop
2 years ago
1 year ago
static void init_memory(const struct stivale2_struct_tag_memmap* memmap_tag,
1 year ago
const struct stivale2_struct_tag_framebuffer* framebuffer_tag) {
1 year ago
log_debug("init memory...");
init_physical_allocator(memmap_tag);
init_paging(memmap_tag);
// map MMIOs
map_pages(
1 year ago
early_virtual_to_physical((void *)framebuffer_tag->framebuffer_addr),
MMIO_BEGIN,
1 year ago
(framebuffer_tag->framebuffer_height * framebuffer_tag->framebuffer_pitch+0x0fff) / 0x1000,
PRESENT_ENTRY
);
1 year ago
// map lapic & hpet registers
map_acpi_mmios();
1 year ago
}
// Registers %rbp, %rbx and %r12 through %r15 “belong” to the calling functio
// The following will be our kernel's entry point.
void _start(struct stivale2_struct *stivale2_struct) {
// Let's get the terminal structure tag from the bootloader.
1 year ago
const struct stivale2_struct_tag_terminal* term_str_tag;
const struct stivale2_struct_tag_memmap* memmap_tag;
1 year ago
const struct stivale2_struct_tag_framebuffer* framebuffer_tag;
1 year ago
const struct stivale2_struct_tag_rsdp* rsdp_tag_ptr;
1 year ago
const struct stivale2_struct_tag_boot_volume* boot_volume_tag;
1 year ago
1 year ago
term_str_tag = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_TERMINAL_ID);
memmap_tag = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_MEMMAP_ID);
framebuffer_tag = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID);
rsdp_tag_ptr = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_RSDP_ID);
boot_volume_tag = stivale2_get_tag(stivale2_struct, 0x9b4358364c19ee62);
1 year ago
// term_str_tag == NULL is not a blocking
// errror: stivale2 terminal is only used
// to print potential errors occuring when
// initializing bincows' terminal
if (term_str_tag != NULL) {
void *term_write_ptr = (void *)term_str_tag->term_write;
// the default terminal handler does nothing
set_terminal_handler(term_write_ptr);
}
1 year ago
// print all logging messages
set_logging_level(LOG_LEVEL_DEBUG);
1 year ago
setup_isrs();
read_acpi_tables((void*)rsdp_tag_ptr->rsdp);
1 year ago
init_memory(memmap_tag, framebuffer_tag);
1 year ago
// first initialize our terminal
1 year ago
initVideo(framebuffer_tag, (void *)MMIO_BEGIN);
1 year ago
init_gdt_table();
1 year ago
// we cannot use stivale2 terminal
// after loading our gdt
// so we need to load our gdt after our
// terminal is successfully installed
append_paging_initialization();
void empty_terminal_handler(const char* s, size_t l) {
(void) (s + l);
// empty handler by default,
// make sure not to execute the address 0 :)
}
set_terminal_handler(empty_terminal_handler);
// init kernel heap
heap_init();
terminal_install_early();
terminal_set_colors(0xfff0a0, 0x212121);
terminal_install_late();
1 year ago
1 year ago
puts(&_binary_bootmessage_txt);
1 year ago
asm volatile("hlt");
1 year ago
printf("boot logs:\n");
puts(log_get());
log_flush();
1 year ago
pcie_init();
pcie_init_devices();
1 year ago
pic_init();
ps2kb_init();
1 year ago
1 year ago
void kbhandler(const struct kbevent* ev) {
if(ev->type == KEYRELEASED && ev->scancode == PS2KB_ESCAPE) {
shutdown();
}
};
ps2kb_set_event_callback(kbhandler);
hpet_init();
1 year ago
apic_setup_clock();
2 years ago
2 years ago
for(;;) {
asm volatile("hlt");
}
__builtin_unreachable();
}