ableOS build system

master
Able 2021-11-16 00:09:27 -06:00
commit 911b37533b
103 changed files with 9491 additions and 0 deletions

2
.cargo/config.toml Normal file
View File

@ -0,0 +1,2 @@
[alias]
repbuild = "run --manifest-path ./repbuild/Cargo.toml --"

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
repbuild/target
ableos/target

11
ableos/.cargo/config.toml Normal file
View File

@ -0,0 +1,11 @@
[build]
target = "./json_targets/x86_64-ableos.json"
[unstable]
build-std-features = ["compiler-builtins-mem"]
build-std = ["core", "compiler_builtins"]
[target.'cfg(target_arch = "x86_64")']
# --quiet suppresses warning messages from the bootimage crate
runner = "bootimage runner --quiet"

22
ableos/.github/workflows/rust.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Build
on:
- push
- pull_request
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
components: rust-src
- uses: actions-rs/cargo@v1
with:
command: build
args: --release

5
ableos/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"files.associations": {
"stddef.h": "c"
}
}

202
ableos/Cargo.lock generated Normal file
View File

@ -0,0 +1,202 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ableos"
version = "0.1.0"
dependencies = [
"bootloader",
"cpuio",
"lazy_static",
"pic8259",
"psp",
"spin",
"uart_16550",
"volatile 0.2.7",
"x86_64",
]
[[package]]
name = "bit_field"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bootloader"
version = "0.9.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c452074efc3c0bfb241fb7bc87df04741c7c85e926f6a07c05f8fbd6008240"
[[package]]
name = "cpuio"
version = "0.3.0"
source = "git+https://github.com/anyusernameworks/cpuio.git#3908ecab79df80670ee1c5121870fc131f07627b"
[[package]]
name = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [
"spin",
]
[[package]]
name = "num_enum"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f"
dependencies = [
"derivative",
"num_enum_derive",
]
[[package]]
name = "num_enum_derive"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "paste"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
dependencies = [
"paste-impl",
"proc-macro-hack",
]
[[package]]
name = "paste-impl"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
dependencies = [
"proc-macro-hack",
]
[[package]]
name = "pic8259"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ec21f514e2e16e94649f1d041ca4a7069b512c037ac156360652a775e6229d"
dependencies = [
"x86_64",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
"unicode-xid",
]
[[package]]
name = "psp"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b3021953a10d1bc6735a606ab9d5a1510282df7a55a160a270e9ea3cf479669"
dependencies = [
"bitflags",
"num_enum",
"num_enum_derive",
"paste",
]
[[package]]
name = "quote"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "syn"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "uart_16550"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65ad019480ef5ff8ffe66d6f6a259cd87cf317649481394981db1739d844f374"
dependencies = [
"bitflags",
"x86_64",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "volatile"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6b06ad3ed06fef1713569d547cdbdb439eafed76341820fb0e0344f29a41945"
[[package]]
name = "volatile"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4c2dbd44eb8b53973357e6e207e370f0c1059990df850aca1eca8947cf464f0"
[[package]]
name = "x86_64"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbc6ed1ed2cd4536b083c34041aff7b84448ee25ac4aa5e9d54802ce226f9815"
dependencies = [
"bit_field",
"bitflags",
"volatile 0.4.4",
]

40
ableos/Cargo.toml Normal file
View File

@ -0,0 +1,40 @@
[package]
name = "ableos"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
panic = "abort"
[package.metadata.bootimage]
test-args = [
"-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-serial", "stdio"
]
run-args=["-serial", "stdio"]
[dependencies]
spin = "0.5.2"
# linked_list_allocator = "0.9.0"
[dependencies.lazy_static]
features = ["spin_no_std"]
version = "1.0"
# alloc required
# [dependencies.wasmi]
# version = "*"
# default-features = false
# features = ["core"]
[target.'cfg(target_arch = "mips")'.dependencies]
psp = "0.1.5"
[target.'cfg(target_arch = "x86_64")'.dependencies]
volatile = "0.2.6"
bootloader = "0.9.8"
cpuio = { git = "https://github.com/anyusernameworks/cpuio.git" }
x86_64 = "*"
uart_16550 = "0.2.0"
pic8259 = "0.10.1"

22
ableos/README.md Normal file
View File

@ -0,0 +1,22 @@
# ableOS
![Discord](https://img.shields.io/discord/831368967385120810) ![Code Size](https://img.shields.io/github/languages/code-size/abletheabove/ableos)
## Set up
Install [Qemu](https://www.qemu.org/)
> On Windows be sure to add `C:\Program Files\qemu` to your `PATH` variable
`rustup component add rust-src`
`rustup component add llvm-tools-preview`
`cargo install bootimage`
## Srange workarounds
- arm/build.rs has to move main.rs
- conditional dependencies for bootloader are broken
## Testing on real hardware
I recommend using an old x86_64 computer
* `cargo run --release` to generate a binary image that is bootable
* flash it to a USB device via `dd` or belenaEtcher
* Remove said USB device and plug into test machine
* assure test machine boots from USB devices

2
ableos/TODO.md Normal file
View File

@ -0,0 +1,2 @@
- [ ] Simple interactive "painting" "program"
- [ ] monotty like desktop environment

View File

@ -0,0 +1 @@
{"rustc_fingerprint":3542195962280373086,"outputs":{"17598535894874457435":{"success":true,"status":"","code":0,"stdout":"rustc 1.58.0-nightly (efd048394 2021-10-20)\nbinary: rustc\ncommit-hash: efd0483949496b067cd5f7569d1b28cd3d5d3c72\ncommit-date: 2021-10-20\nhost: x86_64-unknown-linux-gnu\nrelease: 1.58.0-nightly\nLLVM version: 13.0.0\n","stderr":""},"2797684049618456168":{"success":false,"status":"exit status: 1","code":1,"stdout":"","stderr":"error: `-Csplit-debuginfo` is unstable on this platform\n\n"},"15537503139010883884":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n","stderr":""},"931469667778813386":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/elfein/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}

View File

@ -0,0 +1,15 @@
{
"llvm-target": "arm-none-eabihf",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"os": "ableos",
"env": "eabi",
"vendor": "unknown",
"arch": "arm",
"linker-flavor": "gcc",
"linker": "arm-none-eabi-gcc",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"relocation-model": "static"
}

View File

@ -0,0 +1,24 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"disable-redzone": true,
"env": "",
"executables": true,
"features": "+strict-align,+neon,+fp-armv8",
"is-builtin": false,
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": ["-Tsrc/arch/aarch64/aarch64-qemu.ld"]
},
"llvm-target": "aarch64-unknown-none",
"max-atomic-width": 128,
"os": "none",
"panic-strategy": "abort",
"relocation-model": "static",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"vendor": ""
}

View File

@ -0,0 +1,15 @@
{
"llvm-target": "arm-none-eabihf",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"os": "ableos",
"env": "eabi",
"vendor": "unknown",
"arch": "arm",
"linker-flavor": "gcc",
"linker": "arm-none-eabi-gcc",
"data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
"executables": true,
"relocation-model": "static"
}

View File

@ -0,0 +1,15 @@
{
"llvm-target": "x86_64-unknown-none",
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort",
"disable-redzone": true,
"features": "-mmx,-sse,+soft-float"
}

256
ableos/keymaps/empty.keymap Normal file
View File

@ -0,0 +1,256 @@
0-
1-
2-
3-
4-
5-
6-
7-
8-
9-
10-
11-
12-
13-
14-
15-
16-
17-
18-
19-
20-
21-
22-
23-
24-
25-
26-
27-
28-
29-
30-
31-
32-
33-
34-
35-
36-
37-
38-
39-
40-
41-
42-
43-
44-
45-
46-
47-
48-
49-
50-
51-
52-
53-
54-
55-
56-
57-
58-
59-
60-
61-
62-
63-
64-
65-
66-
67-
68-
69-
70-
71-
72-
73-
74-
75-
76-
77-
78-
79-
80-
81-
82-
83-
84-
85-
86-
87-
88-
89-
90-
91-
92-
93-
94-
95-
96-
97-
98-
99-
100-
101-
102-
103-
104-
105-
106-
107-
108-
109-
110-
111-
112-
113-
114-
115-
116-
117-
118-
119-
120-
121-
122-
123-
124-
125-
126-
127-
128-
129-
130-
131-
132-
133-
134-
135-
136-
137-
138-
139-
140-
141-
142-
143-
144-
145-
146-
147-
148-
149-
150-
151-
152-
153-
154-
155-
156-
157-
158-
159-
160-
161-
162-
163-
164-
165-
166-
167-
168-
169-
170-
171-
172-
173-
174-
175-
176-
177-
178-
179-
180-
181-
182-
183-
184-
185-
186-
187-
188-
189-
190-
191-
192-
193-
194-
195-
196-
197-
198-
199-
200-
201-
202-
203-
204-
205-
206-
207-
208-
209-
210-
211-
212-
213-
214-
215-
216-
217-
218-
219-
220-
221-
222-
223-
224-
225-
226-
227-
228-
229-
230-
231-
232-
233-
234-
235-
236-
237-
238-
239-
240-
241-
242-
243-
244-
245-
246-
247-
248-
249-
250-
251-
252-
253-
254-
255-

View File

@ -0,0 +1,252 @@
# Able doesn't have a full keyboard
0-NONE
1-
2-
3-BACKSPACE
4-
5-
6-
7-
8-
9-TAB
10-
11-
12-
13-ENTER
14-
15-
16-SHIFT
17-CONTROL
18-ALT
19-PAUSE
20-CAPS_LOCK
21-
22-
23-
24-
25-
26-
27-
28-
29-
30-
31-
32-SPACE
33-PAGE_UP
34-PAGE_DOWN
35-END
36-HOME
37-ARROW_LEFT
38-ARROW_UP
39-ARROW_RIGHT
40-ARROW_DOWN
41-
42-
43-
44-
45-INSERT
46-DELETE
47-
48-0
49-1
50-2
51-3
52-4
53-5
54-6
55-7
56-8
57-9
58-
59-SEMICOLON
60-
61-EQUAL
62-
63-
64-
65-a
66-b
67-c
68-d
69-e
70-f
71-g
72-h
73-i
74-j
75-k
76-l
77-m
78-n
79-o
80-p
81-q
82-r
83-s
84-t
85-u
86-v
87-w
88-x
89-
90-z
91-
92-
93-
94-
95-
96-
97-
98-
99-
100-
101-
102-
103-
106-
107-
108-
109-
110-
111-
112-FUNCTION_1
113-FUNCTION_2
114-FUNCTION_3
115-FUNCTION_4
116-FUNCTION_5
117-FUNCTION_6
118-FUNCTION_7
119-FUNCTION_8
120-FUNCTION_9
121-FUNCTION_10
122-FUNCTION_11
123-FUNCTION_12
124-
125-
126-
127-
128-
129-
130-
131-
132-
134-
135-
136-
137-
138-
139-
140-
141-
142-
143-
145-SCROLL_LOCK
146-
147-
148-
149-
150-
151-
152-
153-
154-
155-
156-
157-
158-
159-
160-
161-
162-
163-
164-
165-
166-
167-
168-
169-
170-
171-
172-
173-MINUS
174-
175-
176-
177-
178-
179-
180-
181-
182-
183-
184-
185-
186-
187-
188-COMMA
189-
190-PERIOD
191-FORWARD_SLASH
192-GRAVE
193-
194-
195-
196-
197-
198-
199-
200-
201-
202-
203-
204-
205-
206-
207-
208-
209-
210-
211-
212-
213-
214-
215-
216-
218-
219-BRACKET_LEFT
220-BACK_SLASH
221-BRACKET_RIGHT
222-QUOTE
223-
224-
225-
226-
227-
228-
229-
230-
231-
232-
233-
234-
235-
236-
237-
238-
239-
240-
241-
242-
243-
244-
245-
246-
247-
248-
249-
250-
251-
252-
253-
254-
255-

9
ableos/notes/NOTES.md Normal file
View File

@ -0,0 +1,9 @@
Don't keep piling on API shit
Good docs are a must!!!!!!!!!!!!
No Bloat
One thing One Way
Bloat makes M!nt sad
Have rust-like strings only
# Don't
memory gun

3
ableos/notes/USER.md Normal file
View File

@ -0,0 +1,3 @@
user
> execute
> file system

1
ableos/rust-toolchain Normal file
View File

@ -0,0 +1 @@
nightly

View File

@ -0,0 +1,27 @@
#[repr(C)]
pub struct ShutterDowner {
smi_cmd: u32,
acpi_enable: u8,
acpi_disable: u8,
pm1a_cnt: u32,
pm1b_cnt: u32,
slp_typa: u16,
slp_typb: u16,
slp_en: u16,
scii_en: u16,
pm1_cnt_len: u8,
}
pub structRSDPtr {
signature: [u8; 8],
checksum: u8,
oem_id: [u8; 6],
revision: u8,
rsdt_address: u32,
}
struct FACP {
signature: [u8; 4],
length: u32,
}

View File

@ -0,0 +1,302 @@
// //
// // here is the slighlty complicated ACPI poweroff code
// //
#include <stddef.h>
#include <print.h>
#include <string.h>
#include <io.h>
#include <time.h>
dword *SMI_CMD;
byte ACPI_ENABLE;
byte ACPI_DISABLE;
dword *PM1a_CNT;
dword *PM1b_CNT;
word SLP_TYPa;
word SLP_TYPb;
word SLP_EN;
word SCI_EN;
byte PM1_CNT_LEN;
struct RSDPtr
{
byte Signature[8];
byte CheckSum;
byte OemID[6];
byte Revision;
dword *RsdtAddress;
};
struct FACP
{
byte Signature[4];
dword Length;
byte unneded1[40 - 8];
dword *DSDT;
byte unneded2[48 - 44];
dword *SMI_CMD;
byte ACPI_ENABLE;
byte ACPI_DISABLE;
byte unneded3[64 - 54];
dword *PM1a_CNT_BLK;
dword *PM1b_CNT_BLK;
byte unneded4[89 - 72];
byte PM1_CNT_LEN;
};
// check if the given address has a valid header
unsigned int *acpiCheckRSDPtr(unsigned int *ptr)
{
char *sig = "RSD PTR ";
struct RSDPtr *rsdp = (struct RSDPtr *)ptr;
byte *bptr;
byte check = 0;
int i;
if (memcmp(sig, rsdp, 8) == 0)
{
// check checksum rsdpd
bptr = (byte *)ptr;
for (i = 0; i < sizeof(struct RSDPtr); i++)
{
check += *bptr;
bptr++;
}
// found valid rsdpd
if (check == 0)
{
/*
if (desc->Revision == 0)
wrstr("acpi 1");
else
wrstr("acpi 2");
*/
return (unsigned int *)rsdp->RsdtAddress;
}
}
return NULL;
}
// finds the acpi header and returns the address of the rsdt
unsigned int *acpiGetRSDPtr(void)
{
unsigned int *addr;
unsigned int *rsdp;
// search below the 1mb mark for RSDP signature
for (addr = (unsigned int *)0x000E0000; (int)addr < 0x00100000; addr += 0x10 / sizeof(addr))
{
rsdp = acpiCheckRSDPtr(addr);
if (rsdp != NULL)
return rsdp;
}
// at address 0x40:0x0E is the RM segment of the ebda
int ebda = *((short *)0x40E); // get pointer
ebda = ebda * 0x10 & 0x000FFFFF; // transform segment into linear address
// search Extended BIOS Data Area for the Root System Description Pointer signature
for (addr = (unsigned int *)ebda; (int)addr < ebda + 1024; addr += 0x10 / sizeof(addr))
{
rsdp = acpiCheckRSDPtr(addr);
if (rsdp != NULL)
return rsdp;
}
return NULL;
}
// checks for a given header and validates checksum
int acpiCheckHeader(unsigned int *ptr, char *sig)
{
if (memcmp(ptr, sig, 4) == 0)
{
char *checkPtr = (char *)ptr;
int len = *(ptr + 1);
char check = 0;
while (0 < len--)
{
check += *checkPtr;
checkPtr++;
}
if (check == 0)
return 0;
}
return -1;
}
int acpiEnable(void)
{
// check if acpi is enabled
if ((inw((unsigned int)PM1a_CNT) & SCI_EN) == 0)
{
// check if acpi can be enabled
if (SMI_CMD != 0 && ACPI_ENABLE != 0)
{
outb((unsigned int)SMI_CMD, ACPI_ENABLE); // send acpi enable command
// give 3 seconds time to enable acpi
int i;
for (i = 0; i < 300; i++)
{
if ((inw((unsigned int)PM1a_CNT) & SCI_EN) == 1)
break;
sleep(10);
}
if (PM1b_CNT != 0)
for (; i < 300; i++)
{
if ((inw((unsigned int)PM1b_CNT) & SCI_EN) == 1)
break;
sleep(10);
}
if (i < 300)
{
wrstr("enabled acpi.\n");
return 0;
}
else
{
wrstr("couldn't enable acpi.\n");
return -1;
}
}
else
{
wrstr("no known way to enable acpi.\n");
return -1;
}
}
else
{
//wrstr("acpi was already enabled.\n");
return 0;
}
}
//
// bytecode of the \_S5 object
// -----------------------------------------
// | (optional) | | | |
// NameOP | \ | _ | S | 5 | _
// 08 | 5A | 5F | 53 | 35 | 5F
//
// -----------------------------------------------------------------------------------------------------------
// | | | ( SLP_TYPa ) | ( SLP_TYPb ) | ( Reserved ) | (Reserved )
// PackageOP | PkgLength | NumElements | byteprefix Num | byteprefix Num | byteprefix Num | byteprefix Num
// 12 | 0A | 04 | 0A 05 | 0A 05 | 0A 05 | 0A 05
//
//----this-structure-was-also-seen----------------------
// PackageOP | PkgLength | NumElements |
// 12 | 06 | 04 | 00 00 00 00
//
// (Pkglength bit 6-7 encode additional PkgLength bytes [shouldn't be the case here])
//
int initAcpi(void)
{
unsigned int *ptr = acpiGetRSDPtr();
// check if address is correct ( if acpi is available on this pc )
if (ptr != NULL && acpiCheckHeader(ptr, "RSDT") == 0)
{
// the RSDT contains an unknown number of pointers to acpi tables
int entrys = *(ptr + 1);
entrys = (entrys - 36) / 4;
ptr += 36 / 4; // skip header information
while (0 < entrys--)
{
// check if the desired table is reached
if (acpiCheckHeader((unsigned int *)*ptr, "FACP") == 0)
{
entrys = -2;
struct FACP *facp = (struct FACP *)*ptr;
if (acpiCheckHeader((unsigned int *)facp->DSDT, "DSDT") == 0)
{
// search the \_S5 package in the DSDT
char *S5Addr = (char *)facp->DSDT + 36; // skip header
int dsdtLength = *(facp->DSDT + 1) - 36;
while (0 < dsdtLength--)
{
if (memcmp(S5Addr, "_S5_", 4) == 0)
break;
S5Addr++;
}
// check if \_S5 was found
if (dsdtLength > 0)
{
// check for valid AML structure
if ((*(S5Addr - 1) == 0x08 || (*(S5Addr - 2) == 0x08 && *(S5Addr - 1) == '\\')) && *(S5Addr + 4) == 0x12)
{
S5Addr += 5;
// calculate PkgLength size
S5Addr += ((*S5Addr &0xC0)>>6) +2;
if (*S5Addr == 0x0A)
S5Addr++; // skip byteprefix
SLP_TYPa = *(S5Addr) << 10;
S5Addr++;
if (*S5Addr == 0x0A)
S5Addr++; // skip byteprefix
SLP_TYPb = *(S5Addr) << 10;
SMI_CMD = facp->SMI_CMD;
ACPI_ENABLE = facp->ACPI_ENABLE;
ACPI_DISABLE = facp->ACPI_DISABLE;
PM1a_CNT = facp->PM1a_CNT_BLK;
PM1b_CNT = facp->PM1b_CNT_BLK;
PM1_CNT_LEN = facp->PM1_CNT_LEN;
SLP_EN = 1 << 13;
SCI_EN = 1;
return 0;
}
else
{
wrstr("\\_S5 parse error.\n");
}
}
else
{
wrstr("\\_S5 not present.\n");
}
}
else
{
wrstr("DSDT invalid.\n");
}
}
ptr++;
}
wrstr("no valid FACP present.\n");
}
else
{
wrstr("no acpi.\n");
}
return -1;
}
void acpiPowerOff(void)
{
// SCI_EN is set to 1 if acpi shutdown is possible
if (SCI_EN == 0)
return;
acpiEnable();
// send the shutdown command
outw((unsigned int)PM1a_CNT, SLP_TYPa | SLP_EN);
if (PM1b_CNT != 0)
outw((unsigned int)PM1b_CNT, SLP_TYPb | SLP_EN);
wrstr("acpi poweroff failed.\n");
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
// AArch32 mode
// To keep this in the first portion of the binary.
.section ".text.boot"
// Make _start global.
.globl _start
.org 0x8000
// Entry point for the kernel.
// r15 -> should begin execution at 0x8000.
// r0 -> 0x00000000
// r1 -> 0x00000C42 - machine id
// r2 -> 0x00000100 - start of ATAGS
// preserve these registers as argument for kernel_main
_start:
// Shut off extra cores
mrc p15, 0, r5, c0, c0, 5
and r5, r5, #3
cmp r5, #0
bne halt
// Setup the stack.
ldr r5, =_start
mov sp, r5
// Clear out bss.
ldr r4, =__bss_start
ldr r9, =__bss_end
mov r5, #0
mov r6, #0
mov r7, #0
mov r8, #0
b 2f
1:
// store multiple at r4.
stmia r4!, {r5-r8}
// If we are still below bss_end, loop.
2:
cmp r4, r9
blo 1b
// Call kernel_main
ldr r3, =kernel_main
blx r3
// halt
halt:
wfe
b halt

View File

@ -0,0 +1,7 @@
arm-none-eabi-gcc -mcpu=cortex-a7 -fpic -ffreestanding -c src/arch/aarch32/boot.s -o boot.o
mv src/main.rs src/main.rs.pass
cargo build --release --target json_targets/aarch32-ableos.json
arm-none-eabi-gcc -T src/arch/aarch32/linker.ld -o ableos.elf -ffreestanding -O2 -nostdlib boot.o \
target/aarch32-ableos/release/libableos.rlib
mv src/main.rs.pass src/main.rs
rm boot.o

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
pub mod graphics;

View File

@ -0,0 +1,4 @@
use super::write;
pub fn init() {
write("booted on arm :>\n");
}

View File

@ -0,0 +1,43 @@
ENTRY(_start)
SECTIONS
{
/* Starts at LOADER_ADDR. */
. = 0x80000;
__start = .;
__text_start = .;
.text :
{
KEEP(*(.text.boot))
*(.text)
}
. = ALIGN(4096); /* align to page size */
__text_end = .;
__rodata_start = .;
.rodata :
{
*(.rodata)
}
. = ALIGN(4096); /* align to page size */
__rodata_end = .;
__data_start = .;
.data :
{
*(.data)
}
. = ALIGN(4096); /* align to page size */
__data_end = .;
__bss_start = .;
.bss :
{
bss = .;
*(.bss)
}
. = ALIGN(4096); /* align to page size */
__bss_end = .;
__bss_size = __bss_end - __bss_start;
__end = .;
}

View File

@ -0,0 +1,2 @@
const MMIO_BASE: u32 = 0x3F00_0000;
const VIDEOCORE_MBOX: u32 = MMIO_BASE + 0xB880;

View File

@ -0,0 +1,38 @@
#![allow(warnings)]
pub const ARCH: &'static str = "aarch32";
use core::intrinsics::{volatile_load, volatile_store};
pub mod drivers;
pub mod init;
pub mod mbox;
// raspi2 and raspi3 have peripheral base address 0x3F000000,
// b ut raspi1 has peripheral base address 0x20000000. Ensure
// you are using the correct peripheral address for your
// hardware.
const UART_DR: u32 = 0x3F201000;
const UART_FR: u32 = 0x3F201018;
pub fn mmio_write(reg: u32, val: u32) {
unsafe { volatile_store(reg as *mut u32, val) }
}
pub fn mmio_read(reg: u32) -> u32 {
unsafe { volatile_load(reg as *const u32) }
}
pub fn transmit_fifo_full() -> bool {
mmio_read(UART_FR) & (1 << 5) > 0
}
pub fn receive_fifo_empty() -> bool {
mmio_read(UART_FR) & (1 << 4) > 0
}
pub fn writec(c: u8) {
while transmit_fifo_full() {}
mmio_write(UART_DR, c as u32);
}
pub fn getc() -> u8 {
while receive_fifo_empty() {}
mmio_read(UART_DR) as u8
}
pub fn write(msg: &str) {
for c in msg.chars() {
writec(c as u8)
}
}
pub fn shutdown() {}

View File

@ -0,0 +1,3 @@
sh src/arch/aarch32/build.sh && \
qemu-system-arm -M raspi2 -kernel ableos.elf --serial stdio && \
rm ableos.elf

View File

@ -0,0 +1,14 @@
ENTRY(_start)
SECTIONS
{
. = 0x40000000;
.text.boot : { *(.text.boot) }
.text : { *(.text) }
.data : { *(.data) }
.rodata : { *(.rodata) }
.bss : { *(.bss) }
. = ALIGN(8);
. = . + 0x4000;
LD_STACK_PTR = .;
}

View File

@ -0,0 +1,15 @@
.globl _start
.extern LD_STACK_PTR
.section ".text.boot"
_start:
ldr x30, =LD_STACK_PTR
mov sp, x30
bl not_main
.equ PSCI_SYSTEM_OFF, 0x84000008
.globl system_off
system_off:
ldr x0, =PSCI_SYSTEM_OFF
hvc #0

View File

@ -0,0 +1,31 @@
use crate::driver_traits::graphics::{Graphics, Point, Rgb};
pub struct GraphicsBuffer;
#[allow(unused)]
impl Graphics for GraphicsBuffer {
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb) {
todo!()
}
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb) {
todo!()
}
fn put_circle(coords: Point, radius: u32) {
todo!()
}
fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb) {
todo!();
}
fn put_pixel(coords: Point, color: Rgb) {
todo!()
}
fn paint_cursor(coords: Point) {
todo!()
}
fn hide_cursor() {}
fn show_cursor() {}
fn draw() {}
fn clear() {
todo!()
}
}

View File

@ -0,0 +1,2 @@
pub mod graphics;
pub mod nrf52;

View File

@ -0,0 +1,73 @@
#![allow(dead_code)]
// A not-very-useful abstraction of GPIOs in Rust
use core::sync::atomic::{AtomicBool, Ordering::SeqCst};
/// A struct that represents an nRF52 Pin
pub struct Pin(u8);
/// A struct that represents P0 of the nRF52
pub struct Pins {
pub p0_31: Pin,
}
impl Pins {
/// A function to obtain a Port 0 singleton structure
pub fn take() -> Self {
static TAKEN: AtomicBool = AtomicBool::new(false);
// Enforce this as a singleton
assert!(!TAKEN.swap(true, SeqCst));
Self { p0_31: Pin(31) }
}
}
/// The level of a GPIO
#[derive(Copy, Clone)]
pub enum Level {
Low,
High,
}
const REG_P0_PIN_CNF_BASE: *mut u32 = 0x5000_0700 as *mut u32;
const REG_P0_OUT_SET: *mut u32 = 0x5000_0508 as *mut u32;
const REG_P0_OUT_CLR: *mut u32 = 0x5000_050C as *mut u32;
const PIN_CNF_DIR_OUTPUT: u32 = 0x0000_0001;
const PIN_CNF_INPUT_CONNECT: u32 = 0x0000_0000;
const PIN_CNF_PULL_DISABLED: u32 = 0x0000_0000;
const PIN_CNF_DRIVE_S0S1: u32 = 0x0000_0000;
const PIN_CNF_SENSE_DISABLED: u32 = 0x0000_0000;
impl Pin {
/// Set a pin to be a push pull output
pub fn set_push_pull_output(&mut self, level: Level) {
// set level
match level {
Level::High => self.set_high(),
Level::Low => self.set_low(),
}
let set_val = PIN_CNF_DIR_OUTPUT
| PIN_CNF_INPUT_CONNECT
| PIN_CNF_PULL_DISABLED
| PIN_CNF_DRIVE_S0S1
| PIN_CNF_SENSE_DISABLED;
unsafe {
core::ptr::write_volatile(REG_P0_PIN_CNF_BASE.offset(self.0 as isize), set_val);
}
}
/// Set a pin to output level low
pub fn set_low(&mut self) {
unsafe { core::ptr::write_volatile(REG_P0_OUT_SET, 1 << (self.0 as u32)) }
}
/// Set a pin to output level high
pub fn set_high(&mut self) {
unsafe { core::ptr::write_volatile(REG_P0_OUT_CLR, 1 << (self.0 as u32)) }
}
}

View File

@ -0,0 +1 @@
pub fn init() {}

View File

@ -0,0 +1,67 @@
use core::ptr;
// mod panic;
pub mod drivers;
pub mod init;
pub mod serial;
use crate::arch::drivers::nrf52::{Level, Pins};
use core::ptr::write_volatile;
global_asm!(include_str!("boot.s"));
fn delay(ticks: usize) {
static mut DUMMY: usize = 0;
// Reduce the number of iterations when in debug mode
#[cfg(debug_assertions)]
let ticks = ticks / 128;
for t in 0..ticks {
// Prevent the optimizer from removing this loop
unsafe {
write_volatile(&mut DUMMY, t);
}
}
}
use crate::print;
#[no_mangle]
pub extern "C" fn not_main() {
const UART0: *mut u8 = 0x0900_0000 as *mut u8;
for byte in b"ableOS Arm 64" {
unsafe {
ptr::write_volatile(UART0, *byte);
}
}
let gpios = Pins::take();
let mut led = gpios.p0_31;
loop {
led.set_high();
delay(2_000_000);
led.set_low();
delay(6_000_000);
}
led.set_push_pull_output(Level::Low);
crate::kmain::kernel_main();
sloop();
}
pub fn sloop() -> ! {
loop {}
}
pub fn print() {
for byte in b"ableOS Arm 64" {
const UART0: *mut u8 = 0x0900_0000 as *mut u8;
unsafe {
ptr::write_volatile(UART0, *byte);
}
}
}
pub fn shutdown() {}

View File

@ -0,0 +1,4 @@
cargo build --target=json_targets/aarch64-ableos.json --release &&\
qemu-system-aarch64 -machine virt -m 1024M -cpu cortex-a53 \
-kernel target/aarch64-ableos/release/ableos -serial stdio \
-device virtio-keyboard

View File

@ -0,0 +1,12 @@
#[macro_export]
macro_rules! serial_print {
($($arg:tt)*) => {};
}
/// Prints to the host through the serial interface, appending a newline.
#[macro_export]
macro_rules! serial_println {
() => {};
($fmt:expr) => {};
($fmt:expr, $($arg:tt)*) => {};
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
pub mod graphics;

View File

@ -0,0 +1,2 @@
use super::*;
pub fn init() {}

View File

@ -0,0 +1,47 @@
#![no_std]
#![no_main]
pub const ARCH: &'static str = "mipsr4000";
pub mod drivers;
static mut LIST: psp::Align16<[u32; 0x40000]> = psp::Align16([0; 0x40000]);
// Create a module named "sample_module" with version 1.0
psp::module!("ableos", 1, 0);
fn psp_main() {
// println!("AbleOS booted on PSP");
// todo
// println!("{}", crate::experiments::systeminfo::format_system_info());
// gl_basic();
println!("{}", crate::time::kilotime::Kilosecond::from_sec(23944));
let mut second = timer_update().seconds;
loop {
/*
{
let time = timer_update();
// FIXME: this is a little broken
if (second) == time.seconds {
if second == 59 {
second = 0;
}
// time
print!(
"{:?}/{:?}/{:?} {:02}:{:02}:{:02} UTC\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
time.year, time.month, time.day, time.hour, time.minutes, time.seconds
);
second += 1;
}
}
*/
}
}
pub fn shutdown() {}
mod simple_graphics;
use simple_graphics::gl_basic;
mod timer;
use crate::arch::timer::timer_update;
use core::ffi::c_void;
use psp::{
sys::{self, DisplayPixelFormat, GuState, TexturePixelFormat},
vram_alloc::get_vram_allocator,
{BUF_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH},
};
pub mod init;
use crate::println;

View File

@ -0,0 +1,27 @@
use crate::arch::*;
/// used as a very basic bare minimum gl example
pub fn gl_basic() {
unsafe {
let mut allocator = get_vram_allocator().unwrap();
let fbp0 = allocator
.alloc_texture_pixels(BUF_WIDTH, SCREEN_HEIGHT, TexturePixelFormat::Psm8888)
.as_mut_ptr_from_zero();
sys::sceGuInit();
sys::sceGuStart(
sys::GuContextType::Direct,
&mut LIST as *mut _ as *mut c_void,
);
sys::sceGuDrawBuffer(DisplayPixelFormat::Psm8888, fbp0 as _, BUF_WIDTH as i32);
sys::sceGuDebugPrint(
100,
100,
0xff0000ff,
b"hi there from ableOS PSP graphics\0" as *const u8,
);
sys::sceGuDebugFlush();
sys::sceGuFinish();
sys::sceGuSync(sys::GuSyncMode::Finish, sys::GuSyncBehavior::Wait);
sys::sceDisplayWaitVblankStart();
sys::sceGuDisplay(true);
}
}

View File

@ -0,0 +1,13 @@
pub fn timer_update() -> ScePspDateTime {
unsafe {
let mut tick = 0;
psp::sys::sceRtcGetCurrentTick(&mut tick);
// Convert the tick to an instance of `ScePspDateTime`
let mut date = MaybeUninit::uninit();
psp::sys::sceRtcSetTick(date.as_mut_ptr(), &tick);
let date = date.assume_init();
return date;
}
}
use core::mem::MaybeUninit;
use psp::sys::ScePspDateTime;

View File

@ -0,0 +1,58 @@
.S
# bootloader for SoS
# Stephen Marz
# 8 February 2019
.option norvc
.section .data
.section .text.init
.global _start
_start:
# Any hardware threads (hart) that are not bootstrapping
# need to wait for an IPI
csrr t0, mhartid
bnez t0, 3f
# SATP should be zero, but let's make sure
csrw satp, zero
.option push
.option norelax
la gp, _global_pointer
.option pop
# The BSS section is expected to be zero
la a0, _bss_start
la a1, _bss_end
bgeu a0, a1, 2f
1:
sd zero, (a0)
addi a0, a0, 8
bltu a0, a1, 1b
2:
3:
wfi
j 3b
# Control registers, set the stack, mstatus, mepc,
# and mtvec to return to the main function.
# li t5, 0xffff;
# csrw medeleg, t5
# csrw mideleg, t5
la sp, _stack
# We use mret here so that the mstatus register
# is properly updated.
li t0, (0b11 << 11) | (1 << 7) | (1 << 3)
csrw mstatus, t0
la t1, kernel_main
csrw mepc, t1
la t2, asm_trap_vector
csrw mtvec, t2
li t3, (1 << 3) | (1 << 7) | (1 << 11)
csrw mie, t3
la ra, 4f
mret
4:
wfi
j 4b

View File

@ -0,0 +1,8 @@
# trap.S
# Assembly-level trap handler.
.section .text
.global asm_trap_vector
asm_trap_vector:
# We get here when the CPU is interrupted
# for any reason.
mret

View File

@ -0,0 +1,2 @@
cargo bootimage --target json_targets/x86_64-ableos.json && \
qemu-system-x86_64 -S -gdb tcp::9000 -drive format=raw,file=target/x86_64-ableos/debug/bootimage-ableos.bin

View File

@ -0,0 +1,2 @@
cargo bootimage --target json_targets/x86_64-ableos.json && \
qemu-system-x86_64 -drive format=raw,file=target/x86_64-ableos/debug/bootimage-ableos.bin

View File

@ -0,0 +1,2 @@
cargo bootimage --target json_targets/x86_64-ableos.json && \
qemu-system-x86_64 -drive format=raw,file=target/x86_64-ableos/debug/bootimage-ableos.bin

View File

@ -0,0 +1,2 @@
cargo bootimage --release --target json_targets/x86_64-ableos.json && \
qemu-system-x86_64 -drive format=raw,file=target/x86_64-ableos/release/bootimage-ableos.bin

View File

@ -0,0 +1,35 @@
use crate::driver_traits::graphics::{Graphics, Point, Rgb};
use cpuio::outw;
pub struct GraphicsBuffer;
#[allow(unused)]
impl Graphics for GraphicsBuffer {
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb) {
todo!()
}
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb) {}
fn put_circle(coords: Point, radius: u32) {
todo!()
}
fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb) {
todo!();
}
fn put_pixel(coords: Point, color: Rgb) {
todo!()
}
fn paint_cursor(coords: Point) {
todo!()
}
fn hide_cursor() {
unsafe {
outw(0x0A, 0x3D4);
outw(0x20, 0x3D5);
}
}
fn show_cursor() {}
fn draw() {}
fn clear() {
todo!()
}
}

