Browse Source

this is such an enormous commit*

master
Mathieu Sérandour 1 year ago
parent
commit
c2008bc6c6
  1. 8
      Makefile
  2. 13
      disk_root/boot/limine.cfg
  3. 55
      kernel/acpi/acpi.c
  4. 7
      kernel/acpi/acpi.h
  5. 41
      kernel/acpi/acpitables.h
  6. 116
      kernel/debug/dump.c
  7. 23
      kernel/debug/dump.h
  8. 21
      kernel/debug/panic.c
  9. 39
      kernel/entry.c
  10. 2
      kernel/int/idt.c
  11. 21
      kernel/int/isr.c
  12. 11
      kernel/memory/gdt.s

8
Makefile

@ -1,11 +1,17 @@
.PHONY: clean all disk kernel force_look threaded_build
.PHONY: clean all run disk kernel force_look threaded_build
HDD_ROOT := disc_root
HDD_FILE := disk.hdd
USED_LOOPBACK := /dev/loop6
QEMU_PATH := "/mnt/d/Program Files/qemu/qemu-system-x86_64.exe"
QEMU_ARGS := -monitor stdio -d cpu_reset -bios "d:/Program Files/qemu/bios/OVMF.fd"
run: all
$(QEMU_PATH) $(QEMU_ARGS) $(HDD_FILE)
all: disk
threaded_build:

13
disk_root/boot/limine.cfg

@ -1,11 +1,14 @@
DEFAULT_ENTRY=1
TIMEOUT=10
GRAPHICS=yes
VERBOSE=yes
#TIMEOUT=10
#GRAPHICS=yes
#VERBOSE=yes
TIMEOUT=0
GRAPHICS=no
VERBOSE=no
THEME_MARGIN=64
#RESOLUTION=800x600
BACKGROUND_PATH=boot:///boot/bg.bmp
#BACKGROUND_PATH=boot:///boot/bg.bmp
#THEME_BACKGROUND=8f000000
BACKGROUND_STYLE=centered
@ -13,6 +16,6 @@ BACKGROUND_STYLE=centered
PROTOCOL=stivale2
#RESOLUTION=800x600
BACKGROUND_PATH=boot:///boot/bg.bmp
#BACKGROUND_PATH=boot:///boot/bg.bmp
KERNEL_PATH=boot:///boot/kernel.elf
BACKGROUND_STYLE=centered

55
kernel/acpi/acpi.c

@ -0,0 +1,55 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "acpi.h"
#include "../common.h"
#include "../debug/assert.h"
#include "../debug/dump.h"
#include "../klib/sprintf.h"
#include "acpitables.h"
bool checksum(void* table, size_t size) {
uint8_t sum = 0;
uint8_t* raw = table;
for(size_t i;size > 0; --size) {
sum += raw[i++];
}
return sum == 0;
}
typedef uint64_t rsdp_entry_t;
void read_acpi_tables(void* rsdp_location) {
struct RSDPDescriptor20* rsdpd = rsdp_location;
dump(rsdpd, sizeof(struct RSDPDescriptor20), 8, DUMP_HEX8);
assert(rsdpd->firstPart.revision >= 2);
// checksum for xsdt
assert(rsdpd->length == sizeof(rsdpd));
assert(checksum(rsdpd, rsdpd->length));
// lets parse it!!
const struct ACPISDTHeader* xsdt = (void *)rsdpd->xsdtAddress;
size_t n_entries = (xsdt->length - sizeof(xsdt)) / sizeof(rsdp_entry_t);
rsdp_entry_t* table = (xsdt + 1);
for(int i = 0; i < n_entries; i++) {
kprintf("%3u: %s\n", table[i])
//table[i]
}
}

7
kernel/acpi/acpi.h

@ -0,0 +1,7 @@
#pragma once
/*
read RSDP, XSDP, MADT, FADT
*/
void read_acpi_tables(void* rsdp_location);

41
kernel/acpi/acpitables.h

