aboutsummaryrefslogtreecommitdiffstats
path: root/src/multiboot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/multiboot.cpp')
-rw-r--r--src/multiboot.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/multiboot.cpp b/src/multiboot.cpp
new file mode 100644
index 0000000..46c505b
--- /dev/null
+++ b/src/multiboot.cpp
@@ -0,0 +1,92 @@
+#include "textoutput.hpp"
+
+#include <cstdint>
+
+extern TextOutput& term;
+
+struct multiboot2_tag
+{
+ alignas(8)
+ std::uint16_t id;
+ std::uint16_t flags;
+ std::uint32_t length;
+ std::uint32_t data[1];
+} __attribute__((packed));
+
+template<int N>
+struct multiboot2
+{
+ static constexpr std::uint32_t MAGIC = 0xE85250D6;
+ static constexpr std::uint32_t FLAGS = 0;
+ static constexpr std::uint32_t LENGTH = 16;
+ static constexpr std::uint32_t CHECKSUM = -(MAGIC + FLAGS + LENGTH);
+
+ alignas(8)
+ std::uint32_t magic = MAGIC;
+ std::uint32_t flags = FLAGS;
+ std::uint32_t length = LENGTH;
+ std::uint32_t checksum = CHECKSUM;
+
+ multiboot2_tag tags[N];
+} __attribute__((packed));
+
+__attribute__((section(".multiboot2")))
+multiboot2 multibootHeader = {
+ .tags = {
+ {
+ 1, 0, sizeof(multiboot2_tag) + sizeof(std::uint32_t),
+ {4}
+ },
+ {
+ 0, 0, 8, {}
+ }
+ }
+};
+
+std::uint32_t multiboot_magic;
+std::uint32_t *multiboot_ptr;
+
+std::uint32_t lowerMem = 0;
+std::uint32_t upperMem = 0;
+std::uint32_t *acpiRsdp = nullptr;
+std::uint32_t *acpiRsdpV2 = nullptr;
+
+bool multiboot_initialize()
+{
+ if (multiboot_magic != 0x36d76289) {
+ term.write("Not multiboot!");
+ return false;
+ }
+
+ term.write("Found multiboot headers: ");
+
+ auto ptr = multiboot_ptr + 2;
+ while (ptr[0] != 0 && ptr[1] != 8) {
+ term.write(ptr[0]);
+ term.write(", ");
+
+ switch (ptr[0]) {
+ case 4:
+ lowerMem = ptr[2] * 1024;
+ upperMem = ptr[3] * 1024;
+ break;
+ case 14:
+ acpiRsdp = ptr + 2;
+ break;
+ case 15:
+ acpiRsdpV2 = ptr + 2;
+ break;
+ default:
+ break;
+ }
+
+ auto next = reinterpret_cast<std::uintptr_t>(ptr);
+ next += ptr[1];
+ next = (next + 7) & ~7;
+ ptr = reinterpret_cast<std::uint32_t *>(next);
+ }
+
+ term.write('\n');
+ return true;
+}
+