Skip to content

Commit 7bed353

Browse files
committed
load elf from vfs
1 parent e8e6efd commit 7bed353

File tree

10 files changed

+106
-10
lines changed

10 files changed

+106
-10
lines changed

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ edition = "2021"
66

77
[workspace]
88
resolver = "2"
9-
members = ["crates/*"]
9+
members = ["crates/*", "userspace/cat"]
1010

1111
[profile.release]
1212
debug = true

crates/kshell/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ hyperion-cpu-id.path = "../cpu-id"
3737
hyperion-kernel-impl.path = "../kernel-impl"
3838

3939
hyperion-sample-elf = { path = "../sample-elf", artifact = "bin", target = "x86_64-unknown-none" }
40+
cat = { path = "../../userspace/cat", artifact = "bin", target = "x86_64-unknown-none" }

crates/kshell/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use futures_util::StreamExt;
1111
use hyperion_color::Color;
1212
use hyperion_framebuffer::framebuffer::Framebuffer;
1313
use hyperion_futures::{keyboard::KeyboardEvents, timer::ticks};
14+
use hyperion_kernel_impl::VFS_ROOT;
1415
use hyperion_random::Rng;
15-
use hyperion_vfs::{error::IoError, path::PathBuf};
16+
use hyperion_vfs::{error::IoError, path::PathBuf, ramdisk};
1617
use snafu::Snafu;
1718
use time::Duration;
1819

