fix: Project restructuring

This commit is contained in:
Daniel Hammer
2025-03-08 00:09:27 +01:00
parent 8cbb8d4472
commit a567bd8437
7 changed files with 183 additions and 155 deletions
+61
View File
@@ -0,0 +1,61 @@
// GCC and Clang reserve the right to generate calls to the following
// 4 functions even if they are not directly called.
// Implement them as the C specification mandates.
// DO NOT remove or rename these functions, or stuff will eventually break!
// They CAN be moved to a different .cpp file.
#include <cstdint>
extern "C" {
void *memcpy(void *dest, const void *src, std::size_t n) {
std::uint8_t *pdest = static_cast<std::uint8_t *>(dest);
const std::uint8_t *psrc = static_cast<const std::uint8_t *>(src);
for (std::size_t i = 0; i < n; i++) {
pdest[i] = psrc[i];
}
return dest;
}
void *memset(void *s, int c, std::size_t n) {
std::uint8_t *p = static_cast<std::uint8_t *>(s);
for (std::size_t i = 0; i < n; i++) {
p[i] = static_cast<uint8_t>(c);
}
return s;
}
void *memmove(void *dest, const void *src, std::size_t n) {
std::uint8_t *pdest = static_cast<std::uint8_t *>(dest);
const std::uint8_t *psrc = static_cast<const std::uint8_t *>(src);
if (src > dest) {
for (std::size_t i = 0; i < n; i++) {
pdest[i] = psrc[i];
}
} else if (src < dest) {
for (std::size_t i = n; i > 0; i--) {
pdest[i-1] = psrc[i-1];
}
}
return dest;
}
int memcmp(const void *s1, const void *s2, std::size_t n) {
const std::uint8_t *p1 = static_cast<const std::uint8_t *>(s1);
const std::uint8_t *p2 = static_cast<const std::uint8_t *>(s2);
for (std::size_t i = 0; i < n; i++) {
if (p1[i] != p2[i]) {
return p1[i] < p2[i] ? -1 : 1;
}
}
return 0;
}
}
+2 -2
View File
@@ -7,11 +7,11 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
// Signatures, defined in main.cpp, probably will move sometime soon // Signatures, defined in CMemory.cpp
extern "C" extern "C"
{ {
void *memcpy(void *dest, const void *src, std::size_t n); void *memcpy(void *dest, const void *src, std::size_t n);
void *memset(void *s, int c, std::size_t n); void *memset(void *s, int c, std::size_t n);
void *memmove(void *dest, const void *src, std::size_t n); void *memmove(void *dest, const void *src, std::size_t n);
int memcmp(const void *s1, const void *s2, std::size_t n); int memcmp(const void *s1, const void *s2, std::size_t n);
} }
+17
View File
@@ -0,0 +1,17 @@
/*
* Itanium.cpp
* Definitions for the Itanium C++ ABI
* Copyright (c) Daniel Hammer, Limine Contributors (via Limine C++ example)
*/
#include <Platform/Util.hpp>
// The following stubs are required by the Itanium C++ ABI (the one we use,
// regardless of the "Itanium" nomenclature).
// Like the memory functions above, these stubs can be moved to a different .cpp file,
// but should not be removed, unless you know what you are doing.
extern "C" {
int __cxa_atexit(void (*)(void *), void *, void *) { return 0; }
void __cxa_pure_virtual() { hcf(); }
void *__dso_handle;
}
+69
View File
@@ -0,0 +1,69 @@
/*
* Limine.hpp
* Limine platform definitions and support
* Copyright (c) Limine Contributors (via Limine C++ example)
*/
#include "../limine.h"
// Set the base revision to 3, this is recommended as this is the latest
// base revision described by the Limine boot protocol specification.
// See specification for further info.
namespace {
__attribute__((used, section(".limine_requests")))
volatile LIMINE_BASE_REVISION(3);
}
// The Limine requests can be placed anywhere, but it is important that
// the compiler does not optimise them away, so, usually, they should
// be made volatile or equivalent, _and_ they should be accessed at least
// once or marked as used with the "used" attribute as done here.
namespace {
__attribute__((used, section(".limine_requests")))
volatile limine_framebuffer_request framebuffer_request = {
.id = LIMINE_FRAMEBUFFER_REQUEST,
.revision = 0,
.response = nullptr
};
__attribute__((used, section(".limine_requests")))
volatile limine_efi_system_table_request system_table_request = {
.id = LIMINE_EFI_SYSTEM_TABLE_REQUEST,
.revision = 0,
.response = nullptr
};
__attribute__((used, section(".limine_requests")))
volatile limine_hhdm_request hhdm_request = {
.id = LIMINE_HHDM_REQUEST,
.revision = 0,
.response = nullptr
};
__attribute__((used, section(".limine_requests")))
volatile limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST,
.revision = 0,
.response = nullptr
};
}
// Finally, define the start and end markers for the Limine requests.
// These can also be moved anywhere, to any .cpp file, as seen fit.
namespace {
__attribute__((used, section(".limine_requests_start")))
volatile LIMINE_REQUESTS_START_MARKER;
__attribute__((used, section(".limine_requests_end")))
volatile LIMINE_REQUESTS_END_MARKER;
}
+20
View File
@@ -0,0 +1,20 @@
/*
* Util.cpp
* Platform utility routines
* Copyright (c) Daniel Hammer, Limine Contributors (via Limine C++ example)
*/
// Halt and catch fire function.
void hcf()
{
for (;;)
{
#if defined(__x86_64__)
asm("hlt");
#elif defined(__aarch64__) || defined(__riscv)
asm("wfi");
#elif defined(__loongarch64)
asm("idle 0");
#endif
}
}
+10
View File
@@ -0,0 +1,10 @@
/*
* Util.hpp
* Declarations of platform utility routines
* Copyright (c) Daniel Hammer, Limine Contributors (via Limine C++ example)
*/
#pragma once
// Halt and catch fire function.
void hcf();
+4 -153
View File
@@ -1,7 +1,7 @@
/* /*
* main.cpp * main.cpp
* Kernel entry point * Kernel entry point
* Copyright (c) 2025 Daniel Hammer * Copyright (c) 2025 Daniel Hammer, Limine Contributors (via Limine C++ example)
*/ */
#include <cstdint> #include <cstdint>
@@ -19,6 +19,9 @@
#include <CppLib/Stream.hpp> #include <CppLib/Stream.hpp>
#include <CppLib/Vector.hpp> #include <CppLib/Vector.hpp>
#include <Platform/Limine.hpp>
#include <Platform/Util.hpp>
using namespace Kt; using namespace Kt;
namespace Memory { namespace Memory {
@@ -29,162 +32,10 @@ namespace Memory {
KernelOutStream kout; KernelOutStream kout;
KernelErrorStream kerr; KernelErrorStream kerr;
// Set the base revision to 3, this is recommended as this is the latest
// base revision described by the Limine boot protocol specification.
// See specification for further info.
namespace {
__attribute__((used, section(".limine_requests")))
volatile LIMINE_BASE_REVISION(3);
}
// The Limine requests can be placed anywhere, but it is important that
// the compiler does not optimise them away, so, usually, they should
// be made volatile or equivalent, _and_ they should be accessed at least
// once or marked as used with the "used" attribute as done here.
namespace {
__attribute__((used, section(".limine_requests")))
volatile limine_framebuffer_request framebuffer_request = {
.id = LIMINE_FRAMEBUFFER_REQUEST,
.revision = 0,
.response = nullptr
};
__attribute__((used, section(".limine_requests")))
volatile limine_efi_system_table_request system_table_request = {
.id = LIMINE_EFI_SYSTEM_TABLE_REQUEST,
.revision = 0,
.response = nullptr
};
__attribute__((used, section(".limine_requests")))
volatile limine_hhdm_request hhdm_request = {
.id = LIMINE_HHDM_REQUEST,
.revision = 0,
.response = nullptr
};
__attribute__((used, section(".limine_requests")))
volatile limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST,
.revision = 0,
.response = nullptr
};
}
// Finally, define the start and end markers for the Limine requests.
// These can also be moved anywhere, to any .cpp file, as seen fit.
namespace {
__attribute__((used, section(".limine_requests_start")))
volatile LIMINE_REQUESTS_START_MARKER;
__attribute__((used, section(".limine_requests_end")))
volatile LIMINE_REQUESTS_END_MARKER;
}
// GCC and Clang reserve the right to generate calls to the following
// 4 functions even if they are not directly called.
// Implement them as the C specification mandates.
// DO NOT remove or rename these functions, or stuff will eventually break!
// They CAN be moved to a different .cpp file.
extern "C" {
void *memcpy(void *dest, const void *src, std::size_t n) {
std::uint8_t *pdest = static_cast<std::uint8_t *>(dest);
const std::uint8_t *psrc = static_cast<const std::uint8_t *>(src);
for (std::size_t i = 0; i < n; i++) {
pdest[i] = psrc[i];
}
return dest;
}
void *memset(void *s, int c, std::size_t n) {
std::uint8_t *p = static_cast<std::uint8_t *>(s);
for (std::size_t i = 0; i < n; i++) {
p[i] = static_cast<uint8_t>(c);
}
return s;
}
void *memmove(void *dest, const void *src, std::size_t n) {
std::uint8_t *pdest = static_cast<std::uint8_t *>(dest);
const std::uint8_t *psrc = static_cast<const std::uint8_t *>(src);
if (src > dest) {
for (std::size_t i = 0; i < n; i++) {
pdest[i] = psrc[i];
}
} else if (src < dest) {
for (std::size_t i = n; i > 0; i--) {
pdest[i-1] = psrc[i-1];
}
}
return dest;
}
int memcmp(const void *s1, const void *s2, std::size_t n) {
const std::uint8_t *p1 = static_cast<const std::uint8_t *>(s1);
const std::uint8_t *p2 = static_cast<const std::uint8_t *>(s2);
for (std::size_t i = 0; i < n; i++) {
if (p1[i] != p2[i]) {
return p1[i] < p2[i] ? -1 : 1;
}
}
return 0;
}
}
// Halt and catch fire function.
namespace {
void hcf() {
for (;;) {
#if defined (__x86_64__)
asm ("hlt");
#elif defined (__aarch64__) || defined (__riscv)
asm ("wfi");
#elif defined (__loongarch64)
asm ("idle 0");
#endif
}
}
}
// The following stubs are required by the Itanium C++ ABI (the one we use,
// regardless of the "Itanium" nomenclature).
// Like the memory functions above, these stubs can be moved to a different .cpp file,
// but should not be removed, unless you know what you are doing.
extern "C" {
int __cxa_atexit(void (*)(void *), void *, void *) { return 0; }
void __cxa_pure_virtual() { hcf(); }
void *__dso_handle;
}
// Extern declarations for global constructors array. // Extern declarations for global constructors array.
extern void (*__init_array[])(); extern void (*__init_array[])();
extern void (*__init_array_end[])(); extern void (*__init_array_end[])();
// The following will be our kernel's entry point.
// If renaming kmain() to something else, make sure to change the
// linker script accordingly.
extern "C" void kmain() { extern "C" void kmain() {
// Ensure the bootloader actually understands our base revision (see spec). // Ensure the bootloader actually understands our base revision (see spec).
if (LIMINE_BASE_REVISION_SUPPORTED == false) { if (LIMINE_BASE_REVISION_SUPPORTED == false) {