From: Amelia Coutard <eliottulio.coutard@gmail.com> Date: Sun, 6 Aug 2023 01:54:28 +0000 (+0200) Subject: Added support for multiple startup modules, and a second module to test yield better X-Git-Url: https://git.ameliathe1st.gay/?a=commitdiff_plain;h=9493ea8dfaa584841004df62ef8e3ed092ed7b44;p=voyage-au-centre-des-fichiers.git Added support for multiple startup modules, and a second module to test yield better --- diff --git a/grub.cfg b/grub.cfg index d008406..fee1476 100644 --- a/grub.cfg +++ b/grub.cfg @@ -11,4 +11,5 @@ menuentry "isos" { multiboot2 /boot/kernel.elf64 module2 /boot/test-module.elf64 test-module + module2 /boot/test-module-2.elf64 test-module-2 } diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index e467397..a0e47ef 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -41,6 +41,46 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s .size = sizeof(bootstrap_pages_for_memory) / sizeof(bootstrap_pages_for_memory[0]) }); + { // 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++) { + isr_info[i].type = os::isr_info::type_t::trap_gate; + } + asm ("movq $handler_0x00,%0" : "=ri"(isr_info[0x00].addr) : ); + asm ("movq $handler_0x01,%0" : "=ri"(isr_info[0x01].addr) : ); + asm ("movq $handler_0x02,%0" : "=ri"(isr_info[0x02].addr) : ); + asm ("movq $handler_0x03,%0" : "=ri"(isr_info[0x03].addr) : ); + asm ("movq $handler_0x04,%0" : "=ri"(isr_info[0x04].addr) : ); + asm ("movq $handler_0x05,%0" : "=ri"(isr_info[0x05].addr) : ); + asm ("movq $handler_0x06,%0" : "=ri"(isr_info[0x06].addr) : ); + asm ("movq $handler_0x07,%0" : "=ri"(isr_info[0x07].addr) : ); + asm ("movq $handler_0x08,%0" : "=ri"(isr_info[0x08].addr) : ); + asm ("movq $handler_0x09,%0" : "=ri"(isr_info[0x09].addr) : ); + asm ("movq $handler_0x0a,%0" : "=ri"(isr_info[0x0a].addr) : ); + asm ("movq $handler_0x0b,%0" : "=ri"(isr_info[0x0b].addr) : ); + asm ("movq $handler_0x0c,%0" : "=ri"(isr_info[0x0c].addr) : ); + asm ("movq $handler_0x0d,%0" : "=ri"(isr_info[0x0d].addr) : ); + asm ("movq $handler_0x0e,%0" : "=ri"(isr_info[0x0e].addr) : ); + asm ("movq $handler_0x0f,%0" : "=ri"(isr_info[0x0f].addr) : ); + asm ("movq $handler_0x10,%0" : "=ri"(isr_info[0x10].addr) : ); + asm ("movq $handler_0x11,%0" : "=ri"(isr_info[0x11].addr) : ); + asm ("movq $handler_0x12,%0" : "=ri"(isr_info[0x12].addr) : ); + asm ("movq $handler_0x13,%0" : "=ri"(isr_info[0x13].addr) : ); + asm ("movq $handler_0x14,%0" : "=ri"(isr_info[0x14].addr) : ); + asm ("movq $handler_0x15,%0" : "=ri"(isr_info[0x15].addr) : ); + asm ("movq $handler_0x16,%0" : "=ri"(isr_info[0x16].addr) : ); + asm ("movq $handler_0x17,%0" : "=ri"(isr_info[0x17].addr) : ); + asm ("movq $handler_0x18,%0" : "=ri"(isr_info[0x18].addr) : ); + asm ("movq $handler_0x19,%0" : "=ri"(isr_info[0x19].addr) : ); + asm ("movq $handler_0x1a,%0" : "=ri"(isr_info[0x1a].addr) : ); + asm ("movq $handler_0x1b,%0" : "=ri"(isr_info[0x1b].addr) : ); + asm ("movq $handler_0x1c,%0" : "=ri"(isr_info[0x1c].addr) : ); + asm ("movq $handler_0x1d,%0" : "=ri"(isr_info[0x1d].addr) : ); + asm ("movq $handler_0x1e,%0" : "=ri"(isr_info[0x1e].addr) : ); + asm ("movq $handler_0x1f,%0" : "=ri"(isr_info[0x1f].addr) : ); + os::enable_interrupts(isr_info, idt); + } + // Allocate those pages so that I only ever need to update the mapping once when I create a new process or port. // TODO: Not an emergency, but adapt in case we need multiple PML4Es. (*NOT* the case right now.) static_assert(sizeof(os::processes) <= 1024 * 1024 * 1024, "Error: processes array too big."); @@ -52,9 +92,6 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s set_base_address(PML4T.contents[index], os::phys_ptr<os::paging::PDPT>(PDPT_alloc.ptr.get_phys_addr())); } - os::paging::setup_page(PML4T, (void*)0xFFFF'C000'0000'0000, 1, 0); // The startup module. - std::int64_t module_process = os::processes.create(); - { struct { os::phys_ptr<os::paging::page> start_address = nullptr; @@ -83,9 +120,8 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s break; case multiboot2::info::type_t::modules: os::print("{}->{}: {}\n", multiboot2::modules_mod_start(it), multiboot2::modules_mod_end(it), multiboot2::modules_string(it)); - os::assert(!module_specified, "Multiple modules specified in the multiboot. This is unsupported."); module_specified = true; - os::elf::load_elf(os::get_process(module_process), + os::elf::load_elf(os::get_process(os::processes.create()), (std::byte*)multiboot2::modules_mod_start(it), multiboot2::modules_mod_end(it) - multiboot2::modules_mod_start(it), PML4T); @@ -142,46 +178,6 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s os::paging::page_allocator.print_all(); os::print("RAM END\n"); - { - os::isr_info isr_info[32]; - for (size_t i = 0; 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) : ); - asm ("movq $handler_0x01,%0" : "=ri"(isr_info[0x01].addr) : ); - asm ("movq $handler_0x02,%0" : "=ri"(isr_info[0x02].addr) : ); - asm ("movq $handler_0x03,%0" : "=ri"(isr_info[0x03].addr) : ); - asm ("movq $handler_0x04,%0" : "=ri"(isr_info[0x04].addr) : ); - asm ("movq $handler_0x05,%0" : "=ri"(isr_info[0x05].addr) : ); - asm ("movq $handler_0x06,%0" : "=ri"(isr_info[0x06].addr) : ); - asm ("movq $handler_0x07,%0" : "=ri"(isr_info[0x07].addr) : ); - asm ("movq $handler_0x08,%0" : "=ri"(isr_info[0x08].addr) : ); - asm ("movq $handler_0x09,%0" : "=ri"(isr_info[0x09].addr) : ); - asm ("movq $handler_0x0a,%0" : "=ri"(isr_info[0x0a].addr) : ); - asm ("movq $handler_0x0b,%0" : "=ri"(isr_info[0x0b].addr) : ); - asm ("movq $handler_0x0c,%0" : "=ri"(isr_info[0x0c].addr) : ); - asm ("movq $handler_0x0d,%0" : "=ri"(isr_info[0x0d].addr) : ); - asm ("movq $handler_0x0e,%0" : "=ri"(isr_info[0x0e].addr) : ); - asm ("movq $handler_0x0f,%0" : "=ri"(isr_info[0x0f].addr) : ); - asm ("movq $handler_0x10,%0" : "=ri"(isr_info[0x10].addr) : ); - asm ("movq $handler_0x11,%0" : "=ri"(isr_info[0x11].addr) : ); - asm ("movq $handler_0x12,%0" : "=ri"(isr_info[0x12].addr) : ); - asm ("movq $handler_0x13,%0" : "=ri"(isr_info[0x13].addr) : ); - asm ("movq $handler_0x14,%0" : "=ri"(isr_info[0x14].addr) : ); - asm ("movq $handler_0x15,%0" : "=ri"(isr_info[0x15].addr) : ); - asm ("movq $handler_0x16,%0" : "=ri"(isr_info[0x16].addr) : ); - asm ("movq $handler_0x17,%0" : "=ri"(isr_info[0x17].addr) : ); - asm ("movq $handler_0x18,%0" : "=ri"(isr_info[0x18].addr) : ); - asm ("movq $handler_0x19,%0" : "=ri"(isr_info[0x19].addr) : ); - asm ("movq $handler_0x1a,%0" : "=ri"(isr_info[0x1a].addr) : ); - asm ("movq $handler_0x1b,%0" : "=ri"(isr_info[0x1b].addr) : ); - asm ("movq $handler_0x1c,%0" : "=ri"(isr_info[0x1c].addr) : ); - asm ("movq $handler_0x1d,%0" : "=ri"(isr_info[0x1d].addr) : ); - asm ("movq $handler_0x1e,%0" : "=ri"(isr_info[0x1e].addr) : ); - asm ("movq $handler_0x1f,%0" : "=ri"(isr_info[0x1f].addr) : ); - os::enable_interrupts(isr_info, idt); - } - // Unmap low RAM, and free corresponding page. PML4T.contents[0].P = false; os::paging::page_allocator.deallocate({.ptr = os::phys_ptr<os::paging::page>(get_base_address(PML4T.contents[0]).get_phys_addr()), .size = 1}); @@ -195,5 +191,5 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s os::enable_syscalls(); os::print("Moving to ring 3.\n"); - os::run_first_process(module_process); + os::run_first_process(0); } diff --git a/test_module/src/test.cpp b/test_module/src/test.cpp index bf45ddf..3e545d9 100644 --- a/test_module/src/test.cpp +++ b/test_module/src/test.cpp @@ -28,8 +28,6 @@ extern "C" void _start() { check_mem(); printstr("Done.\n"); printstr("Prg 1.\n"); - yield(); - printstr("Prg 1 again.\n"); while (true) { yield(); diff --git a/test_module_2/module.mk b/test_module_2/module.mk new file mode 100644 index 0000000..9b92895 --- /dev/null +++ b/test_module_2/module.mk @@ -0,0 +1,46 @@ +# Written in 2023 by Amélia COUTARD <eliottulio.coutard@gmail.com> +# To the extent possible under law, the author(s) have dedicated all copyright +# and related and neighboring rights to this file to the public domain worldwide. +# This file is distributed without any warranty. +# You should have received a copy of the CC0 Public Domain Dedication along with +# this file. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. + +# So, about the license. I don't think I have a copyright on this file's code, but, +# since I gave it the CC0 license in case I do, that doesn't matter either way. + +SRC_DIR := test_module_2/src/ +OUT_DIR := test_module_2/out/ +DEP_DIR := test_module_2/dep/ +EXEC_NAME := test-module-2.elf64 + +TO_ISO += isodir/boot/$(EXEC_NAME) +TO_CLEAN += $(OUT_DIR) $(DEP_DIR) + +LOCAL_CXXFLAGS := $(CXXFLAGS) +LOCAL_LDFLAGS := $(LDFLAGS) + +CPPSRCS := $(shell find $(SRC_DIR) -name '*.cpp') +CPPOBJS := $(CPPSRCS:$(SRC_DIR)%=$(OUT_DIR)%.o) +ASMSRCS := $(shell find $(SRC_DIR) -name '*.S') +ASMOBJS := $(ASMSRCS:$(SRC_DIR)%=$(OUT_DIR)%.o) +OBJS := $(CPPOBJS) $(ASMOBJS) + +isodir/boot/$(EXEC_NAME): $(OUT_DIR)$(EXEC_NAME) + mkdir -p "$(@D)" + install -m 644 "$<" "$@" + +$(OUT_DIR)$(EXEC_NAME): OBJS := $(OBJS) +$(OUT_DIR)$(EXEC_NAME): LDLIBS := -nostdlib -lgcc +$(OUT_DIR)$(EXEC_NAME): LDFLAGS := $(LOCAL_LDFLAGS) +$(OUT_DIR)$(EXEC_NAME): $(OBJS) + mkdir -p "$(@D)" + $(CXX) $(LDFLAGS) -o "$@" $+ $(LDLIBS) + +$(OUT_DIR)%.o: DEP_DIR := $(DEP_DIR) +$(OUT_DIR)%.o: CXXFLAGS := $(LOCAL_CXXFLAGS) +$(OUT_DIR)%.o: $(SRC_DIR)% + mkdir -p $(@D) + mkdir -p $(dir $(DEP_DIR)$*) + $(CXX) $(CXXFLAGS) -c "$<" -MMD -MT "$@" -MF "$(DEP_DIR)$*.d" -o "$@" + +-include $(DEP_DIR)*.d diff --git a/test_module_2/src/test.S b/test_module_2/src/test.S new file mode 100644 index 0000000..348de63 --- /dev/null +++ b/test_module_2/src/test.S @@ -0,0 +1,32 @@ +# Copyright 2023 Amélia COUTARD. +# +# This file from the program isos 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 <https://www.gnu.org/licenses/>. + +.section .text + +.globl print +print: + mov $0, %rax + syscall + ret + +.globl check_mem +check_mem: + mov $1, %rax + syscall + ret + +.globl yield +yield: + mov $2, %rax + syscall + ret diff --git a/test_module_2/src/test.cpp b/test_module_2/src/test.cpp new file mode 100644 index 0000000..f4d1791 --- /dev/null +++ b/test_module_2/src/test.cpp @@ -0,0 +1,38 @@ +// Copyright 2023 Amélia COUTARD. +// +// This file from the program isos 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 <https://www.gnu.org/licenses/>. + +#include <stddef.h> + +extern "C" void print(char c); +extern "C" void check_mem(); +extern "C" void yield(); + +void printstr(const char* str); + +extern "C" void _start() { + printstr("Mem program 2:\n"); + check_mem(); + printstr("Done.\n"); + printstr("Prog 2.\n"); + + while (true) { + yield(); + printstr("Prog 2 again.\n"); + } +} + +void printstr(const char* str) { + for (size_t i = 0; str[i] != '\0'; i++) { + print(str[i]); + } +}