aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 15ec30e96850e0e2f73607166ccf9632dbca0517 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
## asmlinator

[![crate](https://img.shields.io/crates/v/asmlinator.svg?logo=rust)](https://crates.io/crates/asmlinator)
[![documentation](https://docs.rs/asmlinator/badge.svg)](https://docs.rs/asmlinator)

just enough glue on top of KVM to get a VM with one CPU set up to execute `x86_64` instructions.

### usage

```rust
use asmlinator::x86_64::VcpuExit;

let mem_size = 1024 * 1024;
let mut vm = asmlinator::x86_64::Vm::create(mem_size)
    .expect("can create the VM");

let mut regs = vm.get_regs().unwrap();

// program VM with "xor eax, eax; hlt"
vm.program(&[0x33, 0xc0, 0xf4], &mut regs);
vm.set_regs(&regs).unwrap();

let res = vm.run().expect("can run cpu");
assert_eq!(res, VcpuExit::Hlt);

let regs = vm.get_regs().unwrap();
eprintln!("ending rip: {:016x}", regs.rip);
eprintln!("ending rax: {:016x}", regs.rax);
```

for non-x86-64 modes, the path is slightly longer:
```
use asmlinator::x86_64::{IsaMode, VcpuExit, VmSettings, Vm};

let settings = VmSettings::new(1024 * 1024, IsaMode::Real);
let mut vm = Vm::create_by_settings(settings)
    .expect("can create the VM");

let mut regs = vm.get_regs().unwrap();
regs.rax = 0x11223344_55667788;

// program VM with "xor al, al; hlt"
vm.program(&[0x33, 0xc0, 0xf4], &mut regs);
vm.set_regs(&regs).unwrap();

let res = vm.run().expect("can run cpu");
assert_eq!(res, VcpuExit::Hlt);

let regs = vm.get_regs().unwrap();
eprintln!("ending rip: {:016x}", regs.rip);
eprintln!("ending rax: {:016x}", regs.rax);
assert_eq!(regs.rax, 0x1122334455660000);
```

### design

it's just a glorified virtual CPU wrapper. there is no device emulation, there
is no interrupt controller, there's only one CPU, etc. the plan is to support
ad-hoc questions about x86 behavior rather than a general VMM. more "run this
function in that address space" and "single-step these instructions" than "call
into a library".

you could imagine this as a more opinionated and much smaller `hyperlight`,
without any support for IPC into or out of the VM. i don't.

i consider this closer to a missing OS primitive. the OS knows how to boot
itself on native hardware, it knows how to create a virtual machine, it should
be able to create exactly this kind of partially-initialized VM that does not
require setting up an IDT, GDT, paging, ...

### future

it'd be nice to set up aarch64 processors for code execution too. and to do all
this on other OSes with other VM APIs.

it would probably nice to expose a C ffi to embed this into other programs!
such an ffi interface should be straightforward. i haven't needed one yet.

### mirrors

the canonical copy of `asmlinator` is at [https://git.iximeow.net/asmlinator/](https://git.iximeow.net/asmlinator).

`asmlinator` is also mirrored on Codeberg at [https://codeberg.org/iximeow/asmlinator](https://codeberg.org/iximeow/asmlinator).

### changelog

a changelog across crate versions is maintained in the `CHANGELOG` file located in the repo.

### contributing

unfortunately, pushing commits to the canonical repo at `git.iximeow.net` is
impossible. if you'd like to contribute - thank you! - please send patches to
emails iximeow has committed under or by opening PRs against the [Codeberg
mirror](https://codeberg.org/iximeow/asmlinator). both remotes are kept in
sync.