fix: Project restructuring
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user