From: Amelia Coutard Date: Sun, 24 Dec 2023 16:29:04 +0000 (+0100) Subject: Retiré le hack dégueulasse pour importer la librairie standard. Commencé à implémente... X-Git-Url: https://git.ameliathe1st.gay/?a=commitdiff_plain;h=6612d28513742e639786131c721a3cd2f7aa1111;p=voyage-au-centre-des-fichiers.git Retiré le hack dégueulasse pour importer la librairie standard. Commencé à implémenter une librairie "standard" --- diff --git a/Makefile b/Makefile index c308c81..f8ac673 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,8 @@ endif build: # Build as default target CXXFLAGS := -std=c++20 -fno-strict-aliasing -Wall -Wextra -Werror \ - -mgeneral-regs-only -fno-exceptions -fno-rtti -ffreestanding -O2 $(CXXFLAGS) + -mgeneral-regs-only -fno-exceptions -fno-rtti -ffreestanding -O2 \ + -I libcpp $(CXXFLAGS) LDFLAGS := $(CXXFLAGS) $(LDFLAGS) TO_ISO := isodir/boot/grub/grub.cfg diff --git a/kernel/module.mk b/kernel/module.mk index cc8acc3..1263b79 100644 --- a/kernel/module.mk +++ b/kernel/module.mk @@ -24,10 +24,8 @@ TARGETS_TO_VAR := $(OUT_DIR)$(EXEC_NAME) $(PREP) $(DEPS) $(OBJS) $(TARGETS_TO_VAR): SUBDIR := $(SUBDIR) $(TARGETS_TO_VAR): CXX := g++-system -$(TARGETS_TO_VAR): CXXFLAGS := $(CXXFLAGS) -mcmodel=kernel -mno-red-zone\ --isystem $(INCLUDES) -isystem $(INCLUDES)/c++ -isystem $(INCLUDES)/c++/x86_64-unknown-linux-gnu -# The previous line is a dirty hack. But not that much, because it doesn't allow me to include non-freestanding headers anyways -$(TARGETS_TO_VAR): LDFLAGS := $(LDFLAGS) -z max-page-size=0x1000 -mno-red-zone -mcmodel=kernel +$(TARGETS_TO_VAR): CXXFLAGS := $(CXXFLAGS) -mcmodel=kernel -mno-red-zone +$(TARGETS_TO_VAR): LDFLAGS := $(LDFLAGS) -mno-red-zone -mcmodel=kernel -z max-page-size=0x1000 $(TARGETS_TO_VAR): LDLIBS := -nostdlib -lgcc $(OUT_DIR)$(EXEC_NAME): kernel/linker.ld $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(filter-out $(CRTI_OBJ) $(CRTN_OBJ),$(OBJS)) $(CRTEND_OBJ) $(CRTN_OBJ) mkdir -p '$(@D)' diff --git a/kernel/src/elf64.cpp b/kernel/src/elf64.cpp index 1223fcc..1b3f7c9 100644 --- a/kernel/src/elf64.cpp +++ b/kernel/src/elf64.cpp @@ -13,8 +13,8 @@ #include "elf64.hpp" -void os::elf::load_elf(os::process& result, std::byte* start, std::size_t length, const paging::PML4T& original_PML4T) { - os::assert(length >= sizeof(os::elf::header), "Elf file isn't big enough to contain a header: there is an error."); +void os::elf::load_elf(os::process& result, amy::byte* start, amy::size length, const paging::PML4T& original_PML4T) { + os::assert(length >= 0 && (unsigned long long)(length) >= sizeof(os::elf::header), "Elf file isn't big enough to contain a header: there is an error."); // TODO: Check that the elf file sections are all fully inside the file. // Load test-module elf file: @@ -30,14 +30,14 @@ void os::elf::load_elf(os::process& result, std::byte* start, std::size_t length os::assert(elf_header.type == 2, "Elf file not executable."); os::assert(elf_header.arch == 0x3E, "Elf file not x86_64."); - constexpr std::size_t stack_size = 16 * 0x1000 /* 64KiB */; - std::byte* const stack = (std::byte*)0x0000'8000'0000'0000 - stack_size; + constexpr amy::size stack_size = 16 * 0x1000 /* 64KiB */; + amy::byte* const stack = (amy::byte*)0x0000'8000'0000'0000 - stack_size; const auto page = os::paging::page_allocator.allocate(1); os::assert(page.ptr != nullptr, "Not enough memory for elf file loading."); result.PML4T = phys_ptr(page.ptr.get_phys_addr()); - result.rip = std::uint64_t(elf_header.entry); - result.rsp = std::uint64_t(stack + stack_size); + result.rip = amy::u64(elf_header.entry); + result.rsp = amy::u64(stack + stack_size); result.rax = 0; result.rbx = 0; result.rcx = 0; @@ -58,7 +58,7 @@ void os::elf::load_elf(os::process& result, std::byte* start, std::size_t length memset(result.PML4T->contents, 0, 256 * sizeof(os::paging::PML4E)); memcpy(result.PML4T->contents + 256, original_PML4T.contents + 256, 256 * sizeof(os::paging::PML4E)); - for (std::size_t i = 0; i < elf_header.entry_count_program_header_table; i++) { + for (amy::size i = 0; i < elf_header.entry_count_program_header_table; i++) { const os::elf::program_header program_header = *(os::elf::program_header*)( start + elf_header.program_header_table + i * elf_header.entry_size_program_header_table @@ -68,13 +68,13 @@ void os::elf::load_elf(os::process& result, std::byte* start, std::size_t length continue; } os::print("Segment: loadable\n"); - os::assert(0x1000 <= std::uint64_t(program_header.p_vaddr) - && std::uint64_t(program_header.p_vaddr + program_header.p_memsz) < 0x10'0000'0000, + os::assert(0x1000 <= amy::u64(program_header.p_vaddr) + && amy::u64(program_header.p_vaddr + program_header.p_memsz) < 0x10'0000'0000, "Program segments must be contained between 0x1000 and 0x10'0000'0000 (i.e. 64GiB)."); // Allocate, map and initialise memory for segment (memory above program_header.p_filesz is already 0-initialised by the page allocator): - std::size_t nb_pages = (std::uint64_t(program_header.p_vaddr) % 0x1000 + program_header.p_memsz + 0x1000 - 1) / 0x1000; - for (std::size_t i = 0; i < nb_pages; i++) { + amy::size nb_pages = (amy::u64(program_header.p_vaddr) % 0x1000 + program_header.p_memsz + 0x1000 - 1) / 0x1000; + for (amy::size i = 0; i < nb_pages; i++) { auto const alloc = os::paging::page_allocator.allocate(1); os::assert(alloc.ptr != nullptr, "Failed to allocate enough memory for loading of elf binary."); os::paging::map_page(*result.PML4T, (os::paging::page<0>*)(program_header.p_vaddr + i * 0x1000), alloc.ptr, { diff --git a/kernel/src/elf64.hpp b/kernel/src/elf64.hpp index 6136338..8ae4df3 100644 --- a/kernel/src/elf64.hpp +++ b/kernel/src/elf64.hpp @@ -13,7 +13,7 @@ #pragma once -#include +#include #include "lib/phys_ptr.hpp" #include "ring3.hpp" @@ -22,39 +22,39 @@ namespace os { namespace elf { struct program_header; struct header { - std::uint8_t magic[4]; - std::uint8_t bitn; - std::uint8_t endianness; - std::uint8_t header_version; - std::uint8_t abi; - std::uint64_t : 64; - std::uint16_t type; - std::uint16_t arch; - std::uint32_t elf_version; + amy::u8 magic[4]; + amy::u8 bitn; + amy::u8 endianness; + amy::u8 header_version; + amy::u8 abi; + amy::u64 : 64; + amy::u16 type; + amy::u16 arch; + amy::u32 elf_version; void* entry; - std::uint64_t program_header_table; - std::uint64_t section_header_table; - std::uint32_t flags; - std::uint16_t header_size; - std::uint16_t entry_size_program_header_table; - std::uint16_t entry_count_program_header_table; - std::uint16_t entry_size_section_header_table; - std::uint16_t entry_count_section_header_table; - std::uint16_t index_section_names_section_header_table; + amy::u64 program_header_table; + amy::u64 section_header_table; + amy::u32 flags; + amy::u16 header_size; + amy::u16 entry_size_program_header_table; + amy::u16 entry_count_program_header_table; + amy::u16 entry_size_section_header_table; + amy::u16 entry_count_section_header_table; + amy::u16 index_section_names_section_header_table; }; static_assert(sizeof(header) == 64); struct program_header { - std::uint32_t type; - std::uint32_t flags; - std::uint64_t p_offset; - std::byte* p_vaddr; - std::uint64_t : 64; - std::uint64_t p_filesz; - std::uint64_t p_memsz; - std::uint64_t align; + amy::u32 type; + amy::u32 flags; + amy::u64 p_offset; + amy::byte* p_vaddr; + amy::u64 : 64; + amy::u64 p_filesz; + amy::u64 p_memsz; + amy::u64 align; }; static_assert(sizeof(program_header) == 56); - void load_elf(os::process& result, std::byte* start, std::size_t length, const paging::PML4T& original_PML4T); + void load_elf(os::process& result, amy::byte* start, amy::size length, const paging::PML4T& original_PML4T); } } // namespace os::elf diff --git a/kernel/src/interrupts.cpp b/kernel/src/interrupts.cpp index a2b6def..11ca4d7 100644 --- a/kernel/src/interrupts.cpp +++ b/kernel/src/interrupts.cpp @@ -20,7 +20,7 @@ void os::lidt(idtr idtr) { asm volatile("lidt %0" : : "m"(idtr)); } bool os::is_APIC_builtin() { - std::uint32_t eax, ebx, ecx, edx; + amy::u32 eax, ebx, ecx, edx; __cpuid(0x01, eax, ebx, ecx, edx); return (edx & (1 << 9)) != 0; } @@ -28,19 +28,19 @@ void os::disable_PIC() { outb(0xA1, 0xFF); outb(0x21, 0xFF); } -void os::set_APIC_base(os::phys_ptr ptr) { +void os::set_APIC_base(os::phys_ptr ptr) { os::set_msr(0x1B, (ptr.get_phys_addr() & 0xFFFFFFFFFFFFF000) | 0x800); } -os::phys_ptr os::get_APIC_base() { - return os::phys_ptr{os::get_msr(0x1B) & 0xFFFFFFFFFFFFF000}; +os::phys_ptr os::get_APIC_base() { + return os::phys_ptr{os::get_msr(0x1B) & 0xFFFFFFFFFFFFF000}; } -std::uint32_t os::get_APIC_reg(std::ptrdiff_t offset) { +amy::u32 os::get_APIC_reg(amy::dptr offset) { return get_APIC_base()[offset / 4]; } -void os::set_APIC_reg(std::ptrdiff_t offset, std::uint32_t v) { +void os::set_APIC_reg(amy::dptr offset, amy::u32 v) { get_APIC_base()[offset / 4] = v; } -extern "C" void set_APIC_reg_asm(std::ptrdiff_t offset, std::uint32_t v) { +extern "C" void set_APIC_reg_asm(amy::dptr offset, amy::u32 v) { os::set_APIC_reg(offset, v); } @@ -77,7 +77,7 @@ extern "C" void int_device_not_available() { os::print("Interrupt: Device Not Available.\n"); while (true) { os::hlt(); } } -extern "C" void int_double_fault(std::uint32_t err_code) { +extern "C" void int_double_fault(amy::u32 err_code) { os::print("Interrupt: Double Fault.\n"); os::print("Err code: {}.\n", err_code); while (true) { os::hlt(); } @@ -86,27 +86,27 @@ extern "C" void int_coprocessor_segment_overrun() { os::print("Interrupt: Coprocessor Segment Overrun.\n"); while (true) { os::hlt(); } } -extern "C" void int_invalid_TSS(std::uint32_t err_code) { +extern "C" void int_invalid_TSS(amy::u32 err_code) { os::print("Interrupt: Invalid TSS.\n"); os::print("Err code: {}.\n", err_code); while (true) { os::hlt(); } } -extern "C" void int_segment_not_present(std::uint32_t err_code) { +extern "C" void int_segment_not_present(amy::u32 err_code) { os::print("Interrupt: Segment Not Present.\n"); os::print("Err code: {}.\n", err_code); while (true) { os::hlt(); } } -extern "C" void int_stack_segment_fault(std::uint32_t err_code) { +extern "C" void int_stack_segment_fault(amy::u32 err_code) { os::print("Interrupt: Stack-Segment Fault.\n"); os::print("Err code: {}.\n", err_code); while (true) { os::hlt(); } } -extern "C" void int_general_protection_fault(std::uint32_t err_code) { +extern "C" void int_general_protection_fault(amy::u32 err_code) { os::print("Interrupt: General Protection Fault.\n"); os::print("Err code: {}.\n", err_code); while (true) { os::hlt(); } } -extern "C" void int_page_fault(std::uint32_t err_code, std::uint64_t vaddr) { +extern "C" void int_page_fault(amy::u32 err_code, amy::u64 vaddr) { if ( (0xFFFF'C000'0000'0000 <= vaddr && vaddr < 0xFFFF'C000'1000'0000) // process/port info ) { // Kernel memory @@ -135,7 +135,7 @@ extern "C" void int_x87_floating_point_exception() { os::print("Interrupt: x87 Floating-Point Exception.\n"); while (true) { os::hlt(); } } -extern "C" void int_alignment_check(std::uint32_t err_code) { +extern "C" void int_alignment_check(amy::u32 err_code) { os::print("Interrupt: Alignment Check.\n"); os::print("Err code: {}.\n", err_code); while (true) { os::hlt(); } @@ -152,7 +152,7 @@ extern "C" void int_virtualization_exception() { os::print("Interrupt: Virtualization Exception.\n"); while (true) { os::hlt(); } } -extern "C" void int_control_protection_exception(std::uint32_t err_code) { +extern "C" void int_control_protection_exception(amy::u32 err_code) { os::print("Interrupt: Control Protection Exception.\n"); os::print("Err code: {}.\n", err_code); while (true) { os::hlt(); } @@ -161,12 +161,12 @@ extern "C" void int_hypervisor_injection_exception() { os::print("Interrupt: Hypervisor Injection Exception.\n"); while (true) { os::hlt(); } } -extern "C" void int_VMM_communication_exception(std::uint32_t err_code) { +extern "C" void int_VMM_communication_exception(amy::u32 err_code) { os::print("Interrupt: VMM Communication Exception.\n"); os::print("Err code: {}.\n", err_code); while (true) { os::hlt(); } } -extern "C" void int_security_exception(std::uint32_t err_code) { +extern "C" void int_security_exception(amy::u32 err_code) { os::print("Interrupt: Security Exception.\n"); os::print("Err code: {}.\n", err_code); while (true) { os::hlt(); } diff --git a/kernel/src/interrupts.hpp b/kernel/src/interrupts.hpp index d8a3590..2d9aa47 100644 --- a/kernel/src/interrupts.hpp +++ b/kernel/src/interrupts.hpp @@ -13,7 +13,7 @@ #pragma once -#include +#include #include "lib/phys_ptr.hpp" #include "serial.hpp" #include "utils.hpp" @@ -21,69 +21,69 @@ namespace os { struct ide { - std::uint16_t offset_low; - std::uint16_t kernel_cs; - std::uint8_t ist_offset : 3; - std::uint8_t reserved_1 : 5 = 0; - std::uint8_t gate_type : 4; - std::uint8_t bit_0 : 1 = 0; - std::uint8_t dpl : 2; - std::uint8_t present : 1; - std::uint16_t offset_mid; - std::uint32_t offset_high; - std::uint32_t reserved_2 = 0; + amy::u16 offset_low; + amy::u16 kernel_cs; + amy::u8 ist_offset : 3; + amy::u8 reserved_1 : 5 = 0; + amy::u8 gate_type : 4; + amy::u8 bit_0 : 1 = 0; + amy::u8 dpl : 2; + amy::u8 present : 1; + amy::u16 offset_mid; + amy::u32 offset_high; + amy::u32 reserved_2 = 0; }; static_assert(sizeof(ide) == 16); -template +template using idt __attribute__((aligned(0x1000))) = ide[interrupt_nb]; struct __attribute__((packed)) idtr { - std::uint16_t size; - std::uint64_t offset; + amy::u16 size; + amy::u64 offset; }; void lidt(idtr idtr); bool is_APIC_builtin(); void disable_PIC(); -void set_APIC_base(phys_ptr ptr); -phys_ptr get_APIC_base(); -std::uint32_t get_APIC_reg(std::ptrdiff_t offset); -void set_APIC_reg(std::ptrdiff_t offset, std::uint32_t v); +void set_APIC_base(phys_ptr ptr); +phys_ptr get_APIC_base(); +amy::u32 get_APIC_reg(amy::dptr offset); +void set_APIC_reg(amy::dptr offset, amy::u32 v); struct isr_info { - std::uintptr_t addr; + amy::uptr addr; enum class type_t { trap_gate = 0xF, interrupt_gate = 0xE }; type_t type : 4; - std::uint8_t dpl: 2 = 0b00; + amy::u8 dpl: 2 = 0b00; bool present : 1 = true; }; template void assert(bool cond, const char* format, const Ts&... vs); -template +template void enable_interrupts(const isr_info (&ISRs)[interrupt_nb], os::idt& idt) { os::assert(is_APIC_builtin(), "No builtin APIC."); disable_PIC(); set_APIC_reg(0xF0, 0x1FF); // Enable APIC - for (std::size_t i = 0; i < interrupt_nb; i++) { + for (amy::size i = 0; i < interrupt_nb; i++) { idt[i] = { - .offset_low = uint16_t(ISRs[i].addr & 0xFFFF), + .offset_low = amy::u16(ISRs[i].addr & 0xFFFF), .kernel_cs = 0x10, .ist_offset = 0, - .gate_type = std::uint8_t(ISRs[i].type), // Trap gate. + .gate_type = amy::u8(ISRs[i].type), // Trap gate. .dpl = ISRs[i].dpl, - .present = std::uint8_t(ISRs[i].present ? 1 : 0), - .offset_mid = uint16_t((ISRs[i].addr >> 16) & 0xFFFF), - .offset_high = uint32_t((ISRs[i].addr >> 32) & 0xFFFFFFFF), + .present = amy::u8(ISRs[i].present ? 1 : 0), + .offset_mid = amy::u16((ISRs[i].addr >> 16) & 0xFFFF), + .offset_high = amy::u32((ISRs[i].addr >> 32) & 0xFFFFFFFF), }; } os::idtr idtr { .size = sizeof(idt) - 1, - .offset = reinterpret_cast(&idt[0]), + .offset = reinterpret_cast(&idt[0]), }; lidt(idtr); sti(); diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index f1c1459..bffc658 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -44,15 +44,15 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr(os::paging::global_PML4T, (os::paging::page<2>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr>(i), { .RW = false, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = false }); i += 1024 * 1024 * 1024; - } else if (i % (1024 * 1024 * 2) == 0 && i + 1024 * 1024 * 2 < std::size_t(&_kernel_phys_rw_start)) { + } else if (i % (1024 * 1024 * 2) == 0 && i + 1024 * 1024 * 2 < amy::iptr(&_kernel_phys_rw_start)) { os::paging::map_page<1, 3>(os::paging::global_PML4T, (os::paging::page<1>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr>(i), { .RW = false, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = false }); i += 1024 * 1024 * 2; @@ -62,12 +62,12 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr(os::paging::global_PML4T, (os::paging::page<2>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr>(i), { .RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = true }); i += 1024 * 1024 * 1024; - } else if (i % (1024 * 1024 * 2) == 0 && i + 1024 * 1024 * 2 < std::size_t(&_kernel_phys_rw_start)) { + } else if (i % (1024 * 1024 * 2) == 0 && i + 1024 * 1024 * 2 < amy::iptr(&_kernel_phys_rw_start)) { os::paging::map_page<1, 3>(os::paging::global_PML4T, (os::paging::page<1>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr>(i), { .RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = true }); i += 1024 * 1024 * 2; @@ -82,9 +82,9 @@ extern "C" void kmain(unsigned long magic, os::phys_ptrtype) { case multiboot2::info::type_t::memory_map: os::print("RAM:\n"); - for (std::size_t i = 0; i < multiboot2::memory_map_number_of_entries(it); i++) { - std::size_t const s = multiboot2::memory_map_base_addr(it, i); - std::size_t const e = s + multiboot2::memory_map_length(it, i); + for (amy::size i = 0; i < multiboot2::memory_map_number_of_entries(it); i++) { + amy::iptr const s = multiboot2::memory_map_base_addr(it, i); + amy::iptr const e = s + multiboot2::memory_map_length(it, i); os::print("{} -> {} : {}\n", (void*)s, (void*)e, multiboot2::memory_map_type(it, i)); if (multiboot2::memory_map_type(it, i) != 1) { continue; @@ -94,7 +94,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr( os::paging::global_PML4T, @@ -126,11 +126,11 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr{std::uintptr_t(&os::paging::global_PML4T) - 0xFFFF'FFFF'8000'0000}); + os::paging::load_pml4t(os::phys_ptr{amy::uptr(&os::paging::global_PML4T) - 0xFFFF'FFFF'8000'0000}); { // Enable interrupts really early so I don't have to manually manage memory... Will make better later, when I make utils.hpp/incrementing_int64_map better. os::isr_info isr_info[32]; - for (size_t i = 0; i < sizeof(isr_info) / sizeof(isr_info[0]); i++) { + for (amy::size i = 0; (unsigned long long)(i) < sizeof(isr_info) / sizeof(isr_info[0]); i++) { isr_info[i].type = os::isr_info::type_t::trap_gate; } asm ("movq $handler_0x00,%0" : "=ri"(isr_info[0x00].addr) : ); @@ -177,7 +177,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr> (12 + 9 * 3)) & 0x1FF; + amy::size const index = (amy::size(&os::processes) >> (12 + 9 * 3)) & 0x1FF; os::paging::global_PML4T.contents[index].paging_table_info({.RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .AVL = 0, .NX = false}); const auto PDPT_alloc = os::paging::page_allocator.allocate(1); os::memset((void*)PDPT_alloc.ptr, 0, 0x1000); @@ -189,7 +189,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr> start_address = nullptr; os::phys_ptr> end_address = nullptr; } available_ram[50]; - std::size_t available_ram_length = 0; + amy::size available_ram_length = 0; bool module_specified = false; for (auto it = multiboot2::next(info); it->type != multiboot2::info::type_t::end; it = multiboot2::next(it)) { @@ -201,7 +201,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr{}: {}\n", multiboot2::modules_mod_start(it), multiboot2::modules_mod_end(it), multiboot2::modules_string(it)); module_specified = true; os::elf::load_elf(os::get_process(os::processes.create()), - (std::byte*)multiboot2::modules_mod_start(it), + (amy::byte*)multiboot2::modules_mod_start(it), multiboot2::modules_mod_end(it) - multiboot2::modules_mod_start(it), os::paging::global_PML4T); break; @@ -229,11 +229,11 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr> kernel_s{std::size_t(&_kernel_phys_start)}; - const os::phys_ptr> kernel_e{std::size_t(&_kernel_phys_end)}; + const os::phys_ptr> kernel_s{amy::uptr(&_kernel_phys_start)}; + const os::phys_ptr> kernel_e{amy::uptr(&_kernel_phys_end)}; // Remove kernel from available RAM: - for (std::size_t i = 0; i < available_ram_length; i++) { + for (amy::iptr i = 0; i < available_ram_length; i++) { if (kernel_e < available_ram[i].start_address || available_ram[i].end_address < kernel_s) { continue; } @@ -254,10 +254,10 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr +# include # include "phys_ptr.hpp" namespace multiboot2 { #endif // __cplusplus #ifdef __cplusplus - constexpr std::uint32_t magic = 0xE85250D6; - constexpr std::uint32_t arch_i386_32bit = 0; - constexpr std::uint32_t arch_mips_32bit = 4; - constexpr std::uint32_t checksum(std::uint32_t arch, std::uint32_t length) { return -(magic + arch + length); } + constexpr amy::u32 magic = 0xE85250D6; + constexpr amy::u32 arch_i386_32bit = 0; + constexpr amy::u32 arch_mips_32bit = 4; + constexpr amy::u32 checksum(amy::u32 arch, amy::u32 length) { return -(magic + arch + length); } #else # define multiboot2_magic 0xE85250D6 # define multiboot2_arch_i386_32bit 0 @@ -33,11 +33,11 @@ #ifdef __cplusplus struct __attribute__((packed)) info_start { - std::uint32_t total_size; - std::uint32_t reserved; + amy::u32 total_size; + amy::u32 reserved; }; struct __attribute__((packed)) info { - enum class type_t : std::uint32_t { + enum class type_t : amy::u32 { end = 0, basic_memory_info = 4, bios_boot_device = 5, @@ -62,8 +62,8 @@ image_load_base_physical_address = 21, }; type_t type; - std::uint32_t size; - std::uint8_t rest[]; + amy::u32 size; + amy::u8 rest[]; }; inline os::phys_ptr next(os::phys_ptr ptr) { @@ -73,52 +73,52 @@ return os::phys_ptr((ptr.get_phys_addr() + ptr->size + 7) / 8 * 8); // + 7) / 8 * 8 is required for alignment. } - inline std::uint64_t framebuffer_addr(os::phys_ptr ptr) { - return *reinterpret_cast(&ptr->rest[0]); + inline amy::u64 framebuffer_addr(os::phys_ptr ptr) { + return *reinterpret_cast(&ptr->rest[0]); } - inline std::uint32_t framebuffer_pitch(os::phys_ptr ptr) { - return *reinterpret_cast(&ptr->rest[8]); + inline amy::u32 framebuffer_pitch(os::phys_ptr ptr) { + return *reinterpret_cast(&ptr->rest[8]); } - inline std::uint32_t framebuffer_width(os::phys_ptr ptr) { - return *reinterpret_cast(&ptr->rest[12]); + inline amy::u32 framebuffer_width(os::phys_ptr ptr) { + return *reinterpret_cast(&ptr->rest[12]); } - inline std::uint32_t framebuffer_height(os::phys_ptr ptr) { - return *reinterpret_cast(&ptr->rest[16]); + inline amy::u32 framebuffer_height(os::phys_ptr ptr) { + return *reinterpret_cast(&ptr->rest[16]); } - inline std::uint8_t framebuffer_bpp(os::phys_ptr ptr) { - return *reinterpret_cast(&ptr->rest[20]); + inline amy::u8 framebuffer_bpp(os::phys_ptr ptr) { + return *reinterpret_cast(&ptr->rest[20]); } - inline std::uint8_t framebuffer_type(os::phys_ptr ptr) { - return *reinterpret_cast(&ptr->rest[21]); + inline amy::u8 framebuffer_type(os::phys_ptr ptr) { + return *reinterpret_cast(&ptr->rest[21]); } - inline const std::uint8_t* color_info(os::phys_ptr ptr) { - return reinterpret_cast(&ptr->rest[24]); + inline const amy::u8* color_info(os::phys_ptr ptr) { + return reinterpret_cast(&ptr->rest[24]); } - inline std::uint32_t memory_map_entry_size(os::phys_ptr ptr) { - return *reinterpret_cast(&ptr->rest[0]); + inline amy::u32 memory_map_entry_size(os::phys_ptr ptr) { + return *reinterpret_cast(&ptr->rest[0]); } - inline std::uint32_t memory_map_entry_version(os::phys_ptr ptr) { - return *reinterpret_cast(&ptr->rest[4]); + inline amy::u32 memory_map_entry_version(os::phys_ptr ptr) { + return *reinterpret_cast(&ptr->rest[4]); } - inline std::size_t memory_map_number_of_entries(os::phys_ptr ptr) { + inline amy::size memory_map_number_of_entries(os::phys_ptr ptr) { return (ptr->size - 16) / memory_map_entry_size(ptr); } - inline std::uint64_t memory_map_base_addr(os::phys_ptr ptr, std::size_t index) { - return *reinterpret_cast(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 0]); + inline amy::u64 memory_map_base_addr(os::phys_ptr ptr, amy::size index) { + return *reinterpret_cast(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 0]); } - inline std::uint64_t memory_map_length(os::phys_ptr ptr, std::size_t index) { - return *reinterpret_cast(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 8]); + inline amy::u64 memory_map_length(os::phys_ptr ptr, amy::size index) { + return *reinterpret_cast(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 8]); } - inline std::uint32_t memory_map_type(os::phys_ptr ptr, std::size_t index) { - return *reinterpret_cast(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 16]); + inline amy::u32 memory_map_type(os::phys_ptr ptr, amy::size index) { + return *reinterpret_cast(&ptr->rest[8 + memory_map_entry_size(ptr) * index + 16]); } - inline os::phys_ptr modules_mod_start(os::phys_ptr ptr) { - return os::phys_ptr{*reinterpret_cast(&ptr->rest[0])}; + inline os::phys_ptr modules_mod_start(os::phys_ptr ptr) { + return os::phys_ptr{*reinterpret_cast(&ptr->rest[0])}; } - inline os::phys_ptr modules_mod_end(os::phys_ptr ptr) { - return os::phys_ptr{*reinterpret_cast(&ptr->rest[4])}; + inline os::phys_ptr modules_mod_end(os::phys_ptr ptr) { + return os::phys_ptr{*reinterpret_cast(&ptr->rest[4])}; } inline const char* modules_string(os::phys_ptr ptr) { return reinterpret_cast(&ptr->rest[8]); diff --git a/kernel/src/lib/phys_ptr.hpp b/kernel/src/lib/phys_ptr.hpp index 0755c0b..400f5e9 100644 --- a/kernel/src/lib/phys_ptr.hpp +++ b/kernel/src/lib/phys_ptr.hpp @@ -13,8 +13,7 @@ #pragma once -#include -#include +#include namespace os { @@ -24,8 +23,8 @@ class phys_ptr; template <> class phys_ptr { public: - constexpr explicit phys_ptr(std::uintptr_t phys_addr): phys_addr(phys_addr) {} - constexpr phys_ptr(std::nullptr_t): phys_addr(~0ull) {} + constexpr explicit phys_ptr(amy::uptr phys_addr): phys_addr(phys_addr) {} + constexpr phys_ptr(amy::nptr): phys_addr(~0ull) {} inline void* operator->() const { return get_virt_addr(); @@ -34,27 +33,32 @@ public: return get_virt_addr(); } - constexpr std::uintptr_t get_phys_addr() const { + constexpr amy::uptr get_phys_addr() const { return phys_addr; } - friend constexpr auto operator<=>(phys_ptr a, phys_ptr b) = default; + friend constexpr bool operator<(phys_ptr a, phys_ptr b) = default; + friend constexpr bool operator<=(phys_ptr a, phys_ptr b) = default; + friend constexpr bool operator>(phys_ptr a, phys_ptr b) = default; + friend constexpr bool operator>=(phys_ptr a, phys_ptr b) = default; + friend constexpr bool operator==(phys_ptr a, phys_ptr b) = default; + friend constexpr bool operator!=(phys_ptr a, phys_ptr b) = default; private: constexpr void* get_virt_addr() const { return reinterpret_cast(phys_addr + 0xFFFF800000000000); } - std::uintptr_t phys_addr; + amy::uptr phys_addr; }; template class phys_ptr { public: - constexpr explicit phys_ptr(std::uintptr_t phys_addr): phys_addr(phys_addr) {} - constexpr phys_ptr(std::nullptr_t): phys_addr(~0ull) {} + constexpr explicit phys_ptr(amy::uptr phys_addr): phys_addr(phys_addr) {} + constexpr phys_ptr(amy::nptr): phys_addr(~0ull) {} - T& operator[](std::size_t i) const { + T& operator[](amy::size i) const { return get_virt_addr()[i]; } T& operator*() const { @@ -89,38 +93,55 @@ public: operator--(); return old; } - constexpr phys_ptr& operator+=(std::ptrdiff_t offset) { + constexpr phys_ptr& operator+=(amy::dptr offset) { return *this = *this + offset; } - constexpr phys_ptr& operator-=(std::ptrdiff_t offset) { + constexpr phys_ptr& operator-=(amy::dptr offset) { return *this = *this - offset; } - friend constexpr phys_ptr operator+(phys_ptr ptr, std::ptrdiff_t offset) { + friend constexpr phys_ptr operator+(phys_ptr ptr, amy::dptr offset) { return phys_ptr{ptr.phys_addr + offset * sizeof(T)}; } - friend constexpr phys_ptr operator+(std::ptrdiff_t offset, phys_ptr ptr) { + friend constexpr phys_ptr operator+(amy::dptr offset, phys_ptr ptr) { return ptr + offset; } - friend constexpr phys_ptr operator-(phys_ptr ptr, std::ptrdiff_t offset) { + friend constexpr phys_ptr operator-(phys_ptr ptr, amy::dptr offset) { return phys_ptr{ptr.phys_addr - offset * sizeof(T)}; } - friend constexpr std::ptrdiff_t operator-(phys_ptr a, phys_ptr b) { + friend constexpr amy::dptr operator-(phys_ptr a, phys_ptr b) { return (a.phys_addr - b.phys_addr) / sizeof(T); } - constexpr std::uintptr_t get_phys_addr() const { + constexpr amy::uptr get_phys_addr() const { return phys_addr; } - friend constexpr auto operator<=>(phys_ptr a, phys_ptr b) = default; + friend constexpr bool operator<(phys_ptr a, phys_ptr b) { + return a.phys_addr < b.phys_addr; + } + friend constexpr bool operator<=(phys_ptr a, phys_ptr b) { + return a.phys_addr <= b.phys_addr; + } + friend constexpr bool operator>(phys_ptr a, phys_ptr b) { + return a.phys_addr > b.phys_addr; + } + friend constexpr bool operator>=(phys_ptr a, phys_ptr b) { + return a.phys_addr >= b.phys_addr; + } + friend constexpr bool operator==(phys_ptr a, phys_ptr b) { + return a.phys_addr == b.phys_addr; + } + friend constexpr bool operator!=(phys_ptr a, phys_ptr b) { + return a.phys_addr != b.phys_addr; + } private: constexpr T* get_virt_addr() const { return reinterpret_cast(phys_addr + 0xFFFF800000000000); } - std::uintptr_t phys_addr; + amy::uptr phys_addr; }; } // namespace os diff --git a/kernel/src/paging.cpp b/kernel/src/paging.cpp index 38a65e6..1a36a24 100644 --- a/kernel/src/paging.cpp +++ b/kernel/src/paging.cpp @@ -30,7 +30,7 @@ void os::paging::page_allocator_t::print_all() const { } } -os::paging::page_allocator_t::block os::paging::page_allocator_t::allocate(std::uint64_t count) { +os::paging::page_allocator_t::block os::paging::page_allocator_t::allocate(amy::size count) { if (begin == nullptr) { return { .ptr = nullptr, .size = count }; } diff --git a/kernel/src/paging.hpp b/kernel/src/paging.hpp index e085523..bae5657 100644 --- a/kernel/src/paging.hpp +++ b/kernel/src/paging.hpp @@ -13,16 +13,16 @@ #pragma once -#include +#include #include "serial.hpp" #include "utils.hpp" #include "lib/phys_ptr.hpp" namespace os { namespace paging { -template struct paging_entry; -template struct paging_table; -template struct page; +template struct paging_entry; +template struct paging_table; +template struct page; struct page_info { bool RW; @@ -33,7 +33,7 @@ struct page_info { bool D; bool PAT; bool G; - std::uint16_t AVL; // Only 14 bits, actually. + amy::u16 AVL; // Only 14 bits, actually. bool NX; }; struct paging_table_info { @@ -42,12 +42,12 @@ struct paging_table_info { bool PWT; bool PCD; bool A; - std::uint16_t AVL; // Really 16 bits ! + amy::u16 AVL; // Really 16 bits ! bool NX; }; -template struct paging_entry { - std::uint64_t data = 0; +template struct paging_entry { + amy::u64 data = 0; bool is_present() { return (data & (1 << 0)) != 0; @@ -77,7 +77,7 @@ template struct paging_entry { } os::phys_ptr> page_ptr() { os::assert(is_page(), "Cannot access page physical pointer for a non-page."); - std::uintptr_t addr = data & (depth == 0 ? 0x0000'FFFF'FFFF'F000 : 0x0000'FFFF'FFFF'E000); + amy::uptr addr = data & (depth == 0 ? 0x0000'FFFF'FFFF'F000 : 0x0000'FFFF'FFFF'E000); return os::phys_ptr>(addr | ((addr & 0x0000'8000'0000'0000) != 0 ? 0xFFFF'8000'0000'0000 : 0)); } void page_ptr(os::phys_ptr> page) { @@ -104,7 +104,7 @@ template struct paging_entry { } os::phys_ptr> paging_table_ptr() { os::assert(!is_page(), "Cannot access paging table physical pointer for a page."); - std::uintptr_t addr = data & 0x0000'FFFF'FFFF'F000; + amy::uptr addr = data & 0x0000'FFFF'FFFF'F000; return os::phys_ptr>(addr | ((addr & 0x0000'8000'0000'0000) != 0 ? 0xFFFF'8000'0000'0000 : 0)); } void paging_table_ptr(os::phys_ptr> table) { @@ -125,8 +125,8 @@ template struct paging_entry { | (info.D ? (1ull << 6) : 0) | (info.PAT ? (depth == 0 ? 1 << 7: 1 << 12) : 0) | (info.G ? (1ull << 8) : 0) - | (std::uint64_t(info.AVL & 0x7) << 9) - | (std::uint64_t(info.AVL & 0x3FF8) << 49) + | (amy::u64(info.AVL & 0x7) << 9) + | (amy::u64(info.AVL & 0x3FF8) << 49) | (info.NX ? (1ull << 63) : 0); } void paging_table_info(os::paging::paging_table_info info) { @@ -136,18 +136,18 @@ template struct paging_entry { | (info.PWT ? (1ull << 3) : 0) | (info.PCD ? (1ull << 4) : 0) | (info.A ? (1ull << 5) : 0) - | (std::uint64_t(info.AVL & 0x1) << 6) - | (std::uint64_t(info.AVL & 0x1E) << 7) - | (std::uint64_t(info.AVL & 0xFFE0) << 47) + | (amy::u64(info.AVL & 0x1) << 6) + | (amy::u64(info.AVL & 0x1E) << 7) + | (amy::u64(info.AVL & 0xFFE0) << 47) | (info.NX ? (1ull << 63) : 0); } }; -template struct __attribute__((aligned(0x1000))) paging_table { +template struct __attribute__((aligned(0x1000))) paging_table { paging_entry contents[512]; }; // Alignment should be the same as size, but that's literally too big for the compiler. -template struct __attribute__((aligned(0x1000))) page { - std::byte contents[0x1000ull << (9 * depth)]; +template struct __attribute__((aligned(0x1000))) page { + amy::byte contents[0x1000ull << (9 * depth)]; }; static_assert(sizeof(page<0>) == 0x1000); @@ -181,10 +181,10 @@ using PE = paging_entry<0>; extern PML4T global_PML4T; -template +template void map_page(paging_table& paging_table, page const* vaddr, phys_ptr> paddr, os::paging::page_info page_info); -template -void on_all_pages(const paging_table& paging_table, auto f, std::size_t vaddr_offset = 0); +template +void on_all_pages(const paging_table& paging_table, auto f, amy::uptr vaddr_offset = 0); void load_pml4t(phys_ptr PML4T); @@ -195,19 +195,19 @@ class page_allocator_t { public: struct block { phys_ptr> ptr = nullptr; - std::uint64_t size; + amy::size size; }; page_allocator_t(); void print_all() const; - block allocate(std::uint64_t page_count); + block allocate(amy::size page_count); void deallocate(block b); private: struct __attribute__((aligned(0x1000))) page { phys_ptr next; - std::uint64_t size; + amy::size size; }; static_assert(sizeof(page) == 0x1000); static_assert(alignof(page) == 0x1000); @@ -216,9 +216,9 @@ private: bool merge(phys_ptr it); }; -template +template void map_page(paging_table& paging_table, page const* vaddr, phys_ptr> paddr, os::paging::page_info page_info) { - std::size_t const index = (std::uint64_t(vaddr) >> (12 + 9 * paging_depth)) & 0x1FF; + amy::size const index = (amy::uptr(vaddr) >> (12 + 9 * paging_depth)) & 0x1FF; if constexpr (depth == paging_depth) { os::assert(!paging_table.contents[index].is_present(), "Virtual address 0x{} is already mapped.", vaddr); paging_table.contents[index].page_info(page_info); @@ -239,14 +239,14 @@ void map_page(paging_table& paging_table, page const* vaddr } } -template -void on_all_pages(const paging_table& paging_table, auto f, std::size_t vaddr_offset) { - for (std::size_t i = 0; i < 512; i++) { +template +void on_all_pages(const paging_table& paging_table, auto f, amy::uptr vaddr_offset) { + for (amy::size i = 0; i < 512; i++) { if (!is_present(paging_table.contents[i])) { continue; } - std::size_t const new_offset = ([&]() { - std::size_t const new_offset = vaddr_offset + (i << (12 + 9 * depth)); + amy::uptr const new_offset = ([&]() { + amy::uptr const new_offset = vaddr_offset + (i << (12 + 9 * depth)); return new_offset | (new_offset >> 47 ? 0xFFFF'8000'0000'0000 : 0); })(); if constexpr (depth == 3) { diff --git a/kernel/src/ring3.cpp b/kernel/src/ring3.cpp index 0073e07..4625e1e 100644 --- a/kernel/src/ring3.cpp +++ b/kernel/src/ring3.cpp @@ -16,13 +16,13 @@ #include "serial.hpp" #include "paging.hpp" -void os::run_first_process(std::int64_t pid) { +void os::run_first_process(amy::i64 pid) { current_pid = pid; os::paging::load_pml4t(os::get_process(current_pid).PML4T); - os::ftl_to_userspace((void*)os::get_process(current_pid).rip, (std::byte*)os::get_process(current_pid).rsp); + os::ftl_to_userspace((void*)os::get_process(current_pid).rip, (amy::byte*)os::get_process(current_pid).rsp); } -void os::set_ring0_stack(os::tss& tss, std::uint64_t stack) { +void os::set_ring0_stack(os::tss& tss, amy::u64 stack) { tss.rsp0 = stack; } @@ -31,11 +31,11 @@ void os::enable_syscalls() { // This is required to enable syscall/sysret on x86_64 intel. os::set_msr(0xC0000080, os::get_msr(0xC0000080) | (1 << 0)); os::set_msr(0xC0000081, - (std::uint64_t(24 - 8 + 0b11) << 48) + // sysret_cs_and_ss (e.g., userspace segments) - (std::uint64_t( 8 - 8 + 0b00) << 32) + // syscall_cs_and_ss (e.g., kernelspace segments) - std::uint64_t(0) // syscall_target_eip, only relevant to 32-bits so useless here + (amy::u64(24 - 8 + 0b11) << 48) + // sysret_cs_and_ss (e.g., userspace segments) + (amy::u64( 8 - 8 + 0b00) << 32) + // syscall_cs_and_ss (e.g., kernelspace segments) + amy::u64(0) // syscall_target_eip, only relevant to 32-bits so useless here ); - os::set_msr(0xC0000082, std::uint64_t(&syscall_64bit_handler)); // RIP for 64-bit program + os::set_msr(0xC0000082, amy::u64(&syscall_64bit_handler)); // RIP for 64-bit program os::set_msr(0xC0000083, 0); // RIP for 32-bit program, we ignore this one because the OS is only supposed to support programs running with 64 bits. os::set_msr(0xC0000084, 0x00000000); // syscall flag mask, we don't want to change the flags for now. } @@ -49,25 +49,25 @@ void schedule_next_process() { os::paging::load_pml4t(os::processes.get(os::current_pid).PML4T); } -// extern "C" std::int64_t syscall_mount_kernel_device(std::int64_t wd, char device, char const* path, std::int64_t path_len, int mount_type) { -extern "C" std::int64_t syscall_mount_kernel_device(std::int64_t, char, char const*, std::int64_t, int) { +// extern "C" int os::syscall_mount_kernel_device(amy::fd wd, char device, char const* path, amy::size path_len, int mount_type); +extern "C" int os::syscall_mount_kernel_device(amy::fd, char, char const*, amy::size, int) { os::assert(false, "mount_kernel_device not implemented yet."); __builtin_unreachable(); } -// extern "C" std::int64_t syscall_open(std::int64_t wd, char const* path, std::int64_t path_len, int options) { -extern "C" std::int64_t syscall_open(std::int64_t, char const*, std::int64_t, int) { +// extern "C" amy::fd os::syscall_open(amy::fd wd, char const* path, amy::size path_len, int options); +extern "C" amy::fd os::syscall_open(amy::fd, char const*, amy::size, int) { os::assert(false, "open not implemented yet."); __builtin_unreachable(); } -extern "C" std::int64_t syscall_read(std::int64_t file, char* data, std::int64_t len) { +extern "C" amy::size os::syscall_read(amy::fd file, char* data, amy::size len) { os::assert(file == 0, "Read isn't really implemented for now."); os::assert(len >= 0, "Read expects a positive size."); if (len == 0) { return 0; } - for (std::int64_t i = 0; i < len; i++) { + for (amy::size i = 0; i < len; i++) { if (i == 0) { data[i] = os::read_serial(); continue; @@ -81,19 +81,13 @@ extern "C" std::int64_t syscall_read(std::int64_t file, char* data, std::int64_t return len; } -// extern "C" std::int64_t syscall_close(std::int64_t file) { -extern "C" std::int64_t syscall_close(std::int64_t) { - os::assert(false, "Close isn't implemented for now."); - __builtin_unreachable(); -} - -extern "C" std::int64_t syscall_write(std::int64_t file, char const* data, std::int64_t len) { +extern "C" amy::size os::syscall_write(amy::fd file, char const* data, amy::size len) { os::assert(file == 0, "Write isn't really implemented for now."); os::assert(len >= 0, "Write expects a positive size."); if (len == 0) { return 0; } - for (std::int64_t i = 0; i < len; i++) { + for (amy::size i = 0; i < len; i++) { if (os::serial_transmit_empty()) { os::write_serial(data[i]); } else { @@ -103,13 +97,19 @@ extern "C" std::int64_t syscall_write(std::int64_t file, char const* data, std:: return len; } +// extern "C" int syscall_close(amy::fd file); +extern "C" int os::syscall_close(amy::fd) { + os::assert(false, "Close isn't implemented for now."); + __builtin_unreachable(); +} + extern "C" void os::syscall_rax_error_handler() { os::assert(false, "Incorrect %rax for syscall."); __builtin_unreachable(); } os::incrementing_int64_map& os::processes = *reinterpret_cast*>(0xFFFF'C000'0000'0000); -std::int64_t os::current_pid; -os::process& os::get_process(std::int64_t pid) { +amy::pid os::current_pid; +os::process& os::get_process(amy::pid pid) { return processes.get(pid); } diff --git a/kernel/src/ring3.hpp b/kernel/src/ring3.hpp index 4d6bbb0..b79b7a5 100644 --- a/kernel/src/ring3.hpp +++ b/kernel/src/ring3.hpp @@ -13,79 +13,79 @@ #pragma once -#include -#include +#include #include "lib/phys_ptr.hpp" #include "paging.hpp" namespace os { struct __attribute__((packed)) tss { - std::uint32_t reserved_1; - std::uint64_t rsp0; - std::uint64_t rsp1; - std::uint64_t rsp2; - std::uint64_t reserved_2; - std::uint64_t ist1; - std::uint64_t ist2; - std::uint64_t ist3; - std::uint64_t ist4; - std::uint64_t ist5; - std::uint64_t ist6; - std::uint64_t ist7; - char reserved_3[10]; - std::uint16_t iopb; + amy::u32 reserved_1; + amy::u64 rsp0; + amy::u64 rsp1; + amy::u64 rsp2; + amy::u64 reserved_2; + amy::u64 ist1; + amy::u64 ist2; + amy::u64 ist3; + amy::u64 ist4; + amy::u64 ist5; + amy::u64 ist6; + amy::u64 ist7; + amy::byte reserved_3[10]; + amy::u16 iopb; }; struct process; -extern "C" void ftl_to_userspace(void* program, std::byte* stack); -void run_first_process(std::int64_t pid); +extern "C" void ftl_to_userspace(void* program, amy::byte* stack); +void run_first_process(amy::i64 pid); extern "C" void load_tss(); extern "C" void syscall_64bit_handler(); -extern "C" std::int64_t syscall_open(std::int64_t wd, char const* path, std::int64_t path_len, int options); -extern "C" std::int64_t syscall_read(std::int64_t file, char* data, std::int64_t len); -extern "C" std::int64_t syscall_write(std::int64_t file, char const* data, std::int64_t len); -extern "C" std::int64_t syscall_fseek(std::int64_t file, std::int64_t offset, int from); +extern "C" int syscall_mount_kernel_device(amy::fd wd, char device, char const* path, amy::size path_len, int mount_type); +extern "C" amy::fd syscall_open(amy::fd wd, char const* path, amy::size path_len, int options); +extern "C" amy::size syscall_read(amy::fd file, char* data, amy::size len); +extern "C" amy::size syscall_write(amy::fd file, char const* data, amy::size len); +extern "C" int syscall_close(amy::fd file); extern "C" void syscall_rax_error_handler(); -void set_ring0_stack(tss& tss, std::uint64_t stack); +void set_ring0_stack(tss& tss, amy::u64 stack); void enable_syscalls(); struct port { bool exists; bool is_open; - std::uint64_t other_pid; - std::uint64_t other_port; + amy::u64 other_pid; + amy::u64 other_port; }; struct process { phys_ptr PML4T = nullptr; - std::uint64_t rax; - std::uint64_t rbx; - std::uint64_t rcx; - std::uint64_t rdx; - std::uint64_t rsp; - std::uint64_t rbp; - std::uint64_t rsi; - std::uint64_t rdi; - std::uint64_t r8; - std::uint64_t r9; - std::uint64_t r10; - std::uint64_t r11; - std::uint64_t r12; - std::uint64_t r13; - std::uint64_t r14; - std::uint64_t r15; - std::uint64_t rip; + amy::u64 rax; + amy::u64 rbx; + amy::u64 rcx; + amy::u64 rdx; + amy::u64 rsp; + amy::u64 rbp; + amy::u64 rsi; + amy::u64 rdi; + amy::u64 r8; + amy::u64 r9; + amy::u64 r10; + amy::u64 r11; + amy::u64 r12; + amy::u64 r13; + amy::u64 r14; + amy::u64 r15; + amy::u64 rip; incrementing_int64_map ports; }; static_assert(0xFFFF'C000'0000'0000 + sizeof(incrementing_int64_map) < 0xFFFF'FFFF'8000'0000); extern incrementing_int64_map& processes; -extern "C" std::int64_t current_pid; -extern "C" process& get_process(std::int64_t pid); +extern "C" amy::pid current_pid; +extern "C" process& get_process(amy::i64 pid); } // namespace os diff --git a/kernel/src/serial.cpp b/kernel/src/serial.cpp index 3d14b1a..a686584 100644 --- a/kernel/src/serial.cpp +++ b/kernel/src/serial.cpp @@ -11,7 +11,6 @@ // You should have received a copy of the GNU General Public License along with this program. If // not, see . -#include #include "utils.hpp" #include "interrupts.hpp" #include "serial.hpp" @@ -37,14 +36,14 @@ bool os::init_serial_port() { bool os::serial_received() { return (inb(serial_port + 5) & 0x01) != 0; } -std::uint8_t os::read_serial() { +amy::u8 os::read_serial() { while (!serial_received()) {} return inb(serial_port + 0); } bool os::serial_transmit_empty() { return (inb(serial_port + 5) & 0x20) != 0; } -void os::write_serial(std::uint8_t v) { +void os::write_serial(amy::u8 v) { while (!serial_transmit_empty()) {} outb(serial_port + 0, v); } @@ -54,11 +53,11 @@ void os::printc(char c) { } void os::print_formatted(const char* format, const char* val) { os::assert(format[0] == '}', "Format string unsupported. TODO."); - for (std::size_t i = 0; val[i] != '\0'; i++) { + for (amy::size i = 0; val[i] != '\0'; i++) { os::printc(val[i]); } } -void os::print_formatted(const char* format, std::uint64_t val) { +void os::print_formatted(const char* format, amy::u64 val) { os::assert(format[0] == '}', "Format string unsupported. TODO."); char data[20]; char* curr = data + 19; @@ -74,14 +73,14 @@ void os::print_formatted(const char* format, std::uint64_t val) { os::printc(*curr++); } } -void os::print_formatted(const char* format, std::int64_t val) { +void os::print_formatted(const char* format, amy::i64 val) { os::assert(format[0] == '}', "Format string unsupported. TODO."); if (val < 0) { os::printc('-'); - os::print_formatted(format, std::uint64_t(-val)); + os::print_formatted(format, amy::u64(-val)); } else { os::printc(' '); - os::print_formatted(format, std::uint64_t(val)); + os::print_formatted(format, amy::u64(val)); } } void os::print_formatted(const char* format, phys_ptr val) { @@ -96,7 +95,7 @@ void os::print_formatted(const char* format, const void* val) { os::assert(format[0] == '}', "Format string unsupported. TODO."); os::print("0x"); for (int i = 60; i >= 0; i -= 4) { - const int v = (reinterpret_cast(val) >> i) & 0xF; + const int v = (reinterpret_cast(val) >> i) & 0xF; os::printc(v < 10 ? v + '0' : v - 10 + 'a'); } } diff --git a/kernel/src/serial.hpp b/kernel/src/serial.hpp index 56ed9d0..479f1f0 100644 --- a/kernel/src/serial.hpp +++ b/kernel/src/serial.hpp @@ -13,8 +13,7 @@ #pragma once -#include - +#include "types.hpp" #include "lib/phys_ptr.hpp" namespace os { @@ -22,19 +21,19 @@ namespace os { template void assert(bool cond, const char* format, const Ts&... vs); -constexpr std::uint16_t serial_port{0x3F8}; +constexpr amy::u16 serial_port{0x3F8}; bool init_serial_port(); bool serial_received(); -std::uint8_t read_serial(); +amy::u8 read_serial(); bool serial_transmit_empty(); -void write_serial(std::uint8_t v); +void write_serial(amy::u8 v); void printc(char c); void print_formatted(const char* format, const char* val); -void print_formatted(const char* format, std::uint64_t val); -void print_formatted(const char* format, std::int64_t val); +void print_formatted(const char* format, amy::u64 val); +void print_formatted(const char* format, amy::i64 val); void print_formatted(const char* format, phys_ptr val); void print_formatted(const char* format, const void* val); @@ -42,37 +41,35 @@ template struct get_more_general_type_helper { using T = T_; }; template using get_more_general_type_helper_t = get_more_general_type_helper::T; -template <> struct get_more_general_type_helper { using T = std::uint64_t; }; -template <> struct get_more_general_type_helper { using T = std::uint64_t; }; -template <> struct get_more_general_type_helper { using T = std::uint64_t; }; -template <> struct get_more_general_type_helper { using T = std::int64_t; }; -template <> struct get_more_general_type_helper { using T = std::int64_t; }; -template <> struct get_more_general_type_helper { using T = std::int64_t; }; +template <> struct get_more_general_type_helper { using T = amy::u64; }; +template <> struct get_more_general_type_helper { using T = amy::u64; }; +template <> struct get_more_general_type_helper { using T = amy::u64; }; +template <> struct get_more_general_type_helper { using T = amy::i64; }; +template <> struct get_more_general_type_helper { using T = amy::i64; }; +template <> struct get_more_general_type_helper { using T = amy::i64; }; template <> struct get_more_general_type_helper { using T = const char*; }; template <> struct get_more_general_type_helper { using T = const char*; }; template struct get_more_general_type_helper> { using T = phys_ptr; }; template struct get_more_general_type_helper { using T = const void*; }; -template struct get_more_general_type_helper { using T = const char*; }; +template struct get_more_general_type_helper { using T = const char*; }; struct print_nth_helper { - std::size_t n; + amy::size n; const char* format; template inline print_nth_helper operator%(const T& v) { if (n == 0) { print_formatted(format, v); - return print_nth_helper{std::size_t(-1), format}; - } else { - return print_nth_helper{n - 1, format}; } + return print_nth_helper{n - 1, format}; } }; template void print(const char* format, const Ts&... vs) { - std::size_t arg_n = 0; + amy::size arg_n = 0; bool arg_n_is_given = 0; - for (std::size_t i = 0; format[i] != '\0'; i++) { + for (amy::size i = 0; format[i] != '\0'; i++) { if (format[i] == '{') { i++; if (format[i] == '\0') { @@ -81,19 +78,19 @@ void print(const char* format, const Ts&... vs) { printc('{'); continue; } else { - std::size_t format_spec_end = i; + amy::size format_spec_end = i; while (format[format_spec_end] != '}') { if (format[format_spec_end++] == '\0') { os::assert(false, "Error in format string: unterminated '{{}'."); } } - std::size_t n = arg_n; + amy::size n = arg_n; if ('0' <= format[i] && format[i] <= '9') { if (arg_n == 0) { arg_n_is_given = true; } os::assert(arg_n_is_given, "Error in format string: either the arg_id is always given, or never."); - std::size_t n_ = 0; + amy::size n_ = 0; while ('0' <= format[i] && format[i] <= '9') { n_ = n_ * 10 + (format[i++] - '0'); } @@ -109,7 +106,7 @@ void print(const char* format, const Ts&... vs) { } else { os::assert(format[i] == '}', "Error in format string: ':' required before format spec."); } - os::assert(n < sizeof...(vs), "Error in format string: not enough arguments."); + os::assert(n < amy::size(sizeof...(vs)), "Error in format string: not enough arguments."); (print_nth_helper{n, &format[i]} % ... % get_more_general_type_helper_t(vs)); i = format_spec_end; arg_n++; diff --git a/kernel/src/utils.cpp b/kernel/src/utils.cpp index 4643a27..43a8c2b 100644 --- a/kernel/src/utils.cpp +++ b/kernel/src/utils.cpp @@ -28,37 +28,39 @@ void os::hlt() { asm volatile("hlt" :); } -void os::outb(std::uint16_t port, std::uint8_t data) { +void os::outb(amy::u16 port, amy::u8 data) { asm volatile ("outb %1,%0" : : "dN"(port), "a"(data)); } -std::uint8_t os::inb(std::uint16_t port) { - std::uint8_t data; +amy::u8 os::inb(amy::u16 port) { + amy::u8 data; asm volatile ("inb %1,%0" : "=a"(data) : "dN"(port)); return data; } bool os::cpu_has_msr() { - std::uint32_t eax, ebx, ecx, edx; + amy::u32 eax, ebx, ecx, edx; __cpuid(0x01, eax, ebx, ecx, edx); return (edx & (1 << 5)) != 0; } -std::uint64_t os::get_msr(std::uint32_t msr) { - std::uint64_t lo, hi; +amy::u64 os::get_msr(amy::u32 msr) { + amy::u64 lo, hi; asm volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); return lo + (hi << 32); } -void os::set_msr(std::uint32_t msr, std::uint64_t v) { - asm volatile ("wrmsr" : : "a"(v & 0xFFFFFFFF), "d"((v >> 32) & 0xFFFFFFFF), "c"(msr)); +void os::set_msr(amy::u32 msr, amy::u64 v) { + asm volatile ("wrmsr" : : "a"(v & 0xFFFF'FFFF), "d"((v >> 32) & 0xFFFF'FFFF), "c"(msr)); } -extern "C" void* os::memset(void* dest, int c, size_t n) { +extern "C" void* os::memset(void* dest, int c, amy::size n) { + os::assert(n >= 0, "Memset expects a positive size."); while (n-- > 0) { - reinterpret_cast(dest)[n] = std::byte(c); + reinterpret_cast(dest)[n] = amy::byte(c); } return dest; } -extern "C" void* os::memcpy(void* dest, const void* src, size_t n) { +extern "C" void* os::memcpy(void* dest, const void* src, amy::size n) { + os::assert(n >= 0, "Memcpy expects a positive size."); while (n-- > 0) { - reinterpret_cast(dest)[n] = reinterpret_cast(src)[n]; + reinterpret_cast(dest)[n] = reinterpret_cast(src)[n]; } return dest; } diff --git a/kernel/src/utils.hpp b/kernel/src/utils.hpp index df82e9a..035760e 100644 --- a/kernel/src/utils.hpp +++ b/kernel/src/utils.hpp @@ -13,9 +13,8 @@ #pragma once -#include -#include -#include +#include +#include #include "serial.hpp" namespace os { @@ -24,16 +23,16 @@ void invlpg(const void* vaddr); void cli(); void sti(); void hlt(); -void outb(std::uint16_t port, std::uint8_t data); -std::uint8_t inb(std::uint16_t port); +void outb(amy::u16 port, amy::u8 data); +amy::u8 inb(amy::u16 port); bool cpu_has_msr(); -std::uint64_t get_msr(std::uint32_t msr); -void set_msr(std::uint32_t msr, std::uint64_t v); +amy::u64 get_msr(amy::u32 msr); +void set_msr(amy::u32 msr, amy::u64 v); template T clamp(T min, T v, T max) { return v < min ? min : max < v ? max : v; } -extern "C" void* memset(void* dest, int c, size_t n); -extern "C" void* memcpy(void* dest, const void* src, size_t n); +extern "C" void* memset(void* dest, int c, amy::size n); +extern "C" void* memcpy(void* dest, const void* src, amy::size n); template struct incrementing_int64_map { @@ -42,7 +41,7 @@ public: incrementing_int64_map(const incrementing_int64_map& other) = delete; incrementing_int64_map& operator=(const incrementing_int64_map& other) = delete; ~incrementing_int64_map() { - for (std::int64_t i = 0; i < n; i++) { + for (amy::i64 i = 0; i < n; i++) { if (present(i)) { remove(i); } } } @@ -50,36 +49,36 @@ public: bool has_room() { return n < max_n; } - bool present(std::int64_t index) { + bool present(amy::i64 index) { return 0 <= index && index < n && elems[index].present; } - std::int64_t create() { + amy::i64 create() { os::assert(has_room(), "Too many allocated elems in incrementing_int64_map."); elems[n].present = true; new(elems[n].buffer) T; return n++; } - void remove(std::int64_t index) { + void remove(amy::i64 index) { os::assert(present(index), "Tried removing non-existant element of incrementing_int64_map."); get(index).~T(); elems[index].present = false; } - T& get(std::int64_t index) { + T& get(amy::i64 index) { os::assert(present(index), "Tried getting non-existant element of incrementing_int64_map."); - return *std::launder(reinterpret_cast(&elems[index].buffer[0])); + return *amy::launder(reinterpret_cast(&elems[index].buffer[0])); } - const T& get(std::int64_t index) const { + const T& get(amy::i64 index) const { os::assert(present(index), "Tried getting non-existant element of incrementing_int64_map."); - return *std::launder(reinterpret_cast(&elems[index].buffer[0])); + return *amy::launder(reinterpret_cast(&elems[index].buffer[0])); } private: struct elem_t { bool present; - alignas(T) std::byte buffer[sizeof(T)]; + alignas(T) amy::byte buffer[sizeof(T)]; }; - std::int64_t n = 0; - static constexpr std::int64_t max_n = 4096; + amy::i64 n = 0; + static constexpr amy::i64 max_n = 4096; elem_t elems[max_n]; }; diff --git a/libcpp/memory.hpp b/libcpp/memory.hpp new file mode 100644 index 0000000..81ae2a6 --- /dev/null +++ b/libcpp/memory.hpp @@ -0,0 +1,37 @@ +// Copyright 2023 Amélia COUTARD. +// +// This file from the program "voyage au centre des fichiers" is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with this program. If +// not, see . + +#pragma once + +#include + +// See the C++ documentation for documentation. + +// Placement new and delete (taken from glibcxx, should be fine copyright-wise): +[[nodiscard]] inline void* operator new(unsigned long, void* p) noexcept { + return p; +} +[[nodiscard]] inline void* operator new[](unsigned long, void* p) noexcept { + return p; +} +inline void operator delete(void*, void*) noexcept {} +inline void operator delete[](void*, void*) noexcept {} + +namespace amy { + +// Taken from glibcxx, should be fine copyright-wise: +template +[[nodiscard]] constexpr T* launder(T* p) noexcept { + return __builtin_launder(p); +} +} // namespace amy diff --git a/libcpp/types.hpp b/libcpp/types.hpp new file mode 100644 index 0000000..2e7f2d6 --- /dev/null +++ b/libcpp/types.hpp @@ -0,0 +1,40 @@ +// Copyright 2023 Amélia COUTARD. +// +// This file from the program "voyage au centre des fichiers" is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with this program. If +// not, see . + +#pragma once + +#include + +namespace amy { + +enum class byte : unsigned char {}; +using i8 = int8_t; +using u8 = uint8_t; +using i16 = int16_t; +using u16 = uint16_t; +using i32 = int32_t; +using u32 = uint32_t; +using i64 = int64_t; +using u64 = uint64_t; + +using iptr = intptr_t; +using uptr = uintptr_t; +using dptr = __PTRDIFF_TYPE__; +using nptr = decltype(nullptr); + +using size = i64; + +using pid = i64; +using fd = i64; + +} // namespace amy diff --git a/test_module/src/test.S b/test_module/src/test.S index c5919fa..eb6dd23 100644 --- a/test_module/src/test.S +++ b/test_module/src/test.S @@ -44,3 +44,7 @@ close: mov $4, %rax syscall ret + +.globl loop_de_loop +loop_de_loop: +1: jmp 1b diff --git a/test_module/src/test.cpp b/test_module/src/test.cpp index 62a3576..a66ecd2 100644 --- a/test_module/src/test.cpp +++ b/test_module/src/test.cpp @@ -11,8 +11,13 @@ // You should have received a copy of the GNU General Public License along with this program. If // not, see . -#include -#include +#include + +enum mount_type { + MOUNT_REPLACE = 0, + MOUNT_BEFORE = 1, + MOUNT_AFTER = 2, +}; enum open_options { MODE_READ = 0x1, @@ -22,25 +27,23 @@ enum open_options { }; namespace sys { -extern "C" int64_t mount_kernel_device(int64_t wd, char device, char const* path, int64_t path_len); -extern "C" int64_t open(int64_t wd, char const* path, int64_t path_len, open_options options); -extern "C" int64_t read(int64_t file, char* data, int64_t len); -extern "C" int64_t write(int64_t file, char const* data, int64_t len); -extern "C" int64_t close(int64_t file); +extern "C" int mount_kernel_device(amy::fd wd, char device, char const* path, amy::size path_len, mount_type type); +extern "C" amy::fd open(amy::fd wd, char const* path, amy::size path_len, open_options options); +extern "C" amy::size read(amy::fd file, char* data, amy::size len); +extern "C" amy::size write(amy::fd file, char const* data, amy::size len); +extern "C" int close(amy::fd file); } // namespace sys -void loop_de_loop() { - loop_de_loop(); -} +extern "C" void loop_de_loop(); extern "C" void _start() { - sys::mount_kernel_device(-1, 'I', "/", 1); // 'I' is the I/O device. /serial is the serial port /fb is the framebuffer - const int64_t serial = sys::open(-1, "/serial", 7, MODE_WRITE); + sys::mount_kernel_device(-1, 'I', "/", 1, MOUNT_REPLACE); // 'I' is the I/O device. /serial is the serial port /fb is the framebuffer + const amy::fd serial = sys::open(-1, "/serial", 7, MODE_WRITE); sys::write(serial, "Entrez votre nom: ", 18); char data[32]; - int64_t read = 0; - int64_t read_this_time; + amy::size read = 0; + amy::size read_this_time; do { read_this_time = sys::read(serial, data + read, 1); if (read_this_time) {