roughly add c++

This commit is contained in:
2023-10-21 13:12:03 +02:00
parent 321573a42a
commit d8038a18f9
42 changed files with 367 additions and 367 deletions

View File

@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.26)
project(os2 C ASM_NASM)
project(os2 C CXX ASM_NASM)
#set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)
add_subdirectory(./src/)

View File

@@ -1,6 +1,9 @@
add_executable(kernel.elf)
target_compile_options(kernel.elf PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -ffreestanding>)
target_compile_options(kernel.elf PUBLIC $<$<COMPILE_LANGUAGE:C>:-ffreestanding>)
add_subdirectory(./arch/)
add_subdirectory(./kernel/)

View File

@@ -1,27 +1,27 @@
target_sources(kernel.elf PRIVATE
limine_mm.c
limine_mm.cpp
task.asm
tty.c
kmem.c
tty.cpp
kmem.cpp
kmain.asm
paging.asm
gdt.asm
misc.asm
limine_fb.c
idt.c
serial.c
limine_fb.cpp
idt.cpp
serial.cpp
idt.asm
globals.c
memman.c
timer.c
boot.c
io.c
task.c
paging.c
kmain.c
gdt.c
misc.c)
globals.cpp
memman.cpp
timer.cpp
boot.cpp
io.cpp
task.cpp
paging.cpp
kmain.cpp
gdt.cpp
misc.cpp)
target_include_directories(kernel.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -1,26 +1,26 @@
#include <stddef.h>
#include <stdint.h>
#include <cstddef>
#include <cstdint>
#include "gdt.h"
#include "globals.h"
#include "idt.h"
#include "kmem.h"
#include "gdt.hpp"
#include "globals.hpp"
#include "idt.hpp"
#include "kmem.hpp"
#include "limine.h"
#include "limine_fb.h"
#include "limine_mm.h"
#include "memman.h"
#include "misc.h"
#include "paging.h"
#include "serial.h"
#include "limine_fb.hpp"
#include "limine_mm.hpp"
#include "memman.hpp"
#include "misc.hpp"
#include "paging.hpp"
#include "serial.hpp"
struct AddressSpace BOOT_AddressSpace;
extern void kmain();
// Do final preparations in the new address space then call kmain
__attribute__((noreturn))
__attribute__((used))
void real_start() {
extern "C" __attribute__((noreturn))
__attribute__((used)) void
real_start() {
parse_limine_memmap(limine_mm_entries, limine_mm_count, LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE);
limine_fb_remap(KERN_AddressSpace);
init_kern_heap();
@@ -29,7 +29,7 @@ void real_start() {
// Set up the address space for the kernel and prepare other structures to work without the bootloader,
// then call real_start with this address space and the new stack.
void _start(void) {
extern "C" void _start(void) {
_sse_setup();
barrier();
gdt_setup();
@@ -49,7 +49,7 @@ void _start(void) {
parse_limine_memmap(limine_mm_entries, limine_mm_count, LIMINE_MEMMAP_USABLE);
KERN_AddressSpace = get4k();
KERN_AddressSpace = static_cast<AddressSpace *>(get4k());
assert2(!init_addr_space(KERN_AddressSpace), "Couldn't init kernel address space!");
for (int i = 0; i < 512; i++)

View File

@@ -2,8 +2,8 @@
// Created by Stepan Usatiuk on 13.08.2023.
//
#include "gdt.h"
#include "misc.h"
#include "gdt.hpp"
#include "misc.hpp"
static struct tss_entry_struct tss_entry;
static struct tss_entry_struct tss_entry_user;

View File

@@ -1,7 +1,7 @@
#ifndef OS1_GDT_H
#define OS1_GDT_H
#include "stdint.h"
#include <cstdint>
struct gdt_entry_bits {
unsigned int limit_low : 16;
@@ -53,7 +53,7 @@ struct tss_entry_struct {
uint32_t reserved4;
} __attribute__((packed));
void _gdt_setup();
extern "C" void _gdt_setup();
void gdt_setup();
extern volatile struct gdt_entry_bits gdt_null;

View File

@@ -2,6 +2,6 @@
// Created by Stepan Usatiuk on 13.08.2023.
//
#include "globals.h"
#include "globals.hpp"
uint64_t KERN_stack[KERN_STACK_SIZE] __attribute__((aligned(16)));

View File

@@ -1,39 +1,39 @@
#include "idt.h"
#include "idt.hpp"
#include "gdt.h"
#include "io.h"
#include "misc.h"
#include "serial.h"
#include "task.h"
#include "timer.h"
#include "gdt.hpp"
#include "io.hpp"
#include "misc.hpp"
#include "serial.hpp"
#include "task.hpp"
#include "timer.hpp"
__attribute__((aligned(0x10))) static idt_entry_t idt[256];// Create an array of IDT entries; aligned for performance
static idtr_t idtr;
__attribute__((noreturn)) void exception_handler(void) {
extern "C" __attribute__((noreturn)) void exception_handler(void) {
_hcf();
}
extern void pic1_irq_0();
extern void pic1_irq_1();
extern void pic1_irq_2();
extern void pic1_irq_3();
extern void pic1_irq_4();
extern void pic1_irq_5();
extern void pic1_irq_6();
extern void pic1_irq_7();
extern "C" void pic1_irq_0();
extern "C" void pic1_irq_1();
extern "C" void pic1_irq_2();
extern "C" void pic1_irq_3();
extern "C" void pic1_irq_4();
extern "C" void pic1_irq_5();
extern "C" void pic1_irq_6();
extern "C" void pic1_irq_7();
extern void pic2_irq_0();
extern void pic2_irq_1();
extern void pic2_irq_2();
extern void pic2_irq_3();
extern void pic2_irq_4();
extern void pic2_irq_5();
extern void pic2_irq_6();
extern void pic2_irq_7();
extern "C" void pic2_irq_0();
extern "C" void pic2_irq_1();
extern "C" void pic2_irq_2();
extern "C" void pic2_irq_3();
extern "C" void pic2_irq_4();
extern "C" void pic2_irq_5();
extern "C" void pic2_irq_6();
extern "C" void pic2_irq_7();
void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) {
void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags) {
idt_entry_t *descriptor = &idt[vector];
descriptor->isr_low = (uint64_t) isr & 0xFFFF;
@@ -163,7 +163,7 @@ uint16_t pic_get_isr(void) {
return __pic_get_irq_reg(PIC_READ_ISR);
}
void pic1_irq_real_0(struct task_frame *frame) {
extern "C" void pic1_irq_real_0(struct task_frame *frame) {
timer_tick();
assert2(frame->guard == IDT_GUARD, "IDT Guard wrong!");
assert2((frame->ss == GDTSEL(gdt_data) || frame->ss == GDTSEL(gdt_data_user)), "SS wrong!");
@@ -172,53 +172,53 @@ void pic1_irq_real_0(struct task_frame *frame) {
assert2((frame->ss == GDTSEL(gdt_data) || frame->ss == GDTSEL(gdt_data_user)), "SS wrong!");
PIC_sendEOI(0);
}
void pic1_irq_real_1() {
extern "C" void pic1_irq_real_1() {
PIC_sendEOI(1);
}
void pic1_irq_real_2() {
extern "C" void pic1_irq_real_2() {
_hcf();
PIC_sendEOI(2);
}
void pic1_irq_real_3() {
extern "C" void pic1_irq_real_3() {
PIC_sendEOI(3);
}
void pic1_irq_real_4() {
extern "C" void pic1_irq_real_4() {
PIC_sendEOI(4);
}
void pic1_irq_real_5() {
extern "C" void pic1_irq_real_5() {
PIC_sendEOI(5);
}
void pic1_irq_real_6() {
extern "C" void pic1_irq_real_6() {
PIC_sendEOI(6);
}
void pic1_irq_real_7() {
extern "C" void pic1_irq_real_7() {
int irr = pic_get_irr();
if (!(irr & 0x80)) return;
PIC_sendEOI(7);
}
void pic2_irq_real_0() {
extern "C" void pic2_irq_real_0() {
PIC_sendEOI(8);
}
void pic2_irq_real_1() {
extern "C" void pic2_irq_real_1() {
PIC_sendEOI(9);
}
void pic2_irq_real_2() {
extern "C" void pic2_irq_real_2() {
PIC_sendEOI(10);
}
void pic2_irq_real_3() {
extern "C" void pic2_irq_real_3() {
PIC_sendEOI(11);
}
void pic2_irq_real_4() {
extern "C" void pic2_irq_real_4() {
PIC_sendEOI(12);
}
void pic2_irq_real_5() {
extern "C" void pic2_irq_real_5() {
PIC_sendEOI(13);
}
void pic2_irq_real_6() {
extern "C" void pic2_irq_real_6() {
PIC_sendEOI(14);
}
void pic2_irq_real_7() {
extern "C" void pic2_irq_real_7() {
// Probaby wrong
int irr = pic_get_irr();
if (!(irr & (0x80 << 8))) {

View File

@@ -1,96 +0,0 @@
#ifndef OS1_IDT_H
#define OS1_IDT_H
#include <stdint.h>
#include <stddef.h>
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1+1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2+1)
#define PIC_EOI 0x20 /* End-of-interrupt command code */
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
#define PIC1_OFFSET 0x20
#define PIC2_OFFSET 0x28
void PIC_sendEOI(unsigned char irq);
void PIC_init();
void IRQ_set_mask(unsigned char IRQline) ;
void IRQ_clear_mask(unsigned char IRQline);
uint16_t pic_get_irr(void);
uint16_t pic_get_isr(void);
typedef struct {
uint16_t isr_low; // The lower 16 bits of the ISR's address
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
uint8_t attributes; // Type and attributes; see the IDT page
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
uint32_t isr_high; // The higher 32 bits of the ISR's address
uint32_t reserved; // Set to zero
} __attribute__((packed)) idt_entry_t;
typedef struct {
uint16_t limit;
uint64_t base;
} __attribute__((packed)) idtr_t;
#define IDT_GUARD 0xdeadbe3fdeadb3efULL
// Assuming the compiler understands that this is pushed on the stack in the correct order
struct task_frame {
uint64_t guard;
char ssestate[512];
uint64_t r15;
uint64_t r14;
uint64_t r13;
uint64_t r12;
uint64_t r11;
uint64_t r10;
uint64_t r9;
uint64_t r8;
uint64_t rdi;
uint64_t rsi;
uint64_t rbp;
uint64_t rbx;
uint64_t rdx;
uint64_t rcx;
uint64_t rax;
uint64_t ip;
uint64_t cs;
uint64_t flags;
uint64_t sp;
uint64_t ss;
} __attribute__((packed));
void exception_handler(void);
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
void idt_init(void);
extern void* isr_stub_table[];
#endif

96
src/arch/x86/idt.hpp Normal file
View File

@@ -0,0 +1,96 @@
#ifndef OS1_IDT_H
#define OS1_IDT_H
#include <stddef.h>
#include <stdint.h>
#define PIC1 0x20 /* IO base address for master PIC */
#define PIC2 0xA0 /* IO base address for slave PIC */
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1 + 1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2 + 1)
#define PIC_EOI 0x20 /* End-of-interrupt command code */
#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
#define PIC1_OFFSET 0x20
#define PIC2_OFFSET 0x28
void PIC_sendEOI(unsigned char irq);
void PIC_init();
void IRQ_set_mask(unsigned char IRQline);
void IRQ_clear_mask(unsigned char IRQline);
uint16_t pic_get_irr(void);
uint16_t pic_get_isr(void);
typedef struct {
uint16_t isr_low; // The lower 16 bits of the ISR's address
uint16_t kernel_cs;// The GDT segment selector that the CPU will load into CS before calling the ISR
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
uint8_t attributes;// Type and attributes; see the IDT page
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
uint32_t isr_high; // The higher 32 bits of the ISR's address
uint32_t reserved; // Set to zero
} __attribute__((packed)) idt_entry_t;
typedef struct {
uint16_t limit;
uint64_t base;
} __attribute__((packed)) idtr_t;
#define IDT_GUARD 0xdeadbe3fdeadb3efULL
// Assuming the compiler understands that this is pushed on the stack in the correct order
struct task_frame {
uint64_t guard;
char ssestate[512];
uint64_t r15;
uint64_t r14;
uint64_t r13;
uint64_t r12;
uint64_t r11;
uint64_t r10;
uint64_t r9;
uint64_t r8;
uint64_t rdi;
uint64_t rsi;
uint64_t rbp;
uint64_t rbx;
uint64_t rdx;
uint64_t rcx;
uint64_t rax;
uint64_t ip;
uint64_t cs;
uint64_t flags;
uint64_t sp;
uint64_t ss;
} __attribute__((packed));
extern "C" void exception_handler(void);
void idt_set_descriptor(uint8_t vector, void (*isr)(), uint8_t flags);
void idt_init(void);
extern void (*isr_stub_table[])();
#endif

View File

@@ -2,4 +2,4 @@
// Created by Stepan Usatiuk on 12.08.2023.
//
#include "io.h"
#include "io.hpp"

View File

@@ -1,19 +1,18 @@
//
// Created by Stepan Usatiuk on 13.08.2023.
//
#include <stdatomic.h>
#include <stddef.h>
#include <cstddef>
#include "globals.h"
#include "kmem.h"
#include "limine_fb.h"
#include "memman.h"
#include "misc.h"
#include "mutex.h"
#include "serial.h"
#include "task.h"
#include "timer.h"
#include "tty.h"
#include "globals.hpp"
#include "kmem.hpp"
#include "limine_fb.hpp"
#include "memman.hpp"
#include "misc.hpp"
#include "mutex.hpp"
#include "serial.hpp"
#include "task.hpp"
#include "timer.hpp"
#include "tty.hpp"
void ktask();
@@ -27,7 +26,7 @@ void ktask2() {
// Note: we assume the framebuffer model is RGB with 32-bit pixels.
for (size_t i = 0; i < 100; i++) {
sleep_self(25000);
uint32_t *fb_ptr = framebuffer->address;
uint32_t *fb_ptr = static_cast<uint32_t *>(framebuffer->address);
fb_ptr[i * (framebuffer->pitch / 4) + i + 100] = c ? 0 : 0xFFFFFF;
}
}
@@ -46,7 +45,7 @@ void ktask() {
// Note: we assume the framebuffer model is RGB with 32-bit pixels.
for (size_t i = 0; i < 100; i++) {
sleep_self(25000);
uint32_t *fb_ptr = framebuffer->address;
uint32_t *fb_ptr = static_cast<uint32_t *>(framebuffer->address);
fb_ptr[i * (framebuffer->pitch / 4) + i] = c ? 0 : 0xFFFFFF;
}
}
@@ -65,7 +64,7 @@ void freeprinter() {
}
}
static struct Mutex testmutex = DefaultMutex;
static struct Mutex testmutex;
void mtest1() {
m_lock(&testmutex);
@@ -95,7 +94,7 @@ void mtest3() {
}
void stress() {
static atomic_int i = 0;
static std::atomic<int> i = 0;
int curi = i++;
if (curi > 1500) remove_self();
@@ -131,10 +130,16 @@ void dummy_task() {
}
}
extern void (*ctors_begin)();
extern void (*ctors_end)();
void kmain() {
struct tty_funcs serial_tty = {.putchar = write_serial};
add_tty(serial_tty);
for (void (*ctor)() = ctors_begin; ctor < ctors_end; ctor++)
(*ctor)();
init_timer();
new_ktask(ktask_main, "ktask_main");
new_ktask(dummy_task, "dummy");

View File

@@ -1,22 +1,22 @@
#include "kmem.h"
#include "kmem.hpp"
#include "globals.h"
#include "memman.h"
#include "mutex.h"
#include "paging.h"
#include "serial.h"
#include "task.h"
#include "globals.hpp"
#include "memman.hpp"
#include "mutex.hpp"
#include "paging.hpp"
#include "serial.hpp"
#include "task.hpp"
struct HeapEntry *KERN_HeapBegin;
uintptr_t KERN_HeapEnd;// Past the end
static bool initialized = false;
static struct Mutex kmem_lock = DefaultMutex;
static struct Mutex kmem_lock;
static char kmem_lock_tasklist[256];//FIXME:
void init_kern_heap() {
KERN_HeapBegin = get4k();
KERN_HeapBegin = static_cast<HeapEntry *>(get4k());
KERN_HeapBegin->magic = KERN_HeapMagicFree;
KERN_HeapBegin->len = 4096 - (sizeof(struct HeapEntry));
KERN_HeapBegin->next = NULL;
@@ -44,7 +44,7 @@ struct HeapEntry *split_entry(struct HeapEntry *what, size_t n) {
assert(kmem_lock.owner == cur_task());
assert2(what->len > (n + sizeof(struct HeapEntry)), "Trying to split a heap entry that's too small!");
struct HeapEntry *new_entry = (((void *) what) + sizeof(struct HeapEntry) + n);
struct HeapEntry *new_entry = (struct HeapEntry *) (((void *) what) + sizeof(struct HeapEntry) + n);
new_entry->magic = KERN_HeapMagicFree;
new_entry->next = what->next;
@@ -242,7 +242,7 @@ void kfree(void *addr) {
assert(initialized);
m_lock(&kmem_lock);
struct HeapEntry *freed = addr - (sizeof(struct HeapEntry));
struct HeapEntry *freed = (struct HeapEntry *) (addr - (sizeof(struct HeapEntry)));
struct HeapEntry *entry = KERN_HeapBegin;
assert2(freed->magic == KERN_HeapMagicTaken, "Bad free!");
assert2(freed->next == NULL, "Bad free!");
@@ -267,15 +267,15 @@ void kfree(void *addr) {
void *krealloc(void *addr, size_t newsize) {
assert(initialized);
struct HeapEntry *info = addr - (sizeof(struct HeapEntry));
struct HeapEntry *info = (struct HeapEntry *) (addr - (sizeof(struct HeapEntry)));
assert2(info->magic == KERN_HeapMagicTaken, "Bad realloc!");
void *new = kmalloc(newsize);
void *newt = kmalloc(newsize);
memcpy(new, addr, newsize > info->len ? info->len : newsize);
memcpy(newt, addr, newsize > info->len ? info->len : newsize);
kfree(addr);
return new;
return newt;
}
void *memcpy(void *dest, const void *src, size_t n) {

View File

@@ -2,11 +2,11 @@
// Created by Stepan Usatiuk on 12.08.2023.
//
#include "limine_fb.h"
#include "limine_fb.hpp"
#include <stddef.h>
#include "kmem.h"
#include "kmem.hpp"
static volatile struct limine_framebuffer_request framebuffer_request = {
.id = LIMINE_FRAMEBUFFER_REQUEST,
@@ -19,7 +19,7 @@ struct {
uint64_t len;
} framebufferAddrs[10];
void limine_fb_save_response(struct AddressSpace* boot_address_space) {
void limine_fb_save_response(struct AddressSpace *boot_address_space) {
if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) {
framebuffer_count = 0;
return;
@@ -33,7 +33,7 @@ void limine_fb_save_response(struct AddressSpace* boot_address_space) {
}
}
void limine_fb_remap(struct AddressSpace* space) {
void limine_fb_remap(struct AddressSpace *space) {
for (int i = 0; i < framebuffer_count; i++) {
void *base = framebuffers[i].address;
void *realbase = framebufferAddrs[i].base;

View File

@@ -7,10 +7,10 @@
#include "limine.h"
#include "paging.h"
#include "paging.hpp"
void limine_fb_save_response(struct AddressSpace* boot_address_space);
void limine_fb_remap(struct AddressSpace* space);
void limine_fb_save_response(struct AddressSpace *boot_address_space);
void limine_fb_remap(struct AddressSpace *space);
extern int framebuffer_count;
extern struct limine_framebuffer framebuffers[10];

View File

@@ -1,29 +0,0 @@
//
// Created by Stepan Usatiuk on 12.08.2023.
//
#include "limine_mm.h"
#include "kmem.h"
#include "limine.h"
static volatile struct limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST,
.revision = 0};
unsigned int limine_mm_count;
struct limine_memmap_entry limine_mm_entries[LIMINE_MM_MAX];
unsigned int limine_mm_overflow;
void limine_mm_save_response() {
limine_mm_count = memmap_request.response->entry_count;
if (limine_mm_count > LIMINE_MM_MAX) {
limine_mm_count = LIMINE_MM_MAX;
limine_mm_overflow = 1;
} else {
limine_mm_overflow = 0;
}
for (int i = 0; i < limine_mm_count; i++) {
memcpy(&limine_mm_entries[i], memmap_request.response->entries[i], sizeof(struct limine_memmap_entry));
}
}

View File

@@ -0,0 +1,29 @@
//
// Created by Stepan Usatiuk on 12.08.2023.
//
#include "limine_mm.hpp"
#include "kmem.hpp"
#include "limine.h"
static volatile struct limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST,
.revision = 0};
unsigned int limine_mm_count;
struct limine_memmap_entry limine_mm_entries[LIMINE_MM_MAX];
unsigned int limine_mm_overflow;
void limine_mm_save_response() {
limine_mm_count = memmap_request.response->entry_count;
if (limine_mm_count > LIMINE_MM_MAX) {
limine_mm_count = LIMINE_MM_MAX;
limine_mm_overflow = 1;
} else {
limine_mm_overflow = 0;
}
for (int i = 0; i < limine_mm_count; i++) {
memcpy(&limine_mm_entries[i], memmap_request.response->entries[i], sizeof(struct limine_memmap_entry));
}
}

View File

@@ -31,6 +31,11 @@ SECTIONS
. += CONSTANT(MAXPAGESIZE);
.rodata : {
ctors_begin = .;
*(.ctors)
*(.init_array)
ctors_end = .;
*(.rodata .rodata.*)
} :rodata

View File

@@ -2,11 +2,11 @@
// Created by Stepan Usatiuk on 12.08.2023.
//
#include "memman.h"
#include "misc.h"
#include "mutex.h"
#include "paging.h"
#include "serial.h"
#include "memman.hpp"
#include "misc.hpp"
#include "mutex.hpp"
#include "paging.hpp"
#include "serial.hpp"
#include <stddef.h>

View File

@@ -2,7 +2,7 @@
// Created by Stepan Usatiuk on 13.08.2023.
//
void _hcf() {
extern "C" void _hcf() {
while (1)
asm volatile("cli; hlt");
}

View File

@@ -3,10 +3,11 @@
#include <stdint.h>
void _sse_setup();
void _hcf();
extern "C" void _sse_setup();
extern "C" void _hcf();
#define barrier() __asm__ __volatile__ ("" ::: "memory");
#define barrier() __asm__ __volatile__("" :: \
: "memory");
static inline uint64_t *get_cr3() {
uint64_t *cr3;
@@ -52,7 +53,6 @@ static inline void irqrestore(unsigned long flags) {
}
char *itoa(int value, char *str, int base);
#endif

View File

@@ -2,24 +2,24 @@
// Created by Stepan Usatiuk on 09.08.2023.
//
#include "paging.h"
#include "paging.hpp"
#include "limine.h"
#include "memman.h"
#include "misc.h"
#include "serial.h"
#include "memman.hpp"
#include "misc.hpp"
#include "serial.hpp"
struct AddressSpace *KERN_AddressSpace;
int init_addr_space(struct AddressSpace *space) {
assert2(space != NULL, "Got null!");
space->PML4 = get4k();
space->PML4 = static_cast<uint64_t *>(get4k());
if (space->PML4 == NULL) return 1;
return 0;
}
// Returns a free page frame in HHDM
uint64_t *get_free_frame() {
uint64_t *res = get4k();
uint64_t *res = static_cast<uint64_t *>(get4k());
if (res)
for (int j = 0; j < 512; j++)
res[j] = 0;

View File

@@ -40,6 +40,6 @@ void *virt2real(void *virt, struct AddressSpace *space);
void map_hddm(uint64_t *pml4);
void _tlb_flush();
extern "C" void _tlb_flush();
#endif//OS1_PAGING_H

View File

@@ -2,12 +2,12 @@
// Created by Stepan Usatiuk on 12.08.2023.
//
#include "serial.h"
#include "serial.hpp"
#include <stdint.h>
#include "io.h"
#include "task.h"
#include "io.hpp"
#include "task.hpp"
#define PORT 0x3f8// COM1

View File

@@ -5,7 +5,7 @@
#ifndef OS1_SERIAL_H
#define OS1_SERIAL_H
#include "misc.h"
#include "misc.hpp"
int init_serial();
@@ -15,14 +15,14 @@ char read_serial();
int is_transmit_empty();
void write_serial(char a);
void writestr(const char *a);
extern "C" {
static inline void _assert2(int val, const char *msg) {
if (!val) {
writestr(msg);
_hcf();
}
}
}
#define assert2(x, y) _assert2(x, y)
#define assert(x) _assert2(x, "Assertion failed")

View File

@@ -2,16 +2,16 @@
// Created by Stepan Usatiuk on 18.08.2023.
//
#include "task.h"
#include "cv.h"
#include "gdt.h"
#include "kmem.h"
#include "misc.h"
#include "mutex.h"
#include "paging.h"
#include "serial.h"
#include "timer.h"
#include "tty.h"
#include "task.hpp"
#include "cv.hpp"
#include "gdt.hpp"
#include "kmem.hpp"
#include "misc.hpp"
#include "mutex.hpp"
#include "paging.hpp"
#include "serial.hpp"
#include "timer.hpp"
#include "tty.hpp"
void sanity_check_frame(struct task_frame *cur_frame) {
assert2((void *) cur_frame->ip != NULL, "Sanity check");
@@ -36,16 +36,16 @@ struct TaskListNode *RunningTask;
struct TaskList NextTasks;
// New tasks
struct Mutex NewTasks_lock = DefaultMutex;
struct Mutex NewTasks_lock;
struct TaskList NewTasks;
// Unblocked tasks
struct Mutex UnblockedTasks_lock = DefaultMutex;
struct Mutex UnblockedTasks_lock;
struct TaskList UnblockedTasks;
// Task freer
struct Mutex TasksToFree_lock = DefaultMutex;
struct CV TasksToFree_cv = DefaultCV;
struct Mutex TasksToFree_lock;
struct CV TasksToFree_cv;
struct TaskList TasksToFree;
struct TaskList TasksToFreeTemp;
@@ -53,7 +53,7 @@ struct TaskList TasksToFreeTemp;
//struct Mutex WaitingTasks_lock = DefaultMutex;
struct TaskList WaitingTasks;
static volatile atomic_bool initialized = false;
static std::atomic<bool> initialized = false;
static void free_task(struct Task *t) {
kfree(t->stack);
@@ -66,7 +66,7 @@ static void free_task_list_node(struct TaskListNode *t) {
}
static struct TaskListNode *new_task_list_node() {
struct TaskListNode *ret = kmalloc(sizeof(struct TaskListNode));
struct TaskListNode *ret = static_cast<TaskListNode *>(kmalloc(sizeof(struct TaskListNode)));
ret->task = NULL;
ret->next = NULL;
return ret;
@@ -153,7 +153,7 @@ static struct TaskListNode *pop_front_node(struct TaskList *list) {
}
_Noreturn static void task_freer() {
static void task_freer() {
while (true) {
m_lock(&TasksToFree_lock);
cv_wait(&TasksToFree_lock, &TasksToFree_cv);
@@ -165,29 +165,29 @@ _Noreturn static void task_freer() {
}
}
struct Task *new_ktask(void(*fn), char *name) {
struct Task *new = kmalloc(sizeof(struct Task));
new->stack = kmalloc(TASK_SS);
new->name = kmalloc(strlen(name) + 1);
strcpy(name, new->name);
struct Task *new_ktask(void (*fn)(), char *name) {
struct Task *newt = static_cast<Task *>(kmalloc(sizeof(struct Task)));
newt->stack = static_cast<uint64_t *>(kmalloc(TASK_SS));
newt->name = static_cast<char *>(kmalloc(strlen(name) + 1));
strcpy(name, newt->name);
new->frame.sp = ((uint64_t) (&((void *) new->stack)[TASK_SS - 1]) & (~0xFULL));// Ensure 16byte alignment
new->frame.ip = (uint64_t) fn;
new->frame.cs = GDTSEL(gdt_code);
new->frame.ss = GDTSEL(gdt_data);
for (int i = 0; i < 512; i++) new->frame.ssestate[i] = 0;
new->frame.flags = flags();
new->frame.guard = IDT_GUARD;
new->addressSpace = KERN_AddressSpace;
new->state = TS_RUNNING;
new->mode = TASKMODE_KERN;
newt->frame.sp = ((((uintptr_t) newt->stack) + TASK_SS - 1) & (~0xFULL));// Ensure 16byte alignment
newt->frame.ip = (uint64_t) fn;
newt->frame.cs = GDTSEL(gdt_code);
newt->frame.ss = GDTSEL(gdt_data);
for (int i = 0; i < 512; i++) newt->frame.ssestate[i] = 0;
newt->frame.flags = flags();
newt->frame.guard = IDT_GUARD;
newt->addressSpace = KERN_AddressSpace;
newt->state = TS_RUNNING;
newt->mode = TASKMODE_KERN;
sanity_check_frame(&new->frame);
sanity_check_frame(&newt->frame);
m_lock(&NewTasks_lock);
append_task(&NewTasks, new);
append_task(&NewTasks, newt);
m_unlock(&NewTasks_lock);
return new;
return newt;
}
void init_tasks() {
@@ -218,7 +218,7 @@ void yield_self() {
}
void switch_task(struct task_frame *cur_frame) {
extern "C" void switch_task(struct task_frame *cur_frame) {
if (!atomic_load(&initialized)) return;
sanity_check_frame(cur_frame);
@@ -316,7 +316,7 @@ void switch_task_int(struct task_frame *cur_frame) {
void wait_m_on_self(struct Mutex *m) {
if (!m->waiters) {
m->waiters = kmalloc(sizeof(struct TaskList));
m->waiters = static_cast<TaskList *>(kmalloc(sizeof(struct TaskList)));
m->waiters->cur = NULL;
m->waiters->last = NULL;
}
@@ -327,16 +327,16 @@ void wait_m_on_self(struct Mutex *m) {
}
void m_unlock_sched_hook(struct Mutex *m) {
struct TaskListNode *new = NULL;
struct TaskListNode *newt = NULL;
NO_INT(if (m->waiters) {
new = pop_front_node(m->waiters);
newt = pop_front_node(m->waiters);
})
if (new) {
new->task->state = TS_RUNNING;
if (newt) {
newt->task->state = TS_RUNNING;
m_spin_lock(&UnblockedTasks_lock);
append_task_node(&UnblockedTasks, new);
append_task_node(&UnblockedTasks, newt);
m_unlock(&UnblockedTasks_lock);
}
}
@@ -344,7 +344,7 @@ void m_unlock_sched_hook(struct Mutex *m) {
void wait_cv_on_self(struct CV *cv) {
if (!cv->waiters) {
cv->waiters = kmalloc(sizeof(struct TaskList));
cv->waiters = static_cast<TaskList *>(kmalloc(sizeof(struct TaskList)));
cv->waiters->cur = NULL;
cv->waiters->last = NULL;
}
@@ -355,19 +355,19 @@ void wait_cv_on_self(struct CV *cv) {
}
void cv_unlock_sched_hook(struct CV *cv, int who) {
struct TaskListNode *new = NULL;
struct TaskListNode *newt = NULL;
do {
NO_INT(if (cv->waiters) {
new = pop_front_node(cv->waiters);
newt = pop_front_node(cv->waiters);
})
if (new) {
new->task->state = TS_RUNNING;
if (newt) {
newt->task->state = TS_RUNNING;
m_spin_lock(&UnblockedTasks_lock);
append_task_node(&UnblockedTasks, new);
append_task_node(&UnblockedTasks, newt);
m_unlock(&UnblockedTasks_lock);
}
} while (new && (who == CV_NOTIFY_ALL));
} while (newt && (who == CV_NOTIFY_ALL));
}

View File

@@ -7,7 +7,7 @@
#include <stdbool.h>
#include "idt.h"
#include "idt.hpp"
#define TASK_SS 16384
@@ -39,17 +39,17 @@ struct Task {
struct Task *cur_task();
void init_tasks();
struct Task *new_ktask(void(*fn), char *name);
struct Task *new_ktask(void (*fn)(), char *name);
void remove_self();
void sleep_self(uint64_t diff);
void switch_task(struct task_frame *cur_frame);
extern "C" void switch_task(struct task_frame *cur_frame);
void switch_task_int(struct task_frame *cur_frame);
void wait_m_on_self(struct Mutex *m);
void m_unlock_sched_hook(struct Mutex *m);
void wait_cv_on_self(struct CV *cv);
void stop_waiting_on(struct Mutex *m);
void yield_self();
void _yield_self_kern();// Expects the caller to save interrupt state
extern "C" void _yield_self_kern();// Expects the caller to save interrupt state
void cv_unlock_sched_hook(struct CV *cv, int who);
#endif//OS1_TASK_H

View File

@@ -2,10 +2,10 @@
// Created by Stepan Usatiuk on 14.08.2023.
//
#include "timer.h"
#include "timer.hpp"
#include "idt.h"
#include "io.h"
#include "idt.hpp"
#include "io.hpp"
volatile uint64_t ticks;
volatile uint64_t micros;

View File

@@ -2,14 +2,14 @@
// Created by Stepan Usatiuk on 25.08.2023.
//
#include "tty.h"
#include "tty.hpp"
#include "kmem.h"
#include "mutex.h"
#include "serial.h"
#include "kmem.hpp"
#include "mutex.hpp"
#include "serial.hpp"
static unsigned ttyNum = 0;
static struct Mutex ttysMutex = DefaultMutex;
static struct Mutex ttysMutex;
struct ttys {
unsigned num;
@@ -18,16 +18,16 @@ struct ttys {
struct ttys ttys = {.num = 0};
unsigned add_tty(struct tty_funcs funcs) {
void add_tty(struct tty_funcs funcs) {
m_lock(&ttysMutex);
if (ttyNum >= ttys.num) {
if (ttys.num == 0) {
ttys.ttys = kmalloc(sizeof(struct ttys) + sizeof(struct tty));
ttys.ttys = static_cast<tty *>(kmalloc(sizeof(struct ttys) + sizeof(struct tty)));
ttys.num = 1;
} else {
ttys.num *= 2;
ttys.ttys = krealloc(ttys.ttys, sizeof(struct ttys) + sizeof(struct tty) * ttys.num);
ttys.ttys = static_cast<tty *>(krealloc(ttys.ttys, sizeof(struct ttys) + sizeof(struct tty) * ttys.num));
}
assert2(ttys.ttys != NULL, "Couldn't allocate memory for ttys!");
}

View File

@@ -5,7 +5,7 @@
#ifndef OS1_TTY_H
#define OS1_TTY_H
#include "mutex.h"
#include "mutex.hpp"
#include <stdint.h>
struct tty_funcs {
@@ -18,7 +18,7 @@ struct tty {
struct tty_funcs funcs;
};
unsigned add_tty(struct tty_funcs);
void add_tty(struct tty_funcs);
void tty_putchar(struct tty *tty, char c);
void tty_putstr(struct tty *tty, const char *str);

View File

@@ -1,3 +1,3 @@
target_include_directories(kernel.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_sources(kernel.elf PRIVATE mutex.c cv.c)
target_sources(kernel.elf PRIVATE mutex.cpp cv.cpp)

View File

@@ -2,11 +2,11 @@
// Created by Stepan Usatiuk on 20.08.2023.
//
#include "cv.h"
#include "cv.hpp"
#include "mutex.h"
#include "serial.h"
#include "task.h"
#include "mutex.hpp"
#include "serial.hpp"
#include "task.hpp"
void cv_wait(struct Mutex *m, struct CV *cv) {
m_unlock(m);

View File

@@ -5,8 +5,8 @@
#ifndef OS1_CV_H
#define OS1_CV_H
#include <stdatomic.h>
#include <stddef.h>
#include <atomic>
#include <cstddef>
#if !(ATOMIC_INT_LOCK_FREE == 2)
#error Atomic int isnt lock free!
@@ -21,14 +21,10 @@ enum CV_NOTIFY {
};
struct CV {
atomic_int_fast8_t notified;
std::atomic<int> notified;
struct TaskList *waiters;
};
static const struct CV DefaultCV = {
.notified = ATOMIC_VAR_INIT(CV_NOTIFY_NONE),
.waiters = NULL};
void cv_wait(struct Mutex *m, struct CV *cv);
void cv_notify_one(struct CV *cv);
void cv_notify_all(struct CV *cv);

View File

@@ -2,10 +2,10 @@
// Created by Stepan Usatiuk on 20.08.2023.
//
#include "mutex.h"
#include "serial.h"
#include "task.h"
#include "timer.h"
#include "mutex.hpp"
#include "serial.hpp"
#include "task.hpp"
#include "timer.hpp"
void m_init(struct Mutex *m) {
atomic_init(&m->locked, false);
@@ -15,8 +15,8 @@ void m_init(struct Mutex *m) {
}
bool m_try_lock(struct Mutex *m) {
volatile atomic_bool expected = ATOMIC_VAR_INIT(false);
if (!atomic_compare_exchange_strong(&m->locked, &expected, true)) {
bool expected = false;
if (!m->locked.compare_exchange_strong(expected, true)) {
return false;
}
m->owner = cur_task();
@@ -64,8 +64,8 @@ void m_lock(struct Mutex *m) {
}
void m_unlock(struct Mutex *m) {
volatile atomic_bool expected = ATOMIC_VAR_INIT(true);
if (!atomic_compare_exchange_strong(&m->locked, &expected, false))
bool expected = true;
if (!m->locked.compare_exchange_strong(expected, false))
writestr("Unlocking an unlocked mutex!\n");
m_unlock_sched_hook(m);
}

View File

@@ -5,27 +5,18 @@
#ifndef OS1_MUTEX_H
#define OS1_MUTEX_H
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <atomic>
#include <cstddef>
#include <cstdint>
#if !(ATOMIC_BOOL_LOCK_FREE == 2)
#error Atomic bool isnt lock free!
#endif
struct Mutex {
volatile atomic_bool locked;
std::atomic<bool> locked;
struct TaskList *waiters;
struct Task *owner;
uint8_t spin_success;
};
static const struct Mutex DefaultMutex = {
.locked = ATOMIC_VAR_INIT(false),
.spin_success = 150,
.waiters = NULL};
void m_init(struct Mutex *m);
void m_lock(struct Mutex *m);
void m_spin_lock(struct Mutex *m);