aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples
diff options
context:
space:
mode:
authorjohannst <johannes.stoelp@gmail.com>2021-05-26 00:21:06 +0200
committerjohannst <johannes.stoelp@gmail.com>2021-05-26 00:21:06 +0200
commit786a195f8e81d4f7c0af2a82b9d458361d424a71 (patch)
treec0df3de9a71e3ae1db1cdf4a59cde6d1accadf33 /examples
downloadmini-kvm-rs-786a195f8e81d4f7c0af2a82b9d458361d424a71.tar.gz
mini-kvm-rs-786a195f8e81d4f7c0af2a82b9d458361d424a71.zip
minimal KVM abstraction + real mode guest example
Diffstat (limited to 'examples')
-rw-r--r--examples/real_mode.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/examples/real_mode.rs b/examples/real_mode.rs
new file mode 100644
index 0000000..39d1796
--- /dev/null
+++ b/examples/real_mode.rs
@@ -0,0 +1,48 @@
+use kvm_rs::kvm::Kvm;
+use kvm_rs::vcpu::KvmExit;
+use kvm_rs::{PhysAddr, UserMem};
+
+fn main() -> std::io::Result<()> {
+ // Create VM & VCPU.
+ let vm = Kvm::new()?.create_vm()?;
+ let vcpu = vm.create_vpcu(0)?;
+
+ // Map memory for guest VM and initialize with guest image.
+ let mem = UserMem::with_init(0x1000, include_bytes!("../guest/guest16"))?;
+ unsafe {
+ vm.set_user_memory_region(PhysAddr(0x0), &mem)?;
+ }
+
+ // Initialize VPCU registers.
+ let mut regs = vcpu.get_regs()?;
+ regs.rip = 0;
+ regs.rflags.0 = 0x2;
+ vcpu.set_regs(regs)?;
+
+ // Initialize VPCU special registers.
+ let mut sregs = vcpu.get_sregs()?;
+ sregs.cs.base = 0;
+ sregs.cs.selector = 0;
+ vcpu.set_sregs(sregs)?;
+
+ // Run VCPU until `hlt` instruction.
+ while let Ok(exit) = vcpu.run() {
+ match exit {
+ KvmExit::Halt => break,
+ KvmExit::IoOut(_port, data) => {
+ let s = std::str::from_utf8(data).unwrap();
+ print!("{}", s);
+ }
+ KvmExit::MmioWrite(addr, data) => {
+ println!(
+ "MMIO_WRITE: addr={:#x} len={} data={:#x?}",
+ addr,
+ data.len(),
+ data
+ );
+ }
+ };
+ }
+
+ Ok(())
+}