@ -0,0 +1,41 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "../common.h"
struct RSDPDescriptor {
uint8_t signature[8];
uint8_t checksum;
uint8_t OEMID[6];
uint8_t revision;
uint32_t rsdtAddress;
} __packed;
struct RSDPDescriptor20 {
struct RSDPDescriptor firstPart;
uint32_t length;
uint64_t xsdtAddress;
uint8_t extendedChecksum;
uint8_t reserved[3];
} __packed;
// plagia from
// https://github.com/DorianXGH/Lucarnel/blob/master/src/includes/acpi.h
//
struct ACPISDTHeader
{
uint8_t signature[4]; // signature of the table
uint32_t length; // length of the table
uint8_t revision;
uint8_t checksum;
uint8_t OEMID[6];
uint8_t OEMtableID[8];
uint32_t OEMrevision;
uint32_t creatorID;
uint32_t creator_revision;
} __packed;

116
kernel/debug/dump.c

@ -0,0 +1,116 @@
#include "dump.h"
#include "../klib/sprintf.h"
/**
* dump a memory chunk in kprintf
* addr: address of the beginning of the chunk
* size: number of bytes to dump
* line_size: number of words per line
*
* mode: either
* DUMP_HEX8 : hexadecimal integers of size 8 bits
* DUMP_HEX32 : hexadecimal integers of size 32 bits
* DUMP_HEX64 : hexadecimal integers of size 64 bits
* DUMP_DEC8 : decimal integers of size 8 bits
* DUMP_DEC32 : decimal integers of size 32 bits
* DUMP_DEC64 : decimal integers of size 64 bits
*
**/
void dump(const void* addr, size_t size, size_t line_size, uint8_t mode) {
char row_fmt[8], last_row_fmt[8];
size_t pitch; // sizeof word
int i = 0;
row_fmt [i] = '%';
last_row_fmt[i] = '%';
i++;
// create fmts for printf
// word width
if((mode & DUMP_8) != 0) {
// byte mode
row_fmt [i] = '2';
last_row_fmt[i] = '2';
i++;
pitch = 1;
}
else if((mode & DUMP_64) == 0) {
// normal 32bit mode
row_fmt [i] = '8';
last_row_fmt[i] = '8';
i++;
pitch = 4;
}
else {
// long mode
row_fmt [i] = 'l';
last_row_fmt[i] = 'l';
i++;
row_fmt [i] = '1';
last_row_fmt[i] = '1';
i++;
row_fmt [i] = '6';
last_row_fmt[i] = '6';
i++;
pitch = 8;
}
// base
char base_id;
if((mode & DUMP_HEX) == 0) // hex
base_id = 'x';
else // dec
base_id = 'u';
row_fmt [i] = base_id;
last_row_fmt[i] = base_id;
i++;
row_fmt [i] = ' ';
last_row_fmt[i] = '\n';
i++;
row_fmt [i] = '\0';
last_row_fmt[i] = '\0';
i++;
size /= pitch;
size_t lines = (size + line_size - 1) / line_size;
// iterator ptr
const uint8_t* ptr = addr;
// create mask : create the complementary with 0xff...ff << n
// then complement it
const uint64_t mask = ~(~0llu << 8*pitch);
for(size_t i = 0; i < lines; i++) {
// the last line might not be full
// therefore we have to check each one
for(size_t j = 0; j < line_size-1; j++) {
if(size-- <= 1)
break;
else {
kprintf(row_fmt, *(uint64_t *)ptr & mask);
ptr+=pitch;
}
}
kprintf(last_row_fmt, *(uint64_t *)ptr & mask);
ptr+=pitch;
}
}

23
kernel/debug/dump.h

@ -0,0 +1,23 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#define DUMP_HEX 0
#define DUMP_DEC 16
#define DUMP_8 32
#define DUMP_32 0
#define DUMP_64 1
#define DUMP_HEX8 (DUMP_HEX | DUMP_8)
#define DUMP_HEX32 (DUMP_HEX | DUMP_32)
#define DUMP_HEX64 (DUMP_HEX | DUMP_64)
#define DUMP_DEC8 (DUMP_DEC | DUMP_8)
#define DUMP_DEC32 (DUMP_DEC | DUMP_32)
#define DUMP_DEC64 (DUMP_DEC | DUMP_64)
void dump(const void* addr, size_t size, size_t line_size, uint8_t mode);

21
kernel/debug/panic.c

