summaryrefslogtreecommitdiffhomepage
path: root/dev/ddk
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-03-27 17:24:21 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2025-03-27 17:24:21 +0100
commitb8f7ef086d1d1b1cd686fff04d0a587f8fd39d81 (patch)
treeb6c2eb3ca2c51dc87ddd81b6170d5f63eabb9090 /dev/ddk
parenteb86df50ec5afb392998e2e171de54e1f26d8e7a (diff)
add: new driver device kit API. (DDK)
refactor: rename SCIKit -> user (then libuser.dylib) boot/modules/netboot: fixed compilation for amd64. Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/ddk')
-rw-r--r--dev/ddk/ddk.h112
-rw-r--r--dev/ddk/ddk.json23
-rw-r--r--dev/ddk/dev.h35
-rw-r--r--dev/ddk/docs/SPECIFICATION_DDK.md18
-rw-r--r--dev/ddk/io.h18
-rw-r--r--dev/ddk/src/ddk_alloc.c36
-rw-r--r--dev/ddk/src/ddk_dev.c30
-rw-r--r--dev/ddk/src/ddk_io.c37
-rw-r--r--dev/ddk/src/ddk_kernel_call.c60
-rw-r--r--dev/ddk/src/ddk_kernel_call_dispatch.S36
-rw-r--r--dev/ddk/src/ddk_rt_cxx.cc29
-rw-r--r--dev/ddk/src/ddk_str.c40
-rw-r--r--dev/ddk/src/ddk_ver.c25
-rw-r--r--dev/ddk/str.h17
14 files changed, 516 insertions, 0 deletions
diff --git a/dev/ddk/ddk.h b/dev/ddk/ddk.h
new file mode 100644
index 00000000..f6f8d48e
--- /dev/null
+++ b/dev/ddk/ddk.h
@@ -0,0 +1,112 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ FILE: ddk.h
+ PURPOSE: DDK Driver model base header.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+
+#if defined(__cplusplus)
+#define BOOL bool
+#define YES true
+#define NO false
+#define DDK_EXTERN extern "C" __declspec(dllexport)
+#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 __declspec(dllexport)
+#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" __declspec(dllimport)
+#else
+#define DDK_EXTERN __declspec(dllimport)
+#endif
+#endif
+
+#define ATTRIBUTE(X) __attribute__((X))
+
+#ifndef __NEOSKRNL__
+#error !!! Do not include header in EL0/Ring 3 mode !!!
+#endif // __MINOSKRNL__
+
+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;
+ void* s_object;
+};
+
+/// @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(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_add_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 int32_t kApiVersionHighest;
+
+/// @brief The lowest API version of the DDK.
+DDK_EXTERN int32_t kApiVersionLowest;
+
+/// @brief API version in BCD.
+DDK_EXTERN int32_t kApiVersion;
diff --git a/dev/ddk/ddk.json b/dev/ddk/ddk.json
new file mode 100644
index 00000000..ffc05f5f
--- /dev/null
+++ b/dev/ddk/ddk.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": "ddk.sys",
+ "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/dev/ddk/dev.h b/dev/ddk/dev.h
new file mode 100644
index 00000000..98979e52
--- /dev/null
+++ b/dev/ddk/dev.h
@@ -0,0 +1,35 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ File: dev.h
+ Purpose: DDK device support.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <ddk/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.
+} DDK_DEVICE, *DDK_DEVICE_PTR;
+
+/// @brief Open a new device from path.
+/// @param path the device's path.
+DDK_EXTERN DDK_DEVICE_PTR open(const char* path);
+
+/// @brief Close any device.
+/// @param device valid device.
+DDK_EXTERN BOOL close(DDK_DEVICE_PTR device);
diff --git a/dev/ddk/docs/SPECIFICATION_DDK.md b/dev/ddk/docs/SPECIFICATION_DDK.md
new file mode 100644
index 00000000..5fbff990
--- /dev/null
+++ b/dev/ddk/docs/SPECIFICATION_DDK.md
@@ -0,0 +1,18 @@
+===================================
+
+# 0: General Information
+
+===================================
+
+- Programming Language: C/C++
+- Build System: Make/BTB
+- Purpose: Driver Tool Kit, which you link against libddk.sys
+
+===================================
+
+# 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/dev/ddk/io.h b/dev/ddk/io.h
new file mode 100644
index 00000000..cfd6d2d2
--- /dev/null
+++ b/dev/ddk/io.h
@@ -0,0 +1,18 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ Purpose: DDK Text I/O.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <ddk/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/dev/ddk/src/ddk_alloc.c b/dev/ddk/src/ddk_alloc.c
new file mode 100644
index 00000000..9d0ac0db
--- /dev/null
+++ b/dev/ddk/src/ddk_alloc.c
@@ -0,0 +1,36 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ Purpose: DDK allocator.
+
+------------------------------------------- */
+
+#include <ddk/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("mm_new_heap", 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("mm_delete_heap", 1, ptr, 0);
+}
diff --git a/dev/ddk/src/ddk_dev.c b/dev/ddk/src/ddk_dev.c
new file mode 100644
index 00000000..7514bf84
--- /dev/null
+++ b/dev/ddk/src/ddk_dev.c
@@ -0,0 +1,30 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ Purpose: DDK Text I/O.
+
+------------------------------------------- */
+
+#include <ddk/dev.h>
+#include <ddk/str.h>
+
+/// @brief Open a new binary device from path.
+DDK_EXTERN DDK_DEVICE_PTR open(const char* devicePath)
+{
+ if (!devicePath)
+ return nil;
+
+ return ke_call("sk_open_dev", 1, (void*)devicePath, kstrlen(devicePath));
+}
+
+/// @brief Close any device.
+/// @param device valid device.
+DDK_EXTERN BOOL close(DDK_DEVICE_PTR device)
+{
+ if (!device)
+ return NO;
+
+ ke_call("sk_close_dev", 1, device, sizeof(DDK_DEVICE));
+ return YES;
+}
diff --git a/dev/ddk/src/ddk_io.c b/dev/ddk/src/ddk_io.c
new file mode 100644
index 00000000..0e10a0ad
--- /dev/null
+++ b/dev/ddk/src/ddk_io.c
@@ -0,0 +1,37 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ Purpose: DDK Text I/O.
+
+------------------------------------------- */
+
+#include <ddk/io.h>
+
+DDK_EXTERN void kputc(const char ch)
+{
+ char assembled[2] = {0};
+ assembled[0] = ch;
+ assembled[1] = 0;
+
+ ke_call("ke_put_string", 1, assembled, 1);
+}
+
+/// @brief print string to UART.
+/// @param message UART to transmit.
+DDK_EXTERN void kprint(const char* message)
+{
+ if (!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/dev/ddk/src/ddk_kernel_call.c b/dev/ddk/src/ddk_kernel_call.c
new file mode 100644
index 00000000..71dbebeb
--- /dev/null
+++ b/dev/ddk/src/ddk_kernel_call.c
@@ -0,0 +1,60 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ Purpose: DDK Kernel call.
+
+------------------------------------------- */
+
+#include <ddk/ddk.h>
+#include <stdarg.h>
+
+/// @brief this is an internal call, do not use it.
+DDK_EXTERN ATTRIBUTE(naked) void* ke_call_dispatch(const char* name, int32_t cnt, void* data, size_t sz);
+
+/// @brief Interupt Kernel and call it's RPC.
+/// @param KernelRpcName 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(const char* name, int32_t cnt, void* data, size_t sz)
+{
+ if (!name || *name == 0 || cnt == 0)
+ return nil;
+
+ return ke_call_dispatch(name, cnt, data, sz);
+}
+
+/// @brief Add system call.
+/// @param slot system call slot
+/// @param slotFn, syscall slot.
+DDK_EXTERN void ke_add_syscall(const int slot, void (*slotFn)(void* a0))
+{
+ ke_call("ke_add_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("cf_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("cf_set_kobj", slot, (void*)ddk_pr, 1);
+}
diff --git a/dev/ddk/src/ddk_kernel_call_dispatch.S b/dev/ddk/src/ddk_kernel_call_dispatch.S
new file mode 100644
index 00000000..9b32d0c2
--- /dev/null
+++ b/dev/ddk/src/ddk_kernel_call_dispatch.S
@@ -0,0 +1,36 @@
+/**
+ lang: asm
+ compiler: gnu
+ */
+
+.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__)
+
+/* args rcx, rdx, r8, r9 */
+ke_call_dispatch:
+ int $0x33
+ 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, #0x33
+ svc #0
+
+#endif
diff --git a/dev/ddk/src/ddk_rt_cxx.cc b/dev/ddk/src/ddk_rt_cxx.cc
new file mode 100644
index 00000000..1ac66457
--- /dev/null
+++ b/dev/ddk/src/ddk_rt_cxx.cc
@@ -0,0 +1,29 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ Purpose: DDK C++ runtime.
+
+------------------------------------------- */
+
+#include <ddk/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/dev/ddk/src/ddk_str.c b/dev/ddk/src/ddk_str.c
new file mode 100644
index 00000000..1558e636
--- /dev/null
+++ b/dev/ddk/src/ddk_str.c
@@ -0,0 +1,40 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ Purpose: DDK Strings.
+
+------------------------------------------- */
+
+#include <ddk/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)
+{
+ size_t index = 0;
+
+ while (index != len)
+ {
+ dst[index] = src[index];
+ ++index;
+ }
+
+ return index;
+}
diff --git a/dev/ddk/src/ddk_ver.c b/dev/ddk/src/ddk_ver.c
new file mode 100644
index 00000000..9641fb34
--- /dev/null
+++ b/dev/ddk/src/ddk_ver.c
@@ -0,0 +1,25 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ Purpose: DDK version symbols.
+
+------------------------------------------- */
+
+#include <ddk/ddk.h>
+
+#ifndef kDDKVersionHighest
+#define kDDKVersionHighest 1
+#endif // !kDDKVersionHighest
+
+#ifndef kDDKVersionLowest
+#define kDDKVersionLowest 1
+#endif // !kDDKVersionLowest
+
+#ifndef kDDKVersion
+#define kDDKVersion 1
+#endif // !kDDKVersion
+
+int32_t kApiVersionHighest = kDDKVersionHighest;
+int32_t kApiVersionLowest = kDDKVersionLowest;
+int32_t kApiVersion = kDDKVersion;
diff --git a/dev/ddk/str.h b/dev/ddk/str.h
new file mode 100644
index 00000000..e1e206a8
--- /dev/null
+++ b/dev/ddk/str.h
@@ -0,0 +1,17 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss.
+
+ Purpose: DDK Strings.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <ddk/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);