@@ -29,6 +30,11 @@ pub mod term;
2930
pub async fn kshell() {
3031
hyperion_futures::executor::spawn(spinner());
3132

33+
let bin = include_bytes!(env!("CARGO_BIN_FILE_HYPERION_SAMPLE_ELF"));
34+
VFS_ROOT.install_dev("/bin/run", ramdisk::File::new(bin.into()));
35+
let bin = include_bytes!(env!("CARGO_BIN_FILE_CAT"));
36+
VFS_ROOT.install_dev("/bin/cat", ramdisk::File::new(bin.into()));
37+
3238
let term = Term::new();
3339
let mut shell = Shell::new(term);
3440

crates/kshell/src/shell.rs

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl Shell {
143143
"pwd" => self.pwd_cmd(args)?,
144144
"cd" => self.cd_cmd(args)?,
145145
"ls" => self.ls_cmd(args)?,
146-
"cat" => self.cat_cmd(args)?,
146+
// "cat" => self.cat_cmd(args)?,
147147
"date" => self.date_cmd(args)?,
148148
"mem" => self.mem_cmd(args)?,
149149
"sleep" => self.sleep_cmd(args).await?,
@@ -154,7 +154,7 @@ impl Shell {
154154
"snake" => self.snake_cmd(args).await?,
155155
"help" => self.help_cmd(args)?,
156156
"modeltest" => self.modeltest_cmd(args).await?,
157-
"run" => self.run_cmd(args).await?,
157+
// "run" => self.run_cmd(args).await?,
158158
"lapic_id" => self.lapic_id_cmd(args)?,
159159
"cpu_id" => self.cpu_id_cmd(args)?,
160160
"ps" => self.ps_cmd(args)?,
@@ -168,8 +168,30 @@ impl Shell {
168168
}
169169
"" => self.term.write_byte(b'\n'),
170170
other => {
171-
_ = writeln!(self.term, "unknown command {other}");
172-
self.help_cmd(None)?;
171+
let path = format!("/bin/{other}");
172+
let Ok(bin) = VFS_ROOT.find_file(path.as_str(), false, false) else {
173+
_ = writeln!(self.term, "unknown command {other}");
174+
self.help_cmd(None)?;
175+
return Ok(Some(()));
176+
};
177+
178+
let bin = bin.lock();
179+
180+
let mut elf = Vec::new();
181+
182+
loop {
183+
let mut buf = [0; 64];
184+
let len = bin.read(elf.len(), &mut buf).unwrap();
185+
elf.extend_from_slice(&buf[..len]);
186+
if len == 0 {
187+
break;
188+
}
189+
}
190+
191+
drop(bin);
192+
193+
self.run_cmd_from(path.into(), Cow::Owned(elf), args)
194+
.await?;
173195
}
174196
}
175197

@@ -527,7 +549,17 @@ impl Shell {
527549
}
528550

529551
async fn run_cmd(&mut self, args: Option<&str>) -> Result<()> {
530-
let name = "/bin/run";
552+
let elf_bytes = include_bytes!(env!("CARGO_BIN_FILE_HYPERION_SAMPLE_ELF"));
553+
self.run_cmd_from("/bin/run".into(), Cow::Borrowed(elf_bytes), args)
554+
.await
555+
}
556+
557+
async fn run_cmd_from(
558+
&mut self,
559+
name: Cow<'static, str>,
560+
elf: Cow<'static, [u8]>,
561+
args: Option<&str>,
562+
) -> Result<()> {
531563
let args = args.map(String::from);
532564

533565
// let stdin_tx = pipe();
@@ -559,6 +591,7 @@ impl Shell {
559591
});
560592

561593
let pid = schedule(move || {
594+
let name = name.as_ref();
562595
hyperion_scheduler::rename(name);
563596

564597
hyperion_kernel_impl::push_file(hyperion_kernel_impl::FileInner {
@@ -588,16 +621,14 @@ impl Shell {
588621
"ELF file from: {}",
589622
env!("CARGO_BIN_FILE_HYPERION_SAMPLE_ELF")
590623
);
591-
let elf_bytes = include_bytes!(env!("CARGO_BIN_FILE_HYPERION_SAMPLE_ELF"));
592-
let loader = hyperion_loader::Loader::new(elf_bytes);
624+
let loader = hyperion_loader::Loader::new(elf.as_ref());
593625

594626
loader.load();
595627

596628
if loader.enter_userland(args).is_none() {
597629
hyperion_log::debug!("entry point missing");
598630
}
599631
});
600-
hyperion_log::trace!("spawning {name} done (PID:{pid})");
601632

602633
let mut events = select(KeyboardEvents.map(Ok), o_rx.race_stream().map(Err));
603634

crates/vfs/src/device.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,21 @@ impl FileDevice for [u8] {
103103
Ok(len)
104104
}
105105
}
106+
107+
impl<T: FileDevice> FileDevice for &'static T {
108+
fn as_any(&self) -> &dyn Any {
109+
self
110+
}
111+
112+
fn len(&self) -> usize {
113+
(**self).len()
114+
}
115+
116+
fn read(&self, offset: usize, buf: &mut [u8]) -> IoResult<usize> {
117+
(**self).read(offset, buf)
118+
}
119+
120+
fn write(&mut self, _: usize, _: &[u8]) -> IoResult<usize> {
121+
Err(IoError::PermissionDenied)
122+
}
123+
}

crates/vfs/src/ramdisk.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ pub struct File {
1919
bytes: Vec<u8>,
2020
}
2121

22+
impl File {
23+
pub fn new(bytes: Vec<u8>) -> Self {
24+
Self { bytes }
25+
}
26+
}
27+
2228
pub struct Directory<Mut: AnyMutex> {
2329
pub name: Arc<str>,
2430
pub children: BTreeMap<Arc<str>, Node<Mut>>,

userspace/cat/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "cat"
3+
version.workspace = true
4+
edition.workspace = true
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
libstd.path = "../../crates/libstd"

userspace/cat/build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("cargo:rustc-link-arg=-no-pie");
3+
}

userspace/cat/src/main.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![no_std]
2+
#![no_main]
3+
#![feature(format_args_nl)]
4+
5+
//
6+
7+
use libstd::println;
8+
9+
//
10+
11+
#[no_mangle]
12+
fn main() {
13+
println!("Hello, world!");
14+
}

0 commit comments

Comments
 (0)