View File

@ -0,0 +1,5 @@
pub mod graphics;
pub mod serial;
#[deprecated(note = "The use of hardware specific drivers for VGA is discouraged")]
pub mod vga;

View File

@ -0,0 +1,33 @@
use lazy_static::lazy_static;
use spin::Mutex;
use uart_16550::SerialPort;
lazy_static! {
pub static ref SERIAL1: Mutex<SerialPort> = {
let mut serial_port = unsafe { SerialPort::new(0x3F8) };
serial_port.init();
Mutex::new(serial_port)
};
}
#[doc(hidden)]
pub fn _print(args: ::core::fmt::Arguments) {
use core::fmt::Write;
SERIAL1
.lock()
.write_fmt(args)
.expect("Printing to serial failed");
}
/// Prints to the host through the serial interface.
#[macro_export]
macro_rules! serial_print {
($($arg:tt)*) => {
$crate::arch::drivers::serial::_print(format_args!($($arg)*));
};
}
/// Prints to the host through the serial interface, appending a newline.
#[macro_export]
macro_rules! serial_println {
() => ($crate::serial_print!("\n"));
($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => ($crate::serial_print!(
concat!($fmt, "\n"), $($arg)*));
}

View File

@ -0,0 +1,133 @@
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Color {
Black = 0,
Blue = 1,
Green = 2,
Cyan = 3,
Red = 4,
Magenta = 5,
Brown = 6,
LightGray = 7,
DarkGray = 8,
LightBlue = 9,
LightGreen = 10,
LightCyan = 11,
LightRed = 12,
Pink = 13,
Yellow = 14,
White = 15,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
struct ColorCode(u8);
impl ColorCode {
fn new(foreground: Color, background: Color) -> ColorCode {
ColorCode((background as u8) << 4 | (foreground as u8))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(C)]
struct ScreenChar {
ascii_character: u8,
color_code: ColorCode,
}
const BUFFER_HEIGHT: usize = 25;
const BUFFER_WIDTH: usize = 80;
#[repr(transparent)]
struct Buffer {
chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
}
pub struct Writer {
column_position: usize,
color_code: ColorCode,
buffer: &'static mut Buffer,
}
impl Writer {
pub fn write_byte(&mut self, byte: u8) {
match byte {
b'\n' => self.new_line(),
byte => {
if self.column_position >= BUFFER_WIDTH {
self.new_line();
}
let row = BUFFER_HEIGHT - 1;
let col = self.column_position;
let color_code = self.color_code;
self.buffer.chars[row][col].write(ScreenChar {
ascii_character: byte,
color_code,
});
self.column_position += 1;
}
}
}
pub fn write_string(&mut self, s: &str) {
for byte in s.bytes() {
match byte {
// printable ASCII byte or newline
0x20..=0x7e | b'\n' => self.write_byte(byte),
// not part of printable ASCII range
_ => self.write_byte(0xfe),
}
}
}
fn new_line(&mut self) {
for row in 1..BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH {
let character = self.buffer.chars[row][col].read();
self.buffer.chars[row - 1][col].write(character);
}
}
self.clear_row(BUFFER_HEIGHT - 1);
self.column_position = 0;
}
fn clear_row(&mut self, row: usize) {
let blank = ScreenChar {
ascii_character: b' ',
color_code: self.color_code,
};
for col in 0..BUFFER_WIDTH {
self.buffer.chars[row][col].write(blank);
}
}
}
impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write_string(s);
Ok(())
}
}
lazy_static! {
pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer {
column_position: 0,
color_code: ColorCode::new(Color::Green, Color::Black),
buffer: unsafe { &mut *(0xb8000 as *mut Buffer) },
});
}
#[allow(dead_code)]
pub fn set_vga_color() {
WRITER.lock().color_code = ColorCode::new(Color::White, Color::Yellow);
}
use core::fmt;
use lazy_static::lazy_static;
use spin::Mutex;
use volatile::Volatile;
#[macro_export]
macro_rules! kprint {
($($arg:tt)*) => ($crate::arch::drivers::vga::_kprint(format_args!($($arg)*)));
}
#[macro_export]
macro_rules! kprintln {
() => ($crate::kprint!("\n"));
($($arg:tt)*) => ($crate::kprint!("{}\n", format_args!($($arg)*)));
}
#[doc(hidden)]
pub fn _kprint(args: fmt::Arguments) {
use core::fmt::Write;
use x86_64::instructions::interrupts;
interrupts::without_interrupts(|| {
WRITER.lock().write_fmt(args).unwrap();
});
}

