summaryrefslogtreecommitdiffstats
path: root/rsapi/src/lib.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-27 17:16:04 +0200
committersalmonik <salmonik@tuta.io>2026-08-27 17:16:04 +0200
commit8767dbecb45bbe5f748952fb9171b1a96c173f67 (patch)
treec10a66c91a53522feb980d8b59aa8c87293537f8 /rsapi/src/lib.rs
parentstreams: per-invocation channel, pumping mode, filter pipeline wiring (diff)
downloadrs-dos-8767dbecb45bbe5f748952fb9171b1a96c173f67.tar.gz
rs-dos-8767dbecb45bbe5f748952fb9171b1a96c173f67.zip
tool migration: v2 exports + 10 external CLI binaries
rsapi v2: 14 new ABI function pointers appended after v1 — fs_resolve, fs_dir_next (iterator), fs_create, fs_remove, fs_read, fs_write, fs_size, fs_close, rtc_now, mem_stats, pci_probe, pci_device, klog_dump, kernel_version. New C-repr structs: DirEntry, RtcTime, MemStats, PciDevice, KernelVersion. ABI_VERSION bumped to 2. Shell-side: build_exports() constructs the full table at runtime per invocation (replaces static const). 14 kernel-side wrapper functions bridge rsapi types to rsnix kernel APIs; fs_dir_next maintains a per-handle cache of children() results for iteration. Tool binaries (10 crates, all linked against rsapi only): - date: rtc_now → formatted YYYY-MM-DD HH:MM:SS - mem: heap/pages free/total via mem_stats - pci: pci_probe + pci_device enumerate all devices - cat: fs_read paths or get_line stdin; put_line output - ls: fs_resolve + fs_dir_next iteration; trailing / for dirs - mkdir: fs_create(path, true) - touch: fs_create(path, false) - rm: fs_remove(path) - klog: klog_dump 2048 bytes → put_line - info: rtc_now + kernel_version (minimal; mem/pci deferred) Gate verified: date prints RTC; pci lists all 4 QEMU devices (8086:29c0, 1234:1111, 8086:10d3, 8086:2918); hello/boom/count still work; test-disk PASS; poweroff clean.
Diffstat (limited to 'rsapi/src/lib.rs')
-rw-r--r--rsapi/src/lib.rs117
1 files changed, 100 insertions, 17 deletions
diff --git a/rsapi/src/lib.rs b/rsapi/src/lib.rs
index d7b69a2..dfe75d6 100644
--- a/rsapi/src/lib.rs
+++ b/rsapi/src/lib.rs
@@ -15,13 +15,12 @@ pub const EXPORTS_MAGIC: u32 = 0x5245_5853;
15 15
16/// ABI revision. Bump on any signature change; the kernel refuses to run 16/// ABI revision. Bump on any signature change; the kernel refuses to run
17/// binaries whose required major exceeds its own. 17/// binaries whose required major exceeds its own.
18pub const ABI_VERSION: u32 = 1; 18pub const ABI_VERSION: u32 = 2;
19 19
20/// Entry-point signature. `extern "C"` on the x86_64-unknown-uefi 20/// Entry-point signature. `extern "C"` on the x86_64-unknown-uefi
21/// target is the Win64 convention: the three arguments arrive in 21/// target is the Win64 convention: the three arguments arrive in
22/// RCX/RDX/R8 on both sides of the table. 22/// RCX/RDX/R8 on both sides of the table.
23pub type EntryPoint = 23pub type EntryPoint = extern "C" fn(exports: &'static Exports, argc: usize, argv: *const Arg) -> i32;
24 extern "C" fn(exports: &'static Exports, argc: usize, argv: *const Arg) -> i32;
25 24
26/// One C-style argv element: pointer + length (rs-dos strings are not 25/// One C-style argv element: pointer + length (rs-dos strings are not
27/// NUL-terminated in memory). 26/// NUL-terminated in memory).
@@ -39,7 +38,7 @@ pub struct Line {
39} 38}
40 39
41impl Line { 40impl Line {
42 /// Borrow as a &str (lossy is impossible: lines are always UTF-8). 41 /// Borrow as a &str.
43 pub fn as_str(&self) -> &'static str { 42 pub fn as_str(&self) -> &'static str {
44 unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(self.ptr, self.len)) } 43 unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(self.ptr, self.len)) }
45 } 44 }
@@ -48,16 +47,75 @@ impl Line {
48/// Outcome of `get_line`. 47/// Outcome of `get_line`.
49#[derive(Clone, Copy, PartialEq, Eq)] 48#[derive(Clone, Copy, PartialEq, Eq)]
50pub enum StreamResult { 49pub enum StreamResult {
51 /// A line is available (see `out`).
52 Line, 50 Line,
53 /// Input exhausted.
54 Eof, 51 Eof,
55 /// Aborted (^C or upstream killed); stop immediately.
56 Abort, 52 Abort,
57} 53}
58 54
59// --------------------------------------------------------------------------- 55// ---------------------------------------------------------------------------
60// Exports table — v1 56// v2 types
57// ---------------------------------------------------------------------------
58
59/// Opaque file/directory handle returned by `fs_resolve` / `fs_create`.
60pub type FsHandle = i32;
61
62/// One directory entry returned by `fs_dir_next`.
63#[repr(C)]
64#[derive(Clone, Copy)]
65pub struct DirEntry {
66 pub name: Line,
67 pub is_dir: bool,
68 pub _pad: u8,
69 pub size: u64,
70}
71
72/// Real-time clock snapshot.
73#[repr(C)]
74#[derive(Clone, Copy)]
75pub struct RtcTime {
76 pub year: u16,
77 pub month: u8,
78 pub day: u8,
79 pub hour: u8,
80 pub minute: u8,
81 pub second: u8,
82 pub _pad: u8,
83}
84
85/// Memory statistics (heap + page allocator).
86#[repr(C)]
87#[derive(Clone, Copy)]
88pub struct MemStats {
89 pub heap_total: u64,
90 pub heap_free: u64,
91 pub pages_total: u64,
92 pub pages_free: u64,
93}
94
95/// One PCI device discovered at probe time.
96#[repr(C)]
97#[derive(Clone, Copy)]
98pub struct PciDevice {
99 pub bus: u8,
100 pub device: u8,
101 pub function: u8,
102 pub class: u8,
103 pub subclass: u8,
104 pub vendor: u16,
105 pub device_id: u16,
106}
107
108/// Kernel version information.
109#[derive(Clone, Copy)]
110pub struct KernelVersion {
111 pub name: Line,
112 pub major: u16,
113 pub minor: u16,
114 pub patch: u16,
115}
116
117// ---------------------------------------------------------------------------
118// Exports table — v2
61// --------------------------------------------------------------------------- 119// ---------------------------------------------------------------------------
62 120
63/// The function table a binary receives. Layout is fixed by `version`; 121/// The function table a binary receives. Layout is fixed by `version`;
@@ -69,19 +127,44 @@ pub struct Exports {
69 pub version: u32, 127 pub version: u32,
70 128
71 // ---- console / streams (v1) ---- 129 // ---- console / streams (v1) ----
72 /// Print one line to the command's output stream.
73 /// Returns false when the consumer says stop (pager quit / head limit /
74 /// ^C) — the binary should wrap up promptly.
75 pub put_line: fn(line: Line) -> bool, 130 pub put_line: fn(line: Line) -> bool,
76 /// Read one line from the command's input stream (only meaningful for
77 /// input consumers like cat/hexdump; otherwise returns Eof).
78 /// `out` receives the line when the result is `StreamResult::Line`.
79 pub get_line: fn(out: &mut Line) -> StreamResult, 131 pub get_line: fn(out: &mut Line) -> StreamResult,
80 132
81 // ---- lifecycle (v1) ---- 133 // ---- lifecycle (v1) ----
82 /// Log one line to the kernel log ring (/dev/klog).
83 pub log_line: fn(line: Line), 134 pub log_line: fn(line: Line),
84 /// Exit code for the completion message to the spawner.
85 /// (Calling this is optional; returning from the entry point exits 0.)
86 pub exit: fn(code: i32) -> !, 135 pub exit: fn(code: i32) -> !,
136
137 // ---- filesystem queries (v2) ----
138 /// Resolve a path to a handle; returns -1 on error.
139 pub fs_resolve: fn(path: Line) -> FsHandle,
140 /// Iterate directory entries: returns true and fills `out` while
141 /// entries remain; returns false when exhausted. Resets position.
142 pub fs_dir_next: fn(handle: FsHandle, out: &mut DirEntry) -> bool,
143 /// Create a file (is_dir=false) or directory (is_dir=true) at path.
144 /// Returns 0 on success, -1 on error.
145 pub fs_create: fn(path: Line, is_dir: bool) -> i32,
146 /// Remove a file or empty directory. Returns 0 on success.
147 pub fs_remove: fn(path: Line) -> i32,
148 /// Read `len` bytes from `handle` at `pos`. Returns bytes actually
149 /// read, or -1 on error.
150 pub fs_read: fn(handle: FsHandle, buf: *mut u8, pos: u64, len: u64) -> i64,
151 /// Write `len` bytes to `handle` at `pos`. Returns bytes written.
152 pub fs_write: fn(handle: FsHandle, buf: *const u8, pos: u64, len: u64) -> i64,
153 /// Get file/directory size in bytes.
154 pub fs_size: fn(handle: FsHandle) -> u64,
155 /// Close a handle (currently a no-op; reserved for future fd mgmt).
156 pub fs_close: fn(handle: FsHandle),
157
158 // ---- hardware queries (v2) ----
159 pub rtc_now: fn(out: &mut RtcTime),
160 pub mem_stats: fn(out: &mut MemStats),
161 /// Enumerate PCI: returns number of devices discovered.
162 pub pci_probe: fn() -> u32,
163 /// Get one PCI device by index (0-based). Returns true on success.
164 pub pci_device: fn(index: u32, out: &mut PciDevice) -> bool,
165 /// Copy up to `cap` bytes of the kernel log ring into `buf`.
166 /// Returns bytes copied.
167 pub klog_dump: fn(buf: *mut u8, cap: u64) -> u64,
168 /// Fill `out` with kernel version info.
169 pub kernel_version: fn(out: &mut KernelVersion),
87} 170}