feat: initial scalable x86_64 microkernel skeleton with Limine, Rust, C HAL, and C++20 IPC
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||
typedef __INTPTR_TYPE__ intptr_t;
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
typedef __INT8_TYPE__ int8_t;
|
||||
typedef __INT16_TYPE__ int16_t;
|
||||
typedef __INT32_TYPE__ int32_t;
|
||||
typedef __INT64_TYPE__ int64_t;
|
||||
|
||||
typedef __UINT8_TYPE__ uint8_t;
|
||||
typedef __UINT16_TYPE__ uint16_t;
|
||||
typedef __UINT32_TYPE__ uint32_t;
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
typedef __INTPTR_TYPE__ intptr_t;
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
|
||||
#define INT8_MAX 127
|
||||
#define INT16_MAX 32767
|
||||
#define INT32_MAX 2147483647
|
||||
#define INT64_MAX 9223372036854775807LL
|
||||
|
||||
#define UINT8_MAX 255
|
||||
#define UINT16_MAX 65535
|
||||
#define UINT32_MAX 4294967295U
|
||||
#define UINT64_MAX 18446744073709551615ULL
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "stddef.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int puts(const char *s);
|
||||
int putchar(int c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "stddef.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *memset(void *dest, int c, size_t n);
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
|
||||
size_t strlen(const char *s);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strncpy(char *dest, const char *src, size_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "../include/string.h"
|
||||
|
||||
void *memset(void *dest, int c, size_t n) {
|
||||
uint8_t *p = (uint8_t *)dest;
|
||||
uint8_t val = (uint8_t)c;
|
||||
while (n--) {
|
||||
*p++ = val;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n) {
|
||||
uint8_t *d = (uint8_t *)dest;
|
||||
const uint8_t *s = (const uint8_t *)src;
|
||||
while (n--) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n) {
|
||||
uint8_t *d = (uint8_t *)dest;
|
||||
const uint8_t *s = (const uint8_t *)src;
|
||||
if (d < s) {
|
||||
while (n--) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
} else {
|
||||
d += n;
|
||||
s += n;
|
||||
while (n--) {
|
||||
*--d = *--s;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
const uint8_t *p1 = (const uint8_t *)s1;
|
||||
const uint8_t *p2 = (const uint8_t *)s2;
|
||||
while (n--) {
|
||||
if (*p1 != *p2) {
|
||||
return *p1 - *p2;
|
||||
}
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s) {
|
||||
size_t len = 0;
|
||||
while (s[len]) {
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) {
|
||||
while (*s1 && (*s1 == *s2)) {
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return *(const unsigned char *)s1 - *(const unsigned char *)s2;
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||
while (n && *s1 && (*s1 == *s2)) {
|
||||
s1++;
|
||||
s2++;
|
||||
n--;
|
||||
}
|
||||
if (n == 0) return 0;
|
||||
return *(const unsigned char *)s1 - *(const unsigned char *)s2;
|
||||
}
|
||||
|
||||
char *strcpy(char *dest, const char *src) {
|
||||
char *ret = dest;
|
||||
while ((*dest++ = *src++));
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *strncpy(char *dest, const char *src, size_t n) {
|
||||
char *ret = dest;
|
||||
while (n && (*dest++ = *src++)) {
|
||||
n--;
|
||||
}
|
||||
while (n--) {
|
||||
*dest++ = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "stdio.h"
|
||||
#include "abi/syscalls.h"
|
||||
#include "abi/types.h"
|
||||
|
||||
int puts(const char *s) {
|
||||
size_t len = 0;
|
||||
while (s[len]) len++;
|
||||
sys_log_debug(s, len);
|
||||
sys_log_debug("\n", 1);
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
int putchar(int c) {
|
||||
char ch = (char)c;
|
||||
sys_log_debug(&ch, 1);
|
||||
return c;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
|
||||
#include "abi/types.h"
|
||||
#include "abi/syscalls.h"
|
||||
#include "abi/ipc.h"
|
||||
#include "stddef.h"
|
||||
#include "stdint.h"
|
||||
|
||||
namespace ipc {
|
||||
|
||||
// Strongly typed result wrapper (no exceptions)
|
||||
template <typename T>
|
||||
struct Result {
|
||||
sysret_t status;
|
||||
T value;
|
||||
|
||||
constexpr bool is_ok() const noexcept { return status == SYS_OK; }
|
||||
constexpr bool is_err() const noexcept { return status != SYS_OK; }
|
||||
constexpr sysret_t error() const noexcept { return status; }
|
||||
};
|
||||
|
||||
struct FastResponse {
|
||||
uint64_t out0;
|
||||
uint64_t out1;
|
||||
};
|
||||
|
||||
// RAII Capability Handle
|
||||
class Capability {
|
||||
private:
|
||||
cap_t handle_;
|
||||
|
||||
public:
|
||||
constexpr Capability() noexcept : handle_(CAP_NULL) {}
|
||||
constexpr explicit Capability(cap_t handle) noexcept : handle_(handle) {}
|
||||
|
||||
~Capability() {
|
||||
// Future: syscall to drop capability reference
|
||||
}
|
||||
|
||||
Capability(const Capability&) = delete;
|
||||
Capability& operator=(const Capability&) = delete;
|
||||
|
||||
constexpr Capability(Capability&& other) noexcept : handle_(other.handle_) {
|
||||
other.handle_ = CAP_NULL;
|
||||
}
|
||||
|
||||
constexpr Capability& operator=(Capability&& other) noexcept {
|
||||
if (this != &other) {
|
||||
handle_ = other.handle_;
|
||||
other.handle_ = CAP_NULL;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr cap_t get() const noexcept { return handle_; }
|
||||
[[nodiscard]] constexpr bool is_valid() const noexcept { return handle_ != CAP_NULL; }
|
||||
};
|
||||
|
||||
// RAII IPC Endpoint Wrapper
|
||||
class Endpoint {
|
||||
private:
|
||||
Capability cap_;
|
||||
|
||||
public:
|
||||
explicit Endpoint(Capability&& cap) noexcept : cap_(static_cast<Capability&&>(cap)) {}
|
||||
explicit Endpoint(cap_t cap) noexcept : cap_(cap) {}
|
||||
|
||||
// Fast-path synchronous register call (zero allocations)
|
||||
[[nodiscard]] Result<FastResponse> call(
|
||||
uint64_t opcode,
|
||||
uint64_t arg0 = 0,
|
||||
uint64_t arg1 = 0,
|
||||
uint64_t arg2 = 0,
|
||||
uint64_t arg3 = 0
|
||||
) const noexcept {
|
||||
uint64_t out0 = 0;
|
||||
uint64_t out1 = 0;
|
||||
sysret_t ret = sys_ipc_call_raw(cap_.get(), opcode, arg0, arg1, arg2, arg3, &out0, &out1);
|
||||
return Result<FastResponse>{ .status = ret, .value = { out0, out1 } };
|
||||
}
|
||||
|
||||
[[nodiscard]] cap_t raw_handle() const noexcept { return cap_.get(); }
|
||||
};
|
||||
|
||||
// RAII Shared Memory Buffer
|
||||
class SharedBuffer {
|
||||
private:
|
||||
Capability shm_cap_;
|
||||
void* base_addr_;
|
||||
size_t size_;
|
||||
|
||||
public:
|
||||
SharedBuffer(Capability&& cap, void* addr, size_t sz) noexcept
|
||||
: shm_cap_(static_cast<Capability&&>(cap)), base_addr_(addr), size_(sz) {}
|
||||
|
||||
~SharedBuffer() {
|
||||
// Future: sys_unmap(base_addr_, size_)
|
||||
}
|
||||
|
||||
SharedBuffer(const SharedBuffer&) = delete;
|
||||
SharedBuffer& operator=(const SharedBuffer&) = delete;
|
||||
|
||||
SharedBuffer(SharedBuffer&& other) noexcept
|
||||
: shm_cap_(static_cast<Capability&&>(other.shm_cap_)),
|
||||
base_addr_(other.base_addr_),
|
||||
size_(other.size_) {
|
||||
other.base_addr_ = nullptr;
|
||||
other.size_ = 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] void* data() const noexcept { return base_addr_; }
|
||||
[[nodiscard]] size_t size() const noexcept { return size_; }
|
||||
[[nodiscard]] cap_t handle() const noexcept { return shm_cap_.get(); }
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "../include/ipc.hpp"
|
||||
|
||||
namespace ipc {
|
||||
// Shared library routines if needed
|
||||
}
|
||||
Reference in New Issue
Block a user