@ -3,6 +3,9 @@
#include "../video/terminal.h"
int zero = 0;
__attribute__((noreturn)) void panic(const char* panic_string) {
// checks if video is operationnal
if(get_terminal_handler() != NULL) {
@ -11,16 +14,20 @@ __attribute__((noreturn)) void panic(const char* panic_string) {
if(panic_string == NULL)
panic_string = "(null)";
kprintf(
kputs(
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
"!!!!!!!!!!!!! KERNL PANIC !!!!!!!!!!!!!\n"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
"%s\n\n"
"you may manually shutdown the machine.\n",
panic_string
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
kputs(panic_string);
kputs(
"\n\n"
"you may manually shutdown the machine.\n"
);
}
for(;;)
asm volatile("hlt");
asm volatile("cli");
asm volatile("hlt");
__builtin_unreachable();
}

39
kernel/entry.c

@ -7,6 +7,7 @@
#include "klib/sprintf.h"
#include "klib/string.h"
#include "video/terminal.h"
#include "acpi/acpi.h"
#include "common.h"
#include "regs.h"
@ -15,12 +16,6 @@
// 8K stack
static uint8_t stack[8192] __align(16);
// stivale2 offers a runtime terminal service which can be ditched at any
// time, but it provides an easy way to print out to graphical terminal,
// especially during early boot.
// Read the notes about the requirements for using this feature below this
// code block.
static struct stivale2_header_tag_terminal terminal_hdr_tag = {
// All tags need to begin with an identifier and a pointer to the next tag.
.tag = {
@ -95,7 +90,7 @@ void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, uint64_t id) {
// Get a pointer to the next tag in the linked list and repeat.
current_tag = (void *)current_tag->next;
}
}
}
@ -105,20 +100,19 @@ void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, uint64_t id) {
// const char but represents a big string
extern const char _binary_bootmessage_txt;
// print all chars
//#pragma GCC diagnostic push
//#pragma GCC diagnostic ignored "-Wunused-function"
/*
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static void debug_terminal() {
char buff[256];
for(int i = 0; i < 256; i++)
buff[i] = i+1;
kputs(buff);
}
*/
//#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
// Registers %rbp, %rbx and %r12 through %r15 “belong” to the calling functio
@ -146,8 +140,14 @@ void _start(struct stivale2_struct *stivale2_struct) {
struct stivale2_struct_tag_framebuffer fbtag;
struct stivale2_struct_tag_framebuffer* _fbtag = stivale2_get_tag(stivale2_struct,0x506461d2950408fa);
memcpy(&fbtag, _fbtag, sizeof(fbtag));
struct stivale2_struct_tag_rsdp* rsdp_tag_ptr = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_RSDP_ID);
assert(rsdp_tag_ptr != NULL);
uint64_t rsdp_location = rsdp_tag_ptr->rsdp;
memcpy(&fbtag, _fbtag, sizeof(fbtag));
@ -156,7 +156,8 @@ void _start(struct stivale2_struct *stivale2_struct) {
.pitch= fbtag.framebuffer_pitch,
.bpp = fbtag.framebuffer_bpp,
.pix = (void*)fbtag.framebuffer_addr};
init_gdt_table();
initVideo(&sc);
@ -164,16 +165,20 @@ void _start(struct stivale2_struct *stivale2_struct) {
setup_terminal();
setup_isr();
read_acpi_tables((void*)rsdp_location);
asm volatile("sti");
asm volatile("int $0");
kputs(&_binary_bootmessage_txt);
//kprintf("%u\n", y);
for(;;) {
asm volatile ("hlt");
}
__builtin_unreachable();
//*ptr = 0xfffa24821;
asm volatile ("sti");

2
kernel/int/idt.c

@ -69,7 +69,7 @@ static IDTE make_idte(void* handler, type_attr_t type_attr) {
return (IDTE) {
.offset_1 = h & 0xffff,
.selector = 0x28,
.selector = 0x08, // kernel code segment
.ist = 0,
.type_attr = type_attr,
.offset_2 = (h >> 16) & 0xffff,

21
kernel/int/isr.c

@ -1,12 +1,12 @@
#include "../klib/sprintf.h"
#include "../debug/assert.h"
#include "../debug/panic.h"
#include "idt.h"
static void print_frame(struct IFrame* interrupt_frame) {
kprintf(
"RIP: %16lx\n"
@ -33,8 +33,10 @@ __attribute__((interrupt)) void ISR_error_handler(struct IFrame* interrupt_frame
__attribute__((interrupt)) void ISR_div_by_zero_handler(struct IFrame* interrupt_frame) {
kprintf("ISR_div_by_zero_handler():\n");
print_frame(interrupt_frame);
panic("ISR_div_by_zero_handler():\n");
asm volatile("cli");
asm volatile("hlt");
}
@ -60,8 +62,10 @@ __attribute__((interrupt)) void ISR_bound_handler(struct IFrame* interrupt_frame
kprintf("ISR_bound_handler()\n");
}
__attribute__((interrupt)) void ISR_invalid_opcode_handler(struct IFrame* interrupt_frame) {
(void) interrupt_frame;
kprintf("ISR_invalid_opcode_handler()\n");
print_frame(interrupt_frame);
asm volatile("cli");
asm volatile("hlt");
}
__attribute__((interrupt)) void ISR_device_not_available_handler(struct IFrame* interrupt_frame) {
(void) interrupt_frame;
@ -69,6 +73,7 @@ __attribute__((interrupt)) void ISR_device_not_available_handler(struct IFrame*
}
__attribute__((interrupt)) void ISR_double_fault_handler(struct IFrame* interrupt_frame, uint64_t error_code) {
(void) interrupt_frame;
(void) error_code;
kprintf("ISR_double_fault_handler()\n");
}
__attribute__((interrupt)) void ISR_coproc_segment_overrun_handler(struct IFrame* interrupt_frame) {
@ -77,21 +82,27 @@ __attribute__((interrupt)) void ISR_coproc_segment_overrun_handler(struct IFrame
}
__attribute__((interrupt)) void ISR_invalid_TSS_handler(struct IFrame* interrupt_frame, uint64_t error_code) {
(void) interrupt_frame;
(void) error_code;
kprintf("ISR_invalid_TSS_handler()\n");
}
__attribute__((interrupt)) void ISR_segment_not_present_handler(struct IFrame* interrupt_frame, uint64_t error_code) {
(void) error_code;
(void) interrupt_frame;
kprintf("ISR_segment_not_present_handler()\n");
}
__attribute__((interrupt)) void ISR_stack_segment_fault_handler(struct IFrame* interrupt_frame, uint64_t error_code) {
(void) error_code;
(void) interrupt_frame;
kprintf("ISR_stack_segment_fault_handler()\n");
}
__attribute__((interrupt)) void ISR_general_protection_fault_handler(struct IFrame* interrupt_frame, uint64_t error_code) {
(void) error_code;
(void) interrupt_frame;
kprintf("ISR_general_protection_fault_handler()\n");
}
__attribute__((interrupt)) void ISR_page_fault_handler(struct IFrame* interrupt_frame, uint64_t error_code) {
(void) error_code;
(void) interrupt_frame;
kprintf("ISR_page_fault_handler()\n");
}
@ -125,10 +136,6 @@ void setup_isr(void) {
for(int i = 15; i <= 255; i++)
set_interrupt_handler(i, ISR_spurious);
for(size_t i = 0; i < 16; i++) {
kprintf("entry %d:\t%16lx %16lx\n", i, idt[2*i], idt[2*i+1]);
}
setup_idt();
_sti();
}

11
kernel/memory/gdt.s

@ -2,21 +2,24 @@
[global _lgdt]
[global _cr3]
%define KERNEL_CODE_SEGMENT 0x08
%define KERNEL_DATA_SEGMENT 0x10
; argument in RDI
_lgdt:
lgdt [rdi]
mov rax, rsp
push qword 0x30
push qword KERNEL_DATA_SEGMENT
;0x30
push qword rax
pushf
push qword 0x28
pushfq ; push rflags
push qword KERNEL_CODE_SEGMENT
push qword far_ret
iretq
far_ret:
mov ax, 0x30
mov ax, 0x10
mov ds, ax
mov ss, ax
mov es, ax

Loading…
Cancel
Save