summaryrefslogtreecommitdiffhomepage
path: root/src/libDDK
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-11-23 21:06:27 -0500
committerGitHub <noreply@github.com>2025-11-23 21:06:27 -0500
commit23040fad647634c08697451fc22ee2ca999629c8 (patch)
tree72888f88c7728c82f3f6df1f4f70591de15eab36 /src/libDDK
parente5cc7351f0577b54c528fb827a7c7e6306c3e843 (diff)
parent83d870e58457a1d335a1d9b9966a6a1887cc297b (diff)
Merge pull request #81 from nekernel-org/dev
feat! breaking changes on kernel sources.
Diffstat (limited to 'src/libDDK')
-rw-r--r--src/libDDK/DriverKit/ddk.h76
-rw-r--r--src/libDDK/DriverKit/dev.h36
-rw-r--r--src/libDDK/DriverKit/dki/contract.h34
-rw-r--r--src/libDDK/DriverKit/io.h18
-rw-r--r--src/libDDK/DriverKit/macros.h48
-rw-r--r--src/libDDK/DriverKit/net.h16
-rw-r--r--src/libDDK/DriverKit/str.h17
-rw-r--r--src/libDDK/docs/SPECIFICATION_DDK.md18
-rw-r--r--src/libDDK/libDDK.json23
-rw-r--r--src/libDDK/obj/.gitkeep0
-rw-r--r--src/libDDK/src/ddk_abi_cxx.cc27
-rw-r--r--src/libDDK/src/ddk_alloc.c32
-rw-r--r--src/libDDK/src/ddk_dev.c27
-rw-r--r--src/libDDK/src/ddk_io.c36
-rw-r--r--src/libDDK/src/ddk_kernel_call.c77
-rw-r--r--src/libDDK/src/ddk_kernel_call_dispatch.S47
-rw-r--r--src/libDDK/src/ddk_str.c36
-rw-r--r--src/libDDK/src/ddk_ver.c25
18 files changed, 593 insertions, 0 deletions
diff --git a/src/libDDK/DriverKit/ddk.h b/src/libDDK/DriverKit/ddk.h
new file mode 100644
index 00000000..45f7d356
--- /dev/null
+++ b/src/libDDK/DriverKit/ddk.h
@@ -0,0 +1,76 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss 2025, licensed under the Apache 2.0 license.
+
+ FILE: ddk.h
+ PURPOSE: DDK Driver model base header.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/macros.h>
+
+struct DDK_STATUS_STRUCT;
+struct DDK_OBJECT_MANIFEST;
+
+/// \brief Object handle manifest.
+struct DDK_OBJECT_MANIFEST DDK_FINAL {
+ char* p_name;
+ int32_t p_kind;
+ void* p_object;
+};
+
+/// \brief DDK status ping structure.
+struct DDK_STATUS_STRUCT DDK_FINAL {
+ int32_t s_action_id;
+ int32_t s_issuer_id;
+ int32_t s_group_id;
+ struct DDK_OBJECT_MANIFEST* s_object;
+};
+
+typedef void* ptr_t;
+
+/// @brief Call Kernel procedure.
+/// @param name the procedure name.
+/// @param cnt number of elements in **dat**
+/// @param dat data argument pointer.
+/// @param sz sz of whole data argument pointer.
+/// @return result of call
+DDK_EXTERN void* ke_call_dispatch(const char* name, int32_t cnt, void* dat, size_t sz);
+
+/// @brief add a system call.
+/// @param slot system call slot id.
+/// @param slotFn, syscall slot.
+DDK_EXTERN void ke_set_syscall(const int32_t slot, void (*slotFn)(void* a0));
+
+/// @brief Allocates an heap ptr.
+/// @param sz size of the allocated struct/type.
+/// @return the pointer allocated or **nil**.
+DDK_EXTERN void* kalloc(size_t sz);
+
+/// @brief Frees an heap ptr.
+/// @param pointer kernel pointer to free.
+DDK_EXTERN void kfree(void* the_ptr);
+
+/// @brief Gets a Kernel object.
+/// @param slot object id (can be 0)
+/// @param name the property's name.
+/// @return DDK_OBJECT_MANIFEST.
+DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* name);
+
+/// @brief Set a Kernel object.
+/// @param slot object id (can be 0)
+/// @param name the property's name.
+/// @param ddk_pr pointer to a object's DDK_OBJECT_MANIFEST.
+/// @return returned object.
+DDK_EXTERN void* ke_set_obj(const int32_t slot, const struct DDK_OBJECT_MANIFEST* ddk_pr);
+
+/// @brief The highest API version of the DDK.
+DDK_EXTERN uint32_t kApiVersionHighest;
+
+/// @brief The lowest API version of the DDK.
+DDK_EXTERN uint32_t kApiVersionLowest;
+
+/// @brief API version in BCD.
+DDK_EXTERN uint32_t kApiVersion;
diff --git a/src/libDDK/DriverKit/dev.h b/src/libDDK/DriverKit/dev.h
new file mode 100644
index 00000000..a88a00dd
--- /dev/null
+++ b/src/libDDK/DriverKit/dev.h
@@ -0,0 +1,36 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ File: dev.h
+ Purpose: DDK device support.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/ddk.h>
+
+struct _DDK_DEVICE;
+
+#define DDK_DEVICE_NAME_LEN (255)
+
+/// @brief Kernel Device driver.
+typedef struct _DDK_DEVICE DDK_FINAL {
+ char d_name[DDK_DEVICE_NAME_LEN]; // the device name. Could be /./DEVICE_NAME/
+ void* (*d_read)(void* arg, int len); // read from device.
+ void (*d_write)(void* arg, int len);
+ void (*d_wait)(void); // write to device.
+ struct _DDK_DEVICE* (*d_open)(const char* path); // open device.
+ void (*d_close)(struct _DDK_DEVICE* dev); // close device.
+ void (*d_seek)(struct _DDK_DEVICE* dev, size_t off);
+ size_t (*d_tell)(struct _DDK_DEVICE* dev);
+} DDK_DEVICE, *DDK_DEVICE_PTR;
+
+/// @brief Open a new device from path.
+/// @param path the device's path.
+DDK_EXTERN DDK_DEVICE_PTR kopen_dev(const char* path);
+
+/// @brief Close any device.
+/// @param device valid device.
+DDK_EXTERN BOOL kclose_dev(DDK_DEVICE_PTR device);
diff --git a/src/libDDK/DriverKit/dki/contract.h b/src/libDDK/DriverKit/dki/contract.h
new file mode 100644
index 00000000..7361d792
--- /dev/null
+++ b/src/libDDK/DriverKit/dki/contract.h
@@ -0,0 +1,34 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss 2025, licensed under the Apache 2.0 license.
+
+ FILE: ddk.h
+ PURPOSE: Driver Kernel Interface Model base header.
+
+ ======================================== */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <libDDK/DriverKit/macros.h>
+
+#define DKI_CONTRACT_IMPL final : public ::Kernel::DKI::DKIContract
+
+/// @author Amlal El Mahrouss
+
+namespace Kernel::DKI {
+class DKIContract {
+ public:
+ explicit DKIContract() = default;
+ virtual ~DKIContract() = default;
+
+ NE_COPY_DEFAULT(DKIContract);
+
+ using PtrType = VoidPtr;
+
+ virtual BOOL IsCastable() { return NO; }
+ virtual BOOL IsActive() { return NO; }
+ virtual VoidPtr Leak() { return nullptr; }
+ virtual Int32 Type() { return 0; }
+};
+} // namespace Kernel::DKI
diff --git a/src/libDDK/DriverKit/io.h b/src/libDDK/DriverKit/io.h
new file mode 100644
index 00000000..58b625ac
--- /dev/null
+++ b/src/libDDK/DriverKit/io.h
@@ -0,0 +1,18 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK Text I/O.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/str.h>
+
+/// @brief print character into UART.
+DDK_EXTERN void kputc(const char ch);
+
+/// @brief print string to UART.
+/// @param message string to transmit to UART.
+DDK_EXTERN void kprint(const char* message);
diff --git a/src/libDDK/DriverKit/macros.h b/src/libDDK/DriverKit/macros.h
new file mode 100644
index 00000000..7fd1403b
--- /dev/null
+++ b/src/libDDK/DriverKit/macros.h
@@ -0,0 +1,48 @@
+/* ========================================
+
+ Copyright 2025 Amlal El Mahrouss.
+
+ FILE: ddk.h
+ PURPOSE: DDK Driver model base header.
+
+======================================== */
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(__cplusplus)
+#define BOOL bool
+#define YES true
+#define NO false
+#define DDK_EXTERN extern "C"
+#define nil nullptr
+#undef NULL
+#define NULL 0
+#define DDK_FINAL final
+#else
+#define BOOL char
+#define YES 1
+#define NO 0
+#define DDK_EXTERN extern
+#define nil ((void*) 0)
+#undef NULL
+#define NULL ((void*) 0)
+#define DDK_FINAL
+#endif // defined(__cplusplus)
+
+#ifndef __DDK__
+#undef DDK_EXTERN
+#if defined(__cplusplus)
+#define DDK_EXTERN extern "C"
+#else
+#define DDK_EXTERN
+#endif
+#endif
+
+#define ATTRIBUTE(X) __attribute__((X))
+
+#ifndef __NEOSKRNL__
+#error !!! Do not include header in EL0/Ring 3 mode !!!
+#endif // __NEOSKRNL__ \ No newline at end of file
diff --git a/src/libDDK/DriverKit/net.h b/src/libDDK/DriverKit/net.h
new file mode 100644
index 00000000..5dfe6374
--- /dev/null
+++ b/src/libDDK/DriverKit/net.h
@@ -0,0 +1,16 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ FILE: net.h
+ PURPOSE: Network model base header.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/macros.h>
+
+struct DDK_NET_MANIFEST;
+
+/// @brief IFS hooks to plug into the FileMgr.
diff --git a/src/libDDK/DriverKit/str.h b/src/libDDK/DriverKit/str.h
new file mode 100644
index 00000000..6409b1a7
--- /dev/null
+++ b/src/libDDK/DriverKit/str.h
@@ -0,0 +1,17 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK Strings.
+
+======================================== */
+
+#pragma once
+
+#include <DriverKit/ddk.h>
+
+/// @brief DDK equivalent of POSIX's string.h
+/// @file str.h
+
+DDK_EXTERN size_t kstrlen(const char* in);
+DDK_EXTERN int kstrncpy(char* dst, const char* src, size_t len);
diff --git a/src/libDDK/docs/SPECIFICATION_DDK.md b/src/libDDK/docs/SPECIFICATION_DDK.md
new file mode 100644
index 00000000..d59b6e77
--- /dev/null
+++ b/src/libDDK/docs/SPECIFICATION_DDK.md
@@ -0,0 +1,18 @@
+===================================
+
+# 0: General Information
+
+===================================
+
+- Programming Language: C/C++
+- Build System: Make/NeBuild
+- Purpose: Driver Tool Kit, which you link against libDDK.dll
+
+===================================
+
+# 1: How It works
+
+===================================
+
+- Driver shall directly call the kernel at specific ports. (Or a kernel call)
+- Kernel must respond according to kernel call, otherwise a panic will occur. \ No newline at end of file
diff --git a/src/libDDK/libDDK.json b/src/libDDK/libDDK.json
new file mode 100644
index 00000000..113dd585
--- /dev/null
+++ b/src/libDDK/libDDK.json
@@ -0,0 +1,23 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-gcc",
+ "compiler_std": "c++20",
+ "headers_path": ["../", "./"],
+ "sources_path": ["src/*.c", "src/*.cc", "src/*.S"],
+ "output_name": "libDDK.dll",
+ "compiler_flags": [
+ "-ffreestanding",
+ "-shared",
+ "-std=c17",
+ "-fno-rtti",
+ "-fno-exceptions",
+ "-Wl,--subsystem=17"
+ ],
+ "cpp_macros": [
+ "__NEOSKRNL__",
+ "__DDK_AMD64__",
+ "__DDK__",
+ "kDDKVersionHighest=0x0100",
+ "kDDKVersionLowest=0x0100",
+ "kDDKVersion=0x0100"
+ ]
+}
diff --git a/src/libDDK/obj/.gitkeep b/src/libDDK/obj/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/libDDK/obj/.gitkeep
diff --git a/src/libDDK/src/ddk_abi_cxx.cc b/src/libDDK/src/ddk_abi_cxx.cc
new file mode 100644
index 00000000..196f7f6a
--- /dev/null
+++ b/src/libDDK/src/ddk_abi_cxx.cc
@@ -0,0 +1,27 @@
+/* ========================================
+
+ DDK
+ Copyright Amlal El Mahrouss.
+
+ Author: Amlal El Mahrouss
+ Purpose: DDK C++ ABI.
+
+======================================== */
+
+#include <DriverKit/ddk.h>
+
+void* operator new(size_t sz) {
+ return ::kalloc(sz);
+}
+
+void operator delete(void* ptr) {
+ ::kfree(ptr);
+}
+
+void* operator new[](size_t sz) {
+ return ::kalloc(sz);
+}
+
+void operator delete[](void* ptr) {
+ ::kfree(ptr);
+}
diff --git a/src/libDDK/src/ddk_alloc.c b/src/libDDK/src/ddk_alloc.c
new file mode 100644
index 00000000..09f3034f
--- /dev/null
+++ b/src/libDDK/src/ddk_alloc.c
@@ -0,0 +1,32 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK allocator.
+
+======================================== */
+
+#include <DriverKit/ddk.h>
+
+/**
+ \brief Allocates a new heap on the Kernel's side.
+ \param sz the size of the heap block.
+ \return the newly allocated pointer.
+*/
+DDK_EXTERN void* kalloc(size_t sz) {
+ if (!sz) ++sz;
+
+ void* ptr = ke_call_dispatch("mm_alloc_ptr", 1, &sz, sizeof(size_t));
+
+ return ptr;
+}
+
+/**
+ \brief Frees a pointer from the heap.
+ \param ptr the pointer to free.
+*/
+DDK_EXTERN void kfree(void* ptr) {
+ if (!ptr) return;
+
+ ke_call_dispatch("mm_free_ptr", 1, ptr, 0);
+}
diff --git a/src/libDDK/src/ddk_dev.c b/src/libDDK/src/ddk_dev.c
new file mode 100644
index 00000000..64ecefb6
--- /dev/null
+++ b/src/libDDK/src/ddk_dev.c
@@ -0,0 +1,27 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK Text I/O.
+
+======================================== */
+
+#include <DriverKit/dev.h>
+#include <DriverKit/str.h>
+
+/// @brief Open a new binary device from path.
+DDK_EXTERN DDK_DEVICE_PTR kopen_dev(const char* devicePath) {
+ if (nil == devicePath) return nil;
+
+ return (DDK_DEVICE_PTR) ke_call_dispatch("dk_open_dev", 1, (void*) devicePath,
+ kstrlen(devicePath));
+}
+
+/// @brief Close any device.
+/// @param device valid device.
+DDK_EXTERN BOOL kclose_dev(DDK_DEVICE_PTR device) {
+ if (nil == device) return NO;
+
+ ke_call_dispatch("dk_close_dev", 1, device, sizeof(DDK_DEVICE));
+ return YES;
+}
diff --git a/src/libDDK/src/ddk_io.c b/src/libDDK/src/ddk_io.c
new file mode 100644
index 00000000..07287b91
--- /dev/null
+++ b/src/libDDK/src/ddk_io.c
@@ -0,0 +1,36 @@
+/* ========================================
+
+ libDDK - Device Driver Kit
+ Copyright 2025 - Amlal El Mahrouss and NeKernel contributors.
+
+ File: ddk_io.c
+ Purpose: DDK Text I/O.
+
+======================================== */
+
+#include <DriverKit/io.h>
+
+DDK_EXTERN void kputc(const char ch) {
+ if (!ch) return;
+
+ char assembled[2] = {0};
+ assembled[0] = ch;
+ assembled[1] = 0;
+
+ ke_call_dispatch("ke_put_string", 1, assembled, 1);
+}
+
+/// @brief print string to UART.
+/// @param message UART to transmit.
+DDK_EXTERN void kprint(const char* message) {
+ if (nil == message) return;
+ if (*message == '\0') return;
+
+ size_t index = 0;
+ size_t len = kstrlen(message);
+
+ while (index < len) {
+ kputc(message[index]);
+ ++index;
+ }
+}
diff --git a/src/libDDK/src/ddk_kernel_call.c b/src/libDDK/src/ddk_kernel_call.c
new file mode 100644
index 00000000..92652969
--- /dev/null
+++ b/src/libDDK/src/ddk_kernel_call.c
@@ -0,0 +1,77 @@
+/* ========================================
+
+ DDK
+ Copyright Amlal El Mahrouss.
+
+ Author: Amlal El Mahrouss
+ Purpose: DDK kernel dispatch system.
+
+======================================== */
+
+#include <DriverKit/ddk.h>
+#include <stdarg.h>
+
+/// @brief this is an internal call, do not use it.
+DDK_EXTERN ATTRIBUTE(naked) ptr_t
+ __ke_call_dispatch(const int32_t name, int32_t cnt, void* data, size_t sz);
+
+/// @brief This function hashes the path into a FNV symbol.
+/// @param path the path to hash.
+/// @retval 0 symbol wasn't hashed.
+/// @retval > 0 hashed symbol.
+static uint64_t ddk_fnv_64(const char* path) {
+ if (path == nil || *path == 0) return 0;
+
+ const uint64_t kFnvOffsetBase = 0xcbf29ce484222325ULL;
+ const uint64_t kFnvPrime64 = 0x100000001b3ULL;
+
+ uint64_t hash = kFnvOffsetBase;
+
+ while (*path) {
+ hash ^= (char) (*path++);
+ hash *= kFnvPrime64;
+ }
+
+ return hash;
+}
+
+/// @brief Interrupt Kernel and call it's RPC.
+/// @param name RPC name
+/// @param cnt number of elements in **data** pointer.
+/// @param data data pointer.
+/// @param sz The size of the whole data pointer.
+/// @retval void* Kernel call was successful.
+/// @retval nil Kernel call failed, call KernelLastError(void)
+DDK_EXTERN void* ke_call_dispatch(const char* name, int32_t cnt, void* data, size_t sz) {
+ if (name == nil || *name == 0 || data == nil || cnt == 0) return nil;
+ return __ke_call_dispatch(ddk_fnv_64(name), cnt, data, sz);
+}
+
+/// @brief Add system call.
+/// @param slot system call slot
+/// @param slotFn, syscall slot.
+DDK_EXTERN void ke_set_syscall(const int slot, void (*slotFn)(void* a0)) {
+ ke_call_dispatch("ke_set_syscall", slot, slotFn, 1);
+}
+
+/// @brief Get a Kernel object.
+/// @param slot property id (always 0)
+/// @param name the object's name.
+/// @return Object manifest.
+DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* name) {
+ struct DDK_OBJECT_MANIFEST* manifest =
+ (struct DDK_OBJECT_MANIFEST*) ke_call_dispatch("cfkit_get_kobj", slot, (void*) name, 1);
+
+ if (!manifest) return nil;
+
+ return manifest;
+}
+
+/// @brief Set a Kernel object.
+/// @param slot property id (always 0)
+/// @param name the object's name.
+/// @param ddk_pr pointer to a object's DDK_OBJECT_MANIFEST.
+/// @return property's object.
+DDK_EXTERN void* ke_set_obj(const int slot, const struct DDK_OBJECT_MANIFEST* ddk_pr) {
+ return ke_call_dispatch("cfkit_set_kobj", slot, (void*) ddk_pr, 1);
+}
diff --git a/src/libDDK/src/ddk_kernel_call_dispatch.S b/src/libDDK/src/ddk_kernel_call_dispatch.S
new file mode 100644
index 00000000..a607fe40
--- /dev/null
+++ b/src/libDDK/src/ddk_kernel_call_dispatch.S
@@ -0,0 +1,47 @@
+/**
+ lang: asm
+ compiler: gnu
+ */
+
+#define kKernelCallTrapId 51
+
+.globl __ke_call_dispatch
+
+.text
+
+/* Really simple function, takes our va-list,
+ and brings it to the trap handler in the Kernel. */
+
+#if defined(__DDK_AMD64__)
+
+ .intel_syntax noprefix
+
+/* args rcx, rdx, r8, r9 */
+__ke_call_dispatch:
+ push rbp
+ mov rbp, rsp
+
+ /* registers have already been pushed. */
+
+ int kKernelCallTrapId
+
+ pop rbp
+ ret
+
+#elif defined(__DDK_POWER64__)
+
+/* args r8, r9, r10, r11 */
+__ke_call_dispatch:
+ /* There is no specific interrupt request id for a system call in POWER. */
+ sc
+ blr
+
+#elif defined(__DDK_ARM64__)
+
+/* args x0, x8, x9, x10, x11 is kept to tell that this is a Kernel call */
+__ke_call_dispatch:
+ /* There is no specific interrupt request id for a system call in ARM64 as well. */
+ mov x9, #kKernelCallTrapId
+ svc #0
+
+#endif
diff --git a/src/libDDK/src/ddk_str.c b/src/libDDK/src/ddk_str.c
new file mode 100644
index 00000000..3021f84a
--- /dev/null
+++ b/src/libDDK/src/ddk_str.c
@@ -0,0 +1,36 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK String API.
+
+======================================== */
+
+#include <DriverKit/str.h>
+
+DDK_EXTERN size_t kstrlen(const char* in) {
+ if (in == nil) return 0;
+
+ if (*in == 0) return 0;
+
+ size_t index = 0;
+
+ while (in[index] != 0) {
+ ++index;
+ }
+
+ return index;
+}
+
+DDK_EXTERN int kstrncpy(char* dst, const char* src, size_t len) {
+ if (nil == dst || nil == src) return 0;
+
+ size_t index = 0;
+
+ while (index != len) {
+ dst[index] = src[index];
+ ++index;
+ }
+
+ return index;
+}
diff --git a/src/libDDK/src/ddk_ver.c b/src/libDDK/src/ddk_ver.c
new file mode 100644
index 00000000..3679bdef
--- /dev/null
+++ b/src/libDDK/src/ddk_ver.c
@@ -0,0 +1,25 @@
+/* ========================================
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK version system.
+
+======================================== */
+
+#include <DriverKit/ddk.h>
+
+#ifndef kDDKVersionHighest
+#define kDDKVersionHighest 1
+#endif // !kDDKVersionHighest
+
+#ifndef kDDKVersionLowest
+#define kDDKVersionLowest 1
+#endif // !kDDKVersionLowest
+
+#ifndef kDDKVersion
+#define kDDKVersion 1
+#endif // !kDDKVersion
+
+uint32_t kApiVersionHighest = kDDKVersionHighest;
+uint32_t kApiVersionLowest = kDDKVersionLowest;
+uint32_t kApiVersion = kDDKVersion;