aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2021-03-21 16:53:07 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2021-03-21 16:53:07 +0200
commite9232199bdd97233dabd59f07c63607c93c0c59c (patch)
tree66aff19650079c9fc990f75d2ed390dd674cfdaa
parentAdd allocator (diff)
downloadkernel.cpp-e9232199bdd97233dabd59f07c63607c93c0c59c.tar.xz
Check multiboot2 header length, and if needed map the next page as well
-rw-r--r--libk/result.h5
-rw-r--r--linker.ld3
-rw-r--r--makefile6
-rw-r--r--src/boot.S48
-rw-r--r--src/kernel.cc23
-rw-r--r--src/kernel/multiboot.cc4
-rw-r--r--src/vmm.cc7
-rw-r--r--src/vmm.h8
-rw-r--r--toolchain.makefile5
9 files changed, 66 insertions, 43 deletions
diff --git a/libk/result.h b/libk/result.h
index 8077baf..e940bd9 100644
--- a/libk/result.h
+++ b/libk/result.h
@@ -7,6 +7,7 @@
template <typename T, error_enum_t E>
class Result {
public:
+ constexpr Result() = default;
explicit constexpr Result(T t) : is_ok(true), data{.t = t} {};
explicit constexpr Result(E e) : is_ok(false), data{.e = e} {};
@@ -15,9 +16,9 @@ public:
constexpr T value() const { return is_ok ? data.t : T{}; }
private:
- const bool is_ok;
+ const bool is_ok = false;
union {
T t;
- E e;
+ E e = E::NoError;
} data;
};
diff --git a/linker.ld b/linker.ld
index d1dedd2..f7010e7 100644
--- a/linker.ld
+++ b/linker.ld
@@ -11,7 +11,8 @@ SECTIONS
*/
. = 0;
.multiboot : {
- *(.multiboot.header)
+ . = ALIGN(8);
+ KEEP(*(.multiboot.header))
}
/* Begin putting sections at 4 MiB */
diff --git a/makefile b/makefile
index fc3338e..7eecced 100644
--- a/makefile
+++ b/makefile
@@ -14,7 +14,7 @@ CXX_OBJ := $(addprefix $(OBJ_DIR)/, $(CXX_OBJ))
CXX_DEP = $(CXX_OBJ:%.o=%.d)
CXX_TEST_OBJ := $(addprefix $(OBJ_DIR)/, $(CXX_TEST_OBJ))
CXX_INCLUDE := $(addprefix -I, $(CXX_INCLUDE))
-CXX_SYSTEM_INCLUDE := $(addprefix -isystem, $(CXX_SYSTEM_INCLUDE))
+SYSTEM_INCLUDE := $(addprefix -isystem, $(SYSTEM_INCLUDE))
$(OBJ_DIR)/glitch.elf: $(autogen) $(AS_OBJ) $(CXX_OBJ) linker.ld
@echo " LD $@"
@@ -23,13 +23,13 @@ $(OBJ_DIR)/glitch.elf: $(autogen) $(AS_OBJ) $(CXX_OBJ) linker.ld
$(AS_OBJ): $(OBJ_DIR)/%.o: %.S
@mkdir -p $(@D)
@echo " AS $<"
- @$(AS) -target $(TARGET) -nostdlib -Wall -Wextra -c $^ -o $@
+ @$(AS) -target $(TARGET) $(AS_FLAGS) $(SYSTEM_INCLUDE) -c $^ -o $@
-include $(CXX_DEP)
$(CXX_OBJ): $(OBJ_DIR)/%.o : %.cc
@mkdir -p $(@D)
@echo " CXX $<"
- @$(CXX) -target $(TARGET) $(CXX_FLAGS) $(CXX_INCLUDE) $(CXX_SYSTEM_INCLUDE) -MMD -c $< -o $@
+ @$(CXX) -target $(TARGET) $(CXX_FLAGS) $(CXX_INCLUDE) $(SYSTEM_INCLUDE) -MMD -c $< -o $@
$(CXX_TEST_OBJ): $(OBJ_DIR)/%.o : %.cc
@mkdir -p $(@D)
diff --git a/src/boot.S b/src/boot.S
index 0451066..3a07c19 100644
--- a/src/boot.S
+++ b/src/boot.S
@@ -1,35 +1,43 @@
-/*
- Declare a multiboot header that marks the program as a kernel.
- https://www.gnu.org/software/grub/manual/multiboot2/html_node/index.html
-
- The Multiboot2 header must be contained completely within the first
- 32kB of the OS image, and must be 64-bit (8 byte) aligned.
-*/
-.set MULTIBOOT_HEADER_MAGIC, 0xe85250d6 # multiboot2 magic number
-.set MULTIBOOT_ARCHITECTURE, 0 # protected mode i386
-.set MULTIBOOT_HEADER_TAG_END, 0
+/* Declare a multiboot header that marks the program as a kernel.
+ * https://www.gnu.org/software/grub/manual/multiboot2/html_node/index.html
+ * The Multiboot2 header must be contained completely within the first 32kB, and must be 8 byte aligned.
+ */
+#define ASM_FILE
+#include <multiboot2.h>
.section .multiboot.header, "a"
.align 8
header_start:
- .int MULTIBOOT_HEADER_MAGIC
- .int MULTIBOOT_ARCHITECTURE
+ .int MULTIBOOT2_HEADER_MAGIC
+ .int MULTIBOOT_ARCHITECTURE_I386
.int header_end - header_start
- .int -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE + (header_end - header_start))
+ .int -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (header_end - header_start))
- # TODO tags go here
+.align 8
+information_tag_start:
+ .short MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST
+ .short 0
+ .int information_tag_end - information_tag_start
+ .int MULTIBOOT_TAG_TYPE_MMAP
+information_tag_end:
+.align 8
+module_tag_start:
+ .short MULTIBOOT_HEADER_TAG_MODULE_ALIGN
+ .short 0
+ .int module_tag_end - module_tag_start
+module_tag_end:
+
+.align 8
.short MULTIBOOT_HEADER_TAG_END
.short 0
.int 8
header_end:
-/*
- The stack on x86 must be 16-byte aligned according to the System V ABI
- standard and de-facto extensions. The compiler will assume the stack is
- properly aligned and failure to align the stack will result in undefined
- behavior.
-*/
+/* The stack on x86 must be 16-byte aligned according to the System V ABI standard and de-facto extensions. The
+ * compiler will assume the stack is properly aligned and failure to align the stack will result in undefined
+ * behavior.
+ */
.section .stack, "aw", @nobits
.align 16
stack_bottom:
diff --git a/src/kernel.cc b/src/kernel.cc
index 05e0daf..53500bc 100644
--- a/src/kernel.cc
+++ b/src/kernel.cc
@@ -32,7 +32,7 @@ extern "C" {
void dump_multiboot(uint32_t mb_magic, uint32_t mb_addr);
void dump_gdt();
-void kernel_main(uint32_t mb_magic, uint32_t mb_addr) {
+void kernel_main(uint32_t mb_magic, const uint32_t mb_addr) {
#ifdef HAS_SERIAL0
if constexpr (serial0_console)
if (serial0.self_check()) Console::set(&serial0);
@@ -54,19 +54,28 @@ void kernel_main(uint32_t mb_magic, uint32_t mb_addr) {
dump_address();
// dump_gdt();
- //
{
- const auto mb_addr_r = kvmm.map(mb_addr, 0xc03fe000);
+ printk("Multiboot2 header at ", uhex{mb_addr}, '\n');
+
+ const auto mb_addr_r = kvmm.map(mb_addr, {768, 1020});
runtime_assert(mb_addr_r, "Failed to map mb_addr");
- mb_addr = mb_addr_r.value();
- const auto mb_size = check_multiboot(mb_magic, mb_addr);
+ const auto mb_addr_ = mb_addr_r.value();
+ const auto mb_size = check_multiboot(mb_magic, mb_addr_);
runtime_assert((mb_size != 0), "Invalid multiboot header");
- printk("Multiboot2 header at ", uhex{mb_addr}, " size: ", mb_size, '\n');
+ const auto mb_addr_re = [mb_addr, mb_size]() -> Result<uint32_t, vmm::Error> {
+ if (mb_addr % 4096 + mb_size >= 4096) return kvmm.map((mb_addr % 4096 + 4096), {768, 1021});
+ return {};
+ }();
+
+ printk("Multiboot2 header mounted at ", uhex{mb_addr}, " size: ", mb_size, '\n');
+
+ dump_multiboot(mb_magic, mb_addr_);
- // dump_multiboot(mb_magic, mb_addr);
+ if (mb_addr_r) kvmm.unmap(mb_addr_r.value());
+ if (mb_addr_re) kvmm.unmap(mb_addr_re.value());
}
GDT gdt;
diff --git a/src/kernel/multiboot.cc b/src/kernel/multiboot.cc
index 024916e..e0626f0 100644
--- a/src/kernel/multiboot.cc
+++ b/src/kernel/multiboot.cc
@@ -1,5 +1,7 @@
#include <multiboot2.h>
-#include <types.h>
+
+typedef multiboot_uint16_t uint16_t;
+typedef multiboot_uint32_t uint32_t;
uint32_t check_multiboot(uint32_t mb_magic, uint32_t mb_addr) {
if (mb_magic != MULTIBOOT2_BOOTLOADER_MAGIC) return 0;
diff --git a/src/vmm.cc b/src/vmm.cc
index 3c90c48..abce5b8 100644
--- a/src/vmm.cc
+++ b/src/vmm.cc
@@ -78,6 +78,13 @@ Result<uint32_t, vmm::Error> vmm::map(uint32_t addr, const vmm::address dest) {
return Result<uint32_t, vmm::Error>{vmm::AddressAlreadyMapped};
}
+void vmm::unmap(const address d) {
+ if (directory[d.table_idx] == 0) return;
+ page_table table{directory[d.table_idx]};
+ table.set(d.page_idx, 0);
+ vmm::reload();
+}
+
vmm::page_table::page_table(uint32_t from) {
// TODO get flags
// convert physical address to a virtual address so we can read it
diff --git a/src/vmm.h b/src/vmm.h
index 252e5bb..1729275 100644
--- a/src/vmm.h
+++ b/src/vmm.h
@@ -28,13 +28,6 @@ public:
vmm(uint32_t* addr = nullptr);
- [[deprecated]] constexpr static size_t table_id(uint32_t offset) {
- offset &= 0xfff00000;
- offset /= (4 * 1024 * 1024);
- return static_cast<size_t>(offset);
- }
- [[deprecated]] constexpr static size_t page_id(uint32_t offset) { return static_cast<size_t>(offset / 4096); }
-
static void reload() {
uint32_t cr0;
asm volatile("mov %%cr0, %0" : "=r"(cr0));
@@ -42,6 +35,7 @@ public:
}
[[nodiscard]] Result<uint32_t, Error> map(uint32_t phys_addr, const address dest);
+ void unmap(const address);
private:
class page_table {
diff --git a/toolchain.makefile b/toolchain.makefile
index a4a0667..dc6194e 100644
--- a/toolchain.makefile
+++ b/toolchain.makefile
@@ -5,7 +5,7 @@ NM := llvm-nm
SED := sed
AS := clang
-AS_FLAGS :=
+AS_FLAGS := -nostdlib -Wall -Wextra
LD := ld.lld
LD_FLAGS := -nostdlib -T linker.ld
@@ -22,7 +22,8 @@ CXX_FLAGS := -std=c++20 -g -O3 -flto=full \
-Wconsumed
CXX_TEST_FLAGS := -std=c++20 -Wall -Wextra -Werror=pedantic
CXX_INCLUDE := $(CURDIR)/libk $(CURDIR)/src $(CURDIR)/drivers
-CXX_SYSTEM_INCLUDE := $(CURDIR)/grub
+
+SYSTEM_INCLUDE := $(CURDIR)/grub
#
GRUB_MKRESCUE := grub-mkrescue