View File

@ -0,0 +1,46 @@
use lazy_static::lazy_static;
use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector};
use x86_64::structures::tss::TaskStateSegment;
use x86_64::VirtAddr;
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
lazy_static! {
static ref TSS: TaskStateSegment = {
let mut tss = TaskStateSegment::new();
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
const STACK_SIZE: usize = 4096 * 5;
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
stack_start + STACK_SIZE
};
tss
};
}
struct Selectors {
code_selector: SegmentSelector,
tss_selector: SegmentSelector,
}
lazy_static! {
static ref GDT: (GlobalDescriptorTable, Selectors) = {
let mut gdt = GlobalDescriptorTable::new();
let code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS));
(
gdt,
Selectors {
code_selector,
tss_selector,
},
)
};
}
pub fn init() {
use x86_64::instructions::segmentation::{Segment, CS};
use x86_64::instructions::tables::load_tss;
GDT.0.load();
unsafe {
CS::set_reg(GDT.1.code_selector);
load_tss(GDT.1.tss_selector);
}
}

View File

@ -0,0 +1,11 @@
#![allow(clippy::print_literal)]
use super::{gdt, interrupts};
use crate::{println, serial_println};
pub fn init() {
gdt::init();
interrupts::init_idt();
unsafe { interrupts::PICS.lock().initialize() };
x86_64::instructions::interrupts::enable();
println!("Initialized");
serial_println!("Initialized");
}

View File

