Next Generation WASM Microkernel Operating System
wasm os rust microkernel
at trap_handler 95 lines 3.2 kB view raw
1// Copyright 2025 Jonas Kruckenberg 2// 3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or 4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or 5// http://opensource.org/licenses/MIT>, at your option. This file may not be 6// copied, modified, or distributed except according to those terms. 7 8use crate::profile::Profile; 9use crate::tracing::OutputOptions; 10use crate::{Options, build, qemu}; 11use clap::{Parser, ValueHint}; 12use std::path::PathBuf; 13use std::process::{Command, Stdio}; 14use std::{fs, thread}; 15 16#[derive(Debug, Parser)] 17pub struct Cmd { 18 /// The path to the build configuration file 19 #[clap(value_hint = ValueHint::FilePath)] 20 profile: PathBuf, 21 /// The TCP port to listen for debug connections on. 22 #[clap(long, default_value = "1234")] 23 gdb_port: u16, 24 /// Extra arguments passed to QEMU. 25 #[clap(raw = true, conflicts_with = "norun")] 26 qemu_args: Vec<String>, 27 /// Do not start a new k23 instance; just run `lldb` 28 #[clap(long, short, conflicts_with = "gdb_port", conflicts_with = "qemu_args")] 29 norun: bool, 30} 31 32impl Cmd { 33 pub fn run(&self, opts: &Options, output: &OutputOptions) -> crate::Result<()> { 34 let profile = Profile::from_file(&self.profile)?; 35 36 let target_dir = opts 37 .target_dir 38 .clone() 39 .unwrap_or(PathBuf::from("target")) 40 .canonicalize()?; 41 42 let (kernel, loader) = if !self.norun { 43 let qemu_opts = qemu::QemuOptions { 44 wait_for_debugger: true, 45 gdb_port: self.gdb_port, 46 qemu_args: self.qemu_args.clone(), 47 }; 48 49 let kernel = build::build_kernel(opts, output, &profile)?; 50 let loader = build::build_loader(opts, output, &profile, &kernel)?; 51 52 let mut qemu = qemu::spawn(&qemu_opts, profile, &loader, false, &[])?; 53 thread::spawn(move || qemu.0.wait().unwrap().exit_ok().unwrap()); 54 55 (kernel, loader) 56 } else { 57 let kernel = target_dir 58 .join(profile.kernel.target.resolve(&profile).name()) 59 .join("debug") 60 .join("kernel"); 61 62 let loader = target_dir 63 .join(profile.loader.target.resolve(&profile).name()) 64 .join("debug") 65 .join("loader"); 66 67 (kernel, loader) 68 }; 69 70 let lldb_script = target_dir.join("lldb_script.txt"); 71 fs::write( 72 &lldb_script, 73 format!( 74 r#" 75 target create {loader} 76 target modules add {kernel} 77 target modules load --file {kernel} -s 0xffffffc000000000 78 gdb-remote localhost:{gdb_port} 79 "#, 80 loader = loader.display(), 81 kernel = kernel.display(), 82 gdb_port = self.gdb_port, 83 ), 84 )?; 85 86 Command::new("rust-lldb") 87 .args(["-s", lldb_script.to_str().unwrap()]) 88 .stdin(Stdio::inherit()) 89 .stdout(Stdio::inherit()) 90 .stderr(Stdio::inherit()) 91 .output()?; 92 93 Ok(()) 94 } 95}