summaryrefslogtreecommitdiffstats
path: root/rsapi/src
diff options
context:
space:
mode:
Diffstat (limited to 'rsapi/src')
-rw-r--r--rsapi/src/lib.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/rsapi/src/lib.rs b/rsapi/src/lib.rs
new file mode 100644
index 0000000..f71e69f
--- /dev/null
+++ b/rsapi/src/lib.rs
@@ -0,0 +1,86 @@
1//! rsapi — the kernel↔binary ABI (ADR 0006).
2//!
3//! One versioned `Exports` table is constructed per invocation and handed
4//! to the binary's entry point. The header starts with a magic and a
5//! `version: u32` so a future kernel can keep old binaries working
6//! (dispatch on the version, never on struct layout).
7//!
8//! Everything here is `no_std`-clean: plain structs and function pointers,
9//! no allocation, no rsnix dependency — binaries link only this crate.
10
11#![no_std]
12
13/// Table magic: "RSEX".
14pub const EXPORTS_MAGIC: u32 = 0x5245_5853;
15
16/// ABI revision. Bump on any signature change; the kernel refuses to run
17/// binaries whose required major exceeds its own.
18pub const ABI_VERSION: u32 = 1;
19
20/// Entry-point signature. `extern "C"` on the x86_64-unknown-uefi
21/// target is the Win64 convention: the three arguments arrive in
22/// RCX/RDX/R8 on both sides of the table.
23pub type EntryPoint = extern "C" fn(exports: &'static Exports, argc: usize, argv: *const Arg) -> i32;
24
25/// One C-style argv element: pointer + length (rs-dos strings are not
26/// NUL-terminated in memory).
27#[derive(Clone, Copy)]
28pub struct Arg {
29 pub ptr: *const u8,
30 pub len: usize,
31}
32
33/// A line of text handed across the ABI (stream I/O).
34#[derive(Clone, Copy)]
35pub struct Line {
36 pub ptr: *const u8,
37 pub len: usize,
38}
39
40impl Line {
41 /// Borrow as a &str (lossy is impossible: lines are always UTF-8).
42 pub fn as_str(&self) -> &'static str {
43 unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(self.ptr, self.len)) }
44 }
45}
46
47/// Outcome of `get_line`.
48#[derive(Clone, Copy, PartialEq, Eq)]
49pub enum StreamResult {
50 /// A line is available (see `out`).
51 Line,
52 /// Input exhausted.
53 Eof,
54 /// Aborted (^C or upstream killed); stop immediately.
55 Abort,
56}
57
58// ---------------------------------------------------------------------------
59// Exports table — v1
60// ---------------------------------------------------------------------------
61
62/// The function table a binary receives. Layout is fixed by `version`;
63/// new functions are appended, existing ones never move.
64#[repr(C)]
65pub struct Exports {
66 // ---- header ----
67 pub magic: u32,
68 pub version: u32,
69
70 // ---- console / streams (v1) ----
71 /// Print one line to the command's output stream.
72 /// Returns false when the consumer says stop (pager quit / head limit /
73 /// ^C) — the binary should wrap up promptly.
74 pub put_line: fn(line: Line) -> bool,
75 /// Read one line from the command's input stream (only meaningful for
76 /// input consumers like cat/hexdump; otherwise returns Eof).
77 /// `out` receives the line when the result is `StreamResult::Line`.
78 pub get_line: fn(out: &mut Line) -> StreamResult,
79
80 // ---- lifecycle (v1) ----
81 /// Log one line to the kernel log ring (/dev/klog).
82 pub log_line: fn(line: Line),
83 /// Exit code for the completion message to the spawner.
84 /// (Calling this is optional; returning from the entry point exits 0.)
85 pub exit: fn(code: i32) -> !,
86}