@ -0,0 +1,112 @@
use crate::{arch::gdt, print, println};
use lazy_static::lazy_static;
use pic8259::ChainedPics;
use spin;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
pub const PIC_1_OFFSET: u8 = 32;
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
pub static PICS: spin::Mutex<ChainedPics> =
spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
use crate::arch::sloop;
use x86_64::structures::idt::PageFaultErrorCode;
/// Interrupt offsets.
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum InterruptIndex {
Timer = PIC_1_OFFSET,
Keyboard,
}
impl InterruptIndex {
fn as_u8(self) -> u8 {
self as u8
}
fn as_usize(self) -> usize {
usize::from(self.as_u8())
}
}
pub fn init_idt() {
IDT.load();
}
lazy_static! {
static ref IDT: InterruptDescriptorTable = {
let mut idt = InterruptDescriptorTable::new();
idt.breakpoint.set_handler_fn(breakpoint_handler);
unsafe {
idt.double_fault.set_handler_fn(double_fault_handler)
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); // new
}
idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer_interrupt_handler);
idt[InterruptIndex::Keyboard.as_usize()] .set_handler_fn(keyboard_interrupt_handler);
idt
};
}
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
}
// new
extern "x86-interrupt" fn double_fault_handler(
stack_frame: InterruptStackFrame,
_error_code: u64,
) -> ! {
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
}
extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) {
crate::kmain::tick();
unsafe {
PICS.lock()
.notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
}
}
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
use crate::keyboard::{
CustomLayout, CustomScanCodeSet, DecodedKey, DecodedKeyKind, HandleControl, KeyCode,
Keyboard,
};
use spin::Mutex;
use x86_64::instructions::port::Port;
lazy_static! {
static ref KEYBOARD: Mutex<Keyboard<CustomLayout, CustomScanCodeSet>> =
Mutex::new(Keyboard::new(
CustomLayout::new_us104key(),
CustomScanCodeSet::default(),
HandleControl::Ignore
));
}
let mut keyboard = KEYBOARD.lock();
let mut port = Port::new(0x60);
let scancode: u8 = unsafe { port.read() };
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
if let Some(key) = keyboard.process_keyevent(key_event) {
match key {
DecodedKey {
kind: DecodedKeyKind::Unicode,
value: character,
} => {
print!("{}", char::try_from(character).unwrap());
// serial_print!("{}", character);
crate::kmain::key_entropy(character.try_into().unwrap());
}
DecodedKey {
kind: DecodedKeyKind::RawKey,
value: key,
} => print!("{:?}", KeyCode::from(key)),
}
}
}
unsafe {
PICS.lock()
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
}
}
extern "x86-interrupt" fn page_fault_handler(
stack_frame: InterruptStackFrame,
error_code: PageFaultErrorCode,
) {
use x86_64::registers::control::Cr2;
println!["Exception: Page Fault"];
println!["Address: {:?}", Cr2::read()];
println!["Error Code: {:?}", error_code];
println!["{:#?}", stack_frame];
sloop();
}

View File

@ -0,0 +1,27 @@
use x86_64::instructions::hlt;
pub mod drivers;
pub mod gdt;
pub mod init;
pub mod interrupts;
#[no_mangle]
pub extern "C" fn _start() -> ! {
crate::kmain::kernel_main();
sloop();
}
#[allow(unused)]
pub fn shutdown() -> ! {
sloop();
}
pub fn sloop() -> ! {
loop {
hlt();
}
}
#[cfg(test)]
pub fn test_runner(tests: &[&dyn Fn()]) {
for test in tests {
test();
}
}

View File

@ -0,0 +1,4 @@
pub trait Device {
fn probe();
fn reset();
}

View File

@ -0,0 +1,37 @@
#![allow(unused)]
pub enum GModes {
Vga800x600,
Custom(u16, u16),
}
pub type GCoord = usize;
pub struct Rgb {
pub r: u32,
pub g: u32,
pub b: u32,
}
impl Rgb {
fn to_vga_color() {
todo!();
}
}
pub type RefreshRate = u8;
pub const REFRESH_RATE: u8 = 60;
pub type Resolution = (usize, usize);
pub type Point = (GCoord, GCoord);
pub struct FrameBuffer;
// [[Rgb; 5]; 5]
pub trait Graphics {
fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb);
fn put_rect(coords_start: Point, coords_end: Point, color: Rgb);
fn put_circle(coords: Point, radius: u32);
fn put_pixel(coords: Point, color: Rgb);
fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb);
fn paint_cursor(coords: Point);
fn hide_cursor();
fn show_cursor();
/// Actually move the double buffer to the single buffer and "update" the screen
fn draw();
fn clear();
}

View File

@ -0,0 +1,2 @@
pub mod graphics;
pub mod serial;

View File

@ -0,0 +1,9 @@
pub enum PS2MouseButton {
LeftMB,
RightMB,
}
pub trait PS2Mouse {
fn movement();
fn button();
}

View File

@ -0,0 +1,4 @@
pub trait Serial {
fn print();
fn recieve();
}

View File

@ -0,0 +1 @@
Anything in experiments is heavily unstable and likely to change

View File

@ -0,0 +1,7 @@
##### #####
## ##### # ###### ## ## # #
# # # # # # # # #
# # ##### # ##### # # #####
###### # # # # # # #
# # # # # # ## ## # #
# # ##### ###### ###### ##### #####

View File

@ -0,0 +1,55 @@
use crate::alloc::vec;
use crate::String;
use crate::Vec;
use lazy_static::lazy_static;
#[derive(Debug)]
pub enum Mime {
None,
Text(String),
}
lazy_static! {
pub static ref CLIPBOARD: spin::Mutex<Clipboard> = {
let clipboard = Clipboard::new();
spin::Mutex::new(clipboard)
};
}
// ctrl+v paste but not pop and pastes
// ctrl+shift+v pops from the stack and pastes
// ctrl+c pushes to the stack
// ctrl+shift+< move stack pointer left
// ctrl+shift+> move stack pointer right
pub struct Clipboard {
pub index: usize,
pub pages: Vec<Mime>,
}
impl Clipboard {
pub fn new() -> Clipboard {
Clipboard {
index: 0,
pages: vec![],
}
}
pub fn clear(&mut self) {
self.pages = vec![];
}
pub fn set_index(&mut self, index_new: usize) {
self.index = index_new;
}
pub fn clip_end(&mut self) {
self.index = 0;
}
pub fn clip_home(&mut self) {
self.index = self.pages.len();
}
pub fn copy(&mut self, copy_mime: Mime) {
self.pages.push(copy_mime);
}
pub fn paste(&mut self) -> &Mime {
let paste_pos = &self.pages[self.index];
paste_pos
}
}

View File

@ -0,0 +1,22 @@
struct Permissions {
write_files: bool,
read_files: bool,
execute_files: bool,
// Every other user is part of global
global_write_files: bool,
global_read_files: bool,
global_execute_files: bool,
}
pub struct File {
owner: u8,
permissions: Permissions,
data: Vec<u8>,
}
pub struct Folder {
owner: u8,
permissions: Permissions,
folders: Vec<Folder>,
files: Vec<File>,
}

View File

@ -0,0 +1,15 @@
<user>/home/app1
<user>/conf/app1
<user>/apps/app1
file:app1
conf:app1
apps:app1
// Discouraged
raw:
/<user>/<protocol>/app1
protocol.toml
hi = ""

View File

@ -0,0 +1,34 @@
// Can be standardized
// NOTE: Move this to relib
pub struct SemanticVersion {
pub major: u8,
pub minor: u8,
pub patch: u8,
}
impl core::fmt::Display for SemanticVersion {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "v{}.{}.{}", self.major, self.minor, self.patch)
}
}
// NOTE: Move to somewhere else
lazy_static! {
pub static ref KINFO: KernelInfo = KernelInfo {
kernel_version: SemanticVersion {
major: 0,
minor: 0,
patch: 0,
},
memory: SystemMemory { used: 0, total: 0 }
};
}
/// simple info you would want to know in a neofetch like program
pub struct KernelInfo {
// os: String,
// host: String,
pub kernel_version: SemanticVersion,
// cpu: String,
// gpu: String,
pub memory: SystemMemory,
}
use super::systeminfo::SystemMemory;
use lazy_static::lazy_static;

View File

@ -0,0 +1,72 @@
#![allow(dead_code)]
use crate::serial_println;
pub struct MailBoxes {
flags: u8,
mailboxes: [u64; 4],
}
impl MailBoxes {
pub fn new() -> Self {
Self {
flags: 0b0000_0000,
mailboxes: [0; 4],
}
}
pub fn reset(&mut self) {
self.flags = 0b0000_0000;
self.mailboxes = [0; 4];
}
pub fn set_mailbox(&mut self, mailbox_num: u8, mailbox_data: u64) {
if let 0..=3 = mailbox_num {
self.mailboxes[mailbox_num as usize] = mailbox_data
}
}
pub fn set_flag(&mut self, flag_num: u8) {
match flag_num {
0 => {
self.flags |= 0b0000_0001;
}
1 => {
self.flags |= 0b0000_0010;
}
2 => {
self.flags |= 0b0000_0100;
}
3 => {
self.flags |= 0b0000_1000;
}
4 => {
self.flags |= 0b0001_0000;
}
5 => {
self.flags |= 0b0010_0000;
}
6 => {
self.flags |= 0b0100_0000;
}
7 => {
self.flags |= 0b1000_0000;
}
_ => {}
}
}
pub fn dump_flags(&self) {
serial_println!("Flag 0: {:08b}", self.flags & 0b0000_0001);
serial_println!("Flag 1: {:08b}", self.flags & 0b0000_0010);
serial_println!("Flag 2: {:08b}", self.flags & 0b0000_0100);
serial_println!("Flag 3: {:08b}", self.flags & 0b0000_1000);
serial_println!("Flag 4: {:08b}", self.flags & 0b0001_0000);
serial_println!("Flag 5: {:08b}", self.flags & 0b0010_0000);
serial_println!("Flag 6: {:08b}", self.flags & 0b0100_0000);
serial_println!("Flag 7: {:08b}", self.flags & 0b1000_0000);
serial_println!("Flag 0: {}", self.flags & 0b0000_0001);
serial_println!("Flag 1: {}", self.flags >> 1 & 0b0000_0001);
serial_println!("Flag 2: {}", self.flags >> 2 & 0b0000_0001);
serial_println!("Flag 3: {}", self.flags >> 3 & 0b0000_0001);
serial_println!("Flag 4: {}", self.flags >> 4 & 0b0000_0001);
serial_println!("Flag 5: {}", self.flags >> 5 & 0b0000_0001);
serial_println!("Flag 6: {}", self.flags >> 6 & 0b0000_0001);
serial_println!("Flag 7: {}", self.flags >> 7 & 0b0000_0001);
}
}

View File

@ -0,0 +1,10 @@
#![allow(dead_code)]
pub mod server;
pub mod systeminfo;
pub mod virtual_memory;
// pub mod wm;
// added for experimental use
pub mod kinfo;
pub mod mail;
pub const BANNER: &str = include_str!("banner.txt");

View File

@ -0,0 +1,44 @@
pub type PackageName = String;
use crate::experiments::kinfo::SemanticVersion;
// Scuffed
pub type Hash = u8;
pub struct MetaPackage {
pub name: u8,
pub version: SemanticVersion,
pub authors: [u8; 8],
pub support_email: u8,
pub hash: Hash,
}
impl MetaPackage {
pub fn new() -> Self {
Self {
name: 0,
version: SemanticVersion {
major: 0,
minor: 0,
patch: 0,
},
authors: [0; 8],
support_email: 8,
hash: 0,
}
}
fn validate_hash(&self) {}
}
impl core::fmt::Display {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(
f,
"Packname: {}
Version: {}
Authors: {:?}
Support Email: {}
Hash: {}",
self.name, self.version, self.authors, self.support_email, self.hash
)
}
}

View File

@ -0,0 +1,24 @@
pub type Priority = [Process; 512];
pub struct VirtualMemoryTable {}
struct Process {
id: u64,
mem_table: *mut VirtualMemoryTable, // Pointer to a memory table
}
pub struct Scheduler {
pub high_priority: Priority, //150
pub medium_priority: Priority, //100
pub low_priority: Priority, // 50
pub next_pid: u64,
}
impl Scheduler {
pub fn bump_up() {}
pub fn bump_down() {}
pub fn schedule(&mut self) {
let current_pid = self.next_pid;
self.next_pid += 1;
}
}

View File

@ -0,0 +1,10 @@
pub trait Server {
/// Initialize the server and return a number
fn initialize() -> u32;
/// kill the server
fn kill() -> bool;
// put data in the servers outbox
fn send();
// put data in the servers inbox and notify it
fn recieve();
}

View File

@ -0,0 +1,39 @@
| low \\ high | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
| ----------- | ------------------- | ------------------------ | ------------------------------------------------------------------------------------------ | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
| 0 | **kill** | <sub>reserved</sub> | **sleep** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 1 | **stdout_reset** | <sub>reserved</sub> | **sleep_until** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 2 | **stdin** | <sub>reserved</sub> | [**nanosleep**](https://www.reddit.com/r/anime/comments/e7sg7g/nichijou_trouble_sleeping/) | **aes_encrypt** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 3 | **stdout** | <sub>reserved</sub> | **nanosleep_until** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 4 | **stdin_get_title** | <sub>reserved</sub> | **get_time** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 5 | **stdin_set_title** | <sub>reserved</sub> | **set_time** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 6 | **get_pid** | **make_directory** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 7 | **pinfo** | **delete_directory** | **socket_bind** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 8 | <sub>reserved</sub> | **rename_directory** | **socket_connect** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 9 | <sub>reserved</sub> | **set_directory_access** | **socket_disconnect** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| A | **set_priority** | **make_file** | **socket_send** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| B | **get_priority** | **delete_file** | **socket_receive** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| C | **get_hostname** | **rename_file** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| D | **set_hostname** | **set_file_access** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| E | <sub>reserved</sub> | **file_read** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| F | <sub>reserved</sub> | **file_write** | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| low \\ high | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A | 1B | 1C | 1D | 1E | 1F |
| ----------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
| 0 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 1 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 2 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 3 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 4 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 5 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 6 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 7 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 8 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| 9 | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| A | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| B | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| C | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| D | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| E | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |
| F | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> | <sub>reserved</sub> |

View File

@ -0,0 +1,33 @@
// Can be standardized
// NOTE: move the file to the src/ dir
pub struct SystemMemory {
pub used: u64,
pub total: u64,
}
impl core::fmt::Display for SystemMemory {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "{} Bytes / {} Bytes", self.used, self.total)
}
}
/*
pub fn format_system_info() -> core::string::String {
let x = format!(
"{}
OS: AbleOS
Host: ComputAble
Kernel: {}
Uptime: 0:0:0
Packages: 0
Shell: Ashell
Gpu: MIPS32 R4000 R4k
Cpu: {}
Memory: {}
",
crate::experiments::BANNER,
crate::experiments::kinfo::KINFO.kernel_version,
crate::arch::ARCH,
crate::experiments::kinfo::KINFO.memory
);
return x;
}
*/

