blob: f60102567e4a5ef83c58bf15613f42a64ad056f3 [file] [log] [blame] [view]
Microsoft Open Sourced683ebe2023-02-03 11:49:58 +00001Getting started
2===============
3
4This repository contains a dev container that installs the toolchain and the gold model emulator.
5The easiest way to use this is with GitHub Code Spaces: simply press . to open an editor with all of the tools set up.
6You can achieve the same locally by cloning the repository and opening it in VS Code with the Dev Container Extension installed.
7
8If you do not wish to use the dev container then please read the [section on how to build the dependencies](#building-the-dependencies).
9
10The dev container installs the toolchain and emulator in `/cheriot-tools/bin`.
11If you have installed them somewhere else then replace `/cheriot-tools/` with your install location in the following instructions.
12
13Cloning the repository
14----------------------
15
16This repository contains submodules and so must be cloned with:
17
18```sh
19$ git clone --recurse https://github.com/microsoft/cheriot-rtos
20```
21
22Building the test suite
23-----------------------
24
25To make sure that everything is working, a good first step is to build the test suite.
26If you are using the dev container with VS Code / GitHub Code Spaces, then this is the default target and so can be built by running the `XMake: Build` command from the command box.
27
28Whether you are building the test suite in the dev container or elsewhere, you can build it from the command line as well.
29The build system requires a configure step and a build step:
30
31```sh
32$ cd tests
33$ xmake config --sdk=/cheriot-tools/
David Chisnall6ff6f882023-02-10 17:29:38 +000034$ xmake
Microsoft Open Sourced683ebe2023-02-03 11:49:58 +000035```
36
37To get more verbose output, you can try adding `--debug-{loader,allocator,scheduler}=y` to the `xmake config` flags.
38These will each turn on (very) verbose debugging output from the named components.
39
40One of the final lines in the output should be something like:
41
42```
43[ 96%]: linking firmware build/cheriot/cheriot/release/test-suite
44```
45
46This tells you the path to the firmware image.
47You can now try running it in the simulator:
48
49```sh
50$ /cheriot-tools/bin/cheriot_sim -V build/cheriot/cheriot/release/test-suite
51```
52
53The `-V` flag disables instruction-level tracing so that you can see the UART output more clearly.
54
55Running the examples
56--------------------
57
58There are several examples in the [`examples/`](../examples/) directory of the repository.
59These show how to use individual features of the platform.
60Each of these is built and run in exactly the same way as the test suite.
61For more detailed instructions [see the examples documentation](../examples/README.md).
62
63Generating `compile_commands.json`
64----------------------------------
65
66The `clangd` language server protocol implementation depends on a `compile_commands.json` file to tell it the various flags for building.
67If you are using the dev container then this is generated automatically but in other scenarios you must create it yourself from the test suite's build by running the following commands after you have configured the test suite:
68
69```sh
70$ cd tests
71$ xmake project -k compile_commands ..
72```
73
74Building the dependencies
75-------------------------
76
77If you do not wish to use the dev container, you will need to build:
78
79 - The LLVM-based toolchain with CHERIoT support
80 - The emulator generated from the Sail formal model of the CHERIoT ISA
81 - The xmake build tool
Marno van der Maas7594bdf2024-11-06 13:26:04 +000082 - [Sonata only] uf2utils to create images that Sonata's loader can boot
Microsoft Open Sourced683ebe2023-02-03 11:49:58 +000083
84Building LLVM is fairly simple, but requires a fast machine and several GiBs of disk space.
85Building the executable model requires a working ocaml installation.
86
87### Building CHERIoT LLVM
88
89To build LLVM, you will need `cmake` and `ninja` installed from your distribution's packaging system.
90For example on Ubuntu Linux distributions you would need to run (as root):
91
92```sh
93# apt install ninja-build
94# snap install cmake --classic
95```
96
97On FreeBSD:
98
99```sh
100# pkg ins cmake ninja
101```
102
David Chisnalld93daf12023-10-25 14:30:23 +0100103The version of LLVM that you need is in the `cheriot` branch of the [CHERI LLVM repository](https://github.com/CHERIoT-Platform/llvm-project/tree/cheriot).
Microsoft Open Sourced683ebe2023-02-03 11:49:58 +0000104This branch is temporary and will eventually be merged into the main CHERI LLVM branch and upstreamed to LLVM.
105
106First, clone this repo somewhere convenient:
107
108```sh
David Chisnalld93daf12023-10-25 14:30:23 +0100109$ git clone --depth 1 https://github.com/CHERIoT-Platform/llvm-project cheriot-llvm
Microsoft Open Sourced683ebe2023-02-03 11:49:58 +0000110$ cd cheriot-llvm
111$ git checkout cheriot
112$ export LLVM_PATH=$(pwd)
113```
114
115If you want to do a custom build of LLVM, follow [their build instructions and adjust any configuration options that you want](https://www.llvm.org/docs/CMake.html).
116If you want to just build something that works, keep reading.
117
118Next create a directory for the build and enter it:
119
120```sh
121$ mkdir -p builds/cheriot-llvm
Marno van der Maas41189e32023-10-16 16:00:20 +0100122$ cd builds/cheriot-llvm
Microsoft Open Sourced683ebe2023-02-03 11:49:58 +0000123```
124
125This can be inside the source checkout but you may prefer to build somewhere else, for example on a different filesystem.
126Next, use `cmake` to configure the build:
127
128```sh
Marno van der Maas8a236f12024-02-16 17:42:37 +0000129$ cmake ${LLVM_PATH}/llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" -DCMAKE_INSTALL_PREFIX=install -DLLVM_ENABLE_UNWIND_TABLES=NO -DLLVM_TARGETS_TO_BUILD=RISCV -DLLVM_DISTRIBUTION_COMPONENTS="clang;clangd;lld;llvm-objdump;llvm-objcopy" -G Ninja
Microsoft Open Sourced683ebe2023-02-03 11:49:58 +0000130```
131
132It is very strongly recommended that you do a release build, debug builds can take several minutes to compile files that take seconds with release builds.
133The `LLVM_DISTRIBUTION_COMPONENTS` flag will let us build only the components that we want.
134You can change the `install` location to somewhere else, for example `~/cheriot-tools` if you want a more memorable path.
135
136Finally, build the toolchain:
137
138```sh
139$ export NINJA_STATUS='%p [%f:%s/%t] %o/s, %es'
140$ ninja install-distribution
141```
142
143The first line here is optional, it will give you a more informative progress indicator.
144At the end of this process, you will have the toolchain files installed in the location that you passed as the `CMAKE_INSTALL_PREFIX` option to `cmake` (the `install` directory inside your build directory if you didn't change the `cmake` line).
145This will include:
146
147 - `clang` / `clang++`, the C/C++ compiler.
148 - `ld.lld`, the linker.
149 - `llvm-objdump`, the tool for creating human-readable dumps of object code.
150 - `clangd`, the language-server protocol implementation that is aware of our C/C++ extensions.
151
152#### Configuring your editor
153
154If your editor supports the language-server protocol then you should tell it to use the version of `clangd` that you have just built.
155There are more ways of doing this than there are editors and so this is not an exhaustive set of instructions.
156The `clangd` binary to use with any of them will be `bin/clangd` inside your LLVM install location.
157
158If you are using VS Code, then you can install the [clangd extension](https://github.com/clangd/vscode-clangd).
159Open its settings and find the entry labeled `Clangd: Path`.
160This should be set to your newly built `clangd` location.
161
162Vim and NeoVim have a number of language-server-protocol implementations.
163The [ALE](https://github.com/dense-analysis/ale) extension has separate configuration options for C and C++.
164You may wish to set these to the CHERIoT `clangd` only for paths that match a pattern where your CHERIoT code will live, by adding something like the following to your `.vimrc`:
165
166```vim
167autocmd BufNewFile,BufRead /home/myuser/cheriot/* let g:ale_c_clangd_executable = "/my/cheriot/llvm/install/bin/clangd"
168autocmd BufNewFile,BufRead /home/myuser/cheriot/* let g:ale_cpp_clangd_executable = "/my/cheriot/llvm/install/bin/clangd"
169```
170
171### Building the emulator
172
173The emulator is generated from a Sail formal model.
174Sail is an ISA specification language that is implemented in ocaml.
175None of the ocaml components (or any dependencies other than `libgmp.so`) are needed after the build and so you may prefer to run this build in a disposable container and just extract the emulator at the end.
176
177The first step in building it is to install the dependencies, including your platform's version of `opam`, the ocaml package manager.
178On Ubuntu:
179
180```sh
181# apt install opam z3 libgmp-dev cvc4
182```
183
184On FreeBSD:
185
186```sh
187# pkg ins ocaml-opam z3 gmp gmake pkgconf gcc
188```
189
190You can then install Sail with `opam`:
191
192```sh
193$ opam init --yes
194$ opam install --yes sail
195```
196
197Now clone the CHERIoT Sail repository:
198
199```sh
200$ git clone --depth 1 --recurse https://github.com/microsoft/cheriot-sail
201```
202
203Make sure that all of the relevant opam environment variables are set and build the model:
204
205```
206$ cd cheriot-sail
207$ eval $(opam env)
Microsoft Open Sourced683ebe2023-02-03 11:49:58 +0000208$ make csim
209```
210
211Note that this is a GNU Make build system, if you are running this on a non-GNU platform then GNU Make may be called `gmake` or similar and not `make`.
212
213This will produce an executable in `c_emulator/cheriot_sim`.
214This can be copied to another location such as somewhere in your path.
215
216### Installing xmake
217
218There are a lot of different ways of installing xmake and you should follow [the instructions that best match your platform](https://xmake.io/#/getting_started?id=installation).
219For Ubuntu, you can do:
220
221```sh
222# add-apt-repository ppa:xmake-io/xmake
223# apt update
224# apt install xmake
225```
226
Marno van der Maas7594bdf2024-11-06 13:26:04 +0000227### Installing uf2utils
David Chisnalleb226212024-06-14 13:51:51 +0100228
229If you are working with Sonata, you will need to convert the ELF files that the linker produces to [USB Flashing Format (UF2)](https://github.com/microsoft/uf2).
230The firmware on the RPi 2040 on the Sonata board can then load these files onto the CHERIoT Ibex and run them.
231
232The [uf2utils](https://github.com/makerdiary/uf2utils) project provides a tool to generate this format, which can be installed from pip.
233You will need to have Python 3 and pip installed.
234You can then follow their instructions to install.
235On *NIX systems, this is typically simply:
236
237```
238python3 -m pip install --pre -U git+https://github.com/makerdiary/uf2utils.git@main
239```
240
241Or the following on Windows:
242
243```
244py -3 -m pip install --pre -U git+https://github.com/makerdiary/uf2utils.git@main
245```
246
247The `xmake run` command for firmware using the `sonata` board will automatically invoke this correctly and provide the correct file.
248
249
Hugo Lefeuvre35f8cc92024-02-08 14:53:36 +0100250Running on the Arty A7
251----------------------
252
253We previously ran the test suite in the simulator.
254Let us now run it on the Arty A7 FPGA development board.
255
256We will first build the CHERIoT [small and fast FPGA emulator](https://github.com/microsoft/cheriot-safe) (SAFE) configuration and load it onto the FPGA.
257Then, we will build, install, and run the CHERIoT RTOS firmware on the board.
258
259### Building and Installing the SAFE FPGA Configuration
260
261We will add documentation for this part later.
262In the meantime, our [blog post](https://cheriot.org/fpga/try/2023/11/16/cheriot-on-the-arty-a7.html) provides pointers on how to do this.
263
speedy-he8dfab92024-05-13 14:18:19 +0100264There are two default clock speeds that SAFE configuration can be synthesised at following the build instructions, 20MHz and 33MHz.
265The expected clock speed for the Arty A7 board in this project is 33MHz, but can be changed if the FPGA design is running at a different clock speed.
266If you want to use the 20MHz, or any other clock speed, implementation, please update the *timer_hz* field in the board file `sdk/boards/ibex-arty-a7-100.json`
267
Hugo Lefeuvre35f8cc92024-02-08 14:53:36 +0100268### Building, Copying, and Running the Firmware
269
270We have now configured the FPGA.
271The LD4 LED on the FPGA board should be blinking green.
272We are ready to build, copy, and run the firmware.
273
274#### Building the Firmware
275
276We first need to reconfigure the build, and rebuild.
277For this example, we'll show rebuilding the test suite, but the same set of steps should work for any CHERIoT RTOS project (try the examples!):
278
279```sh
280$ cd tests
281$ xmake config --sdk=/cheriot-tools/ --board=ibex-arty-a7-100
282$ xmake
283```
284
285Note that `/cheriot-tools` is the location in the dev container.
286This value may vary if you did not use the dev container and must be the directory containing a `bin` directory with your LLVM build in it.
287
288Then, we need to build the firmware.
289This repository comes with a script to do this:
290
291```sh
292$ ../scripts/ibex-build-firmware.sh build/cheriot/cheriot/release/test-suite
293```
294
295The `./firmware` directory should now contain a firmware file `cpu0_iram.vhx`.
296This is the firmware we want copy onto the FPGA development board.
297
298#### Installing and Running the Firmware
299
300To copy the firmware onto the FPGA board, we will use minicom, which you can obtain through your your distribution's packaging system.
301For example on Ubuntu Linux distributions you would need to run (as root):
302
303```sh
304# apt install minicom
305```
306
307Now, plug the FPGA development board to your computer.
308We need to identify which serial device we will be using.
309On Linux, we do this by looking at the dmesg output:
310
311```sh
312$ sudo dmesg | grep tty
313(...)
314[19966.674679] usb 1-4: FTDI USB Serial Device converter now attached to ttyUSB1
315```
316
317The most recent lines of this command appear when plugging and unplugging your FPGA board, and indicate which serial device corresponds to the board.
318Here, it is `ttyUSB1`.
319
320Now we can open minicom (replace `ttyUSB1` with the serial device you just determined):
321
322```sh
323$ sudo minicom -c on -D ttyUSB1
324Welcome to minicom 2.8
325
326OPTIONS: I18n
327Port /dev/ttyUSB1, 13:51:28
328
329Press CTRL-A Z for help on special keys
330
331Ready to load firmware, hold BTN0 to ignore UART input.
332```
333
334Hitting the RESET button on the FPGA should produce the "Ready to load firmware..." line, which is the output from the loader on the FPGA.
335
336The "Press CTRL-A Z for help on special keys" message tells you which meta key is configured on your system.
337Here, the meta key is `CTRL-A`.
338The meta key varies across systems (the default on macOS is `<ESC>`) and configurations and so we refer to it as `<META>`.
339
340We must now configure a few things:
341- Hit `<META>` + `U` to turn carriage return `ON`
342- Hit `<META>` + `W` to turn linewrap `ON`
343- Hit `<META>` + `O`, then select `Serial Port Setup`, to ensure that `Bps/Par/Bits` (E) is set to `115200 8N1`, F to L on `No`, and M and N on `0`.
344
345In particular, make sure that hardware and software flow control are *off*.
346On macOS, the kernel silently ignores these if they are not supported but on Linux the kernel will refuse to send data unless the flow control is in the correct state.
347Unfortunately, the hardware flow control lines in the Arty A7's UART are not physically connected to the USB controller.
348
349We can now send our firmware to the FPGA.
350Hit `<META>` + `Y`, and select the `cpu0_iram.vhx` file we produced earlier.
351Minicom should now start outputing:
352
353```
354Ready to load firmware, hold BTN0 to ignore UART input.
355Starting loading. First word was: 40812A15
356..
357```
358
359Minicom may block after printing a small number of dots.
360If it does, then it will resume if you press any key that would be sent over the serial link.
361Each dot represents 1 KiB of transmitted data.
362
363Once the firmware is fully loaded, the test suite will start executing:
364
365```
366Ready to load firmware, hold BTN0 to ignore UART input.
367Starting loading. First word was: 40812A15
368.............................................................................................
369............
370Finished loading. Last word was: 0300012C
371Number of words loaded to IRAM: 00006892
372Loaded firmware, jumping to IRAM.
373
374Test runner: Checking that rel-ro caprelocs work. This will crash if they don't. CHERI Perm
375issions are:
376Test runner: Global(0x0)
377...
378```
David Chisnalleb226212024-06-14 13:51:51 +0100379
380Running on Sonata
381-----------------
382
383The Sonata board from lowRISC is an FPGA prototyping platform designed specifically to work with the CHERIoT Ibex.
384If you have installed a [release of their system firmware](https://github.com/lowRISC/sonata-system/releases) that is at least v0.2, everything should be ready to work out of the box.
385
386### Building, Copying, and Running the Firmware
387
388The steps to build firmware are the same as for any other CHERIoT hardware, this time specifying `sonata` as the board.
389Let's build the test suite again:
390
391```
392$ cd tests
393$ xmake config --sdk=/cheriot-tools/ --board=sonata
394$ xmake
395```
396
397Note that /cheriot-tools is the location in the dev container.
398This value may vary if you did not use the dev container and must be the directory containing a bin directory with your LLVM build in it.
399
400### Running the firmware
401
402You can usually run firmware on Sonata simply with `xmake run`:
403
404```
405$ xmake run
406[100%]: build ok, spent 4.52s
407Converted to uf2, output size: 258048, start address: 0x101000
408Wrote 258048 bytes to test-suite.uf2
409Firmware copied to /Volumes//SONATA/
410```
411
412If the last line instead says something like the following, one extra step is needed:
413
414```
415Please copy {some path}/cheriot-rtos/tests/build/cheriot/cheriot/release/firmware.uf2 to the SONATA drive to load.
416```
417
418If your SONATA board is connected, you should have a filesystem mounted called `SONATA` as a USB mass storage device.
419You can copy the file mentioned in this line to the `SONATA` drive to run it.
420The script that `xmake run` invokes looks in common mount locations for macOS and some Linux distributions to try to find the SONATA device.
421
422If you are running in the dev container, you are in an isolated environment with no access to this filesystem.
423On most systems, you can add this as an explicit mount by adding the following to the [`devcontainer.json`](https://github.com/microsoft/cheriot-rtos/blob/main/.devcontainer/devcontainer.json) file:
424
425```json
426 "mounts": [
427 "source={/your/SONATA/mount/point},target=/mnt/SONATA,type=bind"
428 ]
429```
430
431Replacing `{/your/SONATA/mount/point}` with the mount point of your `SONATA` filesystem.
432Your editor should prompt to rebuild the container at this point.
433
434If you invoked the dev container directly, rather than via an editor such as VS Code, then you will need to instead add the following to your `docker run` command:
435
436```
437--mount source={/your/SONATA/mount/point},target=/mnt/SONATA,type=bind
438```
439
440Again, replacing `{/your/SONATA/mount/point}` with the real mount point.
441
442If you are on Windows, this will not work because Docker on Windows runs containers in a WSL2 VM and needs to have host filesystems mounted explicitly (Docker on macOS does this automatically).
443In theory, the following steps should work (run in the WSL2 terminal in the Docker WSL2 VM):
444
445```
446sudo mkdir /mnt/d
447sudo mount -t drvfs D: /mnt/d/
448```
449
450Assuming that `SONATA` is mounted as `D:` on Windows.
451The above commands should then work.
452Unfortunately, they do not.
453The cause of this is not currently known but will hopefully be fixed in a newer version of the Sonata RPi2040 firmware.
454
455### Seeing UART output
456
457If you ran the above `xmake run` commands, you will have noted that there is no output from the test suite.
458When you use a simulator, the UART output goes directly to the simulator's standard output.
459In contrast, when you run on an FPGA the output will go to a USB serial device.
460
461You will need to connect a terminal emulator to the corresponding serial port.
462The Sonata system exposes *four* serial devices, typically numbered 0-3.
463The UART is device 2.
464On Linux, this is usually `/dev/ttyUSB2` (if no other USB serial devices are connected).
465On macOS, the device name includes the serial number of the device and so will be something like `/dev/tty.usbserial-LN28292` (the last digit is the serial port number).
466On Windows, it will be a COM port, but unfortunately Windows is not always consistent about the order in which the ports appear.
467
468If you install a serial terminal (for example, `minicom` on *NIX or PuTTY on Windows), you can point it at the relevant serial port.
469
470The serial setup is the same as for the Arty A7 [above](#installing-and-running-the-firmware), aside from the different device name.
471
472Once a serial terminal is connected, running `xmake run` should show the output from the test suite.
473
474If you are unsure which of Sonata's serial ports is the correct one, you can connect your serial console to all four and see which produces output from the test suite.