Skip to content

Commit 854c3fb

Browse files
committed
Merge remote-tracking branch 'kernel/feature/kernel-merge' into feature/kernel-merge
2 parents fc6e692 + b5b0341 commit 854c3fb

File tree

30 files changed

+2900
-0
lines changed

30 files changed

+2900
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
<<<<<<< HEAD
12
build*/
23
.vscode/
34
qemu/
45
.venv/
56
*.gen.*
67
target
78
**.info
9+
=======
10+
target/
11+
Cargo.toml
12+
Cargo.lock
13+
>>>>>>> kernel/feature/kernel-merge

kernel/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
target/
2+
Cargo.toml
3+
Cargo.lock

kernel/CMakeLists.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# kernel/CMakeLists.txt
2+
3+
cmake_minimum_required(VERSION 3.23)
4+
5+
include(FetchContent)
6+
7+
# Path to your Cargo.toml file
8+
set(CARGO_TOML_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml.in")
9+
10+
configure_file(${CARGO_TOML_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml" @ONLY)
11+
12+
FetchContent_Declare(
13+
Corrosion
14+
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
15+
GIT_TAG v0.5
16+
)
17+
FetchContent_MakeAvailable(Corrosion)
18+
19+
corrosion_import_crate(MANIFEST_PATH Cargo.toml NO_STD)
20+
21+
target_sources(kernel
22+
INTERFACE
23+
FILE_SET HEADERS
24+
BASE_DIRS include
25+
FILES
26+
include/kernel/lib.h
27+
include/kernel/syscalls.map.gen.h
28+
)
29+
30+
set(RUST_KERNEL true PARENT_SCOPE)
31+
32+
add_custom_target(syscalls_map DEPENDS cargo-build_kernel)

kernel/Cargo.toml.in

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[package]
2+
name = "kernel"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["staticlib"]
8+
9+
[dependencies]
10+
hal = { path = "@HAL_DIR@", features = ["panic-semih", "panic-exit"] }
11+
macros = { path = "macros" }
12+
13+
[build-dependencies]
14+
cbindgen = "0.26.0"
15+
bindgen = "0.69.5"
16+
walkdir = "2.5.0"
17+
syn = "2.0.90"
18+
quote = "1.0.37"
19+
rand = "0.8.5"
20+
21+
[profile.dev]
22+
panic = "abort"
23+
24+
[profile.release]
25+
panic = "abort"
26+

kernel/LICENSE

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2024, OsirisRTOS
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright notice,
12+
this list of conditions and the following disclaimer in the documentation
13+
and/or other materials provided with the distribution.
14+
15+
3. Neither the name of the copyright holder nor the names of its
16+
contributors may be used to endorse or promote products derived from
17+
this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

kernel/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# kernel
2+
The default kernel of osiris.

kernel/build.rs

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
use std::{collections::HashMap, fs::File, path::Path};
2+
3+
extern crate rand;
4+
extern crate syn;
5+
extern crate walkdir;
6+
7+
use cbindgen::LayoutConfig;
8+
use std::io::Write;
9+
use syn::{Attribute, LitInt};
10+
use walkdir::WalkDir;
11+
12+
extern crate cbindgen;
13+
14+
fn main() {
15+
println!("cargo:rerun-if-changed=src");
16+
println!("cargo:rerun-if-changed=build.rs");
17+
18+
let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
19+
20+
let mut config: cbindgen::Config = Default::default();
21+
22+
config.no_includes = true;
23+
config.includes = vec![
24+
"stdint.h".to_string(),
25+
"stdbool.h".to_string(),
26+
"stdarg.h".to_string(),
27+
];
28+
config.layout = LayoutConfig {
29+
packed: Some("__attribute__((packed))".to_string()),
30+
..Default::default()
31+
};
32+
33+
cbindgen::Builder::new()
34+
.with_crate(crate_dir)
35+
.with_config(config)
36+
.with_language(cbindgen::Language::C)
37+
.with_include_guard("KERNEL_H")
38+
.generate()
39+
.expect("Unable to generate bindings")
40+
.write_to_file("include/kernel/lib.h");
41+
42+
generate_syscall_map("src").expect("Failed to generate syscall map.");
43+
}
44+
45+
fn generate_syscall_map<P: AsRef<Path>>(root: P) -> Result<(), std::io::Error> {
46+
let syscalls = collect_syscalls(root);
47+
48+
let mut file = File::create("../include/syscalls.map.gen.h")?;
49+
50+
writeln!(file, "#ifndef SYSCALLS_MAP_GEN_H")?;
51+
writeln!(file, "#define SYSCALLS_MAP_GEN_H")?;
52+
53+
writeln!(file)?;
54+
55+
writeln!(file, "#include <stdint.h>")?;
56+
57+
writeln!(file)?;
58+
59+
writeln!(
60+
file,
61+
"#define DECLARE_SYSCALL(name, num) case num: name(svc_args); break;"
62+
)?;
63+
64+
writeln!(file)?;
65+
66+
writeln!(file, "#define DECLARE_SYSCALLS() \\")?;
67+
for (name, _) in syscalls.clone() {
68+
writeln!(file, "extern void {}(void *svc_args); \\", name)?;
69+
}
70+
71+
writeln!(file)?;
72+
73+
writeln!(file, "#define IMPLEMENT_SYSCALLS() \\")?;
74+
for (name, (number, _argc)) in syscalls {
75+
writeln!(file, " DECLARE_SYSCALL({}, {})", name, number)?;
76+
}
77+
78+
writeln!(file)?;
79+
80+
writeln!(file, "#endif //SYSCALLS_MAP_GEN_H")?;
81+
82+
Ok(())
83+
}
84+
85+
fn is_syscall(attrs: &[Attribute]) -> Option<(u8, u8)> {
86+
let mut args = 0;
87+
let mut num = 0;
88+
89+
for attr in attrs {
90+
if attr.path().is_ident("syscall_handler") {
91+
attr.parse_nested_meta(|meta| {
92+
if meta.path.is_ident("args") {
93+
let raw = meta.value()?;
94+
let value: LitInt = raw.parse()?;
95+
args = value.base10_parse()?;
96+
97+
if !(0..=4).contains(&args) {
98+
return Err(meta.error("invalid number of arguments"));
99+
}
100+
101+
return Ok(());
102+
}
103+
104+
if meta.path.is_ident("num") {
105+
let raw = meta.value()?;
106+
let value: LitInt = raw.parse()?;
107+
num = value.base10_parse()?;
108+
109+
if !(0..=255).contains(&num) {
110+
return Err(meta.error("invalid syscall number"));
111+
}
112+
113+
return Ok(());
114+
}
115+
116+
Err(meta.error("unknown attribute"))
117+
})
118+
.expect("failed to parse attribute");
119+
}
120+
}
121+
122+
if args == 0 || num == 0 {
123+
return None;
124+
}
125+
126+
Some((num, args))
127+
}
128+
129+
type SyscallData = (u8, u8);
130+
131+
fn collect_syscalls<P: AsRef<Path>>(root: P) -> HashMap<String, SyscallData> {
132+
let mut syscalls = HashMap::new();
133+
let mut numbers = HashMap::new();
134+
135+
for entry in WalkDir::new(root) {
136+
let entry = match entry {
137+
Ok(entry) => entry,
138+
Err(_) => continue,
139+
};
140+
141+
if entry.file_type().is_file() {
142+
let path = entry.path();
143+
144+
let contents = match std::fs::read_to_string(path) {
145+
Ok(contents) => contents,
146+
Err(_) => continue,
147+
};
148+
149+
let file = match syn::parse_file(&contents) {
150+
Ok(file) => file,
151+
Err(_) => continue,
152+
};
153+
154+
for item in file.items {
155+
let item = match item {
156+
syn::Item::Fn(item) => item,
157+
_ => continue,
158+
};
159+
160+
if !item
161+
.sig
162+
.abi
163+
.is_some_and(|abi| abi.name.is_some_and(|name| name.value() == "C"))
164+
{
165+
continue;
166+
}
167+
168+
if let Some((num, argc)) = is_syscall(&item.attrs) {
169+
let name = item.sig.ident.to_string();
170+
171+
if syscalls.contains_key(&name) {
172+
eprintln!("Duplicate syscall handler: {}", name);
173+
continue;
174+
}
175+
176+
syscalls.insert(name.clone(), (num, argc));
177+
numbers.insert(num, name);
178+
}
179+
}
180+
}
181+
}
182+
183+
syscalls
184+
}

kernel/include/kernel/lib.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#ifndef KERNEL_H
2+
#define KERNEL_H
3+
4+
#include "stdint.h"
5+
#include "stdbool.h"
6+
#include "stdarg.h"
7+
8+
/**
9+
* The memory map entry type.
10+
*
11+
* This structure shall be compatible with the multiboot_memory_map_t struct at
12+
* Link: [https://www.gnu.org/software/grub/manual/multiboot/multiboot.html]()
13+
*/
14+
typedef struct __attribute__((packed)) MemMapEntry {
15+
/**
16+
* The size of the entry.
17+
*/
18+
uint32_t size;
19+
/**
20+
* The base address of the memory region.
21+
*/
22+
uint64_t addr;
23+
/**
24+
* The length of the memory region.
25+
*/
26+
uint64_t length;
27+
/**
28+
* The type of the memory region.
29+
*/
30+
uint32_t ty;
31+
} MemMapEntry;
32+
33+
/**
34+
* The boot information structure.
35+
*/
36+
typedef struct BootInfo {
37+
/**
38+
* The implementer of the processor.
39+
*/
40+
const char *implementer;
41+
/**
42+
* The variant of the processor.
43+
*/
44+
const char *variant;
45+
/**
46+
* The memory map.
47+
*/
48+
struct MemMapEntry mmap[8];
49+
/**
50+
* The length of the memory map.
51+
*/
52+
uintptr_t mmap_len;
53+
} BootInfo;
54+
55+
/**
56+
* The kernel initialization function.
57+
*
58+
* `boot_info` - The boot information.
59+
*/
60+
void kernel_init(const struct BootInfo *boot_info);
61+
62+
void syscall_dummy(const void *svc_args);
63+
64+
/**
65+
* Syscall handler: reschedule.
66+
* This syscall is used to request a reschedule.
67+
*
68+
* No arguments are passed to this syscall.
69+
*/
70+
void syscall_reschedule(const void *_svc_args);
71+
72+
#endif /* KERNEL_H */

kernel/macros/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "macros"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
proc-macro = true
8+
9+
[dependencies]
10+
quote = "1.0.38"
11+
syn = "2.0.94"

0 commit comments

Comments
 (0)