View File

@ -0,0 +1,4 @@
pub struct User {
id: u8,
clipboard: Clipboard,
}

View File

@ -0,0 +1,7 @@
#![allow(dead_code)]
pub struct Scheduler {
executables: usize,
}
pub struct RunQueue {}

View File

@ -0,0 +1,23 @@
//! used to give a base line example of windows and window handling
use crate::driver_traits::graphics::Point;
pub struct Window {
// title: String,
position: Point,
fullscreen: bool,
}
// all of these should return a result
impl Window {
pub fn fullscreen(&mut self) -> Result<(), u8> {
self.fullscreen = true;
Ok(())
}
pub fn revert_fullscreen(&mut self) {
self.fullscreen = false;
}
pub fn set_title(&mut self) {
todo!();
}
pub fn set_position(&mut self, pos: Point) {
self.position = pos;
}
}

View File

@ -0,0 +1,623 @@
#![allow(clippy::too_many_arguments)]
use super::*;
pub struct CustomScanCodeSet {
single_byte: [Option<KeyCode>; 256],
extended: [Option<KeyCode>; 256],
}
impl Default for CustomScanCodeSet {
fn default() -> Self {
Self::scancode_set1()
}
}
impl CustomScanCodeSet {
pub fn scancode_set1() -> Self {
let mut scancode_set = Self {
single_byte: [None; 256],
extended: [None; 256],
};
scancode_set.single_byte[0x01] = Some(KeyCode::Escape); // 01
scancode_set.single_byte[0x02] = Some(KeyCode::Key1); // 02
scancode_set.single_byte[0x03] = Some(KeyCode::Key2); // 03
scancode_set.single_byte[0x04] = Some(KeyCode::Key3); // 04
scancode_set.single_byte[0x05] = Some(KeyCode::Key4); // 05
scancode_set.single_byte[0x06] = Some(KeyCode::Key5); // 06
scancode_set.single_byte[0x07] = Some(KeyCode::Key6); // 07
scancode_set.single_byte[0x08] = Some(KeyCode::Key7); // 08
scancode_set.single_byte[0x09] = Some(KeyCode::Key8); // 09
scancode_set.single_byte[0x0A] = Some(KeyCode::Key9); // 0A
scancode_set.single_byte[0x0B] = Some(KeyCode::Key0); // 0B
scancode_set.single_byte[0x0C] = Some(KeyCode::Minus); // 0C
scancode_set.single_byte[0x0D] = Some(KeyCode::Equals); // 0D
scancode_set.single_byte[0x0E] = Some(KeyCode::Backspace); // 0E
scancode_set.single_byte[0x0F] = Some(KeyCode::Tab); // 0F
scancode_set.single_byte[0x10] = Some(KeyCode::Q); // 10
scancode_set.single_byte[0x11] = Some(KeyCode::W); // 11
scancode_set.single_byte[0x12] = Some(KeyCode::E); // 12
scancode_set.single_byte[0x13] = Some(KeyCode::R); // 13
scancode_set.single_byte[0x14] = Some(KeyCode::T); // 14
scancode_set.single_byte[0x15] = Some(KeyCode::Y); // 15
scancode_set.single_byte[0x16] = Some(KeyCode::U); // 16
scancode_set.single_byte[0x17] = Some(KeyCode::I); // 17
scancode_set.single_byte[0x18] = Some(KeyCode::O); // 18
scancode_set.single_byte[0x19] = Some(KeyCode::P); // 19
scancode_set.single_byte[0x1A] = Some(KeyCode::BracketSquareLeft); // 1A
scancode_set.single_byte[0x1B] = Some(KeyCode::BracketSquareRight); // 1B
scancode_set.single_byte[0x1C] = Some(KeyCode::Enter); // 1C
scancode_set.single_byte[0x1D] = Some(KeyCode::ControlLeft); // 1D
scancode_set.single_byte[0x1E] = Some(KeyCode::A); // 1E
scancode_set.single_byte[0x1F] = Some(KeyCode::S); // 1F
scancode_set.single_byte[0x20] = Some(KeyCode::D); // 20
scancode_set.single_byte[0x21] = Some(KeyCode::F); // 21
scancode_set.single_byte[0x22] = Some(KeyCode::G); // 22
scancode_set.single_byte[0x23] = Some(KeyCode::H); // 23
scancode_set.single_byte[0x24] = Some(KeyCode::J); // 24
scancode_set.single_byte[0x25] = Some(KeyCode::K); // 25
scancode_set.single_byte[0x26] = Some(KeyCode::L); // 26
scancode_set.single_byte[0x27] = Some(KeyCode::SemiColon); // 27
scancode_set.single_byte[0x28] = Some(KeyCode::Quote); // 28
scancode_set.single_byte[0x29] = Some(KeyCode::BackTick); // 29
scancode_set.single_byte[0x2A] = Some(KeyCode::ShiftLeft); // 2A
scancode_set.single_byte[0x2B] = Some(KeyCode::BackSlash); // 2B
scancode_set.single_byte[0x2C] = Some(KeyCode::Z); // 2C
scancode_set.single_byte[0x2D] = Some(KeyCode::X); // 2D
scancode_set.single_byte[0x2E] = Some(KeyCode::C); // 2E
scancode_set.single_byte[0x2F] = Some(KeyCode::V); // 2F
scancode_set.single_byte[0x30] = Some(KeyCode::B); // 30
scancode_set.single_byte[0x31] = Some(KeyCode::N); // 31
scancode_set.single_byte[0x32] = Some(KeyCode::M); // 32
scancode_set.single_byte[0x33] = Some(KeyCode::Comma); // 33
scancode_set.single_byte[0x34] = Some(KeyCode::Fullstop); // 34
scancode_set.single_byte[0x35] = Some(KeyCode::Slash); // 35
scancode_set.single_byte[0x36] = Some(KeyCode::ShiftRight); // 36
scancode_set.single_byte[0x37] = Some(KeyCode::NumpadStar); // 37
scancode_set.single_byte[0x38] = Some(KeyCode::AltLeft); // 38
scancode_set.single_byte[0x39] = Some(KeyCode::Spacebar); // 39
scancode_set.single_byte[0x3A] = Some(KeyCode::CapsLock); // 3A
scancode_set.single_byte[0x3B] = Some(KeyCode::F1); // 3B
scancode_set.single_byte[0x3C] = Some(KeyCode::F2); // 3C
scancode_set.single_byte[0x3D] = Some(KeyCode::F3); // 3D
scancode_set.single_byte[0x3E] = Some(KeyCode::F4); // 3E
scancode_set.single_byte[0x3F] = Some(KeyCode::F5); // 3F
scancode_set.single_byte[0x40] = Some(KeyCode::F6); // 40
scancode_set.single_byte[0x41] = Some(KeyCode::F7); // 41
scancode_set.single_byte[0x42] = Some(KeyCode::F8); // 42
scancode_set.single_byte[0x43] = Some(KeyCode::F9); // 43
scancode_set.single_byte[0x44] = Some(KeyCode::F10); // 44
scancode_set.single_byte[0x45] = Some(KeyCode::NumpadLock); // 45
scancode_set.single_byte[0x46] = Some(KeyCode::ScrollLock); // 46
scancode_set.single_byte[0x47] = Some(KeyCode::Numpad7); // 47
scancode_set.single_byte[0x48] = Some(KeyCode::Numpad8); // 48
scancode_set.single_byte[0x49] = Some(KeyCode::Numpad9); // 49
scancode_set.single_byte[0x4A] = Some(KeyCode::NumpadMinus); // 4A
scancode_set.single_byte[0x4B] = Some(KeyCode::Numpad4); // 4B
scancode_set.single_byte[0x4C] = Some(KeyCode::Numpad5); // 4C
scancode_set.single_byte[0x4D] = Some(KeyCode::Numpad6); // 4D
scancode_set.single_byte[0x4E] = Some(KeyCode::NumpadPlus); // 4E
scancode_set.single_byte[0x4F] = Some(KeyCode::Numpad1); // 4F
scancode_set.single_byte[0x50] = Some(KeyCode::Numpad2); // 50
scancode_set.single_byte[0x51] = Some(KeyCode::Numpad3); // 51
scancode_set.single_byte[0x52] = Some(KeyCode::Numpad0); // 52
scancode_set.single_byte[0x53] = Some(KeyCode::NumpadPeriod); // 53
// 0x54
// 0x55
// 0x56
scancode_set.single_byte[0x57] = Some(KeyCode::F11); // 57
scancode_set.single_byte[0x58] = Some(KeyCode::F12); // 58
for i in 0x81..=0xD8 {
scancode_set.single_byte[i] = scancode_set.single_byte[i - 0x80];
}
scancode_set.extended[0x10] = Some(KeyCode::PrevTrack); // E010
//0x11
//0x12
//0x13
//0x14
//0x15
//0x16
//0x17
//0x18
scancode_set.extended[0x19] = Some(KeyCode::NextTrack); // E019
//0x1A
//0x1B
scancode_set.extended[0x1C] = Some(KeyCode::NumpadEnter); // E01C
scancode_set.extended[0x1D] = Some(KeyCode::ControlRight); // E01D
//0x1E
//0x1F
scancode_set.extended[0x20] = Some(KeyCode::Mute); // E020
scancode_set.extended[0x21] = Some(KeyCode::Calculator); // E021
scancode_set.extended[0x22] = Some(KeyCode::Play); // E022
//0x23
scancode_set.extended[0x24] = Some(KeyCode::Stop); // E024
//0x25
//0x26
//0x27
//0x28
//0x29
//0x2A
//0x2B
//0x2C
//0x2D
scancode_set.extended[0x2E] = Some(KeyCode::VolumeDown); // E02E
//0x2F
scancode_set.extended[0x30] = Some(KeyCode::VolumeUp); // E030
//0x31
scancode_set.extended[0x32] = Some(KeyCode::WWWHome); // E032
//0x33
//0x34
scancode_set.extended[0x35] = Some(KeyCode::NumpadSlash); // E035
//0x36
//0x37
scancode_set.extended[0x38] = Some(KeyCode::AltRight); // E038
//0x39
//0x3A
//0x3B
//0x3C
//0x3D
//0x3E
//0x3F
//0x40
//0x41
//0x42
//0x43
//0x44
//0x45
//0x46
scancode_set.extended[0x47] = Some(KeyCode::Home); // E047
scancode_set.extended[0x48] = Some(KeyCode::ArrowUp); // E048
scancode_set.extended[0x49] = Some(KeyCode::PageUp); // E049
//0x4A
scancode_set.extended[0x4B] = Some(KeyCode::ArrowLeft); // E04B
//0x4C
scancode_set.extended[0x4D] = Some(KeyCode::ArrowRight); // E04D
//0x4E
scancode_set.extended[0x4F] = Some(KeyCode::End); // E04F
scancode_set.extended[0x50] = Some(KeyCode::ArrowDown); // E050
scancode_set.extended[0x51] = Some(KeyCode::PageDown); // E051
scancode_set.extended[0x52] = Some(KeyCode::Insert); // E052
scancode_set.extended[0x53] = Some(KeyCode::Delete); // E053
for i in 0x90..=0xED {
scancode_set.extended[i] = scancode_set.extended[i - 0x80];
}
scancode_set
}
pub fn scancode_set2() -> Self {
Self {
single_byte: [None; 256],
extended: [None; 256],
}
}
}
impl ScancodeSet for CustomScanCodeSet {
fn advance_state(&self, state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error> {
match *state {
DecodeState::Start => {
match code {
EXTENDED_KEY_CODE => {
*state = DecodeState::Extended;
Ok(None)
}
0x80..=0xFF => {
// Release codes
Ok(Some(KeyEvent::new(
self.map_scancode(code - 0x80)?,
KeyState::Up,
)))
}
_ => {
// Normal codes
Ok(Some(KeyEvent::new(
self.map_scancode(code)?,
KeyState::Down,
)))
}
}
}
DecodeState::Extended => {
*state = DecodeState::Start;
match code {
0x80..=0xFF => {
// Extended Release codes
Ok(Some(KeyEvent::new(
self.map_extended_scancode(code - 0x80)?,
KeyState::Up,
)))
}
_ => {
// Normal release codes
Ok(Some(KeyEvent::new(
self.map_extended_scancode(code)?,
KeyState::Down,
)))
}
}
}
_ => {
// Can't get in to this state
unimplemented!();
}
}
}
fn map_scancode(&self, code: u8) -> Result<KeyCode, Error> {
if let Some(kc) = self.single_byte[code as usize] {
Ok(kc)
} else {
Err(Error::UnknownKeyCode)
}
}
fn map_extended_scancode(&self, code: u8) -> Result<KeyCode, Error> {
if let Some(kc) = self.extended[code as usize] {
Ok(kc)
} else {
Err(Error::UnknownKeyCode)
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum LayoutEntry {
Regular {
unshifted: Option<DecodedKey>,
shifted: Option<DecodedKey>,
altgr: Option<DecodedKey>,
raw_unicode: Option<DecodedKey>,
},
Numlockable {
unshifted: Option<DecodedKey>,
shifted: Option<DecodedKey>,
locked: Option<DecodedKey>,
locked_shifted: Option<DecodedKey>,
},
Capslockable {
unshifted: Option<DecodedKey>,
shifted: Option<DecodedKey>,
locked: Option<DecodedKey>,
locked_shifted: Option<DecodedKey>,
altgr: Option<DecodedKey>,
raw_unicode: Option<DecodedKey>,
},
}
// Do not edit this file directly. Instead, create a `Keyboard` and modify that.
pub struct CustomLayout {
mapping: [LayoutEntry; 256],
}
impl Default for CustomLayout {
fn default() -> Self {
Self::new_us104key()
}
}
impl CustomLayout {
#[rustfmt::skip]
pub fn new_us104key() -> Self {
let mut mapping = Self {
mapping: [LayoutEntry::Regular { unshifted: None, shifted: None, altgr: None, raw_unicode: None }; 256],
};
mapping.set_ab_c(KeyCode::BackTick, Some('`'.into()), Some('~'.into()), None);
mapping.set_aa_a(KeyCode::Escape, Some('\x1B'.into()));
mapping.set_ab_n(KeyCode::Key0, Some('0'.into()), Some(')'.into()));
mapping.set_ab_n(KeyCode::Key1, Some('1'.into()), Some('!'.into()));
mapping.set_ab_n(KeyCode::Key2, Some('2'.into()), Some('@'.into()));
mapping.set_ab_n(KeyCode::Key3, Some('3'.into()), Some('#'.into()));
mapping.set_ab_n(KeyCode::Key4, Some('4'.into()), Some('$'.into()));
mapping.set_ab_n(KeyCode::Key5, Some('5'.into()), Some('%'.into()));
mapping.set_ab_n(KeyCode::Key6, Some('6'.into()), Some('^'.into()));
mapping.set_ab_n(KeyCode::Key7, Some('7'.into()), Some('&'.into()));
mapping.set_ab_n(KeyCode::Key8, Some('8'.into()), Some('*'.into()));
mapping.set_ab_n(KeyCode::Key9, Some('9'.into()), Some('('.into()));
mapping.set_ab_n(KeyCode::Minus, Some('-'.into()), Some('_'.into()));
mapping.set_ab_n(KeyCode::Equals, Some('='.into()), Some('+'.into()));
mapping.set_aa_a(KeyCode::Backspace,Some('\x08'.into()));
mapping.set_aa_a(KeyCode::Tab,Some('\x09'.into()));
mapping.set_abcd_e_letter(KeyCode::Q, Some('q'.into()), Some('Q'.into()), Some('Q'.into()),Some('q'.into()), Some('\u{0011}'.into()));
mapping.set_abcd_e_letter(KeyCode::W, Some('w'.into()), Some('W'.into()), Some('W'.into()),Some('w'.into()), Some('\u{0017}'.into()));
mapping.set_abcd_e_letter(KeyCode::E, Some('e'.into()), Some('E'.into()), Some('E'.into()),Some('e'.into()), Some('\u{0005}'.into()));
mapping.set_abcd_e_letter(KeyCode::R, Some('r'.into()), Some('R'.into()), Some('R'.into()),Some('r'.into()), Some('\u{0012}'.into()));
mapping.set_abcd_e_letter(KeyCode::T, Some('t'.into()), Some('T'.into()), Some('T'.into()),Some('t'.into()), Some('\u{0014}'.into()));
mapping.set_abcd_e_letter(KeyCode::Y, Some('y'.into()), Some('Y'.into()), Some('Y'.into()),Some('y'.into()), Some('\u{0019}'.into()));
mapping.set_abcd_e_letter(KeyCode::U, Some('u'.into()), Some('U'.into()), Some('U'.into()),Some('u'.into()), Some('\u{0015}'.into()));
mapping.set_abcd_e_letter(KeyCode::I, Some('i'.into()), Some('I'.into()), Some('I'.into()),Some('i'.into()), Some('\u{0009}'.into()));
mapping.set_abcd_e_letter(KeyCode::O, Some('o'.into()), Some('O'.into()), Some('O'.into()),Some('o'.into()), Some('\u{000F}'.into()));
mapping.set_abcd_e_letter(KeyCode::P, Some('p'.into()), Some('P'.into()), Some('P'.into()),Some('p'.into()), Some('\u{0010}'.into()));
mapping.set_abcd_e_letter(KeyCode::A, Some('a'.into()), Some('A'.into()), Some('A'.into()),Some('a'.into()), Some('\u{0001}'.into()));
mapping.set_abcd_e_letter(KeyCode::S, Some('s'.into()), Some('S'.into()), Some('S'.into()),Some('s'.into()), Some('\u{0013}'.into()));
mapping.set_abcd_e_letter(KeyCode::D, Some('d'.into()), Some('D'.into()), Some('D'.into()),Some('d'.into()), Some('\u{0004}'.into()));
mapping.set_abcd_e_letter(KeyCode::F, Some('f'.into()), Some('F'.into()), Some('F'.into()),Some('f'.into()), Some('\u{0006}'.into()));
mapping.set_abcd_e_letter(KeyCode::G, Some('g'.into()), Some('G'.into()), Some('G'.into()),Some('g'.into()), Some('\u{0007}'.into()));
mapping.set_abcd_e_letter(KeyCode::H, Some('h'.into()), Some('H'.into()), Some('H'.into()),Some('h'.into()), Some('\u{0008}'.into()));
mapping.set_abcd_e_letter(KeyCode::J, Some('j'.into()), Some('J'.into()), Some('J'.into()),Some('j'.into()), Some('\u{000A}'.into()));
mapping.set_abcd_e_letter(KeyCode::K, Some('k'.into()), Some('K'.into()), Some('K'.into()),Some('k'.into()), Some('\u{000B}'.into()));
mapping.set_abcd_e_letter(KeyCode::L, Some('l'.into()), Some('L'.into()), Some('L'.into()),Some('l'.into()), Some('\u{000C}'.into()));
mapping.set_abcd_e_letter(KeyCode::Z, Some('z'.into()), Some('Z'.into()), Some('Z'.into()),Some('z'.into()), Some('\u{001A}'.into()));
mapping.set_abcd_e_letter(KeyCode::X, Some('x'.into()), Some('X'.into()), Some('X'.into()),Some('x'.into()), Some('\u{0018}'.into()));
mapping.set_abcd_e_letter(KeyCode::C, Some('c'.into()), Some('C'.into()), Some('C'.into()),Some('c'.into()), Some('\u{0003}'.into()));
mapping.set_abcd_e_letter(KeyCode::V, Some('v'.into()), Some('V'.into()), Some('V'.into()),Some('v'.into()), Some('\u{0016}'.into()));
mapping.set_abcd_e_letter(KeyCode::B, Some('b'.into()), Some('B'.into()), Some('B'.into()),Some('b'.into()), Some('\u{0002}'.into()));
mapping.set_abcd_e_letter(KeyCode::N, Some('n'.into()), Some('N'.into()), Some('N'.into()),Some('n'.into()), Some('\u{000E}'.into()));
mapping.set_abcd_e_letter(KeyCode::M, Some('m'.into()), Some('M'.into()), Some('M'.into()),Some('m'.into()), Some('\u{000D}'.into()));
mapping.set_ab_n(KeyCode::BracketSquareLeft, Some('{'.into()), Some('['.into()));
mapping.set_ab_n(KeyCode::BracketSquareRight, Some('}'.into()), Some(']'.into()));
mapping.set_ab_n(KeyCode::BackSlash, Some('|'.into()), Some('\\'.into()));
mapping.set_ab_n(KeyCode::SemiColon, Some(';'.into()), Some(':'.into()));
mapping.set_ab_n(KeyCode::Quote, Some('\''.into()), Some('"'.into()));
mapping.set_aa_a(KeyCode::Enter,Some('\x0A'.into()));
mapping.set_ab_n(KeyCode::Comma, Some(','.into()), Some('<'.into()));
mapping.set_ab_n(KeyCode::Fullstop, Some('.'.into()), Some('>'.into()));
mapping.set_ab_n(KeyCode::Slash, Some('/'.into()), Some('?'.into()));
mapping.set_aa_a(KeyCode::Spacebar,Some(' '.into()));
mapping.set_aa_a(KeyCode::Delete,Some('\x7F'.into()));
mapping.set_aaaa_num(KeyCode::NumpadSlash, Some('/'.into()), );
mapping.set_aaaa_num(KeyCode::NumpadStar, Some('*'.into()), );
mapping.set_aaaa_num(KeyCode::NumpadMinus, Some('-'.into()), );
mapping.set_abba_num(KeyCode::Numpad7, Some('7'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::Home as u32 }));
mapping.set_abba_num(KeyCode::Numpad8, Some('8'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::ArrowUp as u32 }));
mapping.set_abba_num(KeyCode::Numpad9, Some('9'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::PageUp as u32 }));
mapping.set_aaaa_num(KeyCode::NumpadPlus, Some('+'.into()));
mapping.set_abba_num(KeyCode::Numpad4, Some('4'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::ArrowLeft as u32 }));
mapping.set_aaaa_num(KeyCode::Numpad5, Some('5'.into()));
mapping.set_abba_num(KeyCode::Numpad6, Some('6'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::ArrowRight as u32 }));
mapping.set_abba_num(KeyCode::Numpad1, Some('1'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::End as u32 }));
mapping.set_abba_num(KeyCode::Numpad2, Some('2'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::ArrowDown as u32 }));
mapping.set_abba_num(KeyCode::Numpad3, Some('3'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::PageDown as u32 }));
mapping.set_abba_num(KeyCode::Numpad0, Some('0'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::Insert as u32 }));
mapping.set_abba_num(KeyCode::NumpadPeriod, Some('.'.into()), Some('\x7F'.into()));
mapping.set_aaaa_num(KeyCode::NumpadEnter, Some('\x0A'.into()));
mapping
}
#[rustfmt::skip]
pub fn new_us105key() -> Self {
let mut mapping = Self::new_us104key();
mapping.set_abcde(KeyCode::BackTick, Some('`'.into()), Some('¬'.into()), Some('|'.into()), None);
mapping.set_ab_n(KeyCode::Key2, Some('2'.into()), Some('"'.into()));
mapping.set_ab_n(KeyCode::Quote, Some('\''.into()), Some('@'.into()));
mapping.set_ab_n(KeyCode::Key3, Some('3'.into()), Some('£'.into()));
mapping.set_abcde(KeyCode::BackTick, Some('4'.into()), Some('$'.into()), Some('€'.into()), None);
mapping.set_ab_n(KeyCode::HashTilde, Some('#'.into()), Some('~'.into()));
mapping
}
}
impl KeyboardLayout for CustomLayout {
fn map_keycode(
&self,
keycode: KeyCode,
modifiers: &Modifiers,
handle_ctrl: HandleControl,
) -> DecodedKey {
let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode;
let spot = &self.mapping[keycode as usize];
if let Some(k) = if map_to_unicode && modifiers.is_ctrl() {
match spot {
LayoutEntry::Regular {
unshifted: _,
shifted: _,
altgr: _,
raw_unicode,
} => raw_unicode,
LayoutEntry::Numlockable {
unshifted: _,
shifted: _,
locked: _,
locked_shifted: _,
} => &None,
LayoutEntry::Capslockable {
unshifted: _,
shifted: _,
locked: _,
locked_shifted: _,
raw_unicode,
altgr: _,
} => raw_unicode,
}
} else if modifiers.alt_gr {
match spot {
LayoutEntry::Regular {
unshifted: _,
shifted: _,
altgr,
raw_unicode: _,
} => altgr,
LayoutEntry::Numlockable {
unshifted: _,
shifted: _,
locked: _,
locked_shifted: _,
} => &None,
LayoutEntry::Capslockable {
unshifted: _,
shifted: _,
locked: _,
locked_shifted: _,
raw_unicode: _,
altgr,
} => altgr,
}
} else if modifiers.is_shifted() {
match spot {
LayoutEntry::Regular {
unshifted: _,
shifted,
altgr: _,
raw_unicode: _,
} => shifted,
LayoutEntry::Numlockable {
unshifted: _,
shifted,
locked: _,
locked_shifted,
} => {
if modifiers.numlock {
locked_shifted
} else {
shifted
}
}
LayoutEntry::Capslockable {
unshifted: _,
shifted,
locked: _,
locked_shifted,
raw_unicode: _,
altgr: _,
} => {
if modifiers.is_caps() {
locked_shifted
} else {
shifted
}
}
}
} else {
match spot {
LayoutEntry::Regular {
unshifted,
shifted: _,
altgr: _,
raw_unicode: _,
} => unshifted,
LayoutEntry::Numlockable {
unshifted,
shifted: _,
locked,
locked_shifted: _,
} => {
if modifiers.numlock {
locked
} else {
unshifted
}
}
LayoutEntry::Capslockable {
unshifted,
shifted: _,
locked,
locked_shifted: _,
raw_unicode: _,
altgr: _,
} => {
if modifiers.is_caps() {
locked
} else {
unshifted
}
}
}
} {
*k
} else {
DecodedKey::RawKey(keycode as u8)
}
}
}
// Note(elfein) Not super hard to get right, but still- DO NOT TOUCH
impl CustomLayout {
pub fn set_abcde(
&mut self,
index: KeyCode,
a: Option<DecodedKey>,
b: Option<DecodedKey>,
c: Option<DecodedKey>,
d: Option<DecodedKey>,
) {
self.mapping[index as usize] = {
LayoutEntry::Regular {
unshifted: a,
shifted: b,
altgr: c,
raw_unicode: d,
}
};
}
pub fn set_ab_c(
&mut self,
index: KeyCode,
a: Option<DecodedKey>,
b: Option<DecodedKey>,
c: Option<DecodedKey>,
) {
self.mapping[index as usize] = {
LayoutEntry::Regular {
unshifted: a,
shifted: b,
altgr: None,
raw_unicode: c,
}
};
}
pub fn set_ab_n(&mut self, index: KeyCode, a: Option<DecodedKey>, b: Option<DecodedKey>) {
self.mapping[index as usize] = {
LayoutEntry::Regular {
unshifted: a,
shifted: b,
altgr: None,
raw_unicode: None,
}
};
}
pub fn set_aa_a(&mut self, index: KeyCode, a: Option<DecodedKey>) {
self.mapping[index as usize] = {
LayoutEntry::Regular {
unshifted: a,
shifted: a,
altgr: None,
raw_unicode: a,
}
};
}
pub fn set_abcdef_letter(
&mut self,
index: KeyCode,
a: Option<DecodedKey>,
b: Option<DecodedKey>,
c: Option<DecodedKey>,
d: Option<DecodedKey>,
e: Option<DecodedKey>,
f: Option<DecodedKey>,
) {
self.mapping[index as usize] = {
LayoutEntry::Capslockable {
unshifted: a,
shifted: b,
altgr: c,
locked: d,
locked_shifted: e,
raw_unicode: f,
}
};
}
pub fn set_abcd_e_letter(
&mut self,
index: KeyCode,
a: Option<DecodedKey>,
b: Option<DecodedKey>,
c: Option<DecodedKey>,
d: Option<DecodedKey>,
e: Option<DecodedKey>,
) {
self.mapping[index as usize] = {
LayoutEntry::Capslockable {
unshifted: a,
shifted: b,
locked: c,
locked_shifted: d,
altgr: None,
raw_unicode: e,
}
};
}
pub fn set_aaaa_num(&mut self, index: KeyCode, a: Option<DecodedKey>) {
self.mapping[index as usize] = {
LayoutEntry::Numlockable {
unshifted: a,
shifted: a,
locked: a,
locked_shifted: a,
}
};
}
pub fn set_abba_num(&mut self, index: KeyCode, a: Option<DecodedKey>, b: Option<DecodedKey>) {
self.mapping[index as usize] = {
LayoutEntry::Numlockable {
unshifted: a,
shifted: b,
locked: b,
locked_shifted: a,
}
};
}
}

