CHERI
QEMU-CHERI
QEMU-CHERI is an adaptation of the popular QEMU ISA emulator to implement the CHERI-MIPS instruction set. QEMU-CHERI boots CheriBSD and passes all of the CheriBSD MIPS and CheriABI tests. It implements 128-bit compressed capabilities, as well as CHERI-256 capabilities, and "magic" 128-bit capabilities (in which architectural 256-bit capabilities can be compressed to 128 bits without loss when loaded and stored from memory). This latter mode permits easier diagnosis of software bugs associated with 128-bit-sized capabilities vs. those associated specifically with capability compression (e.g., changed alignment requirements). More information on QEMU itself can be found on the QEMU Wiki.
Contents |
Building and Installing qemu-system-cheri128
On FreeBSD, qemu-system-cheri can be installed using the package command:
# pkg install qemu-cheri128
For 256-bit capabilities use the following instead:
# pkg install qemu-cheri
It can also be installed using FreeBSD ports:
# cd /usr/ports/emulators/qemu-cheri128; make install
For 256-bit capabilities use:
# cd /usr/ports/emulators/qemu-cheri; make install
Building QEMU from git
The latest version can be built from the source in the
CTSRD-CHERI Github
repository.
We strongly recommend that you use the
cheribuild.py script
to build QEMU and a CheriBSD disk image.
The simplest way of getting CheriBSD running is by running
cheribuild.py run --include-dependencies
.
If you want to build only QEMU (e.g. for bare-metal development) you can use
cheribuild.py qemu
.
Further information on how to use cheribuild and configure build paths
and options can be found in the
GitHub README
Running CheriBSD with QEMU-Cheri
CheriBSD Startup and Regression Testing
Using the kernel and disk image created above you can boot CheriBSD into multiuser and run the CheriBSD regression tests. Use the 'malta' system model (-M malta) with 2G of system memory (-m 2048):
$ cheribuild.py run
[...]
Copyright (c) 1992-2015 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 11.0-CURRENT #0 199c896(master)-dirty: Wed Jan 6 16:38:14 UTC 2016
[Javascript required]:/var/tmp/obj/mips.mips64/home/sson/src/cheribsd/sys/CHERI_MALTA64 mips
gcc version 4.2.1 20070831 patched [FreeBSD]
Preloaded elf kernel "kernel" at 0xffffffff806bbb10.
CHERI: compiled for 256-bit capabilities
real memory = 2147483648 (2097152K bytes)
[...]
FreeBSD/mips (cheri) (ttyu0)
login:
At this point you can login as the root user (no password) and run the CheriBSD regression tests:
login: root [...] root@:~ # cheritest -a [...] TEST: test_string_memmove_c: Test explicit capability memmove PASS: test_string_memmove_c SUMMARY: passed 142 failed 1 (1 expected) root@:~ # cheriabitest -a [...] TEST: test_string_memmove_c: Test explicit capability memmove PASS: test_string_memmove_c SUMMARY: passed 142 failed 1 (1 expected) root@:~ #
Note that QEMU can be exited using the key sequence "control-a x" at any time.
Instruction, Register and Memory Tracing
QEMU-Cheri also has support for simple instruction, register and memory tracing. This is very useful for debugging and can be turned on (and off) by the command-line when QEMU is started or via the QEMU monitor. Note that turning on instruction tracing will add a lot of overhead to the QEMU emulation and can generate very large trace log files.
In addition to the disassembled instructions the trace includes changes to registers and memory. Here is a small sample of what the trace log looks like (e.g. start of an exception handler):
0xffffffff80000194: csetdefault c30 Write C00|v:1 s:0 p:7fffffff b:0000000000000000 l:ffffffffffffffff |o:0000000000000000 t:0 [...] 0xffffffff8051d0ec: sd a3,296(k1) Memory Write [c000000000143588] = 000000016004f5a0 0xffffffff8051d0f0: cgetcause k0 Write k0 = 00000000000006ff 0xffffffff8051d0f4: daddiu t4,k1,608 Write t4 = c0000000001436c0 0xffffffff8051d0f8: csc c28,t4,192(c30) Cap Memory Write [c0000000001436c0] = v:1 tps:00000000ffff00fa c:0000000000000000 b:0000000000000000 l:0000010000000000
Starting Instruction Tracing on Start Up
To start instruction tracing on start up add "-D <logfile> -d instr" to the QEMU command-line. For example:
$ qemu-system-cheri -M malta -kernel ./kernel -nographic -hda ./disk.img -m 2048 -D /var/tmp/instr.log -d instr
Starting and Stopping Instruction Tracing via CheriBSD command
CheriBSD also has a tool /usr/bin/qtrace
that can be used to toggle QEMU tracing.
This will log the traces to the file specified using the -D
flag on QEMU startup.
For example:
$ qtrace -u exec /bin/true # trace user-space instructions for cat $ qtrace exec /bin/true # trace all instructions for true $ qtrace exec /bin/true # trace all instructions for true $ qtrace start # turn on instruction tracing $ qtrace stop # turn off instruction tracing
Starting and Stopping Instruction Tracing via QEMU Monitor
Instruction tracing can also be started and stopped using the QEMU Monitor. To do this toggle into the QEMU Monitor using the "control-a c" key sequence. At the QEMU Monitor prompt, to start instruction tracing, do:
(qemu) logfile /var/tmp/instr.log (qemu) log instr
Toggle back to the console with another "control-a c" key sequence.
To stop instruction tracing using the QEMU Monitor:
(qemu) log none
QEMU-Cheri can also create instruction traces that are compatible with the libcheritrace format that is used by the tracedump utility and CheriVis. To generate libcheritrace instruction traces use '-d cvtrace' instead of '-d instr'. For example:
$ qemu-system-cheri128 -M malta -kernel ./kernel -nographic -hda ./disk.img -m 2048 -D /var/tmp/cvtrace.bin -d cvtrace [...] $ tracedump -t /var/tmp/cvtrace.bin [...]