diff options
author | johannst <johannes.stoelp@gmail.com> | 2021-05-26 00:21:06 +0200 |
---|---|---|
committer | johannst <johannes.stoelp@gmail.com> | 2021-05-26 00:21:06 +0200 |
commit | 786a195f8e81d4f7c0af2a82b9d458361d424a71 (patch) | |
tree | c0df3de9a71e3ae1db1cdf4a59cde6d1accadf33 /examples/real_mode.rs | |
download | mini-kvm-rs-786a195f8e81d4f7c0af2a82b9d458361d424a71.tar.gz mini-kvm-rs-786a195f8e81d4f7c0af2a82b9d458361d424a71.zip |
minimal KVM abstraction + real mode guest example
Diffstat (limited to 'examples/real_mode.rs')
-rw-r--r-- | examples/real_mode.rs | 48 |
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(()) +} |