273
ableos/src/keyboard/mod.rs Normal file
View File

@ -0,0 +1,273 @@
#![allow(dead_code)]
mod abstractions;
mod small_types;
mod traits;
pub use abstractions::*;
pub use small_types::*;
pub use traits::*;
const KEYCODE_BITS: u8 = 11;
const EXTENDED_KEY_CODE: u8 = 0xE0;
const KEY_RELEASE_CODE: u8 = 0xF0;
#[derive(Debug)]
pub struct Keyboard<T, S>
where
T: KeyboardLayout,
S: ScancodeSet,
{
register: u16,
num_bits: u8,
decode_state: DecodeState,
handle_ctrl: HandleControl,
modifiers: Modifiers,
layout: T,
set: S,
}
impl<T, S> Keyboard<T, S>
where
T: KeyboardLayout + Default,
S: ScancodeSet + Default,
{
/// Make a new Keyboard object with the given layout.
pub fn new(_layout: T, _set: S, handle_ctrl: HandleControl) -> Keyboard<T, S> {
Keyboard {
register: 0,
num_bits: 0,
decode_state: DecodeState::Start,
handle_ctrl,
modifiers: Modifiers {
lshift: false,
rshift: false,
lctrl: false,
rctrl: false,
numlock: true,
capslock: false,
alt_gr: false,
},
layout: T::default(),
set: S::default(),
}
}
// /// Change the Ctrl key mapping.
pub fn set_ctrl_handling(&mut self, new_value: HandleControl) {
self.handle_ctrl = new_value;
}
// /// Get the current Ctrl key mapping.
pub fn get_ctrl_handling(&self) -> HandleControl {
self.handle_ctrl
}
/// Clears the bit register.
///
/// Call this when there is a timeout reading data from the keyboard.
pub fn clear(&mut self) {
self.register = 0;
self.num_bits = 0;
self.decode_state = DecodeState::Start;
}
/// Processes a 16-bit word from the keyboard.
///
/// * The start bit (0) must be in bit 0.
/// * The data octet must be in bits 1..8, with the LSB in bit 1 and the
/// MSB in bit 8.
/// * The parity bit must be in bit 9.
/// * The stop bit (1) must be in bit 10.
pub fn add_word(&mut self, word: u16) -> Result<Option<KeyEvent>, Error> {
let byte = self.check_word(word)?;
self.add_byte(byte)
}
/// Processes an 8-bit byte from the keyboard.
///
/// We assume the start, stop and parity bits have been processed and
/// verified.
pub fn add_byte(&mut self, byte: u8) -> Result<Option<KeyEvent>, Error> {
self.set.advance_state(&mut self.decode_state, byte)
}
/// Shift a bit into the register.
///
/// Call this /or/ call `add_word` - don't call both.
/// Until the last bit is added you get Ok(None) returned.
pub fn add_bit(&mut self, bit: bool) -> Result<Option<KeyEvent>, Error> {
self.register |= (bit as u16) << self.num_bits;
self.num_bits += 1;
if self.num_bits == KEYCODE_BITS {
let word = self.register;
self.register = 0;
self.num_bits = 0;
self.add_word(word)
} else {
Ok(None)
}
}
/// Processes a `KeyEvent` returned from `add_bit`, `add_byte` or `add_word`
/// and produces a decoded key.
///
/// For example, the KeyEvent for pressing the '5' key on your keyboard
/// gives a DecodedKey of unicode character '5', unless the shift key is
/// held in which case you get the unicode character '%'.
pub fn process_keyevent(&mut self, ev: KeyEvent) -> Option<DecodedKey> {
match ev {
KeyEvent {
code: KeyCode::ShiftLeft,
state: KeyState::Down,
} => {
self.modifiers.lshift = true;
None
}
KeyEvent {
code: KeyCode::ShiftRight,
state: KeyState::Down,
} => {
self.modifiers.rshift = true;
None
}
KeyEvent {
code: KeyCode::ShiftLeft,
state: KeyState::Up,
} => {
self.modifiers.lshift = false;
None
}
KeyEvent {
code: KeyCode::ShiftRight,
state: KeyState::Up,
} => {
self.modifiers.rshift = false;
None
}
KeyEvent {
code: KeyCode::CapsLock,
state: KeyState::Down,
} => {
self.modifiers.capslock = !self.modifiers.capslock;
None
}
KeyEvent {
code: KeyCode::NumpadLock,
state: KeyState::Down,
} => {
self.modifiers.numlock = !self.modifiers.numlock;
None
}
KeyEvent {
code: KeyCode::ControlLeft,
state: KeyState::Down,
} => {
self.modifiers.lctrl = true;
None
}
KeyEvent {
code: KeyCode::ControlLeft,
state: KeyState::Up,
} => {
self.modifiers.lctrl = false;
None
}
KeyEvent {
code: KeyCode::ControlRight,
state: KeyState::Down,
} => {
self.modifiers.rctrl = true;
None
}
KeyEvent {
code: KeyCode::ControlRight,
state: KeyState::Up,
} => {
self.modifiers.rctrl = false;
None
}
KeyEvent {
code: KeyCode::AltRight,
state: KeyState::Down,
} => {
self.modifiers.alt_gr = true;
None
}
KeyEvent {
code: KeyCode::AltRight,
state: KeyState::Up,
} => {
self.modifiers.alt_gr = false;
None
}
KeyEvent {
code: c,
state: KeyState::Down,
} => Some(
self.layout
.map_keycode(c, &self.modifiers, self.handle_ctrl),
),
_ => None,
}
}
fn get_bit(&self, word: u16, offset: usize) -> bool {
((word >> offset) & 0x0001) != 0
}
fn has_even_number_bits(&self, data: u8) -> bool {
(data.count_ones() % 2) == 0
}
/// Check 11-bit word has 1 start bit, 1 stop bit and an odd parity bit.
fn check_word(&self, word: u16) -> Result<u8, Error> {
let start_bit = self.get_bit(word, 0);
let parity_bit = self.get_bit(word, 9);
let stop_bit = self.get_bit(word, 10);
let data = ((word >> 1) & 0xFF) as u8;
if start_bit {
return Err(Error::BadStartBit);
}
if !stop_bit {
return Err(Error::BadStopBit);
}
let need_parity = self.has_even_number_bits(data);
// Odd parity, so these must not match
if need_parity != parity_bit {
return Err(Error::ParityError);
}
Ok(data)
}
}
pub fn parse_format() {
let test = include_str!("../../keymaps/qwerty.keymap").lines();
// r#"0-NONE\n1-HI#Says HI"#
for x in test {
for y in x.split('-') {
if y.parse::<u64>().is_ok() {
todo![];
// NOTE: this unwrap is ok bcause of the above check
// println!("NUM: {:?}", y.parse::<u64>().unwrap());
// serial_println!("NUM: {:?}", y.parse::<u64>().unwrap());
} else if y.starts_with('#') {
// ignore all # delimeted lines
} else {
// println!("STR: {:?}", y);
// serial_println!("STR: {:?}", y);
match y.trim() {
"NONE" => {}
"TAB" => {}
"SHIFT" => {}
"SCROLL_LOCK" => {}
"FUNCTION_1" => {}
"FUNCTION_2" => {}
"FUNCTION_3" => {}
"FUNCTION_4" => {}
"FUNCTION_5" => {}
"FUNCTION_6" => {}
"FUNCTION_7" => {}
"FUNCTION_8" => {}
"FUNCTION_9" => {}
"FUNCTION_10" => {}
"FUNCTION_11" => {}
"FUNCTION_12" => {}
"COMMA" => {}
"PERIOD" => {}
"FORWARDSLASH" => {}
"GRAVE" => {}
"BRACKET_LEFT" => {}
"BACK_SLASH" => {}
"BRACKET_RIGHT" => {}
"QUOTE" => {}
_ => {}
}
}
}
}
}

