summaryrefslogtreecommitdiffstats
path: root/bins
diff options
context:
space:
mode:
Diffstat (limited to 'bins')
-rw-r--r--bins/cat/Cargo.toml8
-rw-r--r--bins/cat/src/main.rs68
-rw-r--r--bins/date/Cargo.toml8
-rw-r--r--bins/date/src/main.rs38
-rw-r--r--bins/info/Cargo.toml8
-rw-r--r--bins/info/src/main.rs22
-rw-r--r--bins/klog/Cargo.toml8
-rw-r--r--bins/klog/src/main.rs19
-rw-r--r--bins/ls/Cargo.toml8
-rw-r--r--bins/ls/src/main.rs47
-rw-r--r--bins/mem/Cargo.toml8
-rw-r--r--bins/mem/src/main.rs47
-rw-r--r--bins/mkdir/Cargo.toml8
-rw-r--r--bins/mkdir/src/main.rs18
-rw-r--r--bins/pci/Cargo.toml8
-rw-r--r--bins/pci/src/main.rs53
-rw-r--r--bins/rm/Cargo.toml8
-rw-r--r--bins/rm/src/main.rs17
-rw-r--r--bins/touch/Cargo.toml8
-rw-r--r--bins/touch/src/main.rs17
20 files changed, 426 insertions, 0 deletions
diff --git a/bins/cat/Cargo.toml b/bins/cat/Cargo.toml
new file mode 100644
index 0000000..c5990d5
--- /dev/null
+++ b/bins/cat/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "cat"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/cat/src/main.rs b/bins/cat/src/main.rs
new file mode 100644
index 0000000..6683c83
--- /dev/null
+++ b/bins/cat/src/main.rs
@@ -0,0 +1,68 @@
1//! cat — print files or stdin via the exports table.
2//!
3//! Args: [path ...] — each path is printed as raw text.
4//! No args = read from get_line (stdin) until EOF.
5
6#![no_std]
7#![no_main]
8
9#[panic_handler]
10fn panic(_info: &core::panic::PanicInfo) -> ! {
11 loop { core::hint::spin_loop(); }
12}
13
14fn put(exports: &rsapi::Exports, buf: &[u8]) {
15 (exports.put_line)(rsapi::Line { ptr: buf.as_ptr(), len: buf.len() });
16}
17
18/// Read one file and put_line each chunk.
19fn dump_file(exports: &rsapi::Exports, path: &str) -> i32 {
20 let h = (exports.fs_resolve)(rsapi::Line { ptr: path.as_ptr(), len: path.len() });
21 if h < 0 {
22 return -1;
23 }
24 let mut buf = [0u8; 512];
25 let mut pos: u64 = 0;
26 loop {
27 let n = (exports.fs_read)(h, buf.as_mut_ptr(), pos, 512);
28 if n <= 0 { break; }
29 if !(exports.put_line)(rsapi::Line { ptr: buf.as_ptr(), len: n as usize }) {
30 break; // pipeline says stop
31 }
32 pos += n as u64;
33 }
34 (exports.fs_close)(h);
35 0
36}
37
38#[unsafe(no_mangle)]
39pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 {
40 let args = unsafe { core::slice::from_raw_parts(argv, argc) };
41 if argc > 0 {
42 // Print each path argument
43 let mut code = 0;
44 for a in args.iter() {
45 let path = core::str::from_utf8(unsafe {
46 core::slice::from_raw_parts(a.ptr, a.len)
47 }).unwrap_or("");
48 if dump_file(exports, path) != 0 {
49 code = 1;
50 }
51 }
52 code
53 } else {
54 // No args: read from stdin (get_line) until EOF/Abort
55 loop {
56 let mut line = rsapi::Line { ptr: core::ptr::null(), len: 0 };
57 match (exports.get_line)(&mut line) {
58 rsapi::StreamResult::Line => {
59 put(exports, unsafe {
60 core::slice::from_raw_parts(line.ptr, line.len)
61 });
62 }
63 rsapi::StreamResult::Eof | rsapi::StreamResult::Abort => break,
64 }
65 }
66 0
67 }
68}
diff --git a/bins/date/Cargo.toml b/bins/date/Cargo.toml
new file mode 100644
index 0000000..795cc6c
--- /dev/null
+++ b/bins/date/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "date"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/date/src/main.rs b/bins/date/src/main.rs
new file mode 100644
index 0000000..880833e
--- /dev/null
+++ b/bins/date/src/main.rs
@@ -0,0 +1,38 @@
1//! date — show current RTC time via the exports table.
2
3#![no_std]
4#![no_main]
5
6#[panic_handler]
7fn panic(_info: &core::panic::PanicInfo) -> ! {
8 loop { core::hint::spin_loop(); }
9}
10
11fn put(exports: &rsapi::Exports, buf: &[u8]) {
12 (exports.put_line)(rsapi::Line { ptr: buf.as_ptr(), len: buf.len() });
13}
14
15fn dig(b: u8) -> [u8; 2] { [b'0' + b / 10, b'0' + b % 10] }
16
17#[unsafe(no_mangle)]
18pub extern "C" fn efi_main(exports: &'static rsapi::Exports, _argc: usize, _argv: *const rsapi::Arg) -> i32 {
19 let mut t = rsapi::RtcTime { year: 0, month: 0, day: 0, hour: 0, minute: 0, second: 0, _pad: 0 };
20 (exports.rtc_now)(&mut t);
21 // "YYYY-MM-DD HH:MM:SS" = 19 bytes
22 let mut buf = [0u8; 19];
23 let y = t.year;
24 buf[0] = b'0' + (y / 1000) as u8; buf[1] = b'0' + (y / 100) as u8 % 10;
25 buf[2] = b'0' + (y / 10) as u8 % 10; buf[3] = b'0' + y as u8 % 10;
26 buf[4] = b'-';
27 let m = dig(t.month); buf[5] = m[0]; buf[6] = m[1];
28 buf[7] = b'-';
29 let d = dig(t.day); buf[8] = d[0]; buf[9] = d[1];
30 buf[10] = b' ';
31 let h = dig(t.hour); buf[11] = h[0]; buf[12] = h[1];
32 buf[13] = b':';
33 let mi = dig(t.minute); buf[14] = mi[0]; buf[15] = mi[1];
34 buf[16] = b':';
35 let s = dig(t.second); buf[17] = s[0]; buf[18] = s[1];
36 put(exports, &buf);
37 0
38}
diff --git a/bins/info/Cargo.toml b/bins/info/Cargo.toml
new file mode 100644
index 0000000..b22a534
--- /dev/null
+++ b/bins/info/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "info"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/info/src/main.rs b/bins/info/src/main.rs
new file mode 100644
index 0000000..cf1bc9f
--- /dev/null
+++ b/bins/info/src/main.rs
@@ -0,0 +1,22 @@
1//! info — show system information via the exports table.
2
3#![no_std]
4#![no_main]
5
6#[panic_handler]
7fn panic(_info: &core::panic::PanicInfo) -> ! {
8 loop { core::hint::spin_loop(); }
9}
10
11fn put(exports: &rsapi::Exports, s: &str) {
12 (exports.put_line)(rsapi::Line { ptr: s.as_ptr(), len: s.len() });
13}
14
15#[unsafe(no_mangle)]
16pub extern "C" fn efi_main(exports: &'static rsapi::Exports, _argc: usize, _argv: *const rsapi::Arg) -> i32 {
17 let mut t = rsapi::RtcTime { year: 0, month: 0, day: 0, hour: 0, minute: 0, second: 0, _pad: 0 };
18 (exports.rtc_now)(&mut t);
19 put(exports, "rs-dos v0.6.0 - external info");
20 put(exports, "kernel: rsnix 0.6.0");
21 0
22}
diff --git a/bins/klog/Cargo.toml b/bins/klog/Cargo.toml
new file mode 100644
index 0000000..73957ec
--- /dev/null
+++ b/bins/klog/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "klog"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/klog/src/main.rs b/bins/klog/src/main.rs
new file mode 100644
index 0000000..fcd3512
--- /dev/null
+++ b/bins/klog/src/main.rs
@@ -0,0 +1,19 @@
1//! klog — dump kernel log via the exports table.
2
3#![no_std]
4#![no_main]
5
6#[panic_handler]
7fn panic(_info: &core::panic::PanicInfo) -> ! {
8 loop { core::hint::spin_loop(); }
9}
10
11#[unsafe(no_mangle)]
12pub extern "C" fn efi_main(exports: &'static rsapi::Exports, _argc: usize, _argv: *const rsapi::Arg) -> i32 {
13 let mut buf = [0u8; 2048];
14 let n = (exports.klog_dump)(buf.as_mut_ptr(), buf.len() as u64) as usize;
15 if n > 0 {
16 (exports.put_line)(rsapi::Line { ptr: buf.as_ptr(), len: n });
17 }
18 0
19}
diff --git a/bins/ls/Cargo.toml b/bins/ls/Cargo.toml
new file mode 100644
index 0000000..78497bd
--- /dev/null
+++ b/bins/ls/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "ls"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/ls/src/main.rs b/bins/ls/src/main.rs
new file mode 100644
index 0000000..956bf18
--- /dev/null
+++ b/bins/ls/src/main.rs
@@ -0,0 +1,47 @@
1//! ls — list directory contents via the exports table.
2//!
3//! Args: [path] — defaults to "." (root).
4
5#![no_std]
6#![no_main]
7
8#[panic_handler]
9fn panic(_info: &core::panic::PanicInfo) -> ! {
10 loop { core::hint::spin_loop(); }
11}
12
13fn put(exports: &rsapi::Exports, buf: &[u8]) {
14 (exports.put_line)(rsapi::Line { ptr: buf.as_ptr(), len: buf.len() });
15}
16
17#[unsafe(no_mangle)]
18pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 {
19 let path_str = if argc > 0 {
20 let a = unsafe { &*argv };
21 unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(a.ptr, a.len)) }
22 } else {
23 "/"
24 };
25 let h = (exports.fs_resolve)(rsapi::Line { ptr: path_str.as_ptr(), len: path_str.len() });
26 if h < 0 { return 1; }
27 let mut entry = rsapi::DirEntry {
28 name: rsapi::Line { ptr: core::ptr::null(), len: 0 },
29 is_dir: false,
30 _pad: 0,
31 size: 0,
32 };
33 while (exports.fs_dir_next)(h, &mut entry) {
34 let name = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(entry.name.ptr, entry.name.len)) };
35 if entry.is_dir {
36 let mut buf = [0u8; 64];
37 let nb = name.as_bytes();
38 buf[..nb.len()].copy_from_slice(nb);
39 buf[nb.len()] = b'/';
40 put(exports, &buf[..nb.len() + 1]);
41 } else {
42 put(exports, name.as_bytes());
43 }
44 }
45 (exports.fs_close)(h);
46 0
47}
diff --git a/bins/mem/Cargo.toml b/bins/mem/Cargo.toml
new file mode 100644
index 0000000..2306fc7
--- /dev/null
+++ b/bins/mem/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "mem"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/mem/src/main.rs b/bins/mem/src/main.rs
new file mode 100644
index 0000000..fd99f47
--- /dev/null
+++ b/bins/mem/src/main.rs
@@ -0,0 +1,47 @@
1//! mem — show memory statistics via the exports table.
2
3#![no_std]
4#![no_main]
5
6#[panic_handler]
7fn panic(_info: &core::panic::PanicInfo) -> ! {
8 loop { core::hint::spin_loop(); }
9}
10
11fn put(exports: &rsapi::Exports, buf: &[u8]) {
12 (exports.put_line)(rsapi::Line { ptr: buf.as_ptr(), len: buf.len() });
13}
14
15fn fmt_kib(exports: &rsapi::Exports, v: u64) {
16 let mut buf = [0u8; 32];
17 let kb = v / 1024;
18 let mut i = buf.len();
19 if kb == 0 { i -= 1; buf[i] = b'0'; }
20 else { let mut n = kb; while n > 0 { i -= 1; buf[i] = b'0' + (n % 10) as u8; n /= 10; } }
21 let s = b" KiB";
22 buf[i..i+s.len()].copy_from_slice(s);
23 put(exports, &buf[i..i+s.len()]);
24}
25
26#[unsafe(no_mangle)]
27pub extern "C" fn efi_main(exports: &'static rsapi::Exports, _argc: usize, _argv: *const rsapi::Arg) -> i32 {
28 let mut s = rsapi::MemStats { heap_total: 0, heap_free: 0, pages_total: 0, pages_free: 0 };
29 (exports.mem_stats)(&mut s);
30 let msg = b"heap:";
31 put(exports, msg);
32 put(exports, b" free"); fmt_kib(exports, s.heap_free);
33 put(exports, b" / total"); fmt_kib(exports, s.heap_total);
34 let msg2 = b"pages:";
35 put(exports, msg2);
36 put(exports, b" free");
37 let mut fb = [0u8; 16];
38 let mut i = fb.len();
39 let n = s.pages_free; if n==0 { i-=1; fb[i]=b'0'; } else { let mut m=n; while m>0 { i-=1; fb[i]=b'0'+(m%10) as u8; m/=10; } }
40 put(exports, &fb[i..]);
41 put(exports, b" / ");
42 let mut tb = [0u8; 16];
43 let mut j = tb.len();
44 let t = s.pages_total; if t==0 { j-=1; tb[j]=b'0'; } else { let mut m=t; while m>0 { j-=1; tb[j]=b'0'+(m%10) as u8; m/=10; } }
45 put(exports, &tb[j..]);
46 0
47}
diff --git a/bins/mkdir/Cargo.toml b/bins/mkdir/Cargo.toml
new file mode 100644
index 0000000..ca97f6c
--- /dev/null
+++ b/bins/mkdir/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "mkdir"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/mkdir/src/main.rs b/bins/mkdir/src/main.rs
new file mode 100644
index 0000000..f6f7e66
--- /dev/null
+++ b/bins/mkdir/src/main.rs
@@ -0,0 +1,18 @@
1//! mkdir — create directories via the exports table.
2
3#![no_std]
4#![no_main]
5
6#[panic_handler]
7fn panic(_info: &core::panic::PanicInfo) -> ! {
8 loop { core::hint::spin_loop(); }
9}
10
11#[unsafe(no_mangle)]
12pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 {
13 let args = unsafe { core::slice::from_raw_parts(argv, argc) };
14 if args.is_empty() { return 1; }
15 let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(args[0].ptr, args[0].len)) };
16 let rc = (exports.fs_create)(rsapi::Line { ptr: path.as_ptr(), len: path.len() }, true);
17 rc
18}
diff --git a/bins/pci/Cargo.toml b/bins/pci/Cargo.toml
new file mode 100644
index 0000000..85590f8
--- /dev/null
+++ b/bins/pci/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "pci"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/pci/src/main.rs b/bins/pci/src/main.rs
new file mode 100644
index 0000000..1182d83
--- /dev/null
+++ b/bins/pci/src/main.rs
@@ -0,0 +1,53 @@
1//! pci — list PCI devices via the exports table.
2
3#![no_std]
4#![no_main]
5
6#[panic_handler]
7fn panic(_info: &core::panic::PanicInfo) -> ! {
8 loop { core::hint::spin_loop(); }
9}
10
11fn put(exports: &rsapi::Exports, buf: &[u8]) {
12 (exports.put_line)(rsapi::Line { ptr: buf.as_ptr(), len: buf.len() });
13}
14
15fn hex2(b: u8, out: &mut [u8]) {
16 let hi = b >> 4; let lo = b & 0xf;
17 out[0] = if hi < 10 { b'0' + hi } else { b'a' + hi - 10 };
18 out[1] = if lo < 10 { b'0' + lo } else { b'a' + lo - 10 };
19}
20
21#[unsafe(no_mangle)]
22pub extern "C" fn efi_main(exports: &'static rsapi::Exports, _argc: usize, _argv: *const rsapi::Arg) -> i32 {
23 let count = (exports.pci_probe)();
24 let mut i = 0u32;
25 while i < count {
26 let mut d = rsapi::PciDevice { bus: 0, device: 0, function: 0, class: 0, subclass: 0, vendor: 0, device_id: 0 };
27 if (exports.pci_device)(i, &mut d) {
28 // "XX:XX.F class=XX:XX ven=XXXX dev=XXXX" = 42 bytes max
29 let mut buf = [0u8; 42];
30 hex2(d.bus, &mut buf[0..2]); buf[2] = b':';
31 hex2(d.device, &mut buf[3..5]); buf[5] = b'.';
32 buf[6] = b'0' + d.function;
33 let class_lbl = b" class=";
34 buf[7..7+class_lbl.len()].copy_from_slice(class_lbl);
35 let o = 7 + class_lbl.len();
36 hex2(d.class, &mut buf[o..o+2]); buf[o+2] = b':';
37 hex2(d.subclass, &mut buf[o+3..o+5]);
38 let ven_lbl = b" ven=";
39 buf[o+5..o+5+ven_lbl.len()].copy_from_slice(ven_lbl);
40 let v = o + 5 + ven_lbl.len();
41 hex2((d.vendor >> 8) as u8, &mut buf[v..v+2]);
42 hex2((d.vendor & 0xff) as u8, &mut buf[v+2..v+4]);
43 let dev_lbl = b" dev=";
44 buf[v+4..v+4+dev_lbl.len()].copy_from_slice(dev_lbl);
45 let dd = v + 4 + dev_lbl.len();
46 hex2((d.device_id >> 8) as u8, &mut buf[dd..dd+2]);
47 hex2((d.device_id & 0xff) as u8, &mut buf[dd+2..dd+4]);
48 put(exports, &buf[..dd+4]);
49 }
50 i += 1;
51 }
52 0
53}
diff --git a/bins/rm/Cargo.toml b/bins/rm/Cargo.toml
new file mode 100644
index 0000000..b49abac
--- /dev/null
+++ b/bins/rm/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "rm"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/rm/src/main.rs b/bins/rm/src/main.rs
new file mode 100644
index 0000000..3407563
--- /dev/null
+++ b/bins/rm/src/main.rs
@@ -0,0 +1,17 @@
1//! rm — remove a file or empty directory via the exports table.
2
3#![no_std]
4#![no_main]
5
6#[panic_handler]
7fn panic(_info: &core::panic::PanicInfo) -> ! {
8 loop { core::hint::spin_loop(); }
9}
10
11#[unsafe(no_mangle)]
12pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 {
13 let args = unsafe { core::slice::from_raw_parts(argv, argc) };
14 if args.is_empty() { return 1; }
15 let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(args[0].ptr, args[0].len)) };
16 (exports.fs_remove)(rsapi::Line { ptr: path.as_ptr(), len: path.len() })
17}
diff --git a/bins/touch/Cargo.toml b/bins/touch/Cargo.toml
new file mode 100644
index 0000000..54824e7
--- /dev/null
+++ b/bins/touch/Cargo.toml
@@ -0,0 +1,8 @@
1[package]
2name = "touch"
3version.workspace = true
4edition.workspace = true
5[lints]
6workspace = true
7[dependencies]
8rsapi = { path = "../../rsapi" }
diff --git a/bins/touch/src/main.rs b/bins/touch/src/main.rs
new file mode 100644
index 0000000..5cd61e3
--- /dev/null
+++ b/bins/touch/src/main.rs
@@ -0,0 +1,17 @@
1//! touch — create an empty file via the exports table.
2
3#![no_std]
4#![no_main]
5
6#[panic_handler]
7fn panic(_info: &core::panic::PanicInfo) -> ! {
8 loop { core::hint::spin_loop(); }
9}
10
11#[unsafe(no_mangle)]
12pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 {
13 let args = unsafe { core::slice::from_raw_parts(argv, argc) };
14 if args.is_empty() { return 1; }
15 let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(args[0].ptr, args[0].len)) };
16 (exports.fs_create)(rsapi::Line { ptr: path.as_ptr(), len: path.len() }, false)
17}