diff --git a/apps/rust/Cargo.toml b/apps/rust/Cargo.toml index 5dd7f74..2f2f6d7 100644 --- a/apps/rust/Cargo.toml +++ b/apps/rust/Cargo.toml @@ -19,6 +19,7 @@ members = [ "hello", "fibonacci", + "keyval", "panic", ] resolver = "2" diff --git a/apps/rust/keyval/Cargo.toml b/apps/rust/keyval/Cargo.toml new file mode 100644 index 0000000..1a539cb --- /dev/null +++ b/apps/rust/keyval/Cargo.toml @@ -0,0 +1,40 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[package] +name = "keyval" +version = "0.1.0" +edition = "2021" +build = "build.rs" + +[build-dependencies] +# build.rs depends on SEL4_OUT_DIR = "${ROOTDIR}/out/kata/kernel" +sel4-config = { path = "../../system/components/kata-os-common/src/sel4-config" } + +[features] +default = [] +# Used by sel4-config to extract kernel config +CONFIG_PRINTING = [] + +[lib] +name = "keyval" +path = "keyval.rs" +crate-type = ["staticlib"] + +[dependencies] +cstr_core = { version = "0.2.3", default-features = false } +kata-os-common = { path = "../../system/components/kata-os-common", default-features = false } +kata-sdk-interface = { path = "../../system/components/SDKRuntime/kata-sdk-interface" } +libkata = { path = "../libkata" } +log = "0.4" diff --git a/apps/rust/keyval/Makefile b/apps/rust/keyval/Makefile new file mode 100644 index 0000000..acff99a --- /dev/null +++ b/apps/rust/keyval/Makefile @@ -0,0 +1,18 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +APPNAME := keyval + +LIBKATA ?= ../libkata +include ${LIBKATA}/make/app.mk diff --git a/apps/rust/keyval/build.rs b/apps/rust/keyval/build.rs new file mode 100644 index 0000000..69753b1 --- /dev/null +++ b/apps/rust/keyval/build.rs @@ -0,0 +1,34 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +extern crate sel4_config; +use std::env; + +fn main() { + // If SEL4_OUT_DIR is not set we expect the kernel build at a fixed + // location relative to the ROOTDIR env variable. + println!("SEL4_OUT_DIR {:?}", env::var("SEL4_OUT_DIR")); + let sel4_out_dir = env::var("SEL4_OUT_DIR") + .unwrap_or_else(|_| format!("{}/out/kata/kernel", env::var("ROOTDIR").unwrap())); + println!("sel4_out_dir {}", sel4_out_dir); + + // Dredge seL4 kernel config for settings we need as features to generate + // correct code: e.g. CONFIG_KERNEL_MCS enables MCS support which changes + // the system call numbering. + let features = sel4_config::get_sel4_features(&sel4_out_dir); + println!("features={:?}", features); + for feature in features { + println!("cargo:rustc-cfg=feature=\"{}\"", feature); + } +} diff --git a/apps/rust/keyval/keyval.rs b/apps/rust/keyval/keyval.rs new file mode 100644 index 0000000..f9caa8a --- /dev/null +++ b/apps/rust/keyval/keyval.rs @@ -0,0 +1,75 @@ +/* + * Copyright 2021, Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ +#![no_std] +#![no_main] + +extern crate alloc; +extern crate libkata; +use alloc::format; +use alloc::string::String; +use kata_os_common::allocator; +use kata_os_common::logger::KataLogger; +use kata_os_common::sel4_sys; +use kata_sdk_interface::*; +use SDKRuntimeError::*; + +// Message output is sent through the kata-os-logger which calls logger_log +// to deliver data to the console. We use seL4_DebugPutChar to write to the +// console which only works if DEBUG_PRINTING is enabled in the kernel. +#[no_mangle] +#[allow(unused_variables)] +pub fn logger_log(_level: u8, msg: *const cstr_core::c_char) { + #[cfg(feature = "CONFIG_PRINTING")] + unsafe { + for c in cstr_core::CStr::from_ptr(msg).to_bytes() { + let _ = sel4_sys::seL4_DebugPutChar(*c); + } + let _ = sel4_sys::seL4_DebugPutChar(b'\n'); + } +} + +#[no_mangle] +// XXX need SDK specification of main, use hack for now +pub fn main(_a0: u32, _a1: u32, _a2: u32, _a3: u32) { + // Setup logger; (XXX maybe belongs in the SDKRuntime) + static KATA_LOGGER: KataLogger = KataLogger; + log::set_logger(&KATA_LOGGER).unwrap(); + log::set_max_level(log::LevelFilter::Trace); + + static mut HEAP: [u8; 4096] = [0; 4096]; + unsafe { + allocator::ALLOCATOR.init(HEAP.as_mut_ptr() as _, HEAP.len()); + } + + const KEY: &str = "foo"; + let mut keyval: KeyValueData = [0u8; KEY_VALUE_DATA_SIZE]; + let _ = match kata_sdk_read_key(KEY, &mut keyval) { + Err(SDKReadKeyFailed) => kata_sdk_log("read(foo) failed as expected"), + Err(e) => kata_sdk_log(&format!("read error {:?}", e)), + Ok(kv) => kata_sdk_log(&format!("read returned {:?}", kv)), + }; + keyval + .split_at_mut(3) + .0 + .copy_from_slice(String::from("123").as_bytes()); + let _ = match kata_sdk_write_key(KEY, &keyval) { + Ok(_) => kata_sdk_log("write ok"), + Err(e) => kata_sdk_log(&format!("write error {:?}", e)), + }; + let _ = match kata_sdk_read_key(KEY, &mut keyval) { + Err(SDKReadKeyFailed) => kata_sdk_log("read(foo) failed as expected"), + Err(e) => kata_sdk_log(&format!("read failed: {:?}", e)), + Ok(kv) => kata_sdk_log(&format!("read returned {:?}", kv)), + }; + let _ = match kata_sdk_delete_key(KEY) { + Ok(_) => kata_sdk_log("delete ok"), + Err(e) => kata_sdk_log(&format!("delete error {:?}", e)), + }; + let _ = match kata_sdk_delete_key(KEY) { + Ok(_) => kata_sdk_log("delete ok (for missing key)"), + Err(e) => kata_sdk_log(&format!("delete error {:?}", e)), + }; +}