View File

@ -0,0 +1,246 @@
#![allow(non_snake_case)]
#[derive(Debug)]
pub struct Modifiers {
pub lshift: bool,
pub rshift: bool,
pub lctrl: bool,
pub rctrl: bool,
pub numlock: bool,
pub capslock: bool,
pub alt_gr: bool,
}
impl Modifiers {
pub fn is_shifted(&self) -> bool {
self.lshift | self.rshift
}
pub fn is_ctrl(&self) -> bool {
self.lctrl | self.rctrl
}
pub fn is_caps(&self) -> bool {
self.capslock
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum KeyState {
Up,
Down,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct KeyEvent {
pub code: KeyCode,
pub state: KeyState,
}
impl KeyEvent {
pub fn new(code: KeyCode, state: KeyState) -> KeyEvent {
KeyEvent { code, state }
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum HandleControl {
/// If either Ctrl key is held down, convert the letters A through Z into
/// Unicode chars U+0001 through U+001A. If the Ctrl keys are not held
/// down, letters go through normally.
MapLettersToUnicode,
/// Don't do anything special - send through the Ctrl key up/down events,
/// and leave the letters as letters.
Ignore,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum DecodeState {
Start,
Extended,
Release,
ExtendedRelease,
}
/// Indicates different error conditions.
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Error {
BadStartBit,
BadStopBit,
ParityError,
UnknownKeyCode,
InvalidState,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[repr(u8)]
pub enum DecodedKeyKind {
RawKey = 0,
Unicode = 1,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[repr(C)]
pub struct DecodedKey {
pub kind: DecodedKeyKind,
pub value: u32,
}
impl From<char> for DecodedKey {
fn from(ch: char) -> Self {
Self {
kind: DecodedKeyKind::Unicode,
value: ch as u32,
}
}
}
impl DecodedKey {
pub const ZERO: Self = Self {
kind: DecodedKeyKind::Unicode,
value: 0,
};
pub fn Unicode(ch: char) -> Self {
Self {
kind: DecodedKeyKind::Unicode,
value: ch.into(),
}
}
pub fn RawKey(byte: u8) -> Self {
Self {
kind: DecodedKeyKind::RawKey,
value: byte.into(),
}
}
}
macro_rules! keycode_enum {
(@get_last $Variant:ident) => {
Self::$Variant
};
(@get_last $Variant:ident, $($VariantTail:ident),*) => {
keycode_enum![@get_last $($VariantTail),*]
};
($($Variant:ident=$Value:expr,)*) => {
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u8)]
pub enum KeyCode {
$($Variant = $Value),*
}
impl core::convert::From<u32> for KeyCode {
fn from(n: u32) -> Self {
match n {
$($Value => Self::$Variant),*,
_ => keycode_enum![@get_last $($Variant),*]
}
}
}
};
($($Variant:ident=$Value:expr),* ) => {
keycode_enum!($($Variant=$Value,)* );
};
}
// This will be a way to map keys to other keys / keyyngs / macros
keycode_enum! {
AltLeft = 0x00,
AltRight = 0x01,
ArrowDown = 0x02,
ArrowLeft = 0x03,
ArrowRight = 0x04,
ArrowUp = 0x05,
BackSlash = 0x06,
Backspace = 0x07,
BackTick = 0x08,
BracketSquareLeft = 0x09,
BracketSquareRight = 0x0A,
CapsLock = 0x0B,
Comma = 0x0C,
ControlLeft = 0x0D,
ControlRight = 0x0E,
Delete = 0x0F,
End = 0x10,
Enter = 0x11,
Escape = 0x12,
Equals = 0x13,
F1 = 0x14,
F2 = 0x15,
F3 = 0x16,
F4 = 0x17,
F5 = 0x18,
F6 = 0x19,
F7 = 0x1A,
F8 = 0x1B,
F9 = 0x1C,
F10 = 0x1D,
F11 = 0x1E,
F12 = 0x1F,
Fullstop = 0x20,
Home = 0x21,
Insert = 0x22,
Key1 = 0x23,
Key2 = 0x24,
Key3 = 0x25,
Key4 = 0x26,
Key5 = 0x27,
Key6 = 0x28,
Key7 = 0x29,
Key8 = 0x2A,
Key9 = 0x2B,
Key0 = 0x2C,
Menus = 0x2D,
Minus = 0x2E,
Numpad0 = 0x2F,
Numpad1 = 0x30,
Numpad2 = 0x31,
Numpad3 = 0x32,
Numpad4 = 0x33,
Numpad5 = 0x34,
Numpad6 = 0x35,
Numpad7 = 0x36,
Numpad8 = 0x37,
Numpad9 = 0x38,
NumpadEnter = 0x39,
NumpadLock = 0x3A,
NumpadSlash = 0x3B,
NumpadStar = 0x3C,
NumpadMinus = 0x3D,
NumpadPeriod = 0x3E,
NumpadPlus = 0x3F,
PageDown = 0x40,
PageUp = 0x41,
PauseBreak = 0x42,
PrintScreen = 0x43,
ScrollLock = 0x44,
SemiColon = 0x45,
ShiftLeft = 0x46,
ShiftRight = 0x47,
Slash = 0x48,
Spacebar = 0x49,
Tab = 0x4A,
Quote = 0x4B,
WindowsLeft = 0x4C,
WindowsRight = 0x4D,
A = 0x4E,
B = 0x4F,
C = 0x50,
D = 0x51,
E = 0x52,
F = 0x53,
G = 0x54,
H = 0x55,
I = 0x56,
J = 0x57,
K = 0x58,
L = 0x59,
M = 0x5A,
N = 0x5B,
O = 0x5C,
P = 0x5D,
Q = 0x5E,
R = 0x5F,
S = 0x60,
T = 0x61,
U = 0x62,
V = 0x63,
W = 0x64,
X = 0x65,
Y = 0x66,
Z = 0x67,
HashTilde = 0x68,
PrevTrack = 0x69,
NextTrack = 0x6A,
Mute = 0x6B,
Calculator = 0x6C,
Play = 0x6D,
Stop = 0x6E,
VolumeDown = 0x6F,
VolumeUp = 0x70,
WWWHome = 0x71,
PowerOnTestOk = 0x72,
}

View File

@ -0,0 +1,21 @@
use super::*;
pub trait ScancodeSet {
/// Handles the state logic for the decoding of scan codes into key events.
fn advance_state(&self, state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error>;
/// Convert a Scan Code set X byte to our 'KeyType' enum
fn map_scancode(&self, code: u8) -> Result<KeyCode, Error>;
/// Convert a Scan Code Set X extended byte (prefixed E0) to our `KeyType`
/// enum.
fn map_extended_scancode(&self, code: u8) -> Result<KeyCode, Error>;
}
pub trait KeyboardLayout {
/// Convert a `KeyType` enum to a Unicode character, if possible.
/// `KeyType::A` maps to `Some('a')` (or `Some('A')` if shifted), while
/// `KeyType::AltLeft` returns `None`
fn map_keycode(
&self,
keycode: KeyCode,
modifiers: &Modifiers,
handle_ctrl: HandleControl,
) -> DecodedKey;
}

74
ableos/src/kmain.rs Normal file
View File

@ -0,0 +1,74 @@
#![allow(clippy::empty_loop)]
use crate::{
arch::{drivers::graphics::GraphicsBuffer, init},
driver_traits::{graphics::Graphics, serial::Serial},
relib::math::rand::{linearshift::LinearShiftRegister, prand::PRand, RAND_HANDLE, RNG},
serial_print, serial_println,
};
use lazy_static::lazy_static;
#[no_mangle]
#[allow(unconditional_recursion)]
pub extern "C" fn stack_overflow() -> u8 {
stack_overflow();
69 // NOTE: Any specific reason for this number asside from memes?
}
use crate::keyboard::DecodedKey;
lazy_static! {
pub static ref KEY_BUFFER: [DecodedKey; 256] = [DecodedKey::RawKey(123); 256];
pub static ref KEY_BUFFER_POINTER: u8 = 0;
}
#[no_mangle]
pub extern "C" fn kernel_main() {
init::init();
GraphicsBuffer::draw();
GraphicsBuffer::hide_cursor();
GraphicsBuffer::show_cursor();
seed_rng();
/* If AES is present then AES init rng as well
// Maybe via a cfg
AES::init_rng();
*/
println!("init");
{
use crate::experiments::mail::MailBoxes;
let mut x = MailBoxes::new();
x.set_flag(1);
x.set_flag(2);
// x.dump_flags();
}
// stack_overflow();
loop {}
}
// TODO: reimplement for the random handler
pub fn seed_rng() -> PRand {
println!("Seeding PRNG");
let data = TICK.lock();
let mut rand = PRand::new();
let seed = rand.rand();
println!("{:?}", seed);
rand.seed(*data);
println!("Seeded PRNG");
rand
}
lazy_static! {
// TODO: should have a sin wave influence contribution to entropy
pub static ref TICK: spin::Mutex<u64> = spin::Mutex::new(0);
}
/// called by arch specific timers to tick up all kernel related functions
pub fn tick() {
let mut data = TICK.lock();
*data += 1;
// serial_println!("{}", *data);
RAND_HANDLE.lock().seed_entropy_timer(*data);
}
pub fn key_entropy(key: u8) {
RAND_HANDLE.lock().seed_entropy_keyboard(key);
}

43
ableos/src/lib.rs Normal file
View File

@ -0,0 +1,43 @@
#![no_std]
// #![deny(warnings)]
#![feature(asm)]
#![feature(global_asm)]
#![feature(abi_x86_interrupt)]
#![feature(core_intrinsics, lang_items, llvm_asm)]
// #![feature(alloc_error_handler)] // at the top of the file
#![reexport_test_harness_main = "test_main"]
#![feature(custom_test_frameworks)]
#![test_runner(crate::arch::test_runner)]
#[cfg(target_arch = "arm")]
#[path = "arch/aarch32/mod.rs"]
mod arch;
#[cfg(target_arch = "aarch64")]
#[path = "arch/aarch64/mod.rs"]
mod arch;
#[cfg(target_arch = "x86_64")]
#[path = "arch/x86_64/mod.rs"]
mod arch;
#[cfg(target_arch = "mips")]
#[path = "arch/ps_portable/mod.rs"]
mod arch;
#[macro_use]
pub mod print;
#[cfg(not(target_arch = "mips"))]
// pub mod allocator;
mod kmain;
#[cfg(not(target_arch = "mips"))]
mod panic;
mod driver_traits;
mod experiments;
pub use experiments::server;
pub mod keyboard;
pub mod relib;
pub const KERNEL_VERSION: &str = env!("CARGO_PKG_VERSION");
#[cfg(debug_assertions)]
/// A constant to check if the kernel is in debug mode
pub const RELEASE_TYPE: &str = "debug";
#[cfg(not(debug_assertions))]
/// A constant to check if the kernel is in release mode
pub const RELEASE_TYPE: &str = "release";

3
ableos/src/main.rs Normal file
View File

@ -0,0 +1,3 @@
#![no_std]
#![no_main]
pub use ableos::*;

9
ableos/src/panic.rs Normal file
View File

@ -0,0 +1,9 @@
use crate::{arch::sloop, println, serial_println};
use core::panic::PanicInfo;
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
println!("{}", info);
serial_println!("{}", info);
sloop()
}

60
ableos/src/print.rs Normal file
View File

@ -0,0 +1,60 @@
pub struct Stdout;
use core::fmt::Arguments;
use core::fmt::Error;
impl Stdout {
pub fn write_fmt(&mut self, arg: Arguments<'_>) /*-> Result<(), Error> */
{
core::fmt::Write::write_fmt(self, arg);
// Ok(())
}
}
impl core::fmt::Write for Stdout {
#[cfg(target_arch = "arm")]
fn write_str(&mut self, s: &str) -> Result<(), Error> {
use crate::arch::write;
write(s);
Ok(())
}
#[cfg(target_arch = "aarch64")]
fn write_str(&mut self, s: &str) -> Result<(), Error> {
// Don't actually print anything yet lmao
Ok(())
}
#[cfg(target_arch = "x86_64")]
fn write_str(&mut self, s: &str) -> Result<(), Error> {
use crate::kprint;
// FIXME: causes issues
kprint!("{}", s);
Ok(())
}
#[cfg(target_arch = "mips")]
fn write_str(&mut self, s: &str) -> Result<(), Error> {
use psp::dprint;
dprint!("{}", s);
Ok(())
}
}
#[macro_export]
macro_rules! print {
() => {
::core::writeln!($crate::print::Stdout, "")
};
($($tt:tt)*) => {
::core::write!($crate::print::Stdout, $($tt)*)
};
}
#[macro_export]
macro_rules! println {
() =>{
// ::core::writeln!($crate::print::Stdout, "\n")
panic![];
};
($($tt:tt)*) => {
::core::writeln!($crate::print::Stdout, $($tt)*)
// panic![];
};
}

View File

@ -0,0 +1 @@
pub mod rand;

View File

@ -0,0 +1,35 @@
use crate::relib::math::rand::RNG;
pub struct LinearShiftRegister {
reg: u64,
}
// 64 bit
// non-cryptographically secure
impl RNG for LinearShiftRegister {
fn new() -> Self {
Self { reg: (1 << 63) | 1 }
}
fn rand(&mut self) -> u64 {
let newbit = (self.reg >> 1) ^ (self.reg >> 2) ^ (self.reg >> 7);
self.reg = (self.reg >> 1) | (newbit << 3);
newbit
}
fn seed(&mut self, seed: u64) {
let entropy = 34; // replace with hardware entropy
let shifted = (self.reg >> 1) ^ ((self.reg >> 2) + entropy);
let x: u64 = 2983745;
let x123: u64 = 100000000;
let multitude: u64 = x123.wrapping_mul(x) / x;
let mult = shifted.wrapping_mul(multitude);
let seeded_bit = seed / mult;
if false {
// crate::serial_println!("Entropy {}", entropy);
// crate::serial_println!("Multitude {}", multitude);
// crate::serial_println!("Seeded Bit {}", seeded_bit);
}
for _ in 0..seeded_bit {
self.rand();
}
}
}

View File

@ -0,0 +1,87 @@
#![allow(dead_code)]
pub mod linearshift;
pub mod prand;
pub mod wichmanhillrand; // FIXEME: Reimplement
use crate::serial_println;
use lazy_static::lazy_static;
use linearshift::LinearShiftRegister;
use prand::PRand;
pub trait RNG {
fn new() -> Self;
fn rand(&mut self) -> u64;
fn seed(&mut self, seed: u64);
}
pub type KeyEntropyHandler = u8;
pub struct Entropy {
// Everytime entropy is used decrement bits count
bytes_count: u8, // 167 is our lower desired bit count
pool_index: u8,
pool: [u64; 255],
}
impl Entropy {
pub fn new() -> Self {
Self {
bytes_count: 0,
pool: [0; 255],
pool_index: 0,
}
}
pub fn poll_hardware() {
todo!();
}
pub fn read_entropy(&mut self) -> u8 {
self.bytes_count -= 1;
1
}
}
impl Default for Entropy {
fn default() -> Self {
Self::new()
}
}
pub struct RandomHandeler {
prand: prand::PRand,
linearshift: linearshift::LinearShiftRegister,
entropy: Entropy,
}
impl RandomHandeler {
pub fn seed_entropy(&mut self) {
// n is even
self.prand
.seed(self.entropy.pool[self.entropy.pool_index as usize]);
//otherwise odd
self.linearshift
.seed(self.entropy.pool[self.entropy.pool_index as usize]);
}
// FIXME: Likely to panic
pub fn seed_entropy_keyboard(&mut self, key: u8) {
self.entropy.pool_index += key;
if self.entropy.pool_index > 254 {
self.entropy.pool_index = 0
}
self.entropy.pool[self.entropy.pool_index as usize] += key as u64;
self.entropy.pool_index += 1;
}
pub fn seed_entropy_timer(&mut self, seed: u64) {
let bytes = seed.to_be_bytes();
for byte in bytes {
if self.entropy.pool_index > 254 {
self.entropy.pool_index = 0
}
self.entropy.pool[self.entropy.pool_index as usize] += byte as u64;
self.entropy.pool_index += 1;
}
}
}
lazy_static! {
pub static ref RAND_HANDLE: spin::Mutex<RandomHandeler> = spin::Mutex::new(RandomHandeler {
prand: PRand::new(),
linearshift: LinearShiftRegister::new(),
entropy: Entropy::new(),
});
}

View File

@ -0,0 +1,17 @@
use crate::relib::math::rand::RNG;
pub struct PRand {
next: u64,
}
impl RNG for PRand {
fn new() -> Self {
Self { next: 7 }
}
fn rand(&mut self) -> u64 {
let internal_seed_1 = 21354;
self.next = self.next.wrapping_mul(1103515245) + internal_seed_1;
(self.next / 65536) % 32768
}
fn seed(&mut self, seed: u64) {
self.next = seed;
}
}

View File

@ -0,0 +1,27 @@
use crate::relib::math::rand::RNG;
pub struct WichmannHillRand {
seed0: u16,
seed1: u16,
seed2: u16,
}
impl RNG for WichmannHillRand {
fn new() -> Self {
Self {
seed0: 123,
seed1: 456,
seed2: 789,
}
}
fn rand(&mut self) -> u64 {
self.seed0 = (self.seed0.wrapping_mul(170)) % 30269;
self.seed1 = (self.seed1.wrapping_mul(172)) % 30307;
self.seed2 = (self.seed2.wrapping_mul(173)) % 30323;
(self.seed0 / 30269 + self.seed1 / 30307 + self.seed2 / 30323).into()
}
fn seed(&mut self, seed: u64) {
self.seed0 = (seed >> 48) as u16;
self.seed1 = ((seed << 16) >> 48) as u16;
self.seed2 = ((seed << 32) >> 48) as u16;
}
}

6
ableos/src/relib/mod.rs Normal file
View File

@ -0,0 +1,6 @@
pub mod math;
pub mod time;
pub struct VectorTwo {
pub x: i32,
pub y: i32,
}

View File

@ -0,0 +1,72 @@
use super::Time;
use core::fmt::{Display, Error, Formatter};
#[derive(Debug, Clone, Copy)]
#[repr(transparent)]
pub struct Kilosecond(usize);
impl Display for Kilosecond {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let mut reg = self.0;
let mut buf = [0u8, 0, 0, 0, 0];
let mut n = 0;
while n < 8 {
if n > 2 {
buf[7 - n] = match reg % 10 {
0 => b'0',
1 => b'1',
2 => b'2',
3 => b'3',
4 => b'4',
5 => b'5',
6 => b'6',
7 => b'7',
8 => b'8',
9 => b'9',
_ => unreachable!["CPU is borken"],
};
}
reg /= 10;
n += 1;
}
for (n, b) in buf.iter().enumerate() {
write![f, "{}", *b as char]?;
if n == 1 {
write![f, "."]?;
}
}
Ok(())
}
}
impl core::ops::Add for Kilosecond {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self(self.0 + rhs.0)
}
}
impl core::ops::Sub for Kilosecond {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self(self.0 - rhs.0)
}
}
impl From<Time> for Kilosecond {
fn from(t: Time) -> Self {
Self((t.hour as usize * 3600 + t.minutes as usize * 60 + t.seconds as usize) * 1000)
}
}
impl Kilosecond {
pub fn from_ms(ms: usize) -> Self {
Self(ms)
}
pub fn from_sec(sec: usize) -> Self {
Self(sec * 1000)
}
pub fn from_minutes(min: usize) -> Self {
Self(min * 60 * 1000)
}
pub fn from_hours(hrs: usize) -> Self {
Self(hrs * 60 * 60 * 1000)
}
pub fn from_days(days: usize) -> Self {
Self(days * 24 * 60 * 60 * 1000)
}
}

View File

@ -0,0 +1,20 @@
pub struct Time {
pub year: u16,
pub month: u16,
pub day: u16,
pub hour: u16,
pub minutes: u16,
pub seconds: u16,
pub microseconds: u32,
}
impl fmt::Display for Time {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{:?}/{:?}/{:?} {:02}:{:02}:{:02}",
self.year, self.month, self.day, self.hour, self.minutes, self.seconds
)
}
}
pub mod kilotime;
use core::fmt;

248
repbuild/Cargo.lock generated Normal file
View File

@ -0,0 +1,248 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
[[package]]
name = "repbuild"
version = "0.1.0"
dependencies = [
"anyhow",
"structopt",
"xshell",
]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
dependencies = [
"clap",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "xshell"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaad2035244c56da05573d4d7fda5f903c60a5f35b9110e157a14a1df45a9f14"
dependencies = [
"xshell-macros",
]
[[package]]
name = "xshell-macros"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4916a4a3cad759e499a3620523bf9545cc162d7a06163727dde97ce9aaa4cf39"

12
repbuild/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
cargo-features = ["edition2021"]
[package]
name = "repbuild"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.39"
structopt = "0.3.21"
xshell = "0.1.9"

Some files were not shown because too many files have changed in this diff Show More