From 502c045155d773236d2a635712d64ebc312fb30b Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 1 Mar 2024 14:32:51 +1100 Subject: [PATCH 001/103] add new structure for tutorials Signed-off-by: Birgit Brecknell --- TutorialsReworked/CAmkES/camkes-cross-vm.md | 0 TutorialsReworked/CAmkES/camkes-vm.md | 0 TutorialsReworked/CAmkES/camkes1.md | 0 TutorialsReworked/CAmkES/camkes2.md | 0 TutorialsReworked/CAmkES/camkes3.md | 0 TutorialsReworked/CAmkES/hello-camkes.md | 0 .../DynamicLibraries/initialisation.md | 0 TutorialsReworked/DynamicLibraries/ipc.md | 0 .../DynamicLibraries/processes.md | 0 TutorialsReworked/DynamicLibraries/timer.md | 0 .../GettingStarted/about-seL4.md | 0 .../GettingStarted/basic-principles.md | 0 TutorialsReworked/GettingStarted/microkit.md | 0 TutorialsReworked/mcs.md | 0 TutorialsReworked/seL4Kernel/capabilities.md | 0 TutorialsReworked/seL4Kernel/faults.md | 0 TutorialsReworked/seL4Kernel/hello-world.md | 224 +++++++++++++++++ TutorialsReworked/seL4Kernel/interrupts.md | 0 TutorialsReworked/seL4Kernel/ipc.md | 0 TutorialsReworked/seL4Kernel/mapping.md | 0 TutorialsReworked/seL4Kernel/notifications.md | 0 TutorialsReworked/seL4Kernel/setting-up.md | 236 ++++++++++++++++++ TutorialsReworked/seL4Kernel/threads.md | 0 TutorialsReworked/seL4Kernel/untyped.md | 0 index.md | 42 +++- 25 files changed, 501 insertions(+), 1 deletion(-) create mode 100644 TutorialsReworked/CAmkES/camkes-cross-vm.md create mode 100644 TutorialsReworked/CAmkES/camkes-vm.md create mode 100644 TutorialsReworked/CAmkES/camkes1.md create mode 100644 TutorialsReworked/CAmkES/camkes2.md create mode 100644 TutorialsReworked/CAmkES/camkes3.md create mode 100644 TutorialsReworked/CAmkES/hello-camkes.md create mode 100644 TutorialsReworked/DynamicLibraries/initialisation.md create mode 100644 TutorialsReworked/DynamicLibraries/ipc.md create mode 100644 TutorialsReworked/DynamicLibraries/processes.md create mode 100644 TutorialsReworked/DynamicLibraries/timer.md create mode 100644 TutorialsReworked/GettingStarted/about-seL4.md create mode 100644 TutorialsReworked/GettingStarted/basic-principles.md create mode 100644 TutorialsReworked/GettingStarted/microkit.md create mode 100644 TutorialsReworked/mcs.md create mode 100644 TutorialsReworked/seL4Kernel/capabilities.md create mode 100644 TutorialsReworked/seL4Kernel/faults.md create mode 100644 TutorialsReworked/seL4Kernel/hello-world.md create mode 100644 TutorialsReworked/seL4Kernel/interrupts.md create mode 100644 TutorialsReworked/seL4Kernel/ipc.md create mode 100644 TutorialsReworked/seL4Kernel/mapping.md create mode 100644 TutorialsReworked/seL4Kernel/notifications.md create mode 100644 TutorialsReworked/seL4Kernel/setting-up.md create mode 100644 TutorialsReworked/seL4Kernel/threads.md create mode 100644 TutorialsReworked/seL4Kernel/untyped.md diff --git a/TutorialsReworked/CAmkES/camkes-cross-vm.md b/TutorialsReworked/CAmkES/camkes-cross-vm.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/CAmkES/camkes-vm.md b/TutorialsReworked/CAmkES/camkes-vm.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/CAmkES/camkes1.md b/TutorialsReworked/CAmkES/camkes1.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/CAmkES/camkes2.md b/TutorialsReworked/CAmkES/camkes2.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/CAmkES/camkes3.md b/TutorialsReworked/CAmkES/camkes3.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/CAmkES/hello-camkes.md b/TutorialsReworked/CAmkES/hello-camkes.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/DynamicLibraries/initialisation.md b/TutorialsReworked/DynamicLibraries/initialisation.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/DynamicLibraries/ipc.md b/TutorialsReworked/DynamicLibraries/ipc.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/DynamicLibraries/processes.md b/TutorialsReworked/DynamicLibraries/processes.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/DynamicLibraries/timer.md b/TutorialsReworked/DynamicLibraries/timer.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/GettingStarted/about-seL4.md b/TutorialsReworked/GettingStarted/about-seL4.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/GettingStarted/basic-principles.md b/TutorialsReworked/GettingStarted/basic-principles.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/GettingStarted/microkit.md b/TutorialsReworked/GettingStarted/microkit.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/mcs.md b/TutorialsReworked/mcs.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/seL4Kernel/capabilities.md b/TutorialsReworked/seL4Kernel/capabilities.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/seL4Kernel/faults.md b/TutorialsReworked/seL4Kernel/faults.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/seL4Kernel/hello-world.md b/TutorialsReworked/seL4Kernel/hello-world.md new file mode 100644 index 0000000000..a365b07163 --- /dev/null +++ b/TutorialsReworked/seL4Kernel/hello-world.md @@ -0,0 +1,224 @@ +--- +toc: true +layout: api +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2023 seL4 Project a Series of LF Projects, LLC. +--- + +# Hello, world! +Outcomes + +In this tutorial you will +- Run Hello, World! to ensure your setup is working correctly +- Become familiar with the jargon *root task* +- Build and simulate a seL4 project +- Have a basic understanding of the role of the `CMakeLists.txt` file in applications + +## Prerequisites + +- [Set up your machine](setting-up-your-machine). + +## Python Dependencies +Additional python dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: +``` +pip install --user aenum +pip install --user pyelftools +``` +*Hint:* This step only needs to be done once, i.e. before doing your first tutorial + +## Get the code +``` +mkdir sel4-tutorials-manifest +cd sel4-tutorials-manifest +repo init -u https://github.com/seL4/sel4-tutorials-manifest +repo sync +``` + +`repo sync` may take a few moments to run + +*Hint:* The **Get the code** step only needs to be done once, i.e. before doing your first tutorial + + +## Building your first program + +seL4 is a microkernel, not an operating system, and as a result only provides very minimal services. +After the kernel boots, an initial thread called the *root task* is started, which is then responsible for + setting up the user-level system. +When the root task starts there are no available drivers, however a minimal C library is provided. + +The tutorial is already set up to print "Hello, world!", so at this point +all you need to do is build and run the tutorial. + +### Initialise the build directory + +``` +cd sel4-tutorials-manifest +./init --tut hello-world + +``` +This step creates two new directories in `sel4-tutorials-manifest`, namely `hello-world` and `hello-world_build` + +We will now use two terminals, as described in [Setting up your machine](setting-up-your-machine#mapping-a-container). + + - Terminal A is just a normal terminal, and is used for git operations, editing (e.g., vim, emacs), and other normal operations. + - Terminal B is running in a container, and is only used for compilation. + +This gives you the flexibility to use all the normal tools you are used to, while having the seL4 dependencies separated from your machine. + +### Build the program +Open a new terminal, Terminal B, to run a container. + +``` +cd sel4-tutorials-manifest/hello-world_build +``` + +Next, build the program in Terminal B using ninja + +``` +ninja +``` + + +If successful, you should see the final ninja rule passing, e.g.: +``` +[150/150] objcopy kernel into bootable elf +``` + +### Create a container +Then, create a container in Terminal B: +``` +container +``` + + +### Run Hello, World using QEMU +The final image can be run *inside* the container using the command: + +``` +./simulate +``` + +This will run the result on an instance of the [QEMU](https://www.qemu.org) simulator. +If everything has worked, you should see: + +``` +Booting all finished, dropped to user space +Hello, World! +``` + +After that output, there should be a capability violation and a stack dump, +because the program hasn't properly cleaned up after itself yet. (This will come in later examples.) + +`Ctrl-A, X` will terminate QEMU. + +## Looking at the sources +To look at the sources, open a new terminal, Terminal A: + +``` +cd sel4-tutorials-manifest/hello-world +ls +``` + +In your tutorial directory, you will find the following files: + * `CMakeLists.txt` - the file that incorporates the root task into the wider seL4 build system. + * `src/main.c` - the single source file for the initial task. + * `hello-world.md` - A generated README for the tutorial. + +### `CMakeLists.txt` + +Every application and library in an seL4 project requires a `CMakeLists.txt` file in order to be + incorporated into the project build system. + +```cmake +/*-- set build_file --*/ +include(${SEL4_TUTORIALS_DIR}/settings.cmake) +sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR}) + +cmake_minimum_required(VERSION 3.7.2) +# declare the hello-world CMake project and the languages it is written in (just C) +project(hello-world C ASM) + +# In future tutorials, these setup steps will be replaced with +# sel4_tutorials_setup_roottask_tutorial_environment() +find_package(seL4 REQUIRED) +find_package(elfloader-tool REQUIRED) +find_package(musllibc REQUIRED) +find_package(util_libs REQUIRED) +find_package(seL4_libs REQUIRED) + +sel4_import_kernel() +elfloader_import_project() + +# This sets up environment build flags and imports musllibc and runtime libraries. +musllibc_setup_build_environment_with_sel4runtime() +sel4_import_libsel4() +util_libs_import_libraries() +sel4_libs_import_libraries() +sel4_tutorials_import_libsel4tutorials() + +# Name the executable and list source files required to build it +add_executable(hello-world src/main.c) + +# List of libraries to link with the application. +target_link_libraries(hello-world + sel4runtime sel4 + muslc utils sel4tutorials + sel4muslcsys sel4platsupport sel4utils sel4debug) + +# Tell the build system that this application is the root task. +include(rootserver) +DeclareRootserver(hello-world) +/*- endset -*/ +/*? build_file ?*/ +``` + +### `main.c` +The main C is a very typical C file. For a basic root server application, the only requirement is that +a `main` function is provided. + +```c +#include + +/*-- filter TaskContent("hello-world", TaskContentType.ALL) -*/ +int main(int argc, char *argv[]) { + printf("Hello, World!\n"); + + return 0; +} +/*- endfilter --*/ +``` + +## Making a change +Test making a change to `main.c` by adding a second printf to output `"Second hello\n"`. + +```c +/*-- filter TaskContent("hello-world-mod", TaskContentType.COMPLETED) -*/ +int main(int argc, char *argv[]) { + printf("Hello, World!\n"); + + printf("Second hello\n"); + return 0; +} +/*- endfilter --*/ +``` +Once you have made your change, use Terminal B to rebuild the project: + +*Hint:* Remember to exit the QEMU siumator before rerunning the project with `ctrl-A,x`. *And* exit the container using `ctrl-D` + +Then rebuild using ninja and run the simulator again: +``` +ninja +container +./simulate +``` + +On success, you should see the following: + +``` +Hello, World! +Second hello +``` + + +**Include this stuff?** +- Get an understanding of the basic project layout \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/interrupts.md b/TutorialsReworked/seL4Kernel/interrupts.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/seL4Kernel/ipc.md b/TutorialsReworked/seL4Kernel/ipc.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/seL4Kernel/mapping.md b/TutorialsReworked/seL4Kernel/mapping.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/seL4Kernel/notifications.md b/TutorialsReworked/seL4Kernel/notifications.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/seL4Kernel/setting-up.md b/TutorialsReworked/seL4Kernel/setting-up.md new file mode 100644 index 0000000000..d3aa652cf1 --- /dev/null +++ b/TutorialsReworked/seL4Kernel/setting-up.md @@ -0,0 +1,236 @@ +--- +toc: true +layout: api +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2023 seL4 Project a Series of LF Projects, LLC. +--- + +# Setting up your machine +Overview +- Set up your machine - install dependencies required to run seL4 +- Run seL4test on a simulator +- Gain awareness of terminology used for seL4 + + + +## Docker +To compile and use seL4, it is recommended that you use Docker to isolate the dependencies from your machine. + +These instructions assume you are using Debian (or a derivative, such as Ubuntu), and are using Bash for your shell. However, it should be informative enough for users of other distros/shells to adapt. + +These instructions are intended for Ubuntu LTS versions 20.04 and 22.04. + +To begin, you will need at least these two programs: + + * make (`sudo apt install make`) + * docker (See [here](https://get.docker.com) or [here](https://docs.docker.com/engine/installation) for installation instructions) + +For convenience, add your account to the docker group: + +```bash +sudo usermod -aG docker $(whoami) +``` + +
+ More on Docker +
+ + **Available images** + + All the prebuilt docker images are available on [DockerHub here](https://hub.docker.com/u/trustworthysystems) + + These images are used by the Trustworthy Systems Continuous Integration (CI) software, and so represent a standard software setup we use. + The CI software always uses the `latest` docker image, but images are also tagged with the date they were built. + + **More information** + + You can find the dockerfiles and supporting Makefile [here](https://github.com/seL4/seL4-CAmkES-L4v-dockerfiles) + +
+ + +## Google's Repo tool + +The primary way of obtaining and managing seL4 project source is through the use of Google's Repo tool. + +To install run: +```sh + sudo apt-get update + sudo apt-get install repo +``` + +
+More on Repo +
+[More details about on installing Repo](https://source.android.com/setup/develop#installing-repo). + +[seL4 Repo cheatsheet](../projects/buildsystem/repo-cheatsheet) +
+ + +## Base build dependencies +To establish a usable development environment it is important to install your distributions basic build packages. + +### Base dependencies + +The basic build package on Ubuntu is the `build-essential` package. To install run: + +```sh +sudo apt-get update +sudo apt-get install build-essential +``` + +Additional base dependencies for building seL4 projects on Ubuntu include installing: + +```sh +sudo apt-get install cmake ccache ninja-build cmake-curses-gui +sudo apt-get install libxml2-utils ncurses-dev +sudo apt-get install curl git doxygen device-tree-compiler +sudo apt-get install u-boot-tools +sudo apt-get install python3-dev python3-pip python-is-python3 +sudo apt-get install protobuf-compiler python3-protobuf +``` + +### Simulating with QEMU + +To run seL4 projects on a simulator you will need QEMU. QEMU is a generic and open source machine emulator and virtualizer, and can emulate different architectures on different systems. + + +```sh +sudo apt-get install qemu-system-arm qemu-system-x86 qemu-system-misc +``` + +### Cross-compiling for ARM targets + +To build for ARM targets you will need a cross compiler: + +```sh +sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi +sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu +``` + +(you can install the hardware floating point versions as well if you wish) + +```sh +sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf +``` + +### Cross-compiling for RISC-V targets + +To build for RISC-V targets you will need a cross compiler: + +{% include risc-v.md %} + + +
+More on host dependencies +
+[A detailed guide on host dependencies](../projects/buildsystem/host-dependencies) +
+ + +## Python Dependencies + +Regardless of your Linux distribution, python dependencies are required to build seL4, the manual and its proofs. To install you can run: + +```sh +pip3 install --user setuptools +pip3 install --user sel4-deps +``` + +(Some distributions use `pip` for python3, others use `pip3`. Use the Python 3 version for your distribution.) + + +## Getting a build environment +To get a running build environment for seL4 and Camkes, run: + +```bash +git clone https://github.com/seL4/seL4-CAmkES-L4v-dockerfiles.git +cd seL4-CAmkES-L4v-dockerfiles +make user +``` + +This will give you a terminal inside a container that has all the relevant tools to build, simulate, and test seL4 & Camkes programs. + +The first time you run this, docker will fetch the relevant images, which may take a while. + +The last line will say something like: + +``` +Hello, welcome to the seL4/CAmkES/L4v docker build environment +``` + +## Mapping a container +To run the container from other directories (e.g. starting a container for the **[Hello World](hello-world) tutorial, you can setup a bash alias such as this: + +```bash +echo $'alias container=\'make -C ///seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc +# now open a new terminal, or run `source ~/.bashrc` +``` + +Replace `///` to match where you cloned the git repo of the docker files. + +*Reminder:* Include the absolute path to your `seL4-CAmkES-L4v-dockerfiles` folder, e.g. + +```bash +echo $'alias container=\'make -C //home/jblogs/seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc +# now open a new terminal, or run `source ~/.bashrc` + +``` + +This then allows you to run `container` from any directory. + +*Reminder:* Restart Ubuntu or run a new terminal for the changes in ``.bashrc` to take effect. + + +## An example workflow + +A good workflow is to run two terminals: + + - Terminal A is just a normal terminal, and is used for git operations, editing (e.g., vim, emacs), and other normal operations. + - Terminal B is running in a container, and is only used for compilation. + +This gives you the flexibility to use all the normal tools you are used to, while having the seL4 dependencies separated from your machine. + +### Compiling seL4 test + +Start two terminals (terminal A and terminal B). + +In terminal A, run these commands: + +```bash +jblogs@host:~$ mkdir ~/seL4test +jblogs@host:~$ cd ~/seL4test +jblogs@host:~/seL4test$ repo init -u https://github.com/seL4/seL4test-manifest.git +jblogs@host:~/seL4test$ repo sync +``` + +In terminal B, run these commands: + +```bash +jblogs@host:~$ cd ~/seL4test +jblogs@host:~/seL4test$ container # using the bash alias defined above +jblogs@in-container:/host$ mkdir build-x86 +jblogs@in-container:/host$ cd build-x86 +jblogs@in-container:/host/build-x86$ ../init-build.sh -DPLATFORM=x86_64 -DSIMULATION=TRUE +jblogs@in-container:/host/build-x86$ ninja +jblogs@in-container:/host/build-x86$ ./simulate +``` + +If you need to make any code modifications or commit things to git, use terminal A. If you need to recompile or simulate an image, use terminal B. + +`./simulate` will take a few minutes to run. If QEMU works, you'll see something like + +``` +Test suite passed. 121 tests passed. 57 tests disabled. +All is well in the universe +``` + +Note, if QEMU fails when trying to simulate the image, try configuring your Docker host to give the container more memory using [Docker Desktop](https://docs.docker.com/desktop/use-desktop/). + +That's it! seL4 is running. + +To quit QEMU: `Ctrl+a, x` + +## Next steps +- Try the [Hello world](hello-world) tutorial \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/threads.md b/TutorialsReworked/seL4Kernel/threads.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/TutorialsReworked/seL4Kernel/untyped.md b/TutorialsReworked/seL4Kernel/untyped.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/index.md b/index.md index dee4f9691b..06ff8c3715 100644 --- a/index.md +++ b/index.md @@ -76,4 +76,44 @@ This documentation site is for cooperatively developing and sharing documentatio - + From 3321716fcf57f58c70400cc9ef83bbce70f72970 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 1 Mar 2024 15:28:19 +1100 Subject: [PATCH 002/103] add about seL4 text Signed-off-by: Birgit Brecknell --- .../GettingStarted/about-seL4.md | 39 +++++++++++++++++++ index.md | 8 ++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/TutorialsReworked/GettingStarted/about-seL4.md b/TutorialsReworked/GettingStarted/about-seL4.md index e69de29bb2..d0b73b1955 100644 --- a/TutorialsReworked/GettingStarted/about-seL4.md +++ b/TutorialsReworked/GettingStarted/about-seL4.md @@ -0,0 +1,39 @@ +

About seL4

+ +

+ seL4 is a third-generation microkernel. It is broadly based on L4 and influenced by EROS. Like L4 it features abstractions for virtual address spaces, threads, IPC, and, unlike most earlier L4 kernels, an explicit in-kernel memory management model and capabilities for authorisation. +

+

+ Authority in seL4 is conferred by possession of a capability. Capabilities are segregated and stored in capability address spaces composed of capability container objects called CNodes. seL4 has six system calls, of which five require possession of a capability (the sixth is a yield to the scheduler). The five system calls are IPC primitives that are used either to invoke services implemented by other processes (using capabilities to port-like endpoints that facilitate message passing), or invoke kernel services (using capabilities to kernel objects, such as a thread control block (TCB)). While the number of system calls is small, the kernel’s effective API is the sum of all the interfaces presented by all kernel object types. +

+

+ Kernel memory management in seL4 is explicit. All kernel data structures are either statically allocated at boot time, or are dynamically-allocated first-class objects in the API. Kernel objects thus act as both inkernel data structures, and user-invoked fine-grained kernel services. Kernel objects include TCBs, CNodes, and level-1 and level-2 page tables (termed PageDirectories and PageTables). +

+

+ Authority over free memory is encapsulated in an untyped memory object. Creating new kernel objects explicitly involves invoking the retype method of an untyped +memory object, which allocates the memory for the object, initialises it, and returns a capability to the new object. +

+

+ Virtual address spaces are formed by explicit manipulation of virtual-memoryrelated kernel objects: PageDirectories, PageTables, ASIDPools and Frames (mappable physical memory). As such, address spaces have no kernel-defined structure (except for a protected region reserved for the seL4 kernel itself). Whether the userlevel system is Exokernel like, a multi-server, or a para-virtualised monolithic OS is determined by user-level via a map and unmap interface to Frames and PageTables. The distribution of authority to the kernel virtual memory (VM) objects ultimately determines the scope of influence over virtual and physical memory. +

+

+ Threads are the active entity in seL4. By associating a CNode and a virtual address space with a thread, user-level policies create high-level abstractions, such as processes or virtual machines. +

+

+ IPC is supported in two forms: synchronous message passing via endpoints (portlike destinations without in-kernel buffering), and asynchronous notification via asynchronous endpoints (rendezvous objects consisting of a single in-kernel word that is used to combine IPC sends using a logical or). Remote procedure call semantics are facilitated over synchronous IPC via reply capabilities. Send capabilities are minted from an initial endpoint capability. Send capabilities feature an immutable badge which is used by the specific endpoint’s IPC recipients to distinguish which send capability (and thus which authority) was used to send a message. The unforgeable badge, represented by an integer value, is delivered with the message. +

+

+ Exceptions are propagated via synchronous IPC to each thread’s exception handler (registered in the TCB via a capability to an endpoint). Similarly, page faults are also propagated using synchronous IPC to a thread’s page fault handler. Non-native system calls are treated as exceptions to support virtualisation. +

+

+ Device Drivers run as user-mode applications that have access to device registers and memory, either by mapping the device into the virtual address space, or by controlled access to device ports on x86 hardware. seL4 provides a mechanism to receive notification of interrupts (via asynchronous IPC) and acknowledge their receipt. +

+

+ The seL4 kernel runs on multiple platforms, and runs on common architectures like ARM and RiscV. +

+

+ Because sel4 is small, a lot more needs to be done in user space and there are a lot more choices about how to do that. We'll start by building a simple system using the seL4 Microkit, which is a software development kit for building static systems on seL4. +

+

+ Next: The seL4 microkit +

\ No newline at end of file diff --git a/index.md b/index.md index 06ff8c3715..aba01de625 100644 --- a/index.md +++ b/index.md @@ -80,13 +80,13 @@ This documentation site is for cooperatively developing and sharing documentatio

Tutorials

Tutorials and other material to learn about seL4.

    -
  • Getting started
  • +
  • Getting started
  • -
  • The seL4 kernel
  • +
  • The seL4 kernel
  • MCS
  • -
  • Dynamic libraries
  • +
  • Dynamic libraries
  • -
  • CAmkES
  • +
  • CAmkES
    • Hello CAmkES
    • CAmkES 1
    • From ca73b8308792d1d9c269547b1d99842ba4b0ef8f Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 1 Mar 2024 15:56:03 +1100 Subject: [PATCH 003/103] minor update microkit page Signed-off-by: Birgit Brecknell --- TutorialsReworked/GettingStarted/microkit.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/TutorialsReworked/GettingStarted/microkit.md b/TutorialsReworked/GettingStarted/microkit.md index e69de29bb2..5979e5056a 100644 --- a/TutorialsReworked/GettingStarted/microkit.md +++ b/TutorialsReworked/GettingStarted/microkit.md @@ -0,0 +1,17 @@ +

      The seL4 Microkit

      +

      + The seL4 Microkit is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4, while still leveraging the kernel’s benefits of security and performance. +

      +

      + The Microkit is distributed as an SDK that integrates with the build system of your choice, significantly reducing the barrier to entry for new users of seL4. +

      +

      + Go to the Microkit tutorial +

      +

      +

      + Previous: About seL4 +

      +

      + Next: The seL4 microkit +

      \ No newline at end of file From cd889c415f09d87c2a70c198bdc4b4de80e12d80 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 4 Mar 2024 12:51:13 +1100 Subject: [PATCH 004/103] rewrite tuts (incomplete) Signed-off-by: Birgit Brecknell --- .../GettingStarted/about-seL4.md | 8 +- .../GettingStarted/basic-principles.md | 0 TutorialsReworked/GettingStarted/microkit.md | 18 +- TutorialsReworked/seL4Kernel/capabilities.md | 381 ++++++++++++++++++ TutorialsReworked/seL4Kernel/hello-world.md | 66 ++- TutorialsReworked/seL4Kernel/mapping.md | 221 ++++++++++ TutorialsReworked/seL4Kernel/overview.md | 41 ++ TutorialsReworked/seL4Kernel/setting-up.md | 39 +- TutorialsReworked/seL4Kernel/untyped.md | 363 +++++++++++++++++ index.md | 5 +- 10 files changed, 1088 insertions(+), 54 deletions(-) delete mode 100644 TutorialsReworked/GettingStarted/basic-principles.md create mode 100644 TutorialsReworked/seL4Kernel/overview.md diff --git a/TutorialsReworked/GettingStarted/about-seL4.md b/TutorialsReworked/GettingStarted/about-seL4.md index d0b73b1955..74aeaee424 100644 --- a/TutorialsReworked/GettingStarted/about-seL4.md +++ b/TutorialsReworked/GettingStarted/about-seL4.md @@ -1,3 +1,9 @@ +--- +layout: home +title: seL4 Docs +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +---

      About seL4

      @@ -35,5 +41,5 @@ memory object, which allocates the memory for the object, initialises it, and re Because sel4 is small, a lot more needs to be done in user space and there are a lot more choices about how to do that. We'll start by building a simple system using the seL4 Microkit, which is a software development kit for building static systems on seL4.

      - Next: The seL4 microkit + Next: seL4 microkit tutorial

      \ No newline at end of file diff --git a/TutorialsReworked/GettingStarted/basic-principles.md b/TutorialsReworked/GettingStarted/basic-principles.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/TutorialsReworked/GettingStarted/microkit.md b/TutorialsReworked/GettingStarted/microkit.md index 5979e5056a..6b78b95314 100644 --- a/TutorialsReworked/GettingStarted/microkit.md +++ b/TutorialsReworked/GettingStarted/microkit.md @@ -1,17 +1,25 @@ -

      The seL4 Microkit

      +--- +layout: home +title: seL4 Docs +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +

      The seL4 Microkit tutorial

      The seL4 Microkit is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4, while still leveraging the kernel’s benefits of security and performance.

      - The Microkit is distributed as an SDK that integrates with the build system of your choice, significantly reducing the barrier to entry for new users of seL4. + The Microkit is distributed as an SDK that integrates with the build system of your choice, significantly reducing the barrier to entry for new users of seL4. We recommend it as the first tutorial, to familiarise new users with seL4 concepts.

      - Go to the Microkit tutorial + After completing the Microkit tutorial, go to seL4 kernel tutorials for a deep dive into seL4 concepts.

      + Go to the Microkit tutorial +

      - Previous: About seL4 + Previous: About seL4

      - Next: The seL4 microkit + Next: seL4 kernel tutorials

      \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/capabilities.md b/TutorialsReworked/seL4Kernel/capabilities.md index e69de29bb2..08138f87be 100644 --- a/TutorialsReworked/seL4Kernel/capabilities.md +++ b/TutorialsReworked/seL4Kernel/capabilities.md @@ -0,0 +1,381 @@ +--- +toc: true +layout: api +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# Capabilities + +This tutorial provides a basic introduction to seL4 capabilities. + +By the end of this tutorial, you should be familiar with: + +1. The jargon CNode, CSpace, CSlot. +2. Know how to invoke a capability. +3. Know how to delete and copy CSlots. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/TutorialsReworked/seL4Kernel/setting-ip#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut capabilities +# building the tutorial exercise +cd capabilities_build +ninja +``` + +
      +Hint: tutorial solutions +
      +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut capabilities +``` +Answers are also available in drop down menus under each section. +
      + + +## Background + +### What is a capability? + +A *capability* is a unique, unforgeable token that gives the possessor +permission to access an entity or object in system. One way to think of a +capability is as a pointer with access rights. There are three kinds of +capabilities in seL4: + +* capabilities that control access to kernel objects such as thread control blocks, +* capabilities that control access to abstract resources such as `IRQControl`, and +* untyped capabilities, that are responsible for memory ranges and allocation + from those (see also the [Untyped](untyped) tutorial). + +In seL4, capabilities to all resources controlled by the kernel are given to the root +task on initialisation. To change the state of any resource, user code can use +the kernel API, available in `libsel4` to request an operation on the resource +a specific capability points to. + +For example, the root task is provided with a capability to its own thread +control block (TCB), `seL4_CapInitThreadTCB`, a constant defined by `libsel4`. +To change the properties of the initial TCB, one can use any of the [TCB API +methods](https://docs.sel4.systems/projects/sel4/api-doc.html#sel4_tcb) on this +capability. + +Below is an example which changes the stack pointer of the root task's TCB, a +common operation in the root task if a larger stack is needed: + +```c + seL4_UserContext registers; + seL4_Word num_registers = sizeof(seL4_UserContext)/sizeof(seL4_Word); + + /* Read the registers of the TCB that the capability in seL4_CapInitThreadTCB grants access to. */ + seL4_Error error = seL4_TCB_ReadRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, ®isters); + assert(error == seL4_NoError); + + /* set new register values */ + registers.sp = new_sp; // the new stack pointer, derived by prior code. + + /* Write new values */ + error = seL4_TCB_WriteRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, ®isters); + assert(error == seL4_NoError); +``` + +The first argument of `seL4_TCB_ReadRegisters` and `seL4_TCB_WriteRegisters` +addresses the capability in slot `seL4_CapInitThreadTCB`. We will explain +addressing and slots below. The rest of the arguments are specific to the +invocations. Further documentation is available on +[TCB_ReadRegisters](https://docs.sel4.systems/projects/sel4/api-doc.html#read-registers) +and +[TCB_WriteRegisters](https://docs.sel4.systems/projects/sel4/api-doc.html#write-registers). + +### CNodes and CSlots + +A *CNode* (capability-node) is an object full of capabilities: you can think of a CNode as an array of capabilities. +We refer to slots as *CSlots* (capability-slots). In the example above, `seL4_CapInitThreadTCB` is the slot in the root +task's CNode that contains the capability to the root task's TCB. +Each CSlot in a CNode can be in the following state: + +* empty: the CNode slot contains a null capability, +* full: the slot contains a capability to a kernel resource. + +By convention the 0th CSlot is kept empty, for the same reasons as keeping NULL unmapped in + process virtual address spaces: to avoid errors when uninitialised slots are used unintentionally. + +The field `info->CNodeSizeBits` gives a measure of the size of the initial +CNode: it will have `1 << CNodeSizeBits` CSlots. A CSlot has +`1 << seL4_SlotBits` bytes, so the size of a CNode in bytes is +`1 << (CNodeSizeBits + seL4_SlotBits)`. + +### CSpaces + +A *CSpace* (capability-space) is the full range of capabilities accessible to a thread, which may be +formed of one or more CNodes. In this tutorial, we focus on the CSpace constructed for the root task +by seL4's initialisation protocol, which consists of one CNode. + +### CSpace addressing + +To refer to a capability and perform operations on it, you must *address* the +capability. There are two ways to address capabilities in the seL4 API. First is +by invocation, the second is by direct addressing. Invocation is a shorthand and +it is what we used to manipulate the registers of the root task's TCB, which we +now explain in further detail. + +#### Invocation + +Each thread has a special CNode capability installed in its TCB as its *CSpace +root*. This root can be empty (a null cap), for instance when the thread is not +authorised to invoke any capabilities at all, or it can be a capability to a +CNode. The root task always has a CSpace root capability that points to a CNode. + +In an *invocation*, a CSlot is addressed by implicitly invoking the CSpace root +of the thread that is performing the invocation. In the code example above, we +use an invocation on the `seL4_CapInitThreadTCB` CSlot to read from and write to +the registers of the TCB represented by the capability in that specific CSlot. + +```c +seL4_TCB_WriteRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, ®isters); +``` + +This implicitly looks up the `seL4_CapInitThreadTCB` CSlot in the CNode pointed to +by the CSpace root capability of the calling thread, which here is the root task. + +When it is clear by context and not otherwise relevant, we sometimes identify +the capability with the object it points to. So, instead of saying "the CNode +pointed to by the CSpace root capability", we sometimes say "the CSpace root". +If not sure, it is better to be precise. Like structs and pointers in C, objects +and capabilities are not actually interchangeable: one object can be pointed to +by multiple capabilities, and each of these capabilities could have a different +level of permissions to that object. + + +#### Direct CSpace addressing + +In contrast to invocation addressing, *direct addressing* allows you to specify +the CNode to look up in, rather than implicitly using the CSpace root. This form +of addressing is primarily used to construct and manipulate the shape of CSpaces +-- potentially the CSpace of another thread. Note that direct addressing also +requires invocation: the operation occurs by invoking a CNode capability, which +itself is indexed from the CSpace root. + +The following fields are used when directly addressing CSlots: + +* *_service/root* A capability to the CNode to operate on. +* *index* The index of the CSlot in the CNode to address. +* *depth* How far to traverse the CNode before resolving the CSlot. + +For the initial, single-level CSpace, the *depth* value is always `seL4_WordBits`. For invocations, the depth is always + implicitly `seL4_WordBits`. +More on CSpace depth will be discussed in future tutorials. + +In the example below, we directly address the root task's TCB to make a copy of +it in the 0th slot in the CSpace root. [CNode +copy](https://docs.sel4.systems/projects/sel4/api-doc.html#copy) requires two +CSlots to be directly addressed: the destination CSlot, and the source CSlot. +`seL4_CapInitThreadCNode` is used in three different roles here: as source root, +as destination root, and as source slot. It is used as source and destination +root, because we are copying within the same CNode -- the CNode of the initial +thread. It is used as source slot, because within the CNode of the initial +thread, `seL4_CapInitThreadCNode` is the slot of the capability we want to copy +(and the slot `0` is the destination). + +```c + seL4_Error error = seL4_CNode_Copy( + seL4_CapInitThreadCNode, 0, seL4_WordBits, // destination root, slot, and depth + seL4_CapInitThreadCNode, seL4_CapInitThreadTCB, seL4_WordBits, // source root, slot, and depth + seL4_AllRights); + assert(error == seL4_NoError); +``` + +All [CNode invocations](https://docs.sel4.systems/projects/sel4/api-doc.html#sel4_cnode) require direct CSpace addressing. + +### Initial CSpace + +The root task has a CSpace, set up by seL4 during boot, which contains capabilities to all +resources managed by seL4. We have already seen several capabilities in the root CSpace: `seL4_CapInitThreadTCB`, + and `seL4_CapInitThreadCNode`. Both of these are specified by constants in `libsel4`, however not all initial + capabilities are statically specified. Other capabilities are described by the `seL4_BootInfo` data structure, + described in `libsel4` and initialised by seL4. `seL4_BootInfo` describes ranges of initial capabilities, + including free slots available in the initial CSpace. + +## Exercises + +The initial state of this tutorial provides you with the BootInfo structure, +and calculates the size (in slots) of the initial CNode object. + +```c +int main(int argc, char *argv[]) { + + /* parse the location of the seL4_BootInfo data structure from + the environment variables set up by the default crt0.S */ + seL4_BootInfo *info = platsupport_get_bootinfo(); + + size_t initial_cnode_object_size = BIT(info->initThreadCNodeSizeBits); + printf("Initial CNode is %zu slots in size\n", initial_cnode_object_size); +``` + +When you run the tutorial without changes, you will see something like the following output: + +``` +Booting all finished, dropped to user space +Initial CNode is 65536 slots in size +The CNode is 0 bytes in size +<> +main@main.c:33 [Cond failed: error] + Failed to set priority +``` + +By the end of the tutorial all of the output will make sense. For now, the first line is from the kernel. +The second is the `printf`, telling you the size of the initial CNode. +The third line stating the number of slots in the CSpace, is incorrect, and your first task is to fix that. + +### How big is your CSpace? + +**Exercise:** refer to the background above, and calculate the number of bytes occupied by the initial thread's CSpace. + +```c + size_t initial_cnode_object_size_bytes = 0; // TODO calculate this. + printf("The CNode is %zu bytes in size\n", initial_cnode_object_size_bytes); +``` +
      +Quick solution +```c + size_t initial_cnode_object_size_bytes = initial_cnode_object_size * (1u << seL4_SlotBits); +``` +
      + +### Copy a capability between CSlots + +After the output showing the number of bytes in the CSpace, you will see an error: + +``` +<> +main@main.c:33 [Cond failed: error] + Failed to set priority +``` + +The error occurs as the existing code tries to set the priority of the initial thread's TCB by + invoking the last CSlot in the CSpace, which is currently empty. seL4 then returns an error code, + and our check that the operation succeeded fails. + +**Exercise:** fix this problem by making another copy of the TCB capability into the last slot in the CNode. + +```c + seL4_CPtr first_free_slot = info->empty.start; + seL4_Error error = seL4_CNode_Copy(seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits, + seL4_CapInitThreadCNode, seL4_CapInitThreadTCB, seL4_WordBits, + seL4_AllRights); + ZF_LOGF_IF(error, "Failed to copy cap!"); + seL4_CPtr last_slot = info->empty.end - 1; + /* TODO use seL4_CNode_Copy to make another copy of the initial TCB capability to the last slot in the CSpace */ + + /* set the priority of the root task */ + error = seL4_TCB_SetPriority(last_slot, last_slot, 10); + ZF_LOGF_IF(error, "Failed to set priority"); +``` +
      +Quick solution +```c + /* use seL4_CNode_Copy to make another copy of the initial TCB capability to the last slot in the CSpace */ + error = seL4_CNode_Copy(seL4_CapInitThreadCNode, last_slot, seL4_WordBits, + seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits, seL4_AllRights); + ZF_LOGF_IF(error, "Failed to copy cap!"); +``` +
      +On success, you will now see the output: + +``` +<> +main@main.c:44 [Cond failed: error != seL4_FailedLookup] + first_free_slot is not empty +``` + +Which will be fixed in the next exercise. + +### How do you delete capabilities? + +The provided code checks that both `first_free_slot` and `last_slot` are empty, which of course is not +true, as you copied TCB capabilities into those CSlots. Checking if CSlots are empty is done +by a neat hack: by attempting to move the CSlots onto themselves. This should fail with an error code +`seL4_FailedLookup` if the source CSLot is empty, and an `seL4_DeleteFirst` if not. + +**Exercise:** delete both copies of the TCB capability. + +* You can either use `seL4_CNode_Delete` on the copies, or +* `seL4_CNode_Revoke` on the original capability to achieve this. + + + ```c + // TODO delete the created TCB capabilities + + // check first_free_slot is empty + error = seL4_CNode_Move(seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits, + seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits); + ZF_LOGF_IF(error != seL4_FailedLookup, "first_free_slot is not empty"); + + // check last_slot is empty + error = seL4_CNode_Move(seL4_CapInitThreadCNode, last_slot, seL4_WordBits, + seL4_CapInitThreadCNode, last_slot, seL4_WordBits); + ZF_LOGF_IF(error != seL4_FailedLookup, "last_slot is not empty"); +``` +
      +Quick solution +```c + // delete the created TCB capabilities + seL4_CNode_Revoke(seL4_CapInitThreadCNode, seL4_CapInitThreadTCB, seL4_WordBits); +``` +
      + +On success, the output will now show: + +``` +<> +<> +Suspending current thread +main@main.c:56 Failed to suspend current thread +``` + +#### Invoking capabilities + +**Exercise** Use `seL4_TCB_Suspend` to try and suspend the current thread. + +```c + printf("Suspending current thread\n"); + // TODO suspend the current thread + ZF_LOGF("Failed to suspend current thread\n"); +``` +
      +Quick solution +```c + // suspend the current thread + seL4_TCB_Suspend(seL4_CapInitThreadTCB); +``` +
      + +On success, the output will be as follows: + +``` +<> +<> +Suspending current thread +``` + +### Further exercises + +That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, +to become more familiar with CSpaces. + +* Use a data structure to track which CSlots in a CSpace are free. +* Make copies of the entire CSpace described by `seL4_BootInfo` +* Experiment with other [CNode invocations](https://docs.sel4.systems/projects/sel4/api-doc.html#sel4_cnode). + + + +

      + Previous: Hello world +

      +

      + Next: Untyped +

      diff --git a/TutorialsReworked/seL4Kernel/hello-world.md b/TutorialsReworked/seL4Kernel/hello-world.md index a365b07163..0a255af4a5 100644 --- a/TutorialsReworked/seL4Kernel/hello-world.md +++ b/TutorialsReworked/seL4Kernel/hello-world.md @@ -2,43 +2,16 @@ toc: true layout: api SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2023 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- # Hello, world! -Outcomes - In this tutorial you will - Run Hello, World! to ensure your setup is working correctly - Become familiar with the jargon *root task* - Build and simulate a seL4 project - Have a basic understanding of the role of the `CMakeLists.txt` file in applications -## Prerequisites - -- [Set up your machine](setting-up-your-machine). - -## Python Dependencies -Additional python dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: -``` -pip install --user aenum -pip install --user pyelftools -``` -*Hint:* This step only needs to be done once, i.e. before doing your first tutorial - -## Get the code -``` -mkdir sel4-tutorials-manifest -cd sel4-tutorials-manifest -repo init -u https://github.com/seL4/sel4-tutorials-manifest -repo sync -``` - -`repo sync` may take a few moments to run - -*Hint:* The **Get the code** step only needs to be done once, i.e. before doing your first tutorial - - ## Building your first program seL4 is a microkernel, not an operating system, and as a result only provides very minimal services. @@ -54,20 +27,36 @@ all you need to do is build and run the tutorial. ``` cd sel4-tutorials-manifest ./init --tut hello-world - ``` This step creates two new directories in `sel4-tutorials-manifest`, namely `hello-world` and `hello-world_build` -We will now use two terminals, as described in [Setting up your machine](setting-up-your-machine#mapping-a-container). +

      +Hint: tutorial solutions +
      +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut hello-world +``` +This will generate another `hello-world` directory and `hello-world_build` directory, with unique names, e.g. `hello-world44h1po5q` and `hello-world44h1po5q_build`. +
      + +We will now use two terminals, as described in [Setting up your machine](setting-up#mapping-a-container). - Terminal A is just a normal terminal, and is used for git operations, editing (e.g., vim, emacs), and other normal operations. - Terminal B is running in a container, and is only used for compilation. This gives you the flexibility to use all the normal tools you are used to, while having the seL4 dependencies separated from your machine. -### Build the program +### Create a container Open a new terminal, Terminal B, to run a container. +Create a container: +``` +container +``` + +### Build the program + ``` cd sel4-tutorials-manifest/hello-world_build ``` @@ -84,11 +73,6 @@ If successful, you should see the final ninja rule passing, e.g.: [150/150] objcopy kernel into bootable elf ``` -### Create a container -Then, create a container in Terminal B: -``` -container -``` ### Run Hello, World using QEMU @@ -218,7 +202,9 @@ On success, you should see the following: Hello, World! Second hello ``` - - -**Include this stuff?** -- Get an understanding of the basic project layout \ No newline at end of file +

      + Previous: Setting up your machine +

      +

      + Next: Capabilities +

      \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/mapping.md b/TutorialsReworked/seL4Kernel/mapping.md index e69de29bb2..a930e48e4e 100644 --- a/TutorialsReworked/seL4Kernel/mapping.md +++ b/TutorialsReworked/seL4Kernel/mapping.md @@ -0,0 +1,221 @@ +--- +toc: true +layout: api +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +# Mapping + +This tutorial provides an introduction to virtual memory management on seL4. + +By the end of this tutorial, you should be familiar with: + +1. How to map and unmap virtual memory pages in seL4. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/TutorialsReworked/seL4Kernel/setting-ip#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut mapping +# building the tutorial exercise +cd mapping_build +ninja +``` + +
      +Hint: tutorial solutions +
      +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut mapping +``` +Answers are also available in drop down menus under each section. +
      + + +## Background + +### Virtual memory + +seL4 does not provide virtual memory management, beyond kernel primitives for manipulating hardware +paging structures. User-level must provide services for creating intermediate paging structures, +mapping and unmapping pages. + +Users are free to define their own address space layout with one restriction: the seL4 kernel claims +the high part of the virtual memory range. On most 32-bit platforms, this is +0xe0000000 and above. This variable is set per platform, and can be found by finding the `kernelBase` variable +in the seL4 source. + +### Paging structures + +As part of the boot process, seL4 initialises the root task with a top-level hardware virtual +memory object, which is referred to as a *VSpace*. A capability to this structure is made available in the +`seL4_CapInitThreadVSpace` slot in the root tasks CSpace. For each architecture, this capability is +to a different object type corresponding to the hardware, top-level paging structure. The table below + lists the VSpace object type for each supported architecture. + +Architecture | VSpace Object +-------------|-------------- +aarch32 | `seL4_PageDirectory` | +aarch64 | `seL4_PageGlobalDirectory` | +ia32 | `seL4_PageDirectory` | +x86_64 | `seL4_PML4 ` | +RISC-V | `seL4_PageTable` | + +In addition to the top-level paging structure, intermediate hardware virtual memory objects are required to +map pages. The table below lists those objects, in order, for each architecture. + +Architecture | Objects +-------------|-------- +aarch32 | `seL4_PageTable` +aarch64 | `seL4_PageUpperDirectory`, `seL4_PageDirectory`, `seL4_PageTable` +ia32 | `seL4_PageTable` +x86_64 | `seL4_PDPT`, `seL4_PageDirectory`, `seL4_PageTable` +RISC-V | `seL4_PageTable` + +This tutorial covers the x86_64 architecture, but should contain sufficient information on the virtual +memory API provided by seL4 to generalise to other architectures. + +Each paging structure can be invoked in order to map or unmap it. Below is an example of mapping +an x86_64 `seL4_PDPT` object: + +```c + /* map a PDPT at TEST_VADDR */ + error = seL4_X86_PDPT_Map(pdpt, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_X86_Default_VMAttributes); +``` + +All mapping functions take three arguments: +* the VSpace to map the object into, +* the virtual address to map the object at, +* and virtual memory attributes. + +If the virtual memory address provided is not aligned to the size of the paging object, seL4 will mask out any +unused bits e.g a 4KiB page mapped at 0xDEADBEEF will end up mapped at 0xDEADB000. + +Virtual memory attributes determine the caching attributes of the mapping, which is architecture dependent. +Alongside the attributes used in this tutorial (`seL4_X86_Default_VMAttributes`) you can find alternative values, in +`libsel4`. + +### Pages + +Once all of the intermediate paging structures have been mapped for a specific virtual address range, +physical frames can be mapped into that range by invoking the frame capability. The code snippet below +shows an example of mapping a frame at address `TEST_VADDR`. + +```c + /* map a read-only page at TEST_VADDR */ + error = seL4_X86_Page_Map(frame, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_CanRead, seL4_X86_Default_VMAttributes); +``` + +For a page mapping to succeed, all mid-level paging structures must be mapped. The `libsel4` function +`seL4_MappingFailedLookupLevel()` can be used to determine at which level paging structures are missing. +Note that to map a frame multiple times, one must make copies of the frame capability: each frame capability +can only track one mapping. + +In addition to the arguments taken by the map methods for intermediate paging structures, page mapping takes a +`rights` argument which determines the mapping type. In the example above, we map the page read only. + +#### Types and sizes + +Page types and sizes are architecture dependent. For both x86 and ARM architectures, +each size of page is a different object type with a specific size. +On RISC-V, pages are the same object type and variably sized. +Configuration and hardware settings alter the available page sizes. + +## Exercises + +This tutorial uses several helper functions to allocate objects and capabilities. All object and +CSlot allocations have already been done for you using these functions. For more information see the +on these mechanisms, see the capabilities and untyped tutorials. + +### Map a page directory + +On starting the tutorial, you will see the following output: +``` +Missing intermediate paging structure at level 30 +main@main.c:34 [Cond failed: error != seL4_NoError] + Failed to map page +``` +This is because while the provided code maps in a `seL4_PDPT` object, there are two missing levels of +paging structures. The value corresponds to the `libsel4` constant `SEL4_MAPPING_LOOKUP_NO_PD` which is +the number of bits in the virtual address that could not be resolved due to missing paging structures. + +**Exercise** Map in the `pd` structure using (`seL4_PageDirectory_Map`)[https://docs.sel4.systems/ApiDoc.html#map-5]. + +```c + // TODO map a page directory object +``` + +On success, you should see the following: +``` +Missing intermediate paging structure at level 21 +main@main.c:34 [Cond failed: error != seL4_NoError] + Failed to map page +``` + +### Map a page table + +Note that in the above output, the number of failed bits has changed from `30` to `21`: this is because another +9 bits could be resolved from the newly mapped page directory. + +**Exercise** Map in the `pt` structure using [`seL4_PageTable_Map`](https://docs.sel4.systems/ApiDoc.html#map-6). + +```c + // TODO map a page table object +``` + +On success, you should see the following: +``` +Read x: 0 +Set x to 5 +Caught cap fault in send phase at address (nil) +while trying to handle: +vm fault on data at address 0xa000000000 with status 0x7 +in thread 0xffffff801ffb5400 "rootserver" at address 0x401afe +With stack: +0x41c920: 0x41c9d0 +... +``` + +The page is successfully mapped and we read a value of 0: as seL4 zeros all non-device pages when they are retyped from +untyped memory. However, then the code attempts to write to the page. Since you mapped the page as read-only, this fails +and the kernel raises a VM fault. + +Since the initial task does not have a fault handler (more details in the upcoming +threads tutorial), this triggers a subsequent capability fault (cap fault) on slot 0 (nil). Because you are running a +debug kernel for the tutorial, the kernel outputs the details of both faults. + +The vm fault is the most interesting: it shows the fault address, fault status register, and the instruction pointer +that the fault occured on (address). + +### Remap a page + +**Exercise** Fix the fault by remapping the page with `seL4_ReadWrite` permissions, using the +[seL4_X86_Page_Map](https://docs.sel4.systems/ApiDoc.html#map-4) invocation. +```c + // TODO remap the page +``` + +### Unmapping pages + +Pages can be unmapped by either using `Unmap` invocations on the page or any intermediate paging structure, or deleting +the final capability to any of the paging structure. + +### Further exercises + +That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, +to become more familiar with virtual memory management on seL4. + +* Try unmapping the structures you just mapped in. +* Port this tutorial to another architecture (ARM, RISCV). +* Create a generic function for converting from `seL4_MappingFailedLookupLevel` to the required seL4 object. + +

      + Previous: Untyped +

      +

      + Next: Threads +

      diff --git a/TutorialsReworked/seL4Kernel/overview.md b/TutorialsReworked/seL4Kernel/overview.md new file mode 100644 index 0000000000..bdb2cbaa16 --- /dev/null +++ b/TutorialsReworked/seL4Kernel/overview.md @@ -0,0 +1,41 @@ +--- +layout: home +title: seL4 Docs +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +

      Overview

      +We have developed a series of tutorials to on seL4 concepts. These assume a basic understanding of seL4, e.g. by having done the Microkit tutorial. + +

      Prerequisites

      +Note that all of these tutorials require C programming +experience and some understanding of operating systems and computer +architecture. Suggested resources for these include: + +- C programming language + - [C tutorial](https://www.cprogramming.com/tutorial/c-tutorial.html) +- Operating Systems: + - [Modern Operating Systems (book)](https://www.amazon.com/Modern-Operating-Systems-Andrew-Tanenbaum/dp/013359162X) + - [COMP3231 at UNSW](http://www.cse.unsw.edu.au/~cs3231) +- Computer Architecture + - [Computer Architecture (wikipedia)](https://en.wikipedia.org/wiki/Computer_architecture) + - [Instruction Set Architecture (wikipedia)](https://en.wikipedia.org/wiki/Instruction_set_architecture) + +

      Resources

      +We recommend having access to the seL4 manual and the API references. + + +

      Getting help

      +* [FAQ](https://docs.sel4.systems/FrequentlyAskedQuestions) +* [Debugging guide](https://docs.sel4.systems/DebuggingGuide.html) +* [seL4 Discourse forum](https://sel4.discourse.group) +* [Developer's mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) +* [Mattermost Channel](https://mattermost.trustworthy.systems/sel4-external/) + +

      + Previous: Microkit tutorial +

      +

      + Next: Setting up your machine +

      \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/setting-up.md b/TutorialsReworked/seL4Kernel/setting-up.md index d3aa652cf1..c5ab249c86 100644 --- a/TutorialsReworked/seL4Kernel/setting-up.md +++ b/TutorialsReworked/seL4Kernel/setting-up.md @@ -2,11 +2,11 @@ toc: true layout: api SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2023 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- # Setting up your machine -Overview +**Overview** - Set up your machine - install dependencies required to run seL4 - Run seL4test on a simulator - Gain awareness of terminology used for seL4 @@ -161,7 +161,7 @@ Hello, welcome to the seL4/CAmkES/L4v docker build environment ``` ## Mapping a container -To run the container from other directories (e.g. starting a container for the **[Hello World](hello-world) tutorial, you can setup a bash alias such as this: +To run the container from other directories (e.g. starting a container for the [Hello World](hello-world) tutorial, which we'll do next), you can setup a bash alias such as this: ```bash echo $'alias container=\'make -C ///seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc @@ -180,7 +180,7 @@ echo $'alias container=\'make -C //home/jblogs/seL4-CAmkES-L4v-dockerfiles user This then allows you to run `container` from any directory. -*Reminder:* Restart Ubuntu or run a new terminal for the changes in ``.bashrc` to take effect. +*Reminder:* Restart Ubuntu or run a new terminal for the changes in `.bashrc` to take effect. ## An example workflow @@ -232,5 +232,32 @@ That's it! seL4 is running. To quit QEMU: `Ctrl+a, x` -## Next steps -- Try the [Hello world](hello-world) tutorial \ No newline at end of file +# Tutorials +## Python Dependencies +Additional python dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: +``` +pip install --user aenum +pip install --user pyelftools +``` +*Hint:* This step only needs to be done once, i.e. before doing your first tutorial + +## Get the code +All tutorials are in the sel4-tutorials-manifest. Get the code with: +``` +mkdir sel4-tutorials-manifest +cd sel4-tutorials-manifest +repo init -u https://github.com/seL4/sel4-tutorials-manifest +repo sync +``` + +`repo sync` may take a few moments to run + +*Hint:* The **Get the code** step only needs to be done once, i.e. before doing your first tutorial. + + +

      + Previous: Overview +

      +

      + Next: Hello world +

      diff --git a/TutorialsReworked/seL4Kernel/untyped.md b/TutorialsReworked/seL4Kernel/untyped.md index e69de29bb2..2a42b8c633 100644 --- a/TutorialsReworked/seL4Kernel/untyped.md +++ b/TutorialsReworked/seL4Kernel/untyped.md @@ -0,0 +1,363 @@ +--- +toc: true +layout: api +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +# Untyped +This tutorial provides an introduction to physical memory management on seL4. + +By the end of this tutorial, you should be familiar with: + +1. The jargon *untyped*, *device untyped*, and *bit size*. +2. Know how to create objects from untyped memory in seL4. +3. Know how to reclaim objects. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/TutorialsReworked/seL4Kernel/setting-ip#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut untyped +# building the tutorial exercise +cd untyped_build +ninja +``` + +
      +Hint: tutorial solutions +
      +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut untyped +``` +Answers are also available in drop down menus under each section. +
      + + +## Background + +### Physical memory + +Apart from a small, static amount of kernel memory, all physical memory is managed by user level in an seL4 +system. Capabilities to objects created by seL4 at boot, as well as the rest of the physical resources managed by seL4, +are passed to the root task on start up. + +### Untyped memory and capabilities + +Excluding the objects used to create the root task, capabilities to all +available physical memory are passed to the root task as capabilities to +*untyped* memory. Untyped memory is a block of contiguous physical memory with a +specific size. Untyped capabilities are capabilities to untyped memory. Untyped +capabilities can be *retyped* into kernel objects together with capabilities to +them, or into further, usually smaller, untyped capabilities. + +Untyped capabilities have a boolean property *device* which indicates whether +the memory is writable by the kernel or not: it may not be backed by RAM but +some other device, or it may be in an area of RAM not addressable by the kernel. +Device untyped capabilities can only be retyped intro frame objects (physical +memory frames, which can be mapped into virtual memory), and cannot be written +to by the kernel. + + + +### Initial state + +The `seL4_BootInfo` structure provided to the root task describes all of the untyped capabilities, including their size, +if they are a device untyped, and the physical address of the untyped. The code example below +shows how to print out the initial untyped capabilities provided from `seL4_BootInfo`. + +```c + printf(" CSlot \tPaddr \tSize\tType\n"); + for (seL4_CPtr slot = info->untyped.start; slot != info->untyped.end; slot++) { + seL4_UntypedDesc *desc = &info->untypedList[slot - info->untyped.start]; + printf("%8p\t%16p\t2^%d\t%s\n", (void *) slot, (void *) desc->paddr, desc->sizeBits, desc->isDevice ? "device untyped" : "untyped"); + } +``` + +### Retyping + +Untyped capabilities have a single invocation: +[seL4_Untyped_Retype](https://docs.sel4.systems/ApiDoc.html#retype) which is +used to create a new capability (and potentially object) from an untyped +capability. Specifically, the new capability created by a retype invocation +provides access to a subset of the memory range of the original capability, +either as a smaller untyped capability, or pointing to a new object with a +specific type. New capabilities created by retyping an untyped capability are +referred to as *children* of that untyped capability. + +Untyped capabilities are retyped incrementally in a greedy fashion from the +invoked untyped, which is important to understand in order to gain efficient +memory utilisation in seL4 systems. Each untyped capability maintains a single +watermark, with addresses before the watermark being unavailable (already +retyped) and after the watermark being free (not retyped yet). On a retype +operation, the watermark is moved first to the alignment of the object being +created, and then to the end of the size of the object. For example, if we +create first a 4KiB object and then a 16KiB object, the 12KiB between the end of +the 4KiB object and the start of the 16KiB object are wasted due to alignment. +The memory cannot be reclaimed until both children are revoked. + +TL;DR: objects should be allocated in order of size, largest first, to avoid wasting memory. + +```c + error = seL4_Untyped_Retype(parent_untyped, // the untyped capability to retype + seL4_UntypedObject, // type + untyped_size_bits, //size + seL4_CapInitThreadCNode, // root + 0, // node_index + 0, // node_depth + child_untyped, // node_offset + 1 // num_caps + ); +``` + +The above code snippet shows an example of retyping an untyped into a smaller, +4KiB untyped capability (despite the name `seL4_UntypedObject` no object is +created, the new untyped capability simply points to a subset of the untyped +memory of `parent_untyped`. However, it is convenient to treat this memory like +an object for the purposes of this operation). We will refer to this snippet as +we discuss each parameter in the retype invocation. Recall that the first +parameter is the untyped capability being invoked to do the retype. + +#### Types + +Each object in seL4 has a specific type, and all of the type constants can be found in `libsel4`. Some types +are architecture specific, while others are general across architectures. In the example above, we create a +new untyped capability, which can be further retyped. All other object type parameters create kernel objects *and* +capabilities to them, and the type of the created object (and capability) determines the invocations +that can be made on that capability. For example, were we to retype into a thread control block +(TCB -- `seL4_TCBObject`), we could then perform TCB invocations on the capability to the new TCB object, including `seL4_TCB_SetPriority`. + +#### Size + +The size argument determines the size of the new object. The meaning of the argument +depends on the object type that is being requested: + +- most objects in seL4 are fixed size, and for these, the kernel will *ignore* + the size argument; +- the types `seL4_UntypedObject` and `seL4_SchedContextObject` allow a + variable size, which is specified in `size_bits` (more below); +- the type `seL4_CapTableObject` is also of variable size, and the argument specifies + the *number of capability slots*. The same mechanism as for `size_bits` is used, + but for the number of slots, not the size in bytes. + +In general in seL4, if sizes are measured in bits, they are powers +of two. "Bits" does not refer to the number of bits the object takes up, but +the bit-width that is needed to describe its contents. An object of bit size `n` +measures 2`n` bytes. Also, generally in seL4, objects and memory +regions are aligned to their size, i.e. an `n`-bit object is aligned to +2`n` bytes, or, equivalently, the address of the object has 0 as its +`n` bottom bits. + +For `retype`, it is enough to remember that the parameter `size_bits` means the +object will measure 2`size_bits` bytes, and for `seL4_CapTableObject` +that you are requesting 2`size_bits` slots (you can compute the size +in bytes by taking 2`size_bits + seL4_SlotBits`). + +#### Root, node_index & node_depth + +The `root`, `node_index` and `node_depth` parameters are used to specify the CNode in which to place the new capabilities. +Depending on the `depth` parameter, the CSlot to use is addressed by invocation or by direct addressing (see the [capabilities tutorial](https://docs.sel4.systems/Tutorials/capabilities.html) for an explanation of those terms). + +In the example above, `node_depth` is set to 0, which means invocation addressing is used: the `root` parameter is +looked up implicitly using the CSpace root of the current thread at a depth of `seL4_WordBits`. So the example code +specifies the root task's CNode (`seL4_CapInitThreadCNode`). The `node_index` parameter in this case is ignored. + +If the `node_depth` value is not set to 0, then direct addressing is used with the current thread's CSpace root +as the root. Then the `node_index` parameter is used to locate the CNode capability to place new capabilities in, +at the specified `node_depth`. This is designed for managing multi-level CSpaces, and is not covered in this tutorial. + +#### Node_offset + +The node_offset is the CSlot to start creating new capabilities at, in the CNode selected by the previous parameters. + In this case, the first empty CSlot in the initial CNode is selected. + +#### Num_caps + +The retype invocation can be used to create more than 1 capability and object at a time -- the number of capabilities is +specified using this argument. Note that there are two constraints on this value: + +1. The untyped must be big enough to fit all of the memory being retyped (`num_caps * (1u << size_bits)`). +2. The CNode must have enough consecutive free CSlots to fit all of the new capabilities. + +## Exercises + +### Create an untyped capability + +When you first run this tutorial, you will see something like the following output, which lists all of the +untyped capabilities provided to the root task on boot: + +``` +Booting all finished, dropped to user space + CSlot Paddr Size Type + 0x12d 0x100000 2^20 device untyped + 0x12e 0x200000 2^21 device untyped + 0x12f 0x400000 2^22 device untyped + 0x130 0xb2e000 2^13 device untyped +``` + +At the end of the output, there is an error: + +``` +<> +main@main.c:49 [Cond failed: error != seL4_NoError] + Failed to retype +``` + +This error happens because we are trying to create an untyped of size 0. + +**Exercise** Calculate the size of the child untyped required, such that the child untyped can be used + to create all of the objects listed in the `objects` array. Remember that object sizes are measured in + bits, that is, in powers of two. + +```c + // list of general seL4 objects + seL4_Word objects[] = {seL4_TCBObject, seL4_EndpointObject, seL4_NotificationObject}; + // list of general seL4 object size_bits + seL4_Word sizes[] = {seL4_TCBBits, seL4_EndpointBits, seL4_NotificationBits}; + + // TODO work out what size object we need to create to be able to create all of the objects + // listed above. Remember that sizes are in bits, that is, the exponents of powers of two. + seL4_Word untyped_size_bits = 0; + seL4_CPtr parent_untyped = 0; + seL4_CPtr child_untyped = info->empty.start; + + // First, find an untyped big enough to fit all of our objects + for (int i = 0; i < (info->untyped.end - info->untyped.start); i++) { + if (info->untypedList[i].sizeBits >= untyped_size_bits && !info->untypedList[i].isDevice) { + parent_untyped = info->untyped.start + i; + break; + } + } +``` +
      +Quick solution +```c + // seL4_EndpointBits and seL4_NotificationBits are both less than seL4_TCBBits, which + // means that all objects together fit into the size of two TCBs, or 2^(seL4_TCBBits + 1): + seL4_Word untyped_size_bits = seL4_TCBBits + 1; +``` +
      + +On success, the tutorial will progress further, printing "Failed to set priority" + +### Create a TCB Object + +The priority check is failing as `child_tcb` is an empty CSlot. + +**Exercise** fix this by creating a TCB object from `child_untyped` and place its cap into the `child_tcb` CSlot. + +```c + // use the slot after child_untyped for the new TCB cap: + seL4_CPtr child_tcb = child_untyped + 1; + /* TODO create a TCB in CSlot child_tcb */ + + // try to set the TCB priority + error = seL4_TCB_SetPriority(child_tcb, seL4_CapInitThreadTCB, 10); + ZF_LOGF_IF(error != seL4_NoError, "Failed to set priority"); +``` +
      +Quick solution +```c + /* create a TCB in CSlot child_tcb */ + seL4_Untyped_Retype(child_untyped, seL4_TCBObject, 0, seL4_CapInitThreadCNode, 0, 0, child_tcb, 1); +``` +
      + +On success, the tutorial will progress further, printing "Endpoint cap is null cap". + +### Create an endpoint object + +The error you see now is caused be an invalid endpoint capability. + +**Exercise** Create an endpoint object from `child_untyped` and place its cap into the `child_ep` CSlot. + +```c + // use the slot after child_tcb for the new endpoint cap: + seL4_CPtr child_ep = child_tcb + 1; + /* TODO create an endpoint in CSlot child_ep */ + + // identify the type of child_ep + uint32_t cap_id = seL4_DebugCapIdentify(child_ep); + ZF_LOGF_IF(cap_id == 0, "Endpoint cap is null cap"); +``` +
      +Quick solution +```c + /* create an endpoint in CSlot child_ep */ + seL4_Untyped_Retype(child_untyped, seL4_EndpointObject, 0, seL4_CapInitThreadCNode, 0, 0, child_ep, 1); +``` +
      + + +On success, 'Failed to bind notification' should be output. + +### Create a notification object + +The next part of the tutorial attempts to use a notification object that does not yet exist. + +**Exercise** create a notification object from `child_untyped` and place its cap into the `child_ntfn` CSlot. + +```c + // use the slot after child_ep for the new notification cap: + seL4_CPtr child_ntfn = child_ep + 1; + // TODO create a notification object in CSlot child_ntfn + + // try to use child_ntfn + error = seL4_TCB_BindNotification(child_tcb, child_ntfn); + ZF_LOGF_IF(error != seL4_NoError, "Failed to bind notification."); +``` +
      +Quick solution +```c + // create a notification object in CSlot child_ntfn + seL4_Untyped_Retype(child_untyped, seL4_NotificationObject, 0, seL4_CapInitThreadCNode, 0, 0, child_ntfn, 1); +``` +
      + + +### Delete the objects + +The final part of the tutorial attempts to create enough endpoint objects from `child_untyped` to consume the +entire untyped object. However, this fails, because the untyped is already completely consumed by the previous allocations. + +**Exercise** revoke the child untyped, so we can create new objects from it that use up the whole thing. + +```c + // TODO revoke the child untyped + + // allocate the whole child_untyped as endpoints + // Remember the sizes are exponents, so this computes 2^untyped_size_bits / 2^seL4_EndpointBits: + seL4_Word num_eps = BIT(untyped_size_bits - seL4_EndpointBits); + error = seL4_Untyped_Retype(child_untyped, seL4_EndpointObject, 0, seL4_CapInitThreadCNode, 0, 0, child_tcb, num_eps); + ZF_LOGF_IF(error != seL4_NoError, "Failed to create endpoints."); + + printf("Success\n"); +``` +
      +Quick solution +```c + // revoke the child untyped + error = seL4_CNode_Revoke(seL4_CapInitThreadCNode, child_untyped, seL4_WordBits); + assert(error == seL4_NoError); +``` +
      + +Once the tutorial is completed successfully, you should see the message "Success". + +### Further exercises + +That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try +to become more familiar with untyped objects and memory allocation in seL4. + +* Allocate objects at specific physical addresses. +* Create a simple object allocator for allocating seL4 objects. + +

      + Previous: Capabilities +

      +

      + Next: Mapping +

      diff --git a/index.md b/index.md index aba01de625..bb0a1c39ab 100644 --- a/index.md +++ b/index.md @@ -83,13 +83,14 @@ This documentation site is for cooperatively developing and sharing documentatio

    • Getting started
    • The seL4 kernel
      • +
      • Overview
      • Setting up your machine
      • Hello world
      • +
      • Capabilities
      • Untyped
      • Mapping
      • Threads
      • From 0d7dc8867c951897d1cb4db9a9d8e49dadbfaedb Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 4 Mar 2024 14:08:24 +1100 Subject: [PATCH 005/103] add reordered tutorial sidebar Signed-off-by: Birgit Brecknell --- TutorialsReworked/seL4Kernel/capabilities.md | 2 +- TutorialsReworked/seL4Kernel/hello-world.md | 3 +- TutorialsReworked/seL4Kernel/mapping.md | 28 ++++++++++++- TutorialsReworked/seL4Kernel/setting-up.md | 2 +- TutorialsReworked/seL4Kernel/untyped.md | 2 +- _includes/nav-sidebar.html | 42 ++++++++++++++++++++ 6 files changed, 74 insertions(+), 5 deletions(-) diff --git a/TutorialsReworked/seL4Kernel/capabilities.md b/TutorialsReworked/seL4Kernel/capabilities.md index 08138f87be..b3ef3468fa 100644 --- a/TutorialsReworked/seL4Kernel/capabilities.md +++ b/TutorialsReworked/seL4Kernel/capabilities.md @@ -1,6 +1,6 @@ --- toc: true -layout: api +layout: project SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/TutorialsReworked/seL4Kernel/hello-world.md b/TutorialsReworked/seL4Kernel/hello-world.md index 0a255af4a5..54cdb74595 100644 --- a/TutorialsReworked/seL4Kernel/hello-world.md +++ b/TutorialsReworked/seL4Kernel/hello-world.md @@ -1,10 +1,11 @@ --- toc: true -layout: api +layout: project SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- + # Hello, world! In this tutorial you will - Run Hello, World! to ensure your setup is working correctly diff --git a/TutorialsReworked/seL4Kernel/mapping.md b/TutorialsReworked/seL4Kernel/mapping.md index a930e48e4e..ae4bdb9322 100644 --- a/TutorialsReworked/seL4Kernel/mapping.md +++ b/TutorialsReworked/seL4Kernel/mapping.md @@ -1,6 +1,6 @@ --- toc: true -layout: api +layout: project SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- @@ -148,6 +148,15 @@ the number of bits in the virtual address that could not be resolved due to miss ```c // TODO map a page directory object ``` +
        +Quick solution +```c + // TODO map a page directory object + error = seL4_X86_PageDirectory_Map(pd,seL4_CapInitThreadVSpace, TEST_VADDR, seL4_X86_Default_VMAttributes); + assert(error == seL4_NoError); +``` +
        + On success, you should see the following: ``` @@ -166,6 +175,14 @@ Note that in the above output, the number of failed bits has changed from `30` t ```c // TODO map a page table object ``` +
        +Quick solution +```c + // map a page table object + error = seL4_X86_PageTable_Map(pt, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_X86_Default_VMAttributes); + assert(error == seL4_NoError); +``` +
        On success, you should see the following: ``` @@ -198,6 +215,15 @@ that the fault occured on (address). ```c // TODO remap the page ``` +
        +Quick solution +```c + // remap the page + error = seL4_X86_Page_Map(frame, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_ReadWrite, seL4_X86_Default_VMAttributes); + assert(error == seL4_NoError); +``` +
        + ### Unmapping pages diff --git a/TutorialsReworked/seL4Kernel/setting-up.md b/TutorialsReworked/seL4Kernel/setting-up.md index c5ab249c86..e495e62a35 100644 --- a/TutorialsReworked/seL4Kernel/setting-up.md +++ b/TutorialsReworked/seL4Kernel/setting-up.md @@ -1,6 +1,6 @@ --- toc: true -layout: api +layout: project SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/TutorialsReworked/seL4Kernel/untyped.md b/TutorialsReworked/seL4Kernel/untyped.md index 2a42b8c633..40c4c7f454 100644 --- a/TutorialsReworked/seL4Kernel/untyped.md +++ b/TutorialsReworked/seL4Kernel/untyped.md @@ -1,6 +1,6 @@ --- toc: true -layout: api +layout: project SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index ec2e59d4a3..f43bfab129 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -66,3 +66,45 @@
      {% endif %} + +{% if page_url[1] == "TutorialsReworked" %} + +{% endif %} + From c6e88b037bae950350d1f70f92cc97b400d395e1 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 4 Mar 2024 14:26:02 +1100 Subject: [PATCH 006/103] fix nav-sidebar Signed-off-by: Birgit Brecknell --- .../GettingStarted/about-seL4.md | 6 +- TutorialsReworked/GettingStarted/microkit.md | 9 +-- TutorialsReworked/seL4Kernel/capabilities.md | 5 +- TutorialsReworked/seL4Kernel/hello-world.md | 5 +- TutorialsReworked/seL4Kernel/mapping.md | 5 +- TutorialsReworked/seL4Kernel/overview.md | 9 +-- TutorialsReworked/seL4Kernel/setting-up.md | 6 +- TutorialsReworked/seL4Kernel/untyped.md | 5 +- _includes/nav-sidebar.html | 55 +++++++++---------- 9 files changed, 41 insertions(+), 64 deletions(-) diff --git a/TutorialsReworked/GettingStarted/about-seL4.md b/TutorialsReworked/GettingStarted/about-seL4.md index 74aeaee424..b22bb2a8d9 100644 --- a/TutorialsReworked/GettingStarted/about-seL4.md +++ b/TutorialsReworked/GettingStarted/about-seL4.md @@ -1,6 +1,6 @@ --- -layout: home -title: seL4 Docs +toc: true +layout: project SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- @@ -41,5 +41,5 @@ memory object, which allocates the memory for the object, initialises it, and re Because sel4 is small, a lot more needs to be done in user space and there are a lot more choices about how to do that. We'll start by building a simple system using the seL4 Microkit, which is a software development kit for building static systems on seL4.

      - Next: seL4 microkit tutorial + Next tutorial: seL4 microkit tutorial

      \ No newline at end of file diff --git a/TutorialsReworked/GettingStarted/microkit.md b/TutorialsReworked/GettingStarted/microkit.md index 6b78b95314..4df6163097 100644 --- a/TutorialsReworked/GettingStarted/microkit.md +++ b/TutorialsReworked/GettingStarted/microkit.md @@ -1,6 +1,6 @@ --- -layout: home -title: seL4 Docs +toc: true +layout: project SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- @@ -18,8 +18,5 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. Go to the Microkit tutorial

      - Previous: About seL4 -

      -

      - Next: seL4 kernel tutorials + Next tutorial: seL4 kernel tutorials

      \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/capabilities.md b/TutorialsReworked/seL4Kernel/capabilities.md index b3ef3468fa..67d2d736bf 100644 --- a/TutorialsReworked/seL4Kernel/capabilities.md +++ b/TutorialsReworked/seL4Kernel/capabilities.md @@ -374,8 +374,5 @@ to become more familiar with CSpaces.

      - Previous: Hello world -

      -

      - Next: Untyped + Next tutorial: Untyped

      diff --git a/TutorialsReworked/seL4Kernel/hello-world.md b/TutorialsReworked/seL4Kernel/hello-world.md index 54cdb74595..aac5611519 100644 --- a/TutorialsReworked/seL4Kernel/hello-world.md +++ b/TutorialsReworked/seL4Kernel/hello-world.md @@ -204,8 +204,5 @@ Hello, World! Second hello ```

      - Previous: Setting up your machine -

      -

      - Next: Capabilities + Next tutorial: Capabilities

      \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/mapping.md b/TutorialsReworked/seL4Kernel/mapping.md index ae4bdb9322..73ca8e4e3e 100644 --- a/TutorialsReworked/seL4Kernel/mapping.md +++ b/TutorialsReworked/seL4Kernel/mapping.md @@ -240,8 +240,5 @@ to become more familiar with virtual memory management on seL4. * Create a generic function for converting from `seL4_MappingFailedLookupLevel` to the required seL4 object.

      - Previous: Untyped -

      -

      - Next: Threads + Next tutorial: Threads

      diff --git a/TutorialsReworked/seL4Kernel/overview.md b/TutorialsReworked/seL4Kernel/overview.md index bdb2cbaa16..ce8982d496 100644 --- a/TutorialsReworked/seL4Kernel/overview.md +++ b/TutorialsReworked/seL4Kernel/overview.md @@ -1,6 +1,6 @@ --- -layout: home -title: seL4 Docs +toc: true +layout: project SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- @@ -34,8 +34,5 @@ We recommend having access to the Microkit tutorial -

      -

      - Next: Setting up your machine + Next tutorial: Setting up your machine

      \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/setting-up.md b/TutorialsReworked/seL4Kernel/setting-up.md index e495e62a35..e28fc657c6 100644 --- a/TutorialsReworked/seL4Kernel/setting-up.md +++ b/TutorialsReworked/seL4Kernel/setting-up.md @@ -254,10 +254,6 @@ repo sync *Hint:* The **Get the code** step only needs to be done once, i.e. before doing your first tutorial. - -

      - Previous: Overview -

      - Next: Hello world + Next tutorial: Hello world

      diff --git a/TutorialsReworked/seL4Kernel/untyped.md b/TutorialsReworked/seL4Kernel/untyped.md index 40c4c7f454..2959cd1faf 100644 --- a/TutorialsReworked/seL4Kernel/untyped.md +++ b/TutorialsReworked/seL4Kernel/untyped.md @@ -356,8 +356,5 @@ to become more familiar with untyped objects and memory allocation in seL4. * Create a simple object allocator for allocating seL4 objects.

      - Previous: Capabilities -

      -

      - Next: Mapping + Next tutorial: Mapping

      diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index f43bfab129..82c6176a39 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -11,7 +11,7 @@

      @@ -60,7 +60,7 @@ {% assign tutorials = site.pages | where_exp: 'page', 'page.tutorial' | sort: 'tutorial-order' %} {% for t in tutorials %}
    • - {{t.title}} + {{t.title}}
    • {% endfor %}
    @@ -71,40 +71,39 @@ {% endif %} - From 85b95919a3c159fbddaa7e926791ecb5dc2e30ef Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 4 Mar 2024 19:28:40 +1100 Subject: [PATCH 007/103] rework tuts (incomplete); update navbar Signed-off-by: Birgit Brecknell --- TutorialsReworked/seL4Kernel/capabilities.md | 5 +- TutorialsReworked/seL4Kernel/hello-world.md | 5 +- TutorialsReworked/seL4Kernel/ipc.md | 363 +++++++++++++ TutorialsReworked/seL4Kernel/mapping.md | 4 +- TutorialsReworked/seL4Kernel/notifications.md | 224 ++++++++ TutorialsReworked/seL4Kernel/threads.md | 493 ++++++++++++++++++ TutorialsReworked/seL4Kernel/untyped.md | 4 +- _includes/nav-sidebar.html | 5 + 8 files changed, 1090 insertions(+), 13 deletions(-) diff --git a/TutorialsReworked/seL4Kernel/capabilities.md b/TutorialsReworked/seL4Kernel/capabilities.md index 67d2d736bf..e22267ce47 100644 --- a/TutorialsReworked/seL4Kernel/capabilities.md +++ b/TutorialsReworked/seL4Kernel/capabilities.md @@ -372,7 +372,4 @@ to become more familiar with CSpaces. * Experiment with other [CNode invocations](https://docs.sel4.systems/projects/sel4/api-doc.html#sel4_cnode). - -

    - Next tutorial: Untyped -

    +Next tutorial: Untyped diff --git a/TutorialsReworked/seL4Kernel/hello-world.md b/TutorialsReworked/seL4Kernel/hello-world.md index aac5611519..3547daa7ca 100644 --- a/TutorialsReworked/seL4Kernel/hello-world.md +++ b/TutorialsReworked/seL4Kernel/hello-world.md @@ -203,6 +203,5 @@ On success, you should see the following: Hello, World! Second hello ``` -

    - Next tutorial: Capabilities -

    \ No newline at end of file + +Next tutorial: Capabilities \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/ipc.md b/TutorialsReworked/seL4Kernel/ipc.md index e69de29bb2..ae8314e0fd 100644 --- a/TutorialsReworked/seL4Kernel/ipc.md +++ b/TutorialsReworked/seL4Kernel/ipc.md @@ -0,0 +1,363 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +# IPC +This tutorial is about interprocess communication (IPC), the microkernel mechanism for synchronous transmission of small amounts of data. + +You will learn +1. How to use IPC to send data and capabilities between processes. +2. The jargon *cap transfer*. +3. How to to differentiate requests via badged capabilities. +4. Design protocols that use the IPC fastpath. + + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut ipc +# building the tutorial exercise +cd ipc_build +ninja +``` + +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut ipc +``` +Answers are also available in drop down menus under each section. +
    + +## CapDL Loader + +This tutorial uses a the *capDL loader*, a root task which allocates statically + configured objects and capabilities. + +
    +Get CapDL +The capDL loader parses +a static description of the system and the relevant ELF binaries. +It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects +but we also use it in the tutorials to reduce redundant code. +The program that you construct will end up with its own CSpace and VSpace, which are separate +from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning +in applications loaded by the capDL loader. + +More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). + +For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. +
    + +## Background + +Interprocess communication (IPC) is the microkernel mechanism for synchronous transmission of small amounts of data +and capabilities between processes. In seL4, IPC is facilitated by small kernel objects known as *endpoints*, which +act as general communication ports. Invocations on endpoint objects are used to send and receive IPC messages. + +Endpoints consist of a queue of threads waiting to send, or waiting to receive messages. To understand +this, consider an example where *n* threads are waiting for a message on an endpoint. If *n* threads +send messages on the endpoint, all *n* waiting threads will receive the message and wake up. If an *n+1*th +sender sends a message, that sender is now queued. + +### System calls + +Threads can send messages on endpoints with the system call `seL4_Send`, which blocks until the message has been +consumed by another thread. `seL4_NBSend` can also be used, which performs a polling send: the send is only +successful if a receiver is already blocked waiting for a message, and otherwise fails. To avoid a +back channel, `seL4_NBSend` does not return a result indicating if the message was sent or not. + +`seL4_Recv` can be used to receive messages, and `seL4_NBRecv` can be used to poll for messages. + +`seL4_Call` is a system call that essentially combines an `seL4_Send` and an `seL4_Recv` with one +major difference: in the receive phase, thread which uses this function is blocked on a one-time capability termed a +*reply capability*, and not the endpoint itself. In a client-server scenario, where clients use +`seL4_Call` to make requests, the server can explicitly reply to the correct client. + +The reply capability is stored internally in the thread control block (TCB) of the receiver. The system +call `seL4_Reply` invokes this capability, which sends an IPC to the client and wakes it up. `seL4_ReplyRecv` +does the same, except it sends the reply and blocks on the provided endpoint in a combined system call. + +Since TCBs have a single space to store a reply capability, if servers need to service multiple +requests (e.g saving requests to reply at a later time, after hardware operations have been completed), +[`seL4_CNode_SaveCaller`](https://docs.sel4.systems/ApiDoc.html#save-caller) can be used to save +the reply capability to an empty slot in the receivers CSpace. + +### IPC Buffer + +Each thread has a buffer (referred to as the *IPC buffer*), which contains the payload of the IPC message, +consisting of data and capabilities. Senders specify a message length and the kernel copies this (bounded) +amount between the sender and receiver IPC buffer. + +### Data transfer + +The IPC buffer contains a bounded area of message registers (MR) used to transmit data on IPC. Each +register is the machine word size, and the maximum message size is available in the +`seL4_MsgMaxLength` constant provided by `libsel4`. + +Messages can be loaded into the IPC buffer using `seL4_SetMR` and extracted using `seL4_GetMR`. +Small messages are sent in registers and do not require a copy operation. The amount of words +that fit in registers is available in the `seL4_FastMessageRegisters` constant. + +The amount of data being transferred, in terms of the number of message registers used, must be +set in as the `length` field in the `seL4_MessageInfo_t` data structure. + +### Cap transfer + +Along with data, IPC can be used to send capabilities between processes per message. This is referred to as + *cap transfer*. The number of capabilities being transferred is encoded in the `seL4_MessageInfo_t` +structure as `extraCaps`. Below is an example for sending a capability via IPC: + +```c + seL4_MessageInfo info = seL4_MessageInfo_new(0, 0, 1, 0); + seL4_SetCap(0, free_slot); + seL4_Call(endpoint, info); +``` + +To receive a capability, the receiver must specify a cspace address to place the capability in. This is +shown in the code example below: + +```c + seL4_SetCapReceivePath(cnode, badged_endpoint, seL4_WordBits); + seL4_Recv(endpoint, &sender); +``` + +The access rights of the received capability are the same as by the rights that the receiver has to the endpoint. +Note that while senders can send multiple capabilities, receivers can only receive one at a time. + +### Capability unwrapping + +seL4 can also *unwrap* capabilities on IPC. +If the n-th capability in the message refers to the endpoint through which the message +is sent, the capability is unwrapped: its badge is placed into the n-th position of the +receiver's IPC buffer (in the field `caps_or_badges`), and the kernel sets the n-th bit +(counting from the least significant) in the `capsUnwrapped` field of `seL4_MessageInfo_t`. + +### Message Info + +The `seL4_MessageInfo_t` data structure is used to encode the description of an IPC message into a single word. +It is used to describe a message to be sent to seL4, and for seL4 to describe the message that was +sent to the receiver. +It contains the following fields: + +* `length` the amount of message registers (data) in the message (`seL4_MsgMaxLength` maximum), +* `extraCaps` the number of capabilities in the message (`seL4_MsgMaxExtraCaps`) +* `capsUnwrapped` marks any capabilities unwrapped by the kernel. +* `label` data that is transferred unmodified by the kernel from sender to receiver, + +### Badges + +Along with the message the kernel additionally delivers the badge of the endpoint capability +that the sender invoked to send the message. Endpoints can be badged using +[`seL4_CNode_Mint`](https://docs.sel4.systems/ApiDoc.html#mint) or + [`seL4_CNode_Mutate`](https://docs.sel4.systems/ApiDoc.html#mutate). Once an endpoint is badged, +the badge of the endpoint is transferred to any receiver that receives messages on that endpoint. +The code example below demonstrates this: + +```c +seL4_Word badge; +seL4_Recv(endpoint, &badge); +// once a message is received, the badge value is set by seL4 to the +// badge of capability used by the sender to send the message +``` + +### Fastpath + +Fast IPC is essential to microkernel-based systems, as services are often separated from each other +for isolation, with IPC one of the core mechanisms for communication between clients and services. +Consequently, IPC has a fastpath -- a heavily optimised path in the kernel -- which allows these operations +to be very fast. In order to use the fastpath, an IPC must meet the following conditions: + +* `seL4_Call` or `seL4_ReplyRecv` must be used. +* The data in the message must fit into the `seL4_FastMessageRegisters` registers. +* The processes must have valid address spaces. +* No caps should be transferred. +* No other threads in the scheduler of higher priority than the thread unblocked by the IPC can be running. + +## Exercises + +This tutorial has several processes set up by the capDL loader, two clients and a server. All processes have +access to a single endpoint capability, which provides access to the same endpoint object. + +In this tutorial, you will construct a server which echos the contents of messages sent by clients. You +will also alter the ordering of replies from the clients to get the right message. + +When you run the tutorial, the output should be something like this: + +``` +Client 2: waiting for badged endpoint +Badged 2 +Assertion failed: seL4_MessageInfo_get_extraCaps(info) == 1 (../ipcCkQ6Ub/client_2.c: main: 22) +Client 1: waiting for badged endpoint +Badged 1 +Assertion failed: seL4_MessageInfo_get_extraCaps(info) == 1 (../ipcCkQ6Ub/client_1.c: main: 22) +``` + + +On initialisation, both clients use the following protocol: they wait on the provided endpoint for +a badged endpoint to be sent to them via cap transfer. All following messages sent by the client +uses the badged endpoint, such that the server can identify the client. However, the server does not +currently send the badged capability! We have provided code to badge the endpoint capability, and +reply to the client. + +**Exercise** Your task is to set up the cap transfer such that the client successfully +receives the badged endpoint. + +```c + /* No badge! give this sender a badged copy of the endpoint */ + seL4_Word badge = seL4_GetMR(0); + seL4_Error error = seL4_CNode_Mint(cnode, free_slot, seL4_WordBits, + cnode, endpoint, seL4_WordBits, + seL4_AllRights, badge); + printf("Badged %lu\n", badge); + + // TODO use cap transfer to send the badged cap in the reply + + /* reply to the sender and wait for the next message */ + seL4_Reply(info); + + /* now delete the transferred cap */ + error = seL4_CNode_Delete(cnode, free_slot, seL4_WordBits); + assert(error == seL4_NoError); + + /* wait for the next message */ + info = seL4_Recv(endpoint, &sender); +``` +
    +Quick solution +```c + // use cap transfer to send the badged cap in the reply + seL4_SetCap(0, free_slot); + info = seL4_MessageInfo_new(0, 0, 1, 0); +``` +
    + +Now the output should look something like: +```bash +Booting all finished, dropped to user space +Client 2: waiting for badged endpoint +Badged 2 +Client 1: waiting for badged endpoint +Badged 1 +Client 2: received badged endpoint +Client 1: received badged endpoint +``` + +Depending on timing, the messages may be different, the result is the same: the system hangs. +This is because one of the clients has hit the else case, where the badge is set, and the server +does not respond, or wait for new messages from this point. + +**Exercise** Your next task is to implement the echo part of the server. + +```c + // TODO use printf to print out the message sent by the client + // followed by a new line +``` +
    +Quick solution +```c + for (int i = 0; i < seL4_MessageInfo_get_length(info); i++) { + printf("%c", (char) seL4_GetMR(i)); + } + printf("\n"); +``` +
    + +At this point, you should see a single word output to the console in a loop. +``` +the +the +the +``` + +This is because the server does not reply to the client, and continues to spin in a loop + repeating the last message. + +**Exercise** Update the code to reply to the clients after printing the message. + +```c + // TODO reply to the client and wait for the next message +``` +
    +Quick solution +```c + info = seL4_ReplyRecv(endpoint, info, &sender); + for (int i = 0; i < seL4_MessageInfo_get_length(info); i++) { + printf("%c", (char) seL4_GetMR(i)); + } + printf("\n"); +``` +
    + +Now the output should be something like this: + +``` +Client 2: received badged endpoint +the +brown +jumps +the +dog +Client 1: received badged endpoint +quick +fox +over +lazy +``` + +**Exercise** Currently each client is scheduled for its full timeslice until it is preempted. Alter +your server to only print one message from each client, alternating. You will need to use +[`seL4_CNode_SaveCaller`](https://docs.sel4.systems/ApiDoc.html#save-caller) to save the reply +capability for each sender. You can use `free_slot` to store the reply capabilities. + +
    +Quick solution +```c + error = seL4_CNode_SaveCaller(cnode, free_slot, seL4_WordBits); + assert(error == 0); + info = seL4_Recv(endpoint, &sender); + for (int i = 0; i < seL4_MessageInfo_get_length(info); i++) { + printf("%c", (char) seL4_GetMR(i)); + } + printf("\n"); + + seL4_Send(free_slot, seL4_MessageInfo_new(0, 0, 0, 0)); + + info = seL4_ReplyRecv(endpoint, info, &sender); + + +``` +
    + +Depending on your approach, successful output should look something like this: +``` +Client 2: received badged endpoint +the +Client 1: received badged endpoint +quick +fox +brown +jumps +over +lazy +the +dog +``` + +### Further exercises + +That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, +to become more familiar with IPC. + +* Try using `seL4_Send` and `seL4_Recv`. +* Try the non-blocking variants, `seL4_NBSend` and `seL4_NBRecv`. + +Next tutorial: Notifications diff --git a/TutorialsReworked/seL4Kernel/mapping.md b/TutorialsReworked/seL4Kernel/mapping.md index 73ca8e4e3e..68802d07a3 100644 --- a/TutorialsReworked/seL4Kernel/mapping.md +++ b/TutorialsReworked/seL4Kernel/mapping.md @@ -239,6 +239,4 @@ to become more familiar with virtual memory management on seL4. * Port this tutorial to another architecture (ARM, RISCV). * Create a generic function for converting from `seL4_MappingFailedLookupLevel` to the required seL4 object. -

    - Next tutorial: Threads -

    +Next tutorial: Threads diff --git a/TutorialsReworked/seL4Kernel/notifications.md b/TutorialsReworked/seL4Kernel/notifications.md index e69de29bb2..142a3b6fe7 100644 --- a/TutorialsReworked/seL4Kernel/notifications.md +++ b/TutorialsReworked/seL4Kernel/notifications.md @@ -0,0 +1,224 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# Notifications and shared memory +This tuotorial covers notification objects. + +You will learn how to: +1. Set up shared memory between tasks. +2. Use notification objects for synchronisation between tasks. +3. Use badges to differentiate notifications. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut notifications +# building the tutorial exercise +cd notifications_build +ninja +``` + +

    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut notifications +``` +Answers are also available in drop down menus under each section. +
    + +## CapDL Loader + +This tutorial uses a the *capDL loader*, a root task which allocates statically + configured objects and capabilities. + +
    +Get CapDL +The capDL loader parses +a static description of the system and the relevant ELF binaries. +It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects +but we also use it in the tutorials to reduce redundant code. +The program that you construct will end up with its own CSpace and VSpace, which are separate +from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning +in applications loaded by the capDL loader. + +More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). + +For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. +
    + +## Background + +Notifications allow processes to send asynchronous signals to each other, and are primarily used for interrupt handling +and to synchronise access to shared data buffers. + +### Notification objects + +Signals are sent and received with invocations on capabilities to notification objects. +A notification object consists of a data word, which acts as an array of binary semaphores, and a queue of +TCBs waiting for notifications. + +Notification objects can be in three states: +* Waiting - there are TCBs queued on this notification waiting for it to be signalled. +* Active - TCBs have signalled data on this notification, +* Idle - no TCBs are queued and no TCBs have signalled this object since it was last set to idle. + +#### Signalling + +When a task signals a notification object (using `seL4_Signal`), what occurs depends on the state of the object: +* Idle - the data word is set to the badge of the capability used to send the signal, and the object is converted + to active. +* Active - the badge of the capability used to signal the notification object is bitwise-orred with the notifications data word. +* Waiting - the head of the queue of TCBs is woken and the badge sent to that TCB. If the queue is empty, the notification +object is transitioned to idle. + +In this way notification objects can be seen as a binary array of semaphores - if the signallers all use a +different bit in the badge, they can set different badge bits and waiters can observe which bits have been set. + +#### Waiting + +Tasks can wait on a notification object using `seL4_Wait`, which does the following: + +* Idle - the TCB is queued, and the notification transitioned to waiting. +* Active - the TCB receives the data word, the data word is reset to 0 and the notification transitioned to idle, +* Waiting - the TCB is appended to the queue. + +#### Polling + +Notification objects can also be polled with `seL4_Poll`, which is a non-blocking version of `seL4_Wait` that returns +immediately regardless of the state. + +## Interrupts and IPC + +Notification objects can be used to receive signals of interrupt delivery, and can also be bound to TCBs +such that signals and IPC can be received by the same thread. This is explained in more detail in the +timer tutorial. + +## Exercises + +These exercises guide you through a basic producer consumer set up using notifications and shared memory. The +tutorial uses the capDL loader, and already has 2 producer processes (`producer_1.c` and `producer_2`) and 1 consumer + process running (`consumer.c`). Each has access to a number of capabilities. + +Each producer shares a buffer with the consumer, and the consumer processes data from both producers when it is +available. + +When you start the tutorial, the output will look something like this: +``` +Booting all finished, dropped to user space +Waiting for producer +``` +### Set up shared memory + +Both producers start and block immediately, waiting for the consumer to send an IPC with the address of the shared +mapping. We provide code below that sets up the shared page between producer 1 and the consumer: + +```c + /* set up shared memory for consumer 1 */ + /* first duplicate the cap */ + error = seL4_CNode_Copy(cnode, mapping_1, seL4_WordBits, + cnode, buf1_frame_cap, seL4_WordBits, seL4_AllRights); + ZF_LOGF_IFERR(error, "Failed to copy cap"); + /* now do the mapping */ + error = seL4_ARCH_Page_Map(mapping_1, producer_1_vspace, BUF_VADDR, + seL4_AllRights, seL4_ARCH_Default_VMAttributes); + ZF_LOGF_IFERR(error, "Failed to map frame"); +``` + +However, we do not map the second buffer in, so producer 2 crashes immediately. + +**Exercise** Understand the above code, and create a second shared page between `producer_2` and `consumer`. + +```c + // TODO share buf2_frame_cap with producer_2 +``` +
    +Quick solution +```c + error = seL4_CNode_Copy(cnode, mapping_2, seL4_WordBits, + cnode, buf2_frame_cap, seL4_WordBits, seL4_AllRights); + ZF_LOGF_IFERR(error, "Failed to copy cap"); +``` +
    + +Whether this is successful will be visible after the next exercise when the consumers access their buffers. If the shared page setup for producer 2 is not correct, it will fail with a vm fault. + +### Signal the producers to go + +At this point, both producers are waiting on the `empty` notification for a signal that the buffer is ready +to be written to. + +**Exercise** signal both producers via the `buf1_empty` and `buf2_empty` notification objects. + +```c + // TODO signal both producers +``` +
    +Quick solution +```c + seL4_Signal(buf1_empty); + seL4_Signal(buf2_empty); +``` +
    + +### Differentiate signals + +Now you should see something like the following: + +``` +Booting all finished, dropped to user space +Waiting for producer +2: produce +1: produce +Got badge: 2 +Got badge: 1 +``` + +At this point, the consumer should consume data from the appropriate buffer(s) and signal to the appropriate consumer(s) +that the buffer is empty again. The capability to the `full` notification object has already been badged: `producer_1`s +copy has a badge of `0b1` and `producer_2` a badge of `0b10`. By checking the bits in the badge, you can see +which of the producers (it may be both) has produced data. + +**Exercise** Check the badge and signal the empty notification for the producers according to the bits set in the badge + value. + +```c + // TODO, use the badge to check which producer has signalled you, and signal it back. Note that you + // may recieve more than 1 signal at a time. +``` +
    +Quick solution +```c + if (badge & 0b01) { + assert(*buf1 == 1); + *buf1 = 0; + seL4_Signal(buf1_empty); + } + if (badge & 0b10) { + assert(*buf2 == 2); + *buf2 = 0; + seL4_Signal(buf2_empty); + } +``` +
    + +At this point, you should see signals from both producers being processed, and the final `Success!` message printed. + +### Further exercises + +That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, +to become more familiar with IPC. + +* Create a counting semaphore implementation using notification objects. +* Create a bounded-buffer producer consumer with a buffer size greater than 1. + +Next tutorial: Interrupts diff --git a/TutorialsReworked/seL4Kernel/threads.md b/TutorialsReworked/seL4Kernel/threads.md index e69de29bb2..ecdfe92e6f 100644 --- a/TutorialsReworked/seL4Kernel/threads.md +++ b/TutorialsReworked/seL4Kernel/threads.md @@ -0,0 +1,493 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +# Threads + +This is a tutorial for using threads on seL4. + +In this tutorial, you will +1. Learn the jargon TCB. +2. Learn how to start a thread in the same address space. +3. Understand how to read and update TCB register state. +4. Learn how to suspend and resume a thread. +5. Understand thread priorities and their interaction with the seL4 scheduler. +6. Gain a basic understanding of exceptions and debug fault handlers. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/TutorialsReworked/seL4Kernel/setting-ip#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut threads +# building the tutorial exercise +cd untyped_build +ninja +``` + +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut threads +``` +Answers are also available in drop down menus under each section. +
    + +## CapDL Loader + +Previous tutorials have taken place in the root task where the starting CSpace layout is set by the +seL4 boot protocol. This tutorial uses a the *capDL loader*, a root task which allocates statically + configured objects and capabilities. + +The capDL loader parses +a static description of the system and the relevant ELF binaries. +It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects +but we also use it in the tutorials to reduce redundant code. +The program that you construct will end up with its own CSpace and VSpace, which are separate +from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning +in applications loaded by the capDL loader. + +More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). + +For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. + + +## Background + +### Thread Control Blocks + +seL4 provides threads to represent an execution context and manage processor time. Threads in +seL4 are realised by *thread control block* objects (TCBs), one for each kernel thread. + +TCBs contain the following information: +* a priority and maximum control priority, +* register state and floating-point context, +* CSpace capability, +* VSpace capability, +* endpoint capability to send fault messages to, +* and the reply capability slot. + +### Scheduling model + +The seL4 scheduler chooses the next thread to run on a specific +processing core, and is a priority-based round-robin scheduler. The scheduler picks +threads that are runnable: that is, resumed, and not blocked on any IPC operation. + +#### Priorities + +The scheduler picks the highest-priority, runnable thread. seL4 provides a priority range of 0-255, where +255 is the maximum priority (encoded in `libsel4` as `seL4_MinPrio` and `seL4_MaxPrio`). + +TCBs also have a *maximum control priority* (MCP), which acts as an informal capability over priorities. +When setting the priority of a TCB, an explicit TCB capability must be provided to derive the +authority from to set the priority. The priority being set is checked against the authority TCB's +MCP and the target priority is greater, the operation fails. The root task starts with both priority and +MCP set to `seL4_MaxPrio`. + +#### Round robin + +When multiple TCBs are runnable and have the same priority, they are scheduled in a +first-in, first-out round-robin fashion. In more detail, kernel time +is accounted for in fixed-time quanta referred to as ticks, and each TCB has +a timeslice field which represents the number of ticks that TCB is eligible to execute +until preempted. The kernel timer driver is configured to fire a periodic interrupt which +marks each tick, and when the timeslice is exhausted round robin scheduling is applied. +Threads can surrender their current timeslice using the `seL4_Yield` system call. + +#### Domain scheduling + +In order to provide confidentiality seL4 provides a top-level hierarchical scheduler which +provides static, cyclical scheduling of scheduling partitions known as domains. Domains are +statically configured at compile time with a cyclic schedule, and are non-preemptible resulting in +completely deterministic scheduling of domains. + +Threads can be assigned to domains, and threads are only scheduled +when their domain is active. Cross-domain IPC is delayed until a domain switch, and +seL4_Yield between domains is not possible. When there are no threads to run while a +domain is scheduled, a domain-specific idle thread will run until a switch occurs. + +Assigning a thread to a domain requires access to the `seL4_DomainSet` capability. This allows a +thread to be added to any domain. + +```c +/* Set thread's domain */ +seL4_Error seL4_DomainSet_Set(seL4_DomainSet _service, seL4_Uint8 domain, seL4_TCB thread); + +``` + +### Thread Attributes + +seL4 threads are configured by [invocations on the TCB object](https://docs.sel4.systems/ApiDoc.html#sel4_tcb). + +## Exercises + +This tutorial will guide you through using TCB invocations to create a new thread in the same +address space and pass arguments to the new thread. +Additionally, you will learn about how to debug a virtual memory +fault. + +By the end of this tutorial you want to spawn a new thread to call the function in the code example + below. + +```c + +int new_thread(void *arg1, void *arg2, void *arg3) { + printf("Hello2: arg1 %p, arg2 %p, arg3 %p\n", arg1, arg2, arg3); + void (*func)(int) = arg1; + func(*(int *)arg2); + while(1); +} + +``` + + +### Configure a TCB + +When you first build and run the tutorial, you should see something like the following: +``` +Hello, World! +Dumping all tcbs! +Name State IP Prio Core +-------------------------------------------------------------------------------------- +tcb_threads running 0x4012ef 254 0 +idle_thread idle (nil) 0 0 +rootserver inactive 0x4024c2 255 0 +< +main@threads.c:42 [Cond failed: result] +Failed to retype thread: 2 +``` + +`Dumping all tcbs!` and the following table is generated by a debug syscall called `seL4_DebugDumpScheduler()`. +seL4 has a series of debug syscalls that are available in debug kernel builds. The available debug syscalls +can be found in [libsel4](https://docs.sel4.systems/ApiDoc.html#debugging-system-calls). `seL4_DebugDumpScheduler()` +is used to dump the current state of the scheduler and can be useful to debug situations where a +system seems to have hung. + +After the TCB table, you can see the `seL4_Untyped_Retype` invocation is failing due to invalid arguments. +The loader has been configured to set up the following capabilities and symbols: + +```c + +// the root CNode of the current thread +extern seL4_CPtr root_cnode; +// VSpace of the current thread +extern seL4_CPtr root_vspace; +// TCB of the current thread +extern seL4_CPtr root_tcb; +// Untyped object large enough to create a new TCB object + +extern seL4_CPtr tcb_untyped; +extern seL4_CPtr buf2_frame_cap; +extern const char buf2_frame[4096]; + +// Empty slot for the new TCB object +extern seL4_CPtr tcb_cap_slot; +// Symbol for the IPC buffer mapping in the VSpace, and capability to the mapping +extern seL4_CPtr tcb_ipc_frame; +extern const char thread_ipc_buff_sym[4096]; +// Symbol for the top of a 16 * 4KiB stack mapping, and capability to the mapping +extern const char tcb_stack_base[65536]; +static const uintptr_t tcb_stack_top = (const uintptr_t)&tcb_stack_base + sizeof(tcb_stack_base); +``` + +**Exercise** Fix the `seL4_Untyped_Retype` call (shown below) using the capabilities provided above, such +that a new TCB object is created in `tcb_cap_slot`. + +```c +int main(int c, char* arbv[]) { + + printf("Hello, World!\n"); + + seL4_DebugDumpScheduler(); + // TODO fix the parameters in this invocation + seL4_Error result = seL4_Untyped_Retype(seL4_CapNull, seL4_TCBObject, seL4_TCBBits, seL4_CapNull, 0, 0, seL4_CapNull, 1); + ZF_LOGF_IF(result, "Failed to retype thread: %d", result); + seL4_DebugDumpScheduler(); +``` + +
    +Quick solution +```c + seL4_Error result = seL4_Untyped_Retype(tcb_untyped, seL4_TCBObject, seL4_TCBBits, root_cnode, 0, 0, tcb_cap_slot, 1); +``` +
    + +Once the TCB has been created it will show up in the `seL4_DebugDumpScheduler()` output as +`child of: 'tcb_threads'`. Throughout the tutorial you can use this syscall to debug some of the TCB attributes +that you set. + +After the scheduler table, you should see a another error: + +``` + <> +main@threads.c:46 [Cond failed: result] + Failed to configure thread: 2 +``` + +**Exercise** Now that you have a TCB object, configure it to have the same CSpace and VSpace +as the current thread. Use the IPC buffer we have provided, but don't set a fault handler, + as the kernel will print any fault we receive with a debug build. + +```c + //TODO fix the parameters in this invocation + result = seL4_TCB_Configure(seL4_CapNull, seL4_CapNull, 0, seL4_CapNull, 0, 0, (seL4_Word) NULL, seL4_CapNull); + ZF_LOGF_IF(result, "Failed to configure thread: %d", result); +``` +
    +Quick solution +```c + result = seL4_TCB_Configure(tcb_cap_slot, seL4_CapNull, root_cnode, 0, root_vspace, 0, (seL4_Word) thread_ipc_buff_sym, tcb_ipc_frame); +``` +
    + + + +You should now be getting the following error: +``` +< +main@threads.c:51 [Cond failed: result] +Failed to set the priority for the new TCB object. +``` + +### Change priority via `seL4_TCB_SetPriority` + +A newly created thread will have a priority of 0, while the thread created by the loader is at +a priority of 254. You need to change the priority of your new thread such that it will be + scheduled round-robin with the current thread. + +**Exercise** use `seL4_TCB_SetPriority` to set the priority. Remember that to set a thread's priority, +the calling thread must have the authority to do so. In this case, the main thread can use its own +TCB capability, which has an MCP of 254. + +```c + // TODO fix the call to set priority using the authority of the current thread + // and change the priority to 254 + result = seL4_TCB_SetPriority(tcb_cap_slot, seL4_CapNull, 0); + ZF_LOGF_IF(result, "Failed to set the priority for the new TCB object.\n"); + seL4_DebugDumpScheduler(); +``` +
    +Quick solution +```c + result = seL4_TCB_SetPriority(tcb_cap_slot, root_tcb, 254); +``` +
    + + +Fixing up the `seL4_TCB_SetPriority` call should allow you to see that the thread's priority is now +set to the same as the main thread in the next `seL4_DebugDumpScheduler()` call. + +``` +Name State IP Prio Core +-------------------------------------------------------------------------------------- +child of: 'tcb_threads' inactive (nil) 254 0 +tcb_threads running 0x4012ef 254 0 +idle_thread idle (nil) 0 0 +rootserver inactive 0x4024c2 255 0 +< +main@threads.c:57 [Err seL4_InvalidCapability]: +Failed to write the new thread's register set. +``` + +### Set initial register state + +The TCB is nearly ready to run, except for its initial registers. You need to set the +program counter and stack pointer to valid values, otherwise your thread will crash immediately. + +`libsel4utils` contains some functions for setting register contents in a platform agnostic manner. +You can use these methods to set the program counter (instruction pointer) and stack pointer in +this way. _Note: It is assumed that the stack grows downwards on all platforms._ + +**Exercise** Set up the new thread to call the function `new_thread`. You can use the debug syscall to verify that +you have at least set the instruction pointer (IP) correctly. + +```c + seL4_UserContext regs = {0}; + int error = seL4_TCB_ReadRegisters(tcb_cap_slot, 0, 0, sizeof(regs)/sizeof(seL4_Word), ®s); + ZF_LOGF_IFERR(error, "Failed to read the new thread's register set.\n"); + + // TODO use valid instruction pointer + sel4utils_set_instruction_pointer(®s, (seL4_Word)NULL); + // TODO use valid stack pointer + sel4utils_set_stack_pointer(®s, NULL); + // TODO fix parameters to this invocation + error = seL4_TCB_WriteRegisters(seL4_CapNull, 0, 0, 0, ®s); + ZF_LOGF_IFERR(error, "Failed to write the new thread's register set.\n" + "\tDid you write the correct number of registers? See arg4.\n"); + seL4_DebugDumpScheduler(); +``` +
    +Quick solution +```c + // use valid instruction pointer + sel4utils_set_instruction_pointer(®s, (seL4_Word) new_thread); + // use valid stack pointer + sel4utils_set_stack_pointer(®s, tcb_stack_top); + // fix parameters to this invocation + error = seL4_TCB_WriteRegisters(tcb_cap_slot, 0, 0, sizeof(regs)/sizeof(seL4_Word), ®s); +``` +
    + + +On success, you will see the following output: +``` +<> +main@threads.c:63 [Err seL4_InvalidCapability]: + Failed to start new thread. +``` + +### Start the thread + +Finally you are ready to start the thread, which makes the TCB runnable and eligible to be picked by + the seL4 scheduler. This can be done by changing the second argument of +`seL4_TCB_WriteRegisters` to 1 and removing the `seL4_TCB_Resume` call, or by fixing the resume call below. + +**Exercise** resume the new thread. + +```c + // TODO resume the new thread + error = seL4_TCB_Resume(seL4_CapNull); + ZF_LOGF_IFERR(error, "Failed to start new thread.\n"); +``` +
    +Quick solution +```c + error = seL4_TCB_Resume(tcb_cap_slot); +``` +
    + + +If everything has been configured correctly, resuming the thread should result in the string +`Hello2: arg1 0, arg2 0, arg3 0` followed by a fault. + +### Passing arguments + +You will notice that all of the arguments to the new thread are 0. You can set the arguments by +using the helper function `sel4utils_arch_init_local_context` or by directly manipulating the registers +for your target architecture. + +**Exercise** update the values written with `seL4_TCB_WriteRegisters` to pass the values 1, 2, 3 as arg1, +arg2, and arg3 respectively. + +```c + UNUSED seL4_UserContext regs = {0}; + int error = seL4_TCB_ReadRegisters(tcb_cap_slot, 0, 0, sizeof(regs)/sizeof(seL4_Word), ®s); + ZF_LOGF_IFERR(error, "Failed to write the new thread's register set.\n" + "\tDid you write the correct number of registers? See arg4.\n"); + + error = seL4_TCB_WriteRegisters(0, 0, 0, 0, ®s); + ZF_LOGF_IFERR(error, "Failed to write the new thread's register set.\n" + "\tDid you write the correct number of registers? See arg4.\n"); +``` +
    +Quick solution +```c + sel4utils_arch_init_local_context((void*)new_thread, + (void *)1, (void *)2, (void *)3, + (void *)tcb_stack_top, ®s); + error = seL4_TCB_WriteRegisters(tcb_cap_slot, 0, 0, sizeof(regs)/sizeof(seL4_Word), ®s); + +``` +
    + +### Resolving a fault + +At this point, you have created and configured a new thread, and given it initial arguments. +The last part of this tutorial is what to do when your thread faults. We provide further detail + on fault handling in a future tutorial, but for now you can rely on the +kernel printing a fault message, as the thread you have created does not have a fault handler. + +In the output below you can see a cap fault has occurred. The first part of the error is that +the kernel was unable to send a fault to a fault handler as it is set to `(nil)`. The kernel +then prints out the fault it was trying to send. In this case, the fault is a virtual memory fault. +The new thread has tried to access data at address `0x2` which is an invalid and unmapped address. +The output shows that the program counter of the thread when it faulted was `0x401e66`. + +The fault status register is also output, which can be decoded by +using the relevant architecture manual. +Additionally, the kernel prints a raw stack dump from the current stack pointer. +The size of the stack dump is configurable, using the + `KernelUserStackTraceLength` cmake variable. + +``` +Caught cap fault in send phase at address (nil) +while trying to handle: +vm fault on data at address 0x2 with status 0x4 +in thread 0xffffff8008140400 "child of: 'tcb_threads'" at address 0x401e66 +With stack: +0x439fc0: 0x0 +0x439fc8: 0x3 +0x439fd0: 0x2 +0x439fd8: 0x1 +0x439fe0: 0x0 +0x439fe8: 0x1 +0x439ff0: 0x0 +0x439ff8: 0x0 +0x43a000: 0x404fb3 +0x43a008: 0x0 +0x43a010: 0x0 +0x43a018: 0x0 +0x43a020: 0x0 +0x43a028: 0x0 +0x43a030: 0x0 +0x43a038: 0x0 +``` + +To investigate the fault, you can use a tool such as `objdump` on the ELF file that was loaded to +inspect the instruction that caused the fault. + In this case, the ELF file is located at `.///threads`. + +You should be able to see that `arg2` is being dereferenced, but does not point to valid memory. + +**Exercise** pass a valid arg2, by passing the address of a global variable. +
    +Quick solution +Fix `sel4utils_arch_init_local_context` +```c + sel4utils_arch_init_local_context((void*)new_thread, + (void *)1, (void *)&data, (void *)3, + (void *)tcb_stack_top, ®s); +``` +
    + +Next, another fault will occur as the new thread expects `arg1` to be a pointer to a function. + +**Exercise** Pass the address of a function which outputs the argument which is passed to it, as `arg2`. +
    +Quick solution +Create a new function +```c + int call_once(int arg) { + printf("Hello 3 %d\n", arg); + } + +``` +and fix `sel4utils_arch_init_local_context` +```c + sel4utils_arch_init_local_context((void*)new_thread, + (void *)call_once, (void *)&data, (void *)3, + (void *)tcb_stack_top, ®s); +``` +
    + +Now you should have a new thread, which immediately calls the function passed in `arg2`. + +### Further exercises + +That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, +to become more familiar with TCBs and threading in seL4. + +- Using different TCB invocations to change the new thread's attributes or objects +- Investigate how setting different priorities affects when the threads are scheduled to run +- Implementing synchronisation primitives using global memory. +- Trying to repeat this tutorial in the root task where there are more resources available to + create more thread objects. +- Another tutorial... + +Next tutorial: IPC \ No newline at end of file diff --git a/TutorialsReworked/seL4Kernel/untyped.md b/TutorialsReworked/seL4Kernel/untyped.md index 2959cd1faf..1f366ec11a 100644 --- a/TutorialsReworked/seL4Kernel/untyped.md +++ b/TutorialsReworked/seL4Kernel/untyped.md @@ -355,6 +355,4 @@ to become more familiar with untyped objects and memory allocation in seL4. * Allocate objects at specific physical addresses. * Create a simple object allocator for allocating seL4 objects. -

    - Next tutorial: Mapping -

    +Next tutorial: Mapping diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index 82c6176a39..f3f74ddf81 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -105,5 +105,10 @@

  • CAmkES VM
  • CAmkES Cross VM Connectors
+
  • Resources
  • + {% endif %} From f918f4af7e5697b5681d033cc5eca3706597b9dd Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Wed, 6 Mar 2024 17:16:05 +1100 Subject: [PATCH 008/103] add reworked tuts (incomplete) Signed-off-by: Birgit Brecknell --- .../DynamicLibraries/initialisation.md | 575 ++++++++++++++ TutorialsReworked/DynamicLibraries/ipc.md | 722 ++++++++++++++++++ .../DynamicLibraries/processes.md | 461 +++++++++++ TutorialsReworked/seL4Kernel/faults.md | 338 ++++++++ TutorialsReworked/seL4Kernel/interrupts.md | 212 +++++ _includes/nav-sidebar.html | 2 +- index.md | 2 +- 7 files changed, 2310 insertions(+), 2 deletions(-) diff --git a/TutorialsReworked/DynamicLibraries/initialisation.md b/TutorialsReworked/DynamicLibraries/initialisation.md index e69de29bb2..5054d01966 100644 --- a/TutorialsReworked/DynamicLibraries/initialisation.md +++ b/TutorialsReworked/DynamicLibraries/initialisation.md @@ -0,0 +1,575 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# seL4 Dynamic Libraries: initialisation & threading + +This tutorial provides code examples and exercises for using the dynamic libraries +found in [`seL4_libs`](https://github.com/seL4/seL4_libs) to bootstrap a system and start a thread. + +The tutorial is useful in that +it addresses conceptual problems for two different types of developers: + +- Experienced kernel developers whose minds are pre-programmed to + think in terms of "One address space equals one process", and + begins to introduce the seL4 CSpace vs VSpace model. +- New kernel developers, for whom the tutorial will prompt them on + what to read about. + +Don't gloss over the globals declared before `main()` -- they're declared +for your benefit so you can grasp some of the basic data structures. + + +Outcomes: +- Understand the kernel's startup procedure. +- Understand that the kernel centers around certain objects and + capabilities to those objects. +- Understand that libraries exist to automate the very + fine-grained nature of the seL4 API, and get a rough idea of + some of those libraries. +- Learn how the kernel hands over control to userspace. +- Get a feel for how the seL4 API enables developers to manipulate + the objects referred to by the capabilities they encounter. +- Understand the how to spawn new threads in seL4, and the basic + idea that a thread has a TCB, VSpace and CSpace, and that you + must fill these out. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut dynamic-1 +# building the tutorial exercise +cd dynamic-1_build +ninja +``` + +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut dynamic-1 +``` +Answers are also available in drop down menus under each section. +
    + + + +## Exercises + +When you first run the tutorial, you should see the following output: + +``` +Booting all finished, dropped to user space +main@main.c:89 [Cond failed: info == NULL] +Failed to get bootinfo. +``` + +### Obtain BootInfo + +After bootstrapping the system, the seL4 kernel hands over control to the root task. + to an init thread. +This thread receives a structure from the kernel that describes all the +resources available on the machine. This structure is called the +BootInfo structure. It includes information on all IRQs, memory, and +IO-Ports (x86). This structure also tells the init thread where certain +important capability references are. This step is teaching you how to +obtain that structure. + +`seL4_BootInfo* platsupport_get_bootinfo(void)` is a function that returns the BootInfo structure. +It also sets up the IPC buffer so that it can perform some syscalls such as `seL4_DebugNameThread` used by `name_thread`. + +- +- + +```c + + /* TASK 1: get boot info */ + /* hint: platsupport_get_bootinfo() + * seL4_BootInfo* platsupport_get_bootinfo(void); + * @return Pointer to the bootinfo, NULL on failure + */ +} +``` +
    +Quick solution +```c + info = platsupport_get_bootinfo(); + ZF_LOGF_IF(info == NULL, "Failed to get bootinfo."); +``` +
    + +On success, you should see the following: +``` +dynamic-1: main@main.c:124 [Cond failed: allocman == NULL] + Failed to initialize alloc manager. + Memory pool sufficiently sized? + Memory pool pointer valid? +``` + +### Initialise simple + +`libsel4simple` provides an abstraction for the boot environment of a thread. +You need to initialize it with some default state before using it. +- +```c + + /* TASK 2: initialise simple object */ + /* hint: simple_default_init_bootinfo() + * void simple_default_init_bootinfo(simple_t *simple, seL4_BootInfo *bi); + * @param simple Structure for the simple interface object. This gets initialised. + * @param bi Pointer to the bootinfo describing what resources are available + */ +``` +
    +Quick solution +```c + simple_default_init_bootinfo(&simple, info); +``` +
    + +On successful completion of this task, the output should not change. + +### Use simple to print BootInfo + +Use a `simple` function to print out the contents of the `seL4_BootInfo` function. + +```c + + /* TASK 3: print out bootinfo and other info about simple */ + /* hint: simple_print() + * void simple_print(simple_t *simple); + * @param simple Pointer to simple interface. + */ +``` +
    +Quick solution +```c + simple_print(&simple); +``` +
    + + +- + +The error message should remain, but your output should now also contain something like: + +``` +Node 0 of 1 +IOPT levels: 4294967295 +IPC buffer: 0x52c000 +Empty slots: [406 --> 4096) +sharedFrames: [0 --> 0) +userImageFrames: [16 --> 316) +userImagePaging: [12 --> 15) +untypeds: [316 --> 406) +Initial thread domain: 0 +Initial thread cnode size: +dynamic-1: main@main.c:126 [Cond failed: allocman == NULL] +``` + +### Initialise an allocator + +In seL4, memory management is delegated in large part to userspace, and +each thread manages its own page faults with a custom pager. Without +the use of the `allocman` library and the `VKA` library, you would have to +manually allocate a frame, then map the frame into a page-table, before +you could use new memory in your address space. In this tutorial you +don't go through that procedure, but you'll encounter it later. For now, +use the allocman and VKA allocation system. The allocman library +requires some initial memory to bootstrap its metadata. Complete this +step. +- + +```c + + /* TASK 4: create an allocator */ + /* hint: bootstrap_use_current_simple() + * allocman_t *bootstrap_use_current_simple(simple_t *simple, uint32_t pool_size, char *pool); + * @param simple Pointer to simple interface. + * @param pool_size Size of the initial memory pool. + * @param pool Initial memory pool. + * @return returns NULL on error + */ +``` +
    +Quick solution +```c + allocman = bootstrap_use_current_simple(&simple, ALLOCATOR_STATIC_POOL_SIZE, allocator_mem_pool); + ZF_LOGF_IF(allocman == NULL, "Failed to initialize alloc manager.\n" + "\tMemory pool sufficiently sized?\n" + "\tMemory pool pointer valid?\n"); +``` +
    + +The output should now be as follows: +``` +<> +dynamic-1: main@main.c:199 [Err seL4_InvalidCapability]: + Failed to set the priority for the new TCB object. +``` + +### Obtain a generic allocation interface (vka) + +`libsel4vka` is an seL4 type-aware object allocator that will allocate new +kernel objects for you. The term "allocate new kernel objects" in seL4 +is a more detailed process of "retyping" previously un-typed memory. +seL4 considers all memory that hasn't been explicitly earmarked for a +purpose to be "untyped", and in order to repurpose any memory into a +useful object, you must give it an seL4-specific type. This is retyping, +and the VKA library simplifies this for you, among other things. +- + +```c + + /* TASK 5: create a vka (interface for interacting with the underlying allocator) */ + /* hint: allocman_make_vka() + * void allocman_make_vka(vka_t *vka, allocman_t *alloc); + * @param vka Structure for the vka interface object. This gets initialised. + * @param alloc allocator to be used with this vka + */ +``` +
    +Quick solution +```c + allocman_make_vka(&vka, allocman); +``` +
    + +On successful completion this task, the output should not change. + +### Find the CSpace root cap + +```c + + /* TASK 6: get our cspace root cnode */ + /* hint: simple_get_cnode() + * seL4_CPtr simple_get_cnode(simple_t *simple); + * @param simple Pointer to simple interface. + * @return The cnode backing the simple interface. no failure. + */ + seL4_CPtr cspace_cap; +``` +
    +Quick solution +```c + cspace_cap = simple_get_cnode(&simple); +``` +
    + +This is where the differences between seL4 and contemporary kernels +begin to start playing out. Every kernel-object that you "retype" will +be handed to you using a capability reference. The seL4 kernel keeps +multiple trees of these capabilities. Each separate tree of capabilities +is called a "CSpace". Each thread can have its own CSpace, or a CSpace +can be shared among multiple threads. The delineations between +"Processes" aren't well-defined, since seL4 doesn't have any real +concept of "processes". It deals with threads. Sharing and isolation is +based on CSpaces (shared vs not-shared) and VSpaces (shared vs +not-shared). The "process" idea goes as far as perhaps the fact that at +the hardware level, threads sharing the same VSpace are in a traditional +sense, siblings, but logically in seL4, there is no concept of +"Processes" really. + +So you're being made to grab a reference to your thread's CSpace's root +"CNode". A CNode is one of the many blocks of capabilities that make up +a CSpace. +- + +On successful completion this task, the output should not change. + +### Find the VSpace root cap + +```c + + /* TASK 7: get our vspace root page diretory */ + /* hint: simple_get_pd() + * seL4_CPtr simple_get_pd(simple_t *simple); + * @param simple Pointer to simple interface. + * @return The vspace (PD) backing the simple interface. no failure. + */ + seL4_CPtr pd_cap; +``` +
    +Quick solution +```c + pd_cap = simple_get_pd(&simple); +``` +
    + +Just as in the previous step, you were made to grab a reference to the +root of your thread's CSpace, now you're being made to grab a reference +to the root of your thread's VSpace. +- + +On successful completion this task, the output should not change. + +### Allocate a TCB Object + +```c + + /* TASK 8: create a new TCB */ + /* hint: vka_alloc_tcb() + * int vka_alloc_tcb(vka_t *vka, vka_object_t *result); + * @param vka Pointer to vka interface. + * @param result Structure for the TCB object. This gets initialised. + * @return 0 on success + */ + vka_object_t tcb_object = {0}; +``` +
    +Quick solution +```c + error = vka_alloc_tcb(&vka, &tcb_object); + ZF_LOGF_IFERR(error, "Failed to allocate new TCB.\n" + "\tVKA given sufficient bootstrap memory?"); +``` +
    + +In order to manage the threads that are created in seL4, the seL4 kernel +keeps track of TCB (Thread Control Block) objects. Each of these +represents a schedulable executable resource. Unlike other contemporary +kernels, seL4 **doesn't** allocate a stack, virtual-address space +(VSpace) and other metadata on your behalf. This step creates a TCB, +which is a very bare-bones, primitive resource, which requires you to +still manually fill it out. + +- + +After completing this task, the errors should disappear, and you should see the following +output: +``` +main: hello world +``` + +### Configure the new TCB +```c + + /* TASK 9: initialise the new TCB */ + /* hint 1: seL4_TCB_Configure() + * int seL4_TCB_Configure(seL4_TCB _service, seL4_Word fault_ep, seL4_CNode cspace_root, seL4_Word cspace_root_data, seL4_CNode vspace_root, seL4_Word vspace_root_data, seL4_Word buffer, seL4_CPtr bufferFrame) + * @param service Capability to the TCB which is being operated on. + * @param fault_ep Endpoint which receives IPCs when this thread faults (must be in TCB's cspace). + * @param cspace_root The new CSpace root. + * @param cspace_root_data Optionally set the guard and guard size of the new root CNode. If set to zero, this parameter has no effect. + * @param vspace_root The new VSpace root. + * @param vspace_root_data Has no effect on IA-32 or ARM processors. + * @param buffer Address of the thread's IPC buffer. Must be 512-byte aligned. The IPC buffer may not cross a page boundary. + * @param bufferFrame Capability to a page containing the thread?s IPC buffer. + * @return 0 on success. + * Note: this function is generated during build. It is generated from the following definition: + * + * hint 2: use seL4_CapNull for the fault endpoint + * hint 3: use seL4_NilData for cspace and vspace data + * hint 4: we don't need an IPC buffer frame or address yet + */ +``` +
    +Quick solution +```c + error = seL4_TCB_Configure(tcb_object.cptr, seL4_CapNull, cspace_cap, seL4_NilData, pd_cap, seL4_NilData, 0, 0); + ZF_LOGF_IFERR(error, "Failed to configure the new TCB object.\n" + "\tWe're running the new thread with the root thread's CSpace.\n" + "\tWe're running the new thread in the root thread's VSpace.\n" + "\tWe will not be executing any IPC in this app.\n"); +``` +
    + +You must create a new VSpace for your new thread if you need it to +execute in its own isolated address space, and tell the kernel which +VSpace you plan for the new thread to execute in. This opens up the +option for threads to share VSpaces. In similar fashion, you must also +tell the kernel which CSpace your new thread will use -- whether it will +share a currently existing one, or whether you've created a new one for +it. That's what you're doing now. + +In this particular example, you're allowing the new thread to share your +main thread's CSpace and VSpace. + +In addition, a thread needs to have a priority set on it in order for it to run. +`seL4_TCB_SetPriority(tcb_object.cptr, seL4_CapInitThreadTCB, seL4_MaxPrio);` +will give your new thread the same priority as the current thread, allowing it +to be run the next time the seL4 scheduler is invoked. The seL4 scheduler is invoked +everytime there is a kernel timer tick. +- + +On successful completion this task, the output should not change. + +### Name the new TCB +```c + + /* TASK 10: give the new thread a name */ + /* hint: we've done thread naming before */ +``` +
    +Quick solution +```c + NAME_THREAD(tcb_object.cptr, "dynamic-1: thread_2"); +``` +
    + +This is a convenience function -- sets a name string for the TCB object. + +On successful completion this task, the output should not change. + +### Set the instruction pointer +```c + + /* + * set start up registers for the new thread: + */ + UNUSED seL4_UserContext regs = {0}; + + /* TASK 11: set instruction pointer where the thread shoud start running */ + /* hint 1: sel4utils_set_instruction_pointer() + * void sel4utils_set_instruction_pointer(seL4_UserContext *regs, seL4_Word value); + * @param regs Data structure in which to set the instruction pointer value + * @param value New instruction pointer value + * + * hint 2: we want the new thread to run the function "thread_2" + */ +``` +
    +Quick solution +```c + sel4utils_set_instruction_pointer(®s, (seL4_Word)thread_2); + +``` +
    + +Pay attention to the line that precedes this particular task -- the line +that zeroes out a new "seL4_UserContext" object. As we previously +explained, seL4 requires you to fill out the Thread Control Block +manually. That includes the new thread's initial register contents. You +can set the value of the stack pointer, the instruction pointer, and if +you want to get a little creative, you can pass some initial data to +your new thread through its registers. +- + +On successful completion this task, the output should not change. +### Set the stack pointer +```c + + /* TASK 12: set stack pointer for the new thread */ + /* hint 1: sel4utils_set_stack_pointer() + * void sel4utils_set_stack_pointer(seL4_UserContext *regs, seL4_Word value); + * @param regs Data structure in which to set the stack pointer value + * @param value New stack pointer value + * + * hint 2: remember the stack grows down! + */ +``` +
    +Quick solution +```c + sel4utils_set_stack_pointer(®s, thread_2_stack_top); +``` +
    + +This TASK is just some pointer arithmetic. The cautionary note that the +stack grows down is meant to make you think about the arithmetic. +Processor stacks push new values toward decreasing addresses, so give it +some thought. +- + +On successful completion this task, the output should not change. + +### Write the registers +```c + + /* TASK 13: actually write the TCB registers. We write 2 registers: + * instruction pointer is first, stack pointer is second. */ + /* hint: seL4_TCB_WriteRegisters() + * int seL4_TCB_WriteRegisters(seL4_TCB service, seL4_Bool resume_target, seL4_Uint8 arch_flags, seL4_Word count, seL4_UserContext *regs) + * @param service Capability to the TCB which is being operated on. + * @param resume_target The invocation should also resume the destination thread. + * @param arch_flags Architecture dependent flags. These have no meaning on either IA-32 or ARM. + * @param count The number of registers to be set. + * @param regs Data structure containing the new register values. + * @return 0 on success + */ +``` +
    +Quick solution +```c + error = seL4_TCB_WriteRegisters(tcb_object.cptr, 0, 0, 2, ®s); + ZF_LOGF_IFERR(error, "Failed to write the new thread's register set.\n" + "\tDid you write the correct number of registers? See arg4.\n"); +``` +
    + +As explained above, we've been filling out our new thread's TCB for the +last few operations, so now we're writing the values we've chosen, to +the TCB object in the kernel. +- + +On successful completion this task, the output should not change. + +### Start the new thread +```c + + /* TASK 14: start the new thread running */ + /* hint: seL4_TCB_Resume() + * int seL4_TCB_Resume(seL4_TCB service) + * @param service Capability to the TCB which is being operated on. + * @return 0 on success + */ +``` +
    +Quick solution +```c + error = seL4_TCB_Resume(tcb_object.cptr); + ZF_LOGF_IFERR(error, "Failed to start new thread.\n"); +``` +
    + +Finally, we tell the kernel that our new thread is runnable. From here, +the kernel itself will choose when to run the thread based on the +priority we gave it, and according to the kernel's configured scheduling +policy. + +- + +On successful completion this task, the output should not change. +### Print something +```c + + /* TASK 15: print something */ + /* hint: printf() */ +} +``` +
    +Quick solution +```c + printf("thread_2: hallo wereld\n"); +``` +
    + +For the sake of confirmation that our new thread was executed by the +kernel successfully, we cause it to print something to the screen. + +On success, you should see output from your new thread. + +## Links to source + +- `sel4_BootInfo`: + +- `simple_t`: + +- `vka_t`: + +- `allocman_t`: + +- `name_thread()`: + + +That's it for this tutorial. + +Next tutorial: IPC diff --git a/TutorialsReworked/DynamicLibraries/ipc.md b/TutorialsReworked/DynamicLibraries/ipc.md index e69de29bb2..0c056ee083 100644 --- a/TutorialsReworked/DynamicLibraries/ipc.md +++ b/TutorialsReworked/DynamicLibraries/ipc.md @@ -0,0 +1,722 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# seL4 Dynamic Libraries: IPC + +The tutorial is designed to +teach the basics of seL4 IPC using Endpoint objects, and userspace +paging management. You'll be led through the process of creating a new +thread (retyping an untyped object into a TCB object), and also made to +manually do your own memory management to allocate some virtual memory +for use as the shared memory buffer between your two threads. + +Don't gloss over the globals declared before `main()` -- they're declared +for your benefit so you can grasp some of the basic data structures. + +You'll observe that the things you've already covered in the second +tutorial are filled out and you don't have to repeat them: in much the +same way, we won't be repeating conceptual explanations on this page, if +they were covered by a previous tutorial in the series. + +Learning outcomes: +- Repeat the spawning of a thread. "''If it's nice, do it twice''" + -- Caribbean folk-saying. Once again, the new thread will be + sharing its creator's VSpace and CSpace. +- Introduction to the idea of badges, and minting badged copies of + an Endpoint capability. NB: you don't mint a new copy of the + Endpoint object, but a copy of the capability that + references it. +- Basic IPC: sending and receiving: how to make two + threads communicate. +- IPC Message format, and Message Registers. seL4 binds some of + the first Message Registers to hardware registers, and the rest + are transferred in the IPC buffer. +- Understand that each thread has only one IPC buffer, which is + pointed to by its TCB. It's possible to make a thread wait on + both an Endpoint and a Notification using "Bound Notifications". +- Understand CSpace pointers, which are really just integers with + multiple indexes concatenated into one. Understanding them well + however, is important to understanding how capabilities work. Be + sure you understand the diagram on the "**CSpace example and + addressing**" slide. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut dynamic-2 +# building the tutorial exercise +cd dynamic-2_build +ninja +``` + +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut dynamic-2 +``` +Answers are also available in drop down menus under each section. +
    + + +## Exercises + +When you first run this tutorial, you will see a fault as follows: +``` +Booting all finished, dropped to user space +Caught cap fault in send phase at address (nil) +while trying to handle: +vm fault on data at address 0x70003c8 with status 0x6 +in thread 0xffffff801ffb5400 "rootserver" at address 0x402977 +With stack: +0x43df70: 0x0 +0x43df78: 0x0 +``` + +### Allocate an IPC buffer + +As we mentioned in passing before, threads in seL4 do their own memory +management. You implement your own Virtual Memory Manager, essentially. +To the extent that you must allocate a physical memory frame, then map +it into your thread's page directory -- and even manually allocate page +tables on your own, where necessary. + +Here's the first step in a conventional memory manager's process of +allocating memory: first allocate a physical frame. As you would expect, +you cannot directly write to or read from this frame object since it is +not mapped into any virtual address space as yet. Standard restrictions +of a MMU-utilizing kernel apply. + +- + +``` + + /* TASK 1: get a frame cap for the ipc buffer */ + /* hint: vka_alloc_frame() + * int vka_alloc_frame(vka_t *vka, uint32_t size_bits, vka_object_t *result) + * @param vka Pointer to vka interface. + * @param size_bits Frame size: 2^size_bits + * @param result Structure for the Frame object. This gets initialised. + * @return 0 on success + */ + vka_object_t ipc_frame_object; +``` +
    +Quick solution +```c + error = vka_alloc_frame(&vka, IPCBUF_FRAME_SIZE_BITS, &ipc_frame_object); + ZF_LOGF_IFERR(error, "Failed to alloc a frame for the IPC buffer.\n" + "\tThe frame size is not the number of bytes, but an exponent.\n" + "\tNB: This frame is not an immediately usable, virtually mapped page.\n") +``` +
    + +On completion, the output will not change. + +### Try to map a page + +Take note of the line of code that precedes this: the one where a +virtual address is randomly chosen for use. This is because, as we +explained before, the process is responsible for its own Virtual Memory +Management. As such, if it chooses, it can map any page in its VSpace to +physical frame. It can technically choose to do unconventional things, +like not unmap PFN #0. The control of how the address space is managed +is up to the threads that have write-capabilities to that address space. +There is both flexibility and responsibility implied here. Granted, seL4 +itself provides strong guarantees of isolation even if a thread decides +to go rogue. + +Attempt to map the frame you allocated earlier, into your VSpace. A keen +reader will pick up on the fact that it's unlikely that this will work, +since you'd need a new page table to contain the new page-table-entry. +The tutorial deliberately walks you through both the mapping of a frame +into a VSpace, and the mapping of a new page-table into a VSpace. + +- +- + +``` + + /* TASK 2: try to map the frame the first time */ + /* hint 1: seL4_ARCH_Page_Map() + * The *ARCH* versions of seL4 sys calls are abstractions over the architecture provided by libsel4utils + * this one is defined as: + * #define seL4_ARCH_Page_Map seL4_X86_Page_Map + * The signature for the underlying function is: + * int seL4_X86_Page_Map(seL4_X86_Page service, seL4_X86_PageDirectory pd, seL4_Word vaddr, seL4_CapRights rights, seL4_X86_VMAttributes attr) + * @param service Capability to the page to map. + * @param pd Capability to the VSpace which will contain the mapping. + * @param vaddr Virtual address to map the page into. + * @param rights Rights for the mapping. + * @param attr VM Attributes for the mapping. + * @return 0 on success. + * + * Note: this function is generated during build. It is generated from the following definition: + * + * hint 2: for the rights, use seL4_AllRights + * hint 3: for VM attributes use seL4_ARCH_Default_VMAttributes + * Hint 4: It is normal for this function call to fail. That means there are + * no page tables with free slots -- proceed to the next step where you'll + * be led to allocate a new empty page table and map it into the VSpace, + * before trying again. + */ +``` +
    +Quick solution +```c + error = seL4_ARCH_Page_Map(ipc_frame_object.cptr, pd_cap, ipc_buffer_vaddr, + seL4_AllRights, seL4_ARCH_Default_VMAttributes); +``` +
    + + +On completion, the output will be as follows: +``` +dynamic-2: main@main.c:260 [Err seL4_FailedLookup]: + Failed to allocate new page table. +``` + +### Allocate a page table + +So just as you previously had to manually retype a new frame to use for +your IPC buffer, you're also going to have to manually retype a new +page-table object to use as a leaf page-table in your VSpace. + +- + +``` + + /* TASK 3: create a page table */ + /* hint: vka_alloc_page_table() + * int vka_alloc_page_table(vka_t *vka, vka_object_t *result) + * @param vka Pointer to vka interface. + * @param result Structure for the PageTable object. This gets initialised. + * @return 0 on success + */ + ``` +
    +Quick solution +```c + error = vka_alloc_page_table(&vka, &pt_object); + ZF_LOGF_IFERR(error, "Failed to allocate new page table.\n"); +``` +
    + +On completion, you will see another fault. + +### Map a page table + +If you successfully retyped a new page table from an untyped memory +object, you can now map that new page table into your VSpace, and then +try again to finally map the IPC-buffer's frame object into the VSpace. + +- +- + +``` + + /* TASK 4: map the page table */ + /* hint 1: seL4_ARCH_PageTable_Map() + * The *ARCH* versions of seL4 sys calls are abstractions over the architecture provided by libsel4utils + * this one is defined as: + * #define seL4_ARCH_PageTable_Map seL4_X86_PageTable_Map + * The signature for the underlying function is: + * int seL4_X86_PageTable_Map(seL4_X86_PageTable service, seL4_X86_PageDirectory pd, seL4_Word vaddr, seL4_X86_VMAttributes attr) + * @param service Capability to the page table to map. + * @param pd Capability to the VSpace which will contain the mapping. + * @param vaddr Virtual address to map the page table into. + * @param rights Rights for the mapping. + * @param attr VM Attributes for the mapping. + * @return 0 on success. + * + * Note: this function is generated during build. It is generated from the following definition: + * + * hint 2: for VM attributes use seL4_ARCH_Default_VMAttributes + */ +``` +
    +Quick solution +```c + error = seL4_ARCH_PageTable_Map(pt_object.cptr, pd_cap, + ipc_buffer_vaddr, seL4_ARCH_Default_VMAttributes); + ZF_LOGF_IFERR(error, "Failed to map page table into VSpace.\n" + "\tWe are inserting a new page table into the top-level table.\n" + "\tPass a capability to the new page table, and not for example, the IPC buffer frame vaddr.\n") +``` +
    + +On completion, you will see another fault. + +### Map a page + +Use `seL4_ARCH_Page_Map` to map the frame in. +If everything was done correctly, there is no reason why this step +should fail. Complete it and proceed. +``` + + /* TASK 5: then map the frame in */ + /* hint 1: use seL4_ARCH_Page_Map() as above + * hint 2: for the rights, use seL4_AllRights + * hint 3: for VM attributes use seL4_ARCH_Default_VMAttributes + */ +``` +
    +Quick solution +```c + error = seL4_ARCH_Page_Map(ipc_frame_object.cptr, pd_cap, + ipc_buffer_vaddr, seL4_AllRights, seL4_ARCH_Default_VMAttributes); + ZF_LOGF_IFERR(error, "Failed again to map the IPC buffer frame into the VSpace.\n" + "\t(It's not supposed to fail.)\n" + "\tPass a capability to the IPC buffer's physical frame.\n" + "\tRevisit the first seL4_ARCH_Page_Map call above and double-check your arguments.\n"); +``` +
    + +On completion, you will see the following: +``` +main: hello world +dynamic-2: main@main.c:464 [Cond failed: seL4_MessageInfo_get_length(tag) != 1] + Response data from thread_2 was not the length expected. + How many registers did you set with seL4_SetMR within thread_2? +``` + +### Allocate an endpoint + +Now we have a (fully mapped) IPC buffer -- but no Endpoint object to +send our IPC data across. We must retype an untyped object into a kernel +Endpoint object, and then proceed. This could be done via a more +low-level approach using `seL4_Untyped_Retype()`, but instead, the +tutorial makes use of the VKA allocator. Remember that the VKA allocator +is an seL4 type-aware object allocator? So we can simply ask it for a +new object of a particular type, and it will do the low-level retyping +for us, and return a capability to a new object as requested. + +In this case, we want a new Endpoint so we can do IPC. Complete the step +and proceed. + +- + +``` + + /* TASK 6: create an endpoint */ + /* hint: vka_alloc_endpoint() + * int vka_alloc_endpoint(vka_t *vka, vka_object_t *result) + * @param vka Pointer to vka interface. + * @param result Structure for the Endpoint object. This gets initialised. + * @return 0 on success + */ +``` +
    +Quick solution +```c + error = vka_alloc_endpoint(&vka, &ep_object); + ZF_LOGF_IFERR(error, "Failed to allocate new endpoint object.\n"); +``` +
    + +On completion, the output will not change. + +### Badge an endpoint + +Badges are used to uniquely identify a message queued on an endpoint as +having come from a particular sender. Recall that in seL4, each thread +has only one IPC buffer. If multiple other threads are sending data to a +listening thread, how can that listening thread distinguish between the +data sent by each of its IPC partners? Each sender must "badge" its +capability to its target's endpoint. + +Note the distinction: the badge is not applied to the target endpoint, +but to the sender's **capability** to the target endpoint. This +enables the listening thread to mint off copies of a capability to an +Endpoint to multiple senders. Each sender is responsible for applying a +unique badge value to the capability that the listener gave it so that +the listener can identify it. + +In this step, you are badging the endpoint that you will use when +sending data to the thread you will be creating later on. The +`vka_mint_object()` call will return a new, badged copy of the +capability to the endpoint that your new thread will listen on. When you +send data to your new thread, it will receive the badge value with the +data, and know which sender you are. Complete the step and proceed. + +- +- + +``` + + /* TASK 7: make a badged copy of it in our cspace. This copy will be used to send + * an IPC message to the original cap */ + /* hint 1: vka_mint_object() + * int vka_mint_object(vka_t *vka, vka_object_t *object, cspacepath_t *result, seL4_CapRights rights, seL4_Word badge) + * @param[in] vka The allocator for the cspace. + * @param[in] object Target object for cap minting. + * @param[out] result Allocated cspacepath. + * @param[in] rights The rights for the minted cap. + * @param[in] badge The badge for the minted cap. + * @return 0 on success + * + * hint 2: for the rights, use seL4_AllRights + * hint 3: for the badge use EP_BADGE + */ +``` +
    +Quick solution +```c + error = vka_mint_object(&vka, &ep_object, &ep_cap_path, seL4_AllRights, + EP_BADGE); + ZF_LOGF_IFERR(error, "Failed to mint new badged copy of IPC endpoint.\n" + "\tseL4_Mint is the backend for vka_mint_object.\n" + "\tseL4_Mint is simply being used here to create a badged copy of the same IPC endpoint.\n" + "\tThink of a badge in this case as an IPC context cookie.\n"); +``` +
    + +On completion, the output will not change. + +### Message registers + +Here we get a formal introduction to message registers. At first glance, +you might wonder why the `sel4_SetMR()` calls don't specify a message +buffer, and seem to know which buffer to fill out -- and that would be +correct, because they do. They are operating directly on the sending +thread's IPC buffer. Recall that each thread has only one IPC buffer. Go +back and look at your call to `seL4_TCB_Configure()` in step 7 again: +you set the IPC buffer for the new thread in the last 2 arguments to +this function. Likewise, the thread that created **your** main thread +also set an IPC buffer up for you. + +So `seL4_SetMR()` and `seL4_GetMR()` simply write to and read from the IPC +buffer you designated for your thread. `MSG_DATA` is uninteresting -- can +be any value. You'll find the `seL4_MessageInfo_t` type explained in the +manuals. In short, it's a header that is embedded in each message that +specifies, among other things, the number of Message Registers that hold +meaningful data, and the number of capabilities that are going to be +transmitted in the message. + +- +- + +``` + + /* TASK 8: set the data to send. We send it in the first message register */ + /* hint 1: seL4_MessageInfo_new() + * seL4_MessageInfo_t CONST seL4_MessageInfo_new(seL4_Uint32 label, seL4_Uint32 capsUnwrapped, seL4_Uint32 extraCaps, seL4_Uint32 length) + * @param label The value of the label field + * @param capsUnwrapped The value of the capsUnwrapped field + * @param extraCaps The value of the extraCaps field + * @param length The number of message registers to send + * @return The seL4_MessageInfo_t containing the given values. + * + * seL4_MessageInfo_new() is generated during build. It can be found in: + * build/x86/pc99/libsel4/include/sel4/types_gen.h + * + * hint 2: use 0 for the first 3 fields. + * hint 3: send only 1 message register of data + * + * hint 4: seL4_SetMR() + * void seL4_SetMR(int i, seL4_Word mr) + * @param i The message register to write + * @param mr The value of the message register + * + * hint 5: send MSG_DATA + */ +``` +
    +Quick solution +```c + tag = seL4_MessageInfo_new(0, 0, 0, 1); + seL4_SetMR(0, MSG_DATA); +``` +
    + +On completion, the output should change as follows: +``` +dynamic-2: main@main.c:472 [Cond failed: msg != ~MSG_DATA] + Response data from thread_2's content was not what was expected. +``` + +### IPC + +Now that you've constructed your message and badged the endpoint that +you'll use to send it, it's time to send it. The `seL4_Call()` syscall +will send a message across an endpoint synchronously. If there is no +thread waiting at the other end of the target endpoint, the sender will +block until there is a waiter. The reason for this is because the seL4 +kernel would prefer not to buffer IPC data in the kernel address space, +so it just sleeps the sender until a receiver is ready, and then +directly copies the data. It simplifies the IPC logic. There are also +polling send operations, as well as polling receive operations in case +you don't want to be forced to block if there is no receiver on the +other end of an IPC Endpoint. + +When you send your badged data using `seL4_Call()`, our receiving thread +(which we created earlier) will pick up the data, see the badge, and +know that it was us who sent the data. Notice how the sending thread +uses the **badged** capability to the endpoint object, and the +receiving thread uses the unmodified original capability to the same +endpoint? The sender must identify itself. + +Notice also that the fact that both the sender and the receiver share +the same root CSpace, enables the receiving thread to just casually use +the original, unbadged capability without any extra work needed to make +it accessible. + +Notice however also, that while the sending thread has a capability that +grants it full rights to send data across the endpoint since it was the +one that created that capability, the receiver's capability may not +necessarily grant it sending powers (write capability) to the endpoint. +It's entirely possible that the receiver may not be able to send a +response message, if the sender doesn't want it to. + +- +- + +``` + + /* TASK 9: send and wait for a reply. */ + /* hint: seL4_Call() + * seL4_MessageInfo_t seL4_Call(seL4_CPtr dest, seL4_MessageInfo_t msgInfo) + * @param dest The capability to be invoked. + * @param msgInfo The messageinfo structure for the IPC. This specifies information about the message to send (such as the number of message registers to send). + * @return A seL4_MessageInfo_t structure. This is information about the repy message. + * + * hint 2: seL4_MessageInfo_t is generated during build. + * The type definition and generated field access functions are defined in a generated file: + * build/x86/pc99/libsel4/include/sel4/types_gen.h + * It is generated from the following definition: + */ +``` +
    +Quick solution +```c + tag = seL4_Call(ep_cap_path.capPtr, tag); +``` +
    + +On completion, you should see thread_2 fault as follows: +``` +thread_2: hallo wereld +thread_2: got a message 0 from 0 +Caught cap fault in send phase at address (nil) +while trying to handle: +vm fault on data at address (nil) with status 0x4 +in thread 0xffffff801ffb4400 "child of: 'rootserver'" at address (nil) +in thread 0xffffff801ffb4400 "child of: 'rootserver'" at address (nil) +With stack: +``` + +### Receive a reply + +While this task is out of order, since we haven't yet examined the +receive-side of the operation here, it's fairly simple anyway: this task +occurs after the receiver has sent a reply, and it shows the sender now +reading the reply from the receiver. As mentioned before, the +`seL4_GetMR()` calls are simply reading from the calling thread's +designated, single IPC buffer. + +- + +``` + + /* TASK 10: get the reply message */ + /* hint: seL4_GetMR() + * seL4_Word seL4_GetMR(int i) + * @param i The message register to retreive + * @return The message register value + */ +``` +
    +Quick solution +```c + msg = seL4_GetMR(0); +``` +
    + +On completion, the output should not change. + +### Receive an IPC + +We're now in the receiving thread. The `seL4_Recv()` syscall performs a +blocking listen on an Endpoint or Notification capability. When new data +is queued (or when the Notification is signalled), the `seL4_Recv` +operation will unqueue the data and resume execution. + +Notice how the `seL4_Recv()` operation explicitly makes allowance for +reading the badge value on the incoming message? The receiver is +explicitly interested in distinguishing the sender. + +- +- + +``` + + /* TASK 11: wait for a message to come in over the endpoint */ + /* hint 1: seL4_Recv() + * seL4_MessageInfo_t seL4_Recv(seL4_CPtr src, seL4_Word* sender) + * @param src The capability to be invoked. + * @param sender The badge of the endpoint capability that was invoked by the sender is written to this address. + * @return A seL4_MessageInfo_t structure + * + * hint 2: seL4_MessageInfo_t is generated during build. + * The type definition and generated field access functions are defined in a generated file: + * build/x86/pc99/libsel4/include/sel4/types_gen.h + */ +``` +
    +Quick solution +```c + tag = seL4_Recv(ep_object.cptr, &sender_badge); +``` +
    + +On completion, the output should change slightly: +``` +thread_2: got a message 0 from 0x61 +``` + +### Validate the message + +These two calls here are just verification of the fidelity of the +transmitted message. It's very unlikely you'll encounter an error here. +Complete them and proceed to the next step. + +- + +``` + + /* TASK 12: make sure it is what we expected */ + /* hint 1: check the badge. is it EP_BADGE? + * hint 2: we are expecting only 1 message register + * hint 3: seL4_MessageInfo_get_length() + * seL4_Uint32 CONST seL4_MessageInfo_get_length(seL4_MessageInfo_t seL4_MessageInfo) + * @param seL4_MessageInfo the seL4_MessageInfo_t to extract a field from + * @return the number of message registers delivered + * seL4_MessageInfo_get_length() is generated during build. It can be found in: + * build/x86/pc99/libsel4/include/sel4/types_gen.h + */ +``` +
    +Quick solution +```c + ZF_LOGF_IF(sender_badge != EP_BADGE, + "Badge on the endpoint was not what was expected.\n"); + + ZF_LOGF_IF(seL4_MessageInfo_get_length(tag) != 1, + "Length of the data send from root thread was not what was expected.\n" + "\tHow many registers did you set with seL4_SetMR, within the root thread?\n"); +``` +
    + +On completion, the output should not change. + +### Read the message registers + +Again, just reading the data from the Message Registers. + +- + +``` + + /* TASK 13: get the message stored in the first message register */ + /* hint: seL4_GetMR() + * seL4_Word seL4_GetMR(int i) + * @param i The message register to retreive + * @return The message register value + */ +``` +
    +Quick solution +```c + msg = seL4_GetMR(0); + printf("thread_2: got a message %#" PRIxPTR " from %#" PRIxPTR "\n", msg, sender_badge); +``` +
    + +On completion, the output should change slightly: +``` +thread_2: got a message 0x6161 from 0x61 +``` + +### Write the message registers + +And writing Message Registers again. + +- + +``` + + /* TASK 14: copy the modified message back into the message register */ + /* hint: seL4_SetMR() + * void seL4_SetMR(int i, seL4_Word mr) + * @param i The message register to write + * @param mr The value of the message register + */ +``` +
    +Quick solution +```c + seL4_SetMR(0, msg); +``` +
    + +On completion, the output should not change. + +### Reply to a message + +This is a formal introduction to the `Reply` capability which is +automatically generated by the seL4 kernel, whenever an IPC message is +sent using the `seL4_Call()` syscall. This is unique to the `seL4_Call()` +syscall, and if you send data instead with the `seL4_Send()` syscall, the +seL4 kernel will not generate a Reply capability. + +The Reply capability solves the issue of a receiver getting a message +from a sender, but not having a sufficiently permissive capability to +respond to that sender. The "Reply" capability is a one-time capability +to respond to a particular sender. If a sender doesn't want to grant the +target the ability to send to it repeatedly, but would like to allow the +receiver to respond to a specific message once, it can use `seL4_Call()`, +and the seL4 kernel will facilitate this one-time permissive response. +Complete the step and pat yourself on the back. + +- +- + +``` + + /* TASK 15: send the message back */ + /* hint 1: seL4_ReplyRecv() + * seL4_MessageInfo_t seL4_ReplyRecv(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *sender) + * @param dest The capability to be invoked. + * @param msgInfo The messageinfo structure for the IPC. This specifies information about the message to send (such as the number of message registers to send) as the Reply part. + * @param sender The badge of the endpoint capability that was invoked by the sender is written to this address. This is a result of the Wait part. + * @return A seL4_MessageInfo_t structure. This is a result of the Wait part. + * + * hint 2: seL4_MessageInfo_t is generated during build. + * The type definition and generated field access functions are defined in a generated file: + * build/x86/pc99/libsel4/include/sel4/types_gen.h + * It is generated from the following definition: + */ +``` +
    +Quick solution +```c + seL4_ReplyRecv(ep_object.cptr, tag, &sender_badge); +``` +
    + +On completion, the output should change, with the fault message replaced with the following: +``` +main: got a reply: [0xffff9e9e|0xffffffffffff9e9e] +``` +That's it for this tutorial. + +Next tutorial: Processes & Elf loading diff --git a/TutorialsReworked/DynamicLibraries/processes.md b/TutorialsReworked/DynamicLibraries/processes.md index e69de29bb2..5a0d1e28a4 100644 --- a/TutorialsReworked/DynamicLibraries/processes.md +++ b/TutorialsReworked/DynamicLibraries/processes.md @@ -0,0 +1,461 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +# seL4 Dynamic Libraries: Processes & Elf loading + +This tutorial shows how a separate ELF file can be loaded and expanded into a +VSpace, and subsequently executed, while facilitating IPC between the +two modules. It also shows how threads with different CSpaces have to +maneuver in order to pass capabilities to one another. + +Don't gloss over the globals declared before `main()` -- they're declared +for your benefit so you can grasp some of the basic data structures. +Uncomment them one by one as needed when going through the tasks. + +You'll observe that the things you've already covered in the second +tutorial are filled out and you don't have to repeat them: in much the +same way, we won't be repeating conceptual explanations on this page, if +they were covered by a previous tutorial in the series. + +Learning outcomes: +- Once again, repeat the spawning of a thread: however, this time + the two threads will only share the same vspace, but have + different CSpaces. This is an automatic side effect of the way + that sel4utils creates new "processes". +- Learn how the init thread in an seL4 system performs some types + of initialization that aren't traditionally left to userspace. +- Observe and understand the effects of creating thread that do + not share the same CSpace. +- Understand IPC across CSpace boundaries. +- Understand how minting a capability to a thread in another + CSpace works. + + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut dynamic-3 +# building the tutorial exercise +cd dynamic-3_build +ninja +``` +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut dynamic-3 +``` +Answers are also available in drop down menus under each section. +
    + + +## Exercises + +Tasks in this tutorial are in `main.c` and `app.c`. + +When you first run this tutorial, you should see the following output: + +``` +Booting all finished, dropped to user space +Node 0 of 1 +IOPT levels: 4294967295 +IPC buffer: 0x57f000 +Empty slots: [488 --> 4096) +sharedFrames: [0 --> 0) +userImageFrames: [16 --> 399) +userImagePaging: [12 --> 15) +untypeds: [399 --> 488) +Initial thread domain: 0 +Initial thread cnode size: 12 +dynamic-3: vspace_reserve_range_aligned@vspace.h:621 Not implemented +dynamic-3: main@main.c:117 [Cond failed: virtual_reservation.res == NULL] + Failed to reserve a chunk of memory. +``` + +### Virtual memory management + +Aside from receiving information about IRQs in the IRQControl object +capability, and information about available IO-Ports, and ASID +availability, and several other privileged bits of information, the init +thread is also responsible, surprisingly, for reserving certain critical +ranges of memory as being used, and unavailable for applications. + +This call to `sel4utils_bootstrap_vspace_with_bootinfo_leaky()` does +that. For an interesting look at what sorts of things the init thread +does, see: +`static int reserve_initial_task_regions(vspace_t *vspace, void *existing_frames[])`, +which is eventually called on by +`sel4utils_bootstrap_vspace_with_bootinfo_leaky()`. So while this +function may seem tedious, it's doing some important things. + +- +- + +```c + + /* TASK 1: create a vspace object to manage our vspace */ + /* hint 1: sel4utils_bootstrap_vspace_with_bootinfo_leaky() + * int sel4utils_bootstrap_vspace_with_bootinfo_leaky(vspace_t *vspace, sel4utils_alloc_data_t *data, seL4_CPtr page_directory, vka_t *vka, seL4_BootInfo *info) + * @param vspace Uninitialised vspace struct to populate. + * @param data Uninitialised vspace data struct to populate. + * @param page_directory Page directory for the new vspace. + * @param vka Initialised vka that this virtual memory allocator will use to allocate pages and pagetables. This allocator will never invoke free. + * @param info seL4 boot info + * @return 0 on succes. + */ +``` +
    +Quick solution +```c + error = sel4utils_bootstrap_vspace_with_bootinfo_leaky(&vspace, + &data, simple_get_pd(&simple), &vka, info); + ZF_LOGF_IFERR(error, "Failed to prepare root thread's VSpace for use.\n" + "\tsel4utils_bootstrap_vspace_with_bootinfo reserves important vaddresses.\n" + "\tIts failure means we can't safely use our vaddrspace.\n"); +``` +
    + + +On success, you should see a different error: + +``` +<> +halting... +``` + +### Configure a process + +`sel4utils_configure_process_custom` took a large amount of the work +out of creating a new "processs". We skipped a number of steps. Take a +look at the source for `sel4utils_configure_process_custom()` and +notice how it spawns the new thread with its own CSpace by +automatically. This will have an effect on our tutorial! It means that +the new thread we're creating will not share a CSpace with our main +thread. + +- + +```c + + /* TASK 2: use sel4utils to make a new process */ + /* hint 1: sel4utils_configure_process_custom() + * hint 2: process_config_default_simple() + * @param process Uninitialised process struct. + * @param vka Allocator to use to allocate objects. + * @param vspace Vspace allocator for the current vspace. + * @param priority Priority to configure the process to run as. + * @param image_name Name of the elf image to load from the cpio archive. + * @return 0 on success, -1 on error. + * + * hint 2: priority is in APP_PRIORITY and can be 0 to seL4_MaxPrio + * hint 3: the elf image name is in APP_IMAGE_NAME + */ +``` +
    +Quick solution +```c + sel4utils_process_t new_process; + + sel4utils_process_config_t config = process_config_default_simple(&simple, APP_IMAGE_NAME, APP_PRIORITY); + error = sel4utils_configure_process_custom(&new_process, &vka, &vspace, config); + ZF_LOGF_IFERR(error, "Failed to spawn a new thread.\n" + "\tsel4utils_configure_process expands an ELF file into our VSpace.\n" + "\tBe sure you've properly configured a VSpace manager using sel4utils_bootstrap_vspace_with_bootinfo.\n" + "\tBe sure you've passed the correct component name for the new thread!\n"); +``` +
    + + +On success, you should see a different error: + +``` + dynamic-3: main@main.c:196 [Cond failed: new_ep_cap == 0] + Failed to mint a badged copy of the IPC endpoint into the new thread's CSpace. + sel4utils_mint_cap_to_process takes a cspacepath_t: double check what you passed. +``` + +### Get a `cspacepath` + +Now, in this particular case, we are making the new thread be the +sender. Recall that the sender must have a capability to the endpoint +that the receiver is listening on, in order to send to that listener. +But in this scenario, our threads do **not** share the same CSpace! +The only way the new thread will know which endpoint it needs a +capability to, is if we tell it. Furthermore, even if the new thread +knows which endpoint object we are listening on, if it doesn't have a +capability to that endpoint, it still can't send data to us. So we must +provide our new thread with both a capability to the endpoint we're +listening on, and also make sure, that that capability we give it has +sufficient privileges to send across the endpoint. + +There is a number of ways we could approach this, but in this tutorial +we decided to just pre-initialize the sender's CSpace with a sufficient +capability to enable it to send to us right from the start of its +execution. We could also have spawned the new thread as a listener +instead, and made it wait for us to send it a message with a sufficient +capability. + +So we use `vka_cspace_make_path()`, which locates one free capability +slot in the selected CSpace, and returns a handle to it, to us. We then +filled that free slot in the new thread's CSpace with a **badged** +capability to the endpoint we are listening on, so as so allow it to +send to us immediately. We could have filled the slot with an unbadged +capability, but then if we were listening for multiple senders, we +wouldn't know who was whom. + +- + +```c + + /* TASK 3: make a cspacepath for the new endpoint cap */ + /* hint 1: vka_cspace_make_path() + * void vka_cspace_make_path(vka_t *vka, seL4_CPtr slot, cspacepath_t *res) + * @param vka Vka interface to use for allocation of objects. + * @param slot A cslot allocated by the cspace alloc function + * @param res Pointer to a cspacepath struct to fill out + * + * hint 2: use the cslot of the endpoint allocated above + */ + cspacepath_t ep_cap_path; + seL4_CPtr new_ep_cap = 0; + ``` +
    +Quick solution +```c + cspacepath_t ep_cap_path; + seL4_CPtr new_ep_cap = 0; + vka_cspace_make_path(&vka, ep_object.cptr, &ep_cap_path); +``` +
    + +On success, the output should not change. + +### Badge a capability + +As discussed above, we now just mint a badged copy of a capability to +the endpoint we're listening on, into the new thread's CSpace, in the +free slot that the VKA library found for us. + +- +- + +```c + + /* TASK 4: copy the endpont cap and add a badge to the new cap */ + /* hint 1: sel4utils_mint_cap_to_process() + * seL4_CPtr sel4utils_mint_cap_to_process(sel4utils_process_t *process, cspacepath_t src, seL4_CapRights rights, seL4_Word data) + * @param process Process to copy the cap to + * @param src Path in the current cspace to copy the cap from + * @param rights The rights of the new cap + * @param data Extra data for the new cap (e.g., the badge) + * @return 0 on failure, otherwise the slot in the processes cspace. + * + * hint 2: for the rights, use seL4_AllRights + * hint 3: for the badge value use EP_BADGE + */ +``` +
    +Quick solution +```c + new_ep_cap = sel4utils_mint_cap_to_process(&new_process, ep_cap_path, + seL4_AllRights, EP_BADGE); + + ZF_LOGF_IF(new_ep_cap == 0, "Failed to mint a badged copy of the IPC endpoint into the new thread's CSpace.\n" + "\tsel4utils_mint_cap_to_process takes a cspacepath_t: double check what you passed.\n"); +``` +
    + + +On success, the output should look something like: + +``` +NEW CAP SLOT: 6ac. +main: hello world +dynamic-3: main@main.c:247 [Cond failed: sender_badge != EP_BADGE] + The badge we received from the new thread didn't match our expectation +``` + +### Spawn a process + +So now that we've given the new thread everything it needs to +communicate with us, we can let it run. Complete this step and proceed. + +- + +```c + + /* TASK 5: spawn the process */ + /* hint 1: sel4utils_spawn_process_v() + * int sel4utils_spawn_process_v(sel4utils_process_t *process, vka_t *vka, vspace_t *vspace, int argc, char *argv[], int resume) + * @param process Initialised sel4utils process struct. + * @param vka Vka interface to use for allocation of frames. + * @param vspace The current vspace. + * @param argc The number of arguments. + * @param argv A pointer to an array of strings in the current vspace. + * @param resume 1 to start the process, 0 to leave suspended. + * @return 0 on success, -1 on error. + */ + /* hint 2: sel4utils_create_word_args() + * void sel4utils_create_word_args(char strings[][WORD_STRING_SIZE], char *argv[], int argc, ...) + * Create c-formatted argument list to pass to a process from arbitrarily long amount of words. + * + * @param strings empty 2d array of chars to populate with word strings. + * @param argv empty 1d array of char pointers which will be set up with pointers to + * strings in strings. + * @param argc number of words + * @param ... list of words to create arguments from. + * + */ +``` +
    +Quick solution +```c + new_ep_cap = sel4utils_mint_cap_to_process(&new_process, ep_cap_path, + seL4_AllRights, EP_BADGE); + seL4_Word argc = 1; + char string_args[argc][WORD_STRING_SIZE]; + char* argv[argc]; + sel4utils_create_word_args(string_args, argv, argc, new_ep_cap); + + error = sel4utils_spawn_process_v(&new_process, &vka, &vspace, argc, (char**) &argv, 1); + ZF_LOGF_IFERR(error, "Failed to spawn and start the new thread.\n" + "\tVerify: the new thread is being executed in the root thread's VSpace.\n" + "\tIn this case, the CSpaces are different, but the VSpaces are the same.\n" + "\tDouble check your vspace_t argument.\n"); +``` +
    + +On success, you should be able to see the second process running. The output should +be as follows: + +``` +NEW CAP SLOT: 6ac. +process_2: hey hey hey +main@app.c:67 [Cond failed: msg != ~MSG_DATA] + Unexpected response from root thread. +main: hello world +dynamic-3: main@main.c:255 [Cond failed: sender_badge != EP_BADGE] + The badge we received from the new thread didn't match our expectation. +``` + +### Receive a message + +We now wait for the new thread to send us data using `seL4_Recv()`... +Then we verify the fidelity of the data that was transmitted. + +- +- + +```c + + /* TASK 6: wait for a message */ + /* hint 1: seL4_Recv() + * seL4_MessageInfo_t seL4_Recv(seL4_CPtr src, seL4_Word* sender) + * @param src The capability to be invoked. + * @param sender The badge of the endpoint capability that was invoked by the sender is written to this address. + * @return A seL4_MessageInfo_t structure + * + * hint 2: seL4_MessageInfo_t is generated during build. + * hint 3: use the badged endpoint cap that you minted above + */ +``` +
    +Quick solution +```c + tag = seL4_Recv(ep_cap_path.capPtr, &sender_badge); + /* make sure it is what we expected */ + ZF_LOGF_IF(sender_badge != EP_BADGE, + "The badge we received from the new thread didn't match our expectation.\n"); + + ZF_LOGF_IF(seL4_MessageInfo_get_length(tag) != 1, + "Response data from the new process was not the length expected.\n" + "\tHow many registers did you set with seL4_SetMR within the new process?\n"); +``` +
    + + +On success, the badge error should no longer be visible. + +### Send a reply + +Another demonstration of the `sel4_Reply()` facility: we reply to the +message sent by the new thread. + +- +- + +```c + + /* TASK 7: send the modified message back */ + /* hint 1: seL4_ReplyRecv() + * seL4_MessageInfo_t seL4_ReplyRecv(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *sender) + * @param dest The capability to be invoked. + * @param msgInfo The messageinfo structure for the IPC. This specifies information about the message to send (such as the number of message registers to send) as the Reply part. + * @param sender The badge of the endpoint capability that was invoked by the sender is written to this address. This is a result of the Wait part. + * @return A seL4_MessageInfo_t structure. This is a result of the Wait part. + * + * hint 2: seL4_MessageInfo_t is generated during build. + * hint 3: use the badged endpoint cap that you used for Call + */ +``` +
    +Quick solution +```c + seL4_ReplyRecv(ep_cap_path.capPtr, tag, &sender_badge); +``` +
    + + +On success, the output should not change. + +### Client Call + +In the new thread, we initiate communications by using `seL4_Call()`. As +outlined above, the receiving thread replies to us using +`sel4_ReplyRecv()`. The new thread then checks the fidelity of the data +that was sent, and that's the end. + +- + +```c + + /* TASK 8: send and wait for a reply */ + /* hint 1: seL4_Call() + * seL4_MessageInfo_t seL4_Call(seL4_CPtr dest, seL4_MessageInfo_t msgInfo) + * @param dest The capability to be invoked. + * @param msgInfo The messageinfo structure for the IPC. This specifies information about the message to send (such as the number of message registers to send). + * @return A seL4_MessageInfo_t structure. This is information about the repy message. + * + * hint 2: send the endpoint cap using argv (see TASK 6 in the other main.c) + */ + ZF_LOGF_IF(argc < 1, + "Missing arguments.\n"); + seL4_CPtr ep = (seL4_CPtr) atol(argv[0]); +``` +
    +Quick solution +```c + seL4_CPtr ep = (seL4_CPtr) atol(argv[0]); + tag = seL4_Call(ep, tag); +``` +
    + +On success, you should see the following: + +``` +process_2: hey hey hey +main: got a message 0x6161 from 0x61 +process_2: got a reply: 0xffffffffffff9e9e +``` + +That's it for this tutorial. + +Next tutorial: Timer diff --git a/TutorialsReworked/seL4Kernel/faults.md b/TutorialsReworked/seL4Kernel/faults.md index e69de29bb2..0661f5215f 100644 --- a/TutorialsReworked/seL4Kernel/faults.md +++ b/TutorialsReworked/seL4Kernel/faults.md @@ -0,0 +1,338 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# Fault handling +This tutorial covers fault handling in seL4 + +You will learn +1. About thread faults. +2. That a thread fault is different from a processor hardware fault. +3. About fault handlers. +4. What the kernel does to a thread which has faulted. +5. How to set the endpoint that the kernel will deliver fault messages on (master vs MCS). +6. How to resume threads after they have faulted. + + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut fault-handlers +# building the tutorial exercise +cd fault-handlers_build +ninja +``` + +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut fault-handlers +``` +
    + +## CapDL Loader + +This tutorial uses a the *capDL loader*, a root task which allocates statically + configured objects and capabilities. + +
    +Get CapDL +The capDL loader parses +a static description of the system and the relevant ELF binaries. +It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects +but we also use it in the tutorials to reduce redundant code. +The program that you construct will end up with its own CSpace and VSpace, which are separate +from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning +in applications loaded by the capDL loader. + +More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). + +For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. +
    + + + +## Background: What is a fault, and what is a fault handler? + +A fault handler is a separate instruction stream which the CPU can jump to in +order to rectify an anomalous condition in the current thread and then return to +the previous instruction stream. + +In seL4, faults are modeled as separately programmer-designated "fault handler" +threads. In monolithic kernels, faults are not usually delivered to a userspace +handler, but they are handled by the monolithic kernel itself. + +In general, attempting to resume execution of the faulted thread +without rectifying the anomaly will simply re-trigger the fault ad infinitum +until the anomaly is cleared away. + +## Thread faults vs other sources of faults + +There are several sources of faults in a running system; they include: +* Fault events generated by the CPU itself when it encounters anomalies in the instruction stream (aka, "processor exceptions"). +* Fault events generated by hardware in the event of some hardware anomaly (such as a machine check or non-maskable interrupt). +* Fault events generated by the seL4 kernel when it encounters anomalies in the current thread. + +This tutorial is only concerned with those fault events generated by the seL4 +kernel. We will call them "thread faults" from here onward to reduce ambiguity. + +## How does thread fault handling work? + +In seL4, when a thread generates a thread fault, the kernel will **block** the +faulting thread's execution and attempt to deliver a message across a special +endpoint associated with that thread, called its "fault handler" endpoint. + +The only special thing about the fault handler endpoint is that a thread can +only have *one* of them. Otherwise it is created and managed just the same way +as any other kind of seL4 endpoint object. + +The thread which is listening on the other end of the fault endpoint is called +the "fault handler". The kernel expects that the fault handler will correct the +anomaly that ails the faulting thread and then tell the kernel when it is safe +to try executing the faulting thread once again. + +To tell the kernel to resume execution of the faulting thread, the fault handler +can either: +* Invoke a reply operation (with `seL4_Reply()`) on the fault handler endpoint and make sure that the `label` in the `seL4_MessageInfo_t` tag is set to `0`; +* Explicitly tell the kernel to resume executing the faulting thread using `seL4_TCB_Resume()`. + +Please note that if the `handler` sets message registers in the reply message, +the kernel may interpret these as meaning something: some fault replies accept +parameters. See the seL4 manual for the reply message format for all faults. + +If the fault handler did not properly rectify the anomaly in the faulting +thread, resuming the faulting thread will simply cause the kernel to re-generate +the fault. + +## Reasons for thread faults + +Thread faults can be generated for different reasons. When a fault occurs the +kernel will pass information describing the cause of the fault as an IPC +message. At the time of writing, the following faults could be generated by +the Master version of the seL4 kernel: + +* Cap fault: A fault triggered because of an invalid cap access. +* VM fault: A fault triggered by incoherent page table state or incorrect memory accesses by a thread. +* Unknown Syscall fault: Triggered by performing a syscall invocation that is unknown to the kernel. +* Debug fault: Triggered when a breakpoint, watchpoint or single-step debug event occurs. + +In addition, the following fault types are added by the MCS kernel: + +* Timeout fault: Triggered when a thread consumes all of its budget and still has further execution to do in the current period. + +## Thread fault messages + +When a fault is generated, the kernel will deliver an IPC message across the +fault endpoint. This IPC message contains information that tells the fault +handler why the fault occured as well as surrounding contextual information +about the fault which might help the fault handler to rectify the anomaly. + +Each anomaly has its own message format because the information needed to +describe each anomaly will be different. For more information about the contents +of the IPC message sent by the seL4 kernel for each fault anomaly, please see +the [seL4 Manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf). + +The rest of this tutorial will attempt to teach the reader how to receive and +handle seL4 thread faults. + +## Setting up a fault endpoint for a thread + +In the scenario where a fault message is being delivered on a fault endpoint, +the kernel acts as the IPC "sender" and the fault handler acts as a receiver. + +This implies that when caps are being handed out to the fault endpoint object, +one cap to the object must be given to the kernel and one cap to the object must +be given to the handler. + +### Kernel end vs handler end + +Programmers specify the capability to use a fault handler for a thread when +configuring a TCB. As a result the programmer can also set a badge on the +kernel's cap to the fault endpoint object. + +When the kernel sends a fault IPC message using a badged endpoint cap, the badge +is delivered to the receiver just the same way it is delivered for any other +IPC where there is a badge on the sender's cap. + +A keen reader would probably have realized that this means that a badge on the +kernel's cap to a fault endpoint can be used to distinguish fault messages +from different faulting threads, such that a single handler can handle +faults from multiple threads. Please see the +[IPC Tutorial](https://docs.sel4.systems/Tutorials/ipc) for a refresher on how +badged fault endpoints work. + +### Differences between MCS and Master kernel + +There is a minor difference in the way that the kernel is informed of the +cap to a fault endpoint, between the master and MCS kernels. + +Regardless though, on both versions of the kernel, to inform the kernel of the +fault endpoint for a thread, call the usual `seL4_TCB_SetSpace()`. + +See the [MCS tutorial](https://docs.sel4.systems/Tutorials/mcs.html) for more information. + +## Exercises + +This tutorial has one address space set up by the CapDL loader, containing two +threads which share the same CSpace. One of the threads is a fault handler while +the other triggers a virtual memory fault. + +You will be guided through the following broad steps: +1. Badging and configuring a fault handler for the faulting thread. +2. Having the faulting thread trigger a thread fault. +3. Handling the fault in the fault handler. +4. Resuming the execution of the faulting thread. + +### Description of the tutorial program + +The tutorial features two threads in different virtual address spaces. One +thread is the "`faulter`" and the other is the "`handler`". The `faulter` is going to +generate a fault, and the `handler` will "handle" it. + +In order for the `handler` to handle the fault, the `handler` must set up a +fault-handling endpoint and tell the kernel to send all fault IPC messages +generated by the `faulter` thread to itself. This is therefore the first step we +take. + +However, we have to ensure that the fault is only triggered *after* the `handler` +thread has set up the fault-handling endpoint and is ready to receive the fault +IPC message from the kernel. + +If the `faulter` thread generates a fault and there is no thread to handle the +the IPC message, the kernel will simply suspend the `faulting` thread. + +For this reason we make the `faulter` thread `seL4_call()` the `handler` thread +across an endpoint and tell it which slot the `handler` should place the fault +handling endpoint cap into. After the `handler` has set up the handler endpoint, +the `handler` will `seL4_Reply()` to the `faulter` to let it know that it the +`handler` is ready to handle fault IPC messages. + +After that we trigger a fault in the `faulter`, handle the fault in the `handler`, +and then resume the `faulter` and that's the end of the exercise. + +### Setting up the endpoint to be used for thread fault IPC messages + +The first exercise is to configure the TCB of the faulter with a fault endpoint. +This exercise is meant to achieve two learning outcomes: +1. Explain that the end of the endpoint that is given to the kernel can be badged, and the kernel will return that badge value when it sends a fault IPC message. +2. Explain the differences between the Master and MCS kernels when it comes to telling the kernel about the fault endpoint. + +Right now the `faulter` thread is blocked on an Endpoint, waiting for the `handler` +to tell it where to put the fault handler endpoint within its own (the +`faulter`'s) CSpace (for the Master kernel). + +To set up the fault handler endpoint, we will to first badge it so that when the +kernel sends us a fault IPC message, we will be able to identify the faulter. +Fault handlers can handle faults from multiple threads, so a badge +enables handlers to identify the faulters they are handling. + +To badge the endpoint, use the `seL4_CNode_Mint()` syscall: + +```c + error = seL4_CNode_Mint( + handler_cspace_root, + badged_faulter_fault_ep_cap, + seL4_WordBits, + handler_cspace_root, + faulter_fault_ep_cap, + seL4_WordBits, + seL4_AllRights, FAULTER_BADGE_VALUE); +``` + +Since we are using the Master kernel, you will also need to copy the badged cap +into the `faulter`'s CSpace (See the [MCS tutorial](https://docs.sel4.systems/Tutorials/mcs.html) +for an explanation of the differences between the Master and MCS kernel when +configuring fault endpoints): + +```c + error = seL4_CNode_Copy( + faulter_cspace_root, + foreign_badged_faulter_empty_slot_cap, + seL4_WordBits, + handler_cspace_root, + badged_faulter_fault_ep_cap, + seL4_WordBits, + seL4_AllRights); +``` + +Finally, we tell the kernel the cap address of the fault endpoint so that the +kernel can deliver fault IPC messages to the `handler`. Since we're +using the Master kernel, we need to pass a CPtr that can be resolved from within +the CSpace of the `faulter` thread: + +```c + error = seL4_TCB_SetSpace( + faulter_tcb_cap, + foreign_badged_faulter_empty_slot_cap, + faulter_cspace_root, + 0, + faulter_vspace_root, + 0); +``` + +### Receiving the IPC message from the kernel: + +The kernel will deliver the IPC message to any thread waiting on the fault +endpoint. To wait for a fault IPC message simply `seL4_Recv()`, the same way +you'd wait for any other IPC message: + +```c + foreign_faulter_capfault_cap = seL4_GetMR(seL4_CapFault_Addr); +``` + +### Finding out information about the generated thread fault: + +In the thread fault IPC message, the kernel will send information about the +fault including the capability address whose access triggered the thread fault. +The seL4 manual gives detailed information on which message registers in the IPC +buffer contain information about the fault and if you're so inclined, the +libsel4 source code also has the exact code values as well. + +In our example here, our sample code generated a Cap Fault, so according to the +seL4 manual, we can find out the cap fault address using at offset +`seL4_CapFault_Addr` in the IPC message, as you see above in the code snippet. + +### Handling a thread fault: + +Now that we know the cap address that generated a fault in the `faulting` thread, +we can "handle" the fault by putting a random cap into that slot and then when +the `faulter` thread re-tries to access that slot, it will succeed this time and +no thread fault will be generated. + +So here we'll copy an endpoint cap into the faulting slot: + +```c + error = seL4_CNode_Copy( + faulter_cspace_root, + foreign_faulter_capfault_cap, + seL4_WordBits, + handler_cspace_root, + sequencing_ep_cap, + seL4_WordBits, + seL4_AllRights); +``` + +### Resuming a faulting thread: + +Finally, to have the `faulter` thread wake up and try to execute again, we +`seL4_Reply()` to it: + +```c + seL4_Reply(seL4_MessageInfo_new(0, 0, 0, 0)); +``` + +## Further exercises + +If you'd like to challenge yourself, make sure to set up the fault handling on +both versions of the kernel: master and MCS. + +Next tutorial: Dynamic libraries diff --git a/TutorialsReworked/seL4Kernel/interrupts.md b/TutorialsReworked/seL4Kernel/interrupts.md index e69de29bb2..34632204a7 100644 --- a/TutorialsReworked/seL4Kernel/interrupts.md +++ b/TutorialsReworked/seL4Kernel/interrupts.md @@ -0,0 +1,212 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# Interrupts +This tutorial covers seL4 interrupts. + +You will learn +* The purpose of the IRQControl capability. +* How to obtain capabilities for specific interrupts. +* How to handle interrupts and their relation with notification objects. + + +# Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut interrupts +# building the tutorial exercise +cd interrupts_build +ninja +``` +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut interrupts +``` +Answers are also available in drop down menus under each section. +
    + +## CapDL Loader + +This tutorial uses a the *capDL loader*, a root task which allocates statically + configured objects and capabilities. + +
    +Get CapDL +The capDL loader parses +a static description of the system and the relevant ELF binaries. +It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects +but we also use it in the tutorials to reduce redundant code. +The program that you construct will end up with its own CSpace and VSpace, which are separate +from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning +in applications loaded by the capDL loader. + +More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). + +For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. +
    + + +## Outcomes + + +## Background + +### IRQControl + +The root task is given a single capability from which capabilities to all irq numbers +in the system can be derived, `seL4_CapIRQControl`. This capability can be moved between CSpaces +and CSlots but cannot be duplicated. Revoking this capability results in all access to all +irq capabilities being removed. + +### IRQHandlers + +IRQHandler capabilities give access to a single irq and are standard seL4 capabilities: they +*can* be moved and duplicated according to system policy. IRQHandlers are obtained by +invoking the IRQControl capability, with architecture specific parameters. Below is an +example of obtaining an IRQHandler. + +```bash +// Get a capability for irq number 7 and place it in cslot 10 in a single-level cspace. +error = seL4_IRQControl_Get(seL4_IRQControl, 7, cspace_root, 10, seL4_WordBits); +``` + +There are a variety of different invocations to obtain irq capabilities which are hardware +dependent, including: + +* [`seL4_IRQControl_GetIOAPIC`](https://docs.sel4.systems/ApiDoc.html#get-io-apic) (x86) +* [`seL4_IRQControl_GetMSI`](https://docs.sel4.systems/ApiDoc.html#get-msi) (x86) +* [`seL4_IRQControl_GetTrigger`](https://docs.sel4.systems/ApiDoc.html#gettrigger) (ARM) + +### Receiving interrupts + +Interrupts are received by registering a capability to a notification object +with the IRQHandler capability for that irq, as follows: +```bash +seL4_IRQHandler_SetNotification(irq_handler, notification); +``` +On success, this call will result in signals being delivered to the notification object when +an interrupt occurs. To handle multiple interrupts on the same notification object, you +can set different badges on the notification capabilities bound to each IRQHandler. + When an interrupt arrives, +the badge of the notification object bound to that IRQHandler is bitwise orred with the data +word in the notification object. +Recall the badging technique for differentiating signals from the + [notification tutorial](https://docs.sel4.systems/Tutorials/notifications). + +Interrupts can be polled for using `seL4_Poll` or waited for using `seL4_Wait`. Either system +call results in the data word of the notification object being delivered as the badge of the +message, and the data word cleared. + +[`seL4_IRQHandler_Clear`](https://docs.sel4.systems/ApiDoc.html#clear) can be used to unbind +the notification from an IRQHandler. + +### Handling interrupts + +Once an interrupt is received and processed by the software, you can unmask the interrupt +using [`seL4_IRQHandler_Ack`](https://docs.sel4.systems/ApiDoc.html#ack) on the IRQHandler. +seL4 will not deliver any further interrupts after an IRQ is raised until that IRQHandler +has been acked. + +## Exercises + +In this tutorial you will set up interrupt handling for a provided timer driver +on the zynq7000 ARM platform. This timer driver can be located inside the +`projects/sel4-tutorials/zynq_timer_driver` folder from the root of the +projects directory, i.e. where the `.repo` folder can be found and where the +initial `repo init` command was executed. The tutorial has been set up with two +processes: `timer.c`, the timer driver and RPC server, and `client.c`, which +makes a single request. + +On successful initialisation of the tutorial, you will see the following: + +``` +timer client: hey hey hey +timer: got a message from 61 to sleep 2 seconds +<> +main@timer.c:78 [Cond failed: error] + Failed to ack irq +``` + +The timer driver we are using emits an interrupt in the `TTC0_TIMER1_IRQ` number. + +**Exercise** Invoke `irq_control`, which contains the `seL4_IRQControl` capability, +the place the `IRQHandler` capability for `TTC0_TIMER1_IRQ` into the `irq_handler` CSlot. + +``` + /* TODO invoke irq_control to put the interrupt for TTC0_TIMER1_IRQ in + cslot irq_handler (depth is seL4_WordBits) */ +``` +
    +Quick solution +```c + error = seL4_IRQControl_Get(irq_control, TTC0_TIMER1_IRQ, cnode, irq_handler, seL4_WordBits); + ZF_LOGF_IF(error, "Failed to get IRQ capability"); +``` +
    + +On success, you should see the following output, without the error message that occurred earlier, +as the irq_handle capability is now valid: + +``` +Undelivered IRQ: 42 +``` + +This is a warning message from the kernel that an IRQ was recieved for irq number 42, but no +notification capability is set to sent a signal to. + +**Exercise** Now set the notification capability (`ntfn`) by invoking the irq handler. + +``` + /* TODO set ntfn as the notification for irq_handler */ +``` +
    +Quick solution +```c + error = seL4_IRQHandler_SetNotification(irq_handler, ntfn); + ZF_LOGF_IF(error, "Failed to set notification"); +``` +
    + +Now the output will be: + +``` +Tick +``` + +Only one interrupt is delivered, as the interrupt has not been acknowledged. The timer driver is +programmed to emit an interrupt every millisecond, so we need to count 2000 interrupts +before replying to the client. + +**Exercise** Acknowledge the interrupt after handling it in the timer driver. + +``` + /* TODO ack the interrupt */ +``` +
    +Quick solution +```c + error = seL4_IRQHandler_Ack(irq_handler); + ZF_LOGF_IF(error, "Failed to ack irq"); +``` +
    + +Now the timer interrupts continue to come in, and the reply is delivered to the client. + +``` +timer client wakes up +``` + +That's it for this tutorial. + +Next tutorial: Fault handling diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index f3f74ddf81..bbd620a84e 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -86,7 +86,7 @@
  • IPC
  • Notifications
  • Interrupts
  • -
  • Faults
  • +
  • Fault Handling
  • MCS
  • Dynamic libraries
  • diff --git a/index.md b/index.md index bb0a1c39ab..34b8221502 100644 --- a/index.md +++ b/index.md @@ -97,7 +97,7 @@ This documentation site is for cooperatively developing and sharing documentatio
  • IPC
  • Notifications
  • Interrupts
  • -
  • Faults
  • +
  • Fault Handling
  • MCS
  • Dynamic libraries
  • From fa1c85d197cb876009d6f205e070aff5f5157c49 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 8 Mar 2024 16:31:25 +1100 Subject: [PATCH 009/103] add reworked tuts (incomplete) Signed-off-by: Birgit Brecknell --- TutorialsReworked/CAmkES/camkes1.md | 251 +++++++++++ TutorialsReworked/CAmkES/hello-camkes.md | 191 ++++++++ TutorialsReworked/DynamicLibraries/timer.md | 232 ++++++++++ TutorialsReworked/GettingStarted/microkit.md | 2 +- TutorialsReworked/mcs.md | 439 +++++++++++++++++++ TutorialsReworked/seL4Kernel/faults.md | 2 +- _includes/nav-sidebar.html | 2 +- index.md | 2 +- 8 files changed, 1117 insertions(+), 4 deletions(-) diff --git a/TutorialsReworked/CAmkES/camkes1.md b/TutorialsReworked/CAmkES/camkes1.md index e69de29bb2..5730b24252 100644 --- a/TutorialsReworked/CAmkES/camkes1.md +++ b/TutorialsReworked/CAmkES/camkes1.md @@ -0,0 +1,251 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# CAmkES Tutorial 1 +This tutorial is an introduction to +CAmkES: bootstrapping a basic static CAmkES application, describing its +components, and linking them together. + +Outcomes: +1. Understand the structure of a CAmkES application, as a described, +well-defined, static system. +2. Understand the file-layout of a CAmkES ADL project. +3. Become acquainted with the basics of creating a practical CAmkES application. + + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut hello-camkes-1 +# building the tutorial exercise +cd hello-camkes-1_build +ninja +``` +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut hello-camkes-1 +``` +
    + +**TBD: There are no solutions for CAmkES 1-3!!!!** + + +## Background + +The fundamentals of CAmkES are the component, the interface and the connection. + +### Components + +*Components* are logical +groupings of code and resources. They communicate with other component +instances via well-defined interfaces which must be statically defined, +over communication channels. This tutorial will lead you through the +construction of a CAmkES application with two components: an Echo +server, and its Client that makes calls to it. These components are +defined when you initialise your build repository, found in +the following camkes file: + +- `hello-camkes-1/hello-1.camkes` + +Find the Component manual section here: + + +### Connections + + The second fundamental component of CAmkES applications +is the *Connection*: a connection is the representation of a method of +communication between two software components in CAmkES. The underlying +implementation may be shared memory, synchronous IPC, notifications or +some other implementation-provided means. In this particular tutorial, +we are using synchronous IPC. In implementation terms, this boils down +to the `seL4_Call` syscall on seL4. + +Find the "Connection" keyword manual section here: + + +### Interfaces + + All communications over a CAmkES connection must be well +defined: static systems' communications should be able to be reasoned +about at build time. All the function calls which will be delivered over +a communication channel then, also are well defined, and logically +grouped so as to provide clear directional understanding of all +transmissions over a connection. Components are connected together in +CAmkES, yes -- but the interfaces that are exposed over each connection +for calling by other components, are also described. + +There are different +kinds of interfaces: +-Dataports, +-Procedural interfaces, +-and Notifications. + +This tutorial will lead you through the construction of a Procedural +interface, which is an interface over which function calls are made +according to a well-defined pre-determined API. The keyword for this +kind of interface in CAmkES is `procedure`. The definition of this +Procedure interface may be found here: +`hello-camkes-1/interfaces/HelloSimple.idl4` + +Find the "Procedure" keyword definition here: + + +### Component source + + Based on the ADL, CAmkES generates boilerplate which +conforms to your system's architecture, and enables you to fill in the +spaces with your program's logic. The two generated files in this +tutorial application are, in accordance with the Components we have +defined: + +- `hello-camkes-1/components/Echo/src/echo.c` +- `hello-camkes-1/components/Client/src/client.c` + +Now when it comes to invoking the functions that were defined in the +Interface specification +(`hello-camkes-1/interfaces/HelloSimple.idl4`), +you must prefix the API function name with the name of the Interface +instance that you are exposing over the particular connection. + +The reason for this is because it is possible for one component to +expose an interface multiple times, with each instance of that interface +referring to a different function altogether. For example, if a +composite device, such as a network card with with a serial interface +integrated into it, exposes two instances of a procedural interface that +has a particular procedure named `send()` -- how will the caller of +`send()` know whether his `send()` is the one that is exposed over the +NIC connection, or the serial connection? + +The same component provides both. Therefore, CAmkES prefixes the +instances of functions in an Interface with the Interface-instance's +name. In the dual-function NIC device's case, it might have a +`provides serial` and a `provides nic`. +When a caller wants to call for the NIC-send, it would call, +nic_send(), and when a caller wants to invoke the Serial-send, it would +call, "serial_send()". + +So if the `Hello` interface is provided once by `Echo` as `a`, you would +call for the `a` instance of Echo's `Hello` by calling for `a_hello()`. +But what if Echo had provided 2 instances of the `Hello` interface, and +the second one was named `a2`? Then in order to call on that second +`Hello` interface instance on Echo, you would call `a2_hello()`. + +## Exercises + + +**Exercise** First modify `hello-1.camkes`. Define instances of `Echo` and `Client` in the +`composition` section of the ADL. + +``` +assembly { + composition { + component EmptyComponent empty; + // TODO remove the empty component, and define an Echo and a Client component +assembly { + composition { + component EmptyComponent empty; + component Client client; + component Echo echo; +``` + +**Exercise** Now add a connection from `client.hello` to `echo.hello`. + +``` + /* hint 1: use seL4RPCCall as the connector (or you could use seL4RPC if you prefer) + * hint 2: look at + * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application + */ + connection seL4RPCCall hello_con(from client.hello, to echo.hello); +``` + +**Exercise** Define the interface for hello in `interfaces/HelloSimple.idl4`. + +```c +/* Simple RPC interface */ +procedure HelloSimple { + /* TODO define RPC functions */ + /* hint 1: define at least one function that takes a string as input parameter. call it say_hello. no return value + * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application + */ +}; +``` + +**Exercise** Implement the RPC hello function. + +```c +/* + * CAmkES tutorial part 1: components with RPC. Server part. + */ +#include + +/* generated header for our component */ +#include +/* TASK 5: implement the RPC function. */ +/* hint 1: the name of the function to implement is a composition of an interface name and a function name: + * i.e.: _ + * hint 2: the interfaces available are defined by the component, e.g. in hello-1.camkes + * hint 3: the function name is defined by the interface definition, e.g. in interfaces/HelloSimple.idl4 + * hint 4: so the function would be: hello_say_hello() + * hint 5: the CAmkES 'string' type maps to 'const char *' in C + * hint 6: make the function print out a mesage using printf + * hint 7: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application + */ +void hello_say_hello(const char *str) { + printf("Component %s saying: %s\n", get_instance_name(), str); +} +``` + +**Exercise** Invoke the RPC function in `components/Client/src/client.c`. +```c +/* + * CAmkES tutorial part 1: components with RPC. Client part. + */ + +#include + +/* generated header for our component */ +#include + +/* run the control thread */ +int run(void) { + printf("Starting the client\n"); + printf("-------------------\n"); + /* TODO: invoke the RPC function */ + /* hint 1: the name of the function to invoke is a composition of an interface name and a function name: + * i.e.: _ + * hint 2: the interfaces available are defined by the component, e.g. in hello-1.camkes + * hint 3: the function name is defined by the interface definition, e.g. in interfaces/HelloSimple.idl4 + * hint 4: so the function would be: hello_say_hello() + * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application + */ + char *shello = "hello world"; + hello_say_hello(shello); + + printf("After the client\n"); + return 0; +} +``` + +### TASK 5 + Here you define the callee-side invocation functions for +the Hello interface exposed by Echo. + +## Done + +Now build and run the project, if it compiles: Congratulations! Be sure to read up on the keywords and +structure of ADL: it's key to understanding CAmkES. And well done on +writing your first CAmkES application. + +Next tutorial: CAmkES 2 + diff --git a/TutorialsReworked/CAmkES/hello-camkes.md b/TutorialsReworked/CAmkES/hello-camkes.md index e69de29bb2..d24b3832a4 100644 --- a/TutorialsReworked/CAmkES/hello-camkes.md +++ b/TutorialsReworked/CAmkES/hello-camkes.md @@ -0,0 +1,191 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + + +# CAmkES Tutorial: Introduction + +This tutorial is an introduction to CAmkES. This will involve introducing the CAmkES syntax, bootstrapping a basic +static CAmkES application and describing its components. + +Note that it's possible to successfully complete the CAmkES tutorial without having read the manual, however highly +recommended that you familiarise yourself with the [CAmkES manual](https://github.com/seL4/camkes-tool/blob/master/docs/index.md). + + +Outcomes: +- Understand the structure of a CAmkES application, as a described, well-defined, static system. +- Understand the file-layout of a CAmkES ADL project. +- Become acquainted with the basics of creating a practical CAmkES application. + +## Background + +The fundamentals of CAmkES are the component, the interface and the connection. Components are logical +groupings of code and resources. They communicate with other component instances via well-defined +interfaces which must be statically defined, over communication channels. + +### Component + +As briefly described above, we identify a component as a functional grouping of code and resources. We +use the term component in CAmkES to refer to the *type* of our functional grouping (see the Component section in the [manual](https://github.com/seL4/camkes-tool/blob/master/docs/index.md#component)). +An example of this in concrete CAmkES syntax can be seen below: + +```c +component foo { + control; + uses MyInterface a; + attribute Int b; +} +``` + +Disregarding the items defined within the component (we will unpack these in a later tutorial), we defined a component above +whose *type* is `foo`. We later can use our `foo` type to define a component *instance*. +For example, the statement `component foo bar` refers to a component instance `bar` whose type is +`foo`. + +### Describing a static system: Assembly, Composition and Configuration + +In CAmkES, we will commonly see the use of three hierarchical elements, being `assembly`, `composition` and `configuration`. We use these concepts +to build upon a well-defined static system. We firstly use the term 'assembly' to refer to a complete description of our static system. In the CAmkES ADL (Architecture Description Language), +we employ the term `assembly` as a top-level element that will encapsulate our system definition. Each CAmkES project must contain +at least one `assembly` definition. An example of using the `assembly` term in CAmkES can be seen below: + +```c +assembly { + composition { + component foo bar; + } + + configuration { + bar.b = 0; + } +} +``` + +In the above example we can also see the use of the `composition` and `configuration` elements. The `composition` element is +used as a container to encapsulate our component and connector instantiations. Above we declare an instance of +our `foo` component and we appropriately called it `bar`. The `configuration` element is also used to describe settings and attribute +assignments in our given system. + +## Creating your first CAmkES application + +In this tutorial we will create a simple 'Hello World' example within the CAmkES. This will invole creating a CAmkES component that will +print "Hello CAmkES World" when it starts up. + +### Looking at the sources + +In the tutorial directory, you will find the following files: +* `CMakeLists.txt` - the file that defines how to build our CAmkES application +* `client.c` - the single source file for our 'Hello World' client component +* `hello.camkes` - Our CAmkES file describing our static system + +#### `client.c` + +For this tutorial we require our component to simply print "Hello CAmkES World". We define this in +a typical C file `client.c`: + +```c +/* + * CAmkES tutorial part 0: just a component. + */ + +#include + +/* generated header for our component */ +#include + +/* run the control thread */ +int run(void) { + printf("Hello CAmkES World\n"); + return 0; +} +``` + +Note above that in the source code of `client.c` instead of typically using `main`, we place +our runtime code in the function `int run(void)`. `run` is the entry point +of a CAmkES component. + +#### `hello.camkes` + +The `hello.camkes` file is where we form our description of a static CAmkES system. Our `.camkes` +files are written using the CAmkES syntax. Employing the concepts discussed in the background +section, we define the following: + +```c +/* + * CAmkES tutorial part 0: just a component. + */ + +component Client { + control; +} + +assembly { + composition { + component Client client; + } +} +``` + +In the source above we create a minimal static system with a single component instance. We define +our component `Client` and declare an instance of that component in our system. + +#### `CMakeLists.txt` + +Every CAmkES project requires a `CMakeLists.txt` file to be incorporated in the seL4 build system. Our tutorial +directory should contain the following `CMakeLists.txt` file: + +```cmake + +include(${SEL4_TUTORIALS_DIR}/settings.cmake) +sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR}) + +cmake_minimum_required(VERSION 3.7.2) + +project(hello-camkes-0 C ASM) + +find_package(camkes-tool REQUIRED) +camkes_tool_setup_camkes_build_environment() + +DeclareCAmkESComponent(Client SOURCES client.c) + +DeclareCAmkESRootserver(hello.camkes) + +GenerateCAmkESRootserver() +``` + +Our `CMakeLists.txt` file declares our `Client` component, linking it with our `client.c` source +file. In addition it declares the CAmkES Root Server using our `hello.camkes` system description. + +### Building your first CAmkES system + +At this point all you need to do is build and run the tutorial: + + +```sh +# In build directory +ninja +``` + +If build successfully, we can run our system as follows: + + +```sh +# In build directory +./simulate +``` + +and should see the following once the system has booted: + +``` +Hello CAmkES World +``` + +## Done + Congratulations: be sure to read up on the keywords and +structure of ADL: it's key to understanding CAmkES. And well done on +building and running your first CAmkES application. + +Next tutorial: CAmkES 1 diff --git a/TutorialsReworked/DynamicLibraries/timer.md b/TutorialsReworked/DynamicLibraries/timer.md index e69de29bb2..c8e66131c3 100644 --- a/TutorialsReworked/DynamicLibraries/timer.md +++ b/TutorialsReworked/DynamicLibraries/timer.md @@ -0,0 +1,232 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +# seL4 Dynamic Libraries: Timer tutorial + +This tutorial demonstrates how to set up and use a basic timer driver using the +`seL4_libs` dynamic libraries. + +You'll observe that the things you've already covered in the other +tutorials are already filled out and you don't have to repeat them: in +much the same way, we won't be repeating conceptual explanations on this +page, if they were covered by a previous tutorial in the series. + +Learning outcomes: +- Allocate a notification object. +- Set up a timer provided by `util_libs`. +- Use `seL4_libs` and `util_libs` functions to manipulate timer and + handle interrupts. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut dynamic-4 +# building the tutorial exercise +cd dynamic-4_build +ninja +``` +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut dynamic-4 +``` +Answers are also available in drop down menus under each section. +
    + + +## Prerequisites + +1. [Set up your machine](https://docs.sel4.systems/HostDependencies). +1. [dynamic-3](https://docs.sel4.systems/Tutorials/dynamic-3) + +## Exercises + +Once you initialise and run the tutorials, you will see the following output: + +``` +Booting all finished, dropped to user space +Node 0 of 1 +IOPT levels: 4294967295 +IPC buffer: 0x5a1000 +Empty slots: [523 --> 4096) +sharedFrames: [0 --> 0) +userImageFrames: [16 --> 433) +userImagePaging: [12 --> 15) +untypeds: [433 --> 523) +Initial thread domain: 0 +Initial thread cnode size: 12 +timer client: hey hey hey +main: hello world +main: got a message from 0x61 to sleep 2 seconds +ltimer_get_time@ltimer.h:267 get_time not implemented +timer client wakes up: + got the current timer tick: + 0 +``` +### Allocate a notification object + +The first task is to allocate a notification object to receive +interrupts on. +```c + + /* TASK 1: create a notification object for the timer interrupt */ + /* hint: vka_alloc_notification() + * int vka_alloc_notification(vka_t *vka, vka_object_t *result) + * @param vka Pointer to vka interface. + * @param result Structure for the notification object. This gets initialised. + * @return 0 on success + * https://github.com/seL4/libsel4vka/blob/master/include/vka/object.h#L98 + */ + vka_object_t ntfn_object = {0}; +``` +
    +Quick solution +```c + error = vka_alloc_notification(&vka, &ntfn_object); + assert(error == 0); +``` +
    + +The output will not change as a result of completing this task. + +### Initialise the timer + +Use our library function `ltimer_default_init` to +initialise a timer driver. Assign it to the `timer` global variable. +```c + + /* TASK 2: call ltimer library to get the default timer */ + /* hint: ltimer_default_init, you can set NULL for the callback and token + */ + ps_io_ops_t ops = {{0}}; + error = sel4platsupport_new_malloc_ops(&ops.malloc_ops); + assert(error == 0); + error = sel4platsupport_new_io_mapper(&vspace, &vka, &ops.io_mapper); + assert(error == 0); + error = sel4platsupport_new_fdt_ops(&ops.io_fdt, &simple, &ops.malloc_ops); + assert(error == 0); + if (ntfn_object.cptr != seL4_CapNull) { + error = sel4platsupport_new_mini_irq_ops(&ops.irq_ops, &vka, &simple, &ops.malloc_ops, + ntfn_object.cptr, MASK(seL4_BadgeBits)); + assert(error == 0); + } + error = sel4platsupport_new_arch_ops(&ops, &simple, &vka); + assert(error == 0); +``` +
    +Quick solution +```c + error = ltimer_default_init(&timer, ops, NULL, NULL); + assert(error == 0); +``` +
    + +After this change, the server will output non-zero for the tick value at the end. +``` + got the current timer tick: + 1409040 +``` + +### Use the timer + +While at the end of the previous task the tutorial appears to be +working, the main thread replies immediately to the client and doesn't +wait at all. + +Consequently, the final task is to interact with the timer: set a +timeout, wait for an interrupt on the created notification, and handle +it. + +```c + + /* + * TASK 3: Start and configure the timer + * hint 1: ltimer_set_timeout + * hint 2: set period to 1 millisecond + */ +``` +
    +Quick solution +```c + error = ltimer_set_timeout(&timer, NS_IN_MS, TIMEOUT_PERIODIC); + assert(error == 0); +``` +
    + +The output will cease after the following line as a result of completing this task. +``` +main: got a message from 0x61 to sleep 2 seconds +``` + +### Handle the interrupt + +In order to receive more interrupts, you need to handle the interrupt in the driver +and acknowledge the irq. + +```c + + /* + * TASK 4: Handle the timer interrupt + * hint 1: wait for the incoming interrupt and handle it + * The loop runs for (1000 * msg) times, which is basically 1 second * msg. + * + * hint2: seL4_Wait + * hint3: sel4platsupport_irq_handle + * hint4: 'ntfn_id' should be MINI_IRQ_INTERFACE_NTFN_ID and handle_mask' should be the badge + * + */ +``` +
    +Quick solution +```c + seL4_Word badge; + seL4_Wait(ntfn_object.cptr, &badge); + sel4platsupport_irq_handle(&ops.irq_ops, MINI_IRQ_INTERFACE_NTFN_ID, badge); + count++; + if (count == 1000 * msg) { + break; + } +``` +
    + +The timer interrupts are bound to the IRQ interface initialised in Task 2, +hence when we receive an interrupt, we forward it to the interface and let it notify the timer driver. + +After this task is completed you should see a 2 second wait, then output from the + client as follows: +``` +timer client wakes up: + got the current timer tick: + 2365866120 +``` + +### Destroy the timer + +```c + + /* + * TASK 5: Stop the timer + * hint: ltimer_destroy + */ +``` +
    +Quick solution +```c + ltimer_destroy(&timer); +``` +
    + +The output should not change on successful completion of completing this task. + +That's it for this tutorial. + +Next tutorial: Hello CAmkES diff --git a/TutorialsReworked/GettingStarted/microkit.md b/TutorialsReworked/GettingStarted/microkit.md index 4df6163097..89de82b981 100644 --- a/TutorialsReworked/GettingStarted/microkit.md +++ b/TutorialsReworked/GettingStarted/microkit.md @@ -4,7 +4,7 @@ layout: project SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- -

    The seL4 Microkit tutorial

    +

    Using the seL4 Microkit tutorial to get started with seL4

    The seL4 Microkit is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4, while still leveraging the kernel’s benefits of security and performance.

    diff --git a/TutorialsReworked/mcs.md b/TutorialsReworked/mcs.md index e69de29bb2..1e04ab19bb 100644 --- a/TutorialsReworked/mcs.md +++ b/TutorialsReworked/mcs.md @@ -0,0 +1,439 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# MCS Extensions +This tutorial presents the features in the upcoming MCS extensions for seL4, which are currently undergoing +verification. For further context on the new features, please see the +[paper](https://trustworthy.systems/publications/csiro_full_text/Lyons_MAH_18.pdf) or [phd](https://github.com/pingerino/phd/blob/master/phd.pdf) + which provides a comprehensive background on the changes. + +Learn: +1. About the MCS new kernel API. +1. How to create and configure scheduling contexts. +2. The jargon *passive server*. +3. How to spawn round-robin and periodic threads. + + + +## Initialising + +Then initialise the tutorial: + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut mcs +# building the tutorial exercise +cd mcs_build +ninja +``` + +
    +Hint: tutorial solutions +
    +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut mcs +``` +
    + + +## Background + +The MCS extensions provide capability-based access to CPU time, and provide mechanisms to limit the upper +bound of execution of a thread. + +### Scheduling Contexts + +Scheduling contexts are a new object type in the kernel, which contain scheduling parameters amoung other +accounting details. Most importantly, scheduling contexts contain a *budget* and a *period*, which +represent an upper bound on execution time allocated: the kernel will enforce that threads cannot execute +for more than *budget* microseconds out of *period* microseconds. + +### SchedControl + +Parameters for scheduling contexts are configured by invoking `seL4_SchedControl` capabilities, one of +which is provided per CPU. The invoked `seL4_SchedControl` determines which processing core that specific +scheduling context provides access to. + +Scheduling contexts can be configured as *full* or *partial*. Full scheduling contexts have `budget == +period` and grant access to 100% of CPU time. Partial scheduling contexts grant access to an upper bound of + `budget/period` CPU time. + +The code example below configures a +scheduling context with a budget and period both equal to 1000us. Because the budget and period are equal, +the scheduling context is treated as round-robin + +```c + error = seL4_SchedControl_Configure(sched_control, sched_context, US_IN_S, US_IN_S, 0, 0); + ZF_LOGF_IF(error != seL4_NoError, "Failed to configure schedcontext"); +``` + +### SchedContext Binding + +Thread control blocks (TCBs) must have a scheduling context configured with non-zero budget and period + in order to be picked by the scheduler. This +can by invoking the scheduling context capability with the `seL4_SchedContext_Bind` invocation, or by +using `seL4_TCB_SetSchedParams`, which takes a scheduling context capability. Below is example code for +binding a TCB and a scheduling context. + +```c + error = seL4_SchedContext_Bind(sched_context, spinner_tcb); + ZF_LOGF_IF(error != seL4_NoError, "Failed to bind sched_context to round_robin_tcb"); +``` + +TCB's can only be bound to one scheduling context at a time, and vice versa. If a scheduling context has not +been configured with any time, then although the TCB has a scheduling context it will remain ineligible +for scheduling. + +### Bounding execution + +For partial scheduling contexts, an upper bound on execution is enforced by seL4 using the *sporadic server* +algorithm, which work by guaranteeing the *sliding window* constrain, meaning that during any period, the +budget cannot be exceeded. This is achieved by tracking the eligible budget in chunks called +*replenishments* (abbreviated to `refills` in the API for brevity). A replenishment is simply an amount + of time, and a timestamp from which that time can be consumed. We explain this now through an example: + +Consider a scheduling context with period *T* and budget *C*. Initially, the scheduling context has +a single replenishment of size *C* which is eligible to be used from time *t*. + +The scheduling context is scheduled at time *t* and blocks at time *t + n*. A new replenishment is then scheduled +for time *t+T* for *n*. The existing replenishment is updated to *C - n*, subtracting the amount consumed. +For further details on the sporadic server algorithm, see the +[original paper](https://dl.acm.org/citation.cfm?id=917665). + +If the replenishment data structure is full, replenishments are merged and the upper bound on execution is +reduced. For this reason, the bound on execution is configurable with the `extra_refills` parameter +on scheduling contexts. By default, scheduling contexts contain only two parameters, meaning if a +scheduling context is blocked, switched or preempted more than twice, the rest of the budget is forfeit until +the next period. `extra_refills` provides more replenishment data structures in a scheduling context. Note +that the higher the number of replenishments the more fragmentation of budget can occur, which will increase +scheduling overhead. + +`extra_refills` itself is bounded by the size of a scheduling context, which is itself configurable. +On scheduling context creation a size can be specified, and must be `> seL4_MinSchedContextBits`. The +maximum number of extra refills that can fit into a specific scheduling context size can be calculated +with the function `seL4_MaxExtraRefills()` provided in `libsel4`. + +Threads bound to scheduling contexts that do not have an available replenishment are placed into an ordered +queue of threads, and woken once their next replenishment is ready. + +### Scheduler + +The seL4 scheduler is largely unchanged: the highest priority, non-blocked thread with a configured + scheduling context that has available budget is chosen by the scheduler to run. + +### Passive servers + +The MCS extensions allow for RPC style servers to run on client TCBs' scheduling contexts. This is achived by +unbinding the scheduling context once a server is blocked on an endpoint, rendering the server *passive*. +Caller scheduling contexts are donated to the server on `seL4_Call` and returned on `seL4_ReplyRecv`. + +Passive servers can also receive scheduling contexts from their bound notification object, which is +achieved by binding a notification object using `seL4_SchedContext_Bind`. + +### Timeout faults + +Threads can register a timeout fault handler using `seL4_TCB_SetTimeoutEndpoint`. Timeout fault +handlers are optional and are raised when a thread's replenishment expires *and* they have a valid handler +registered. The timeout fault message from the kernel contains the data word which can be used to identify the +scheduling context that the thread was using when the timeout fault occurred, and the amount of time +consumed by the thread since the last fault or `seL4_SchedContext_Consumed`. + +### New invocations + +* `seL4_SchedContext_Bind` - bind a TCB or Notification capability to the invoked scheduling context. +* `seL4_SchedContext_Unbind` - unbind any objects from the invoked scheduling context. +* `seL4_SchedContext_UnbindObject`- unbind a specific object from the invoked scheduling context. +* `seL4_SchedContext_YieldTo` - if the thread running on the invoked scheduling context is +schedulable, place it at the head of the scheduling queue for its priority. For same priority threads, this +will result in the target thread being scheduled. Return the amount of time consumed by this scheduling +context since the last timeout fault, `YieldTo` or `Consumed` invocation. +* `seL4_SchedContext_Consumed` - Return the amount of time consumed by this scheduling +context since the last timeout fault, `YieldTo` or `Consumed` invocation. +* `seL4_TCB_SetTimeoutEndpoint` - Set the timeout fault endpoint for a TCB. + +### Reply objects + +The MCS API also makes the reply channel explicit: reply capabilities are now fully fledged objects +which must be provided by a thread on `seL4_Recv` operations. They are used to track the scheduling +context donation chain and return donated scheduling contexts to callers. + +Please see the [release notes](https://docs.sel4.systems/sel4_release/seL4_9.0.0-mcs) and +[manual](https://docs.sel4.systems/sel4_release/seL4_9.0.0-mcs.html) for further details + on the API changes. + +## Exercises + +In the initial state of the tutorial, the main function in `mcs.c` is running in one process, and the +following loop from `spinner.c` is running in another process: + + +``` + int i = 0; + while (1) { + printf("Yield\n"); + seL4_Yield(); + } +``` + +Both processes share the same priority. The code in `mcs.c` binds +a scheduling context (`sched_context`) to the TCB of the spinner process (`spinner_tcb)` with round-robin scheduling parameters. As a result, you should see + something like the following output, which continues uninterrupted: + +``` +Yield +Yield +Yield +``` + +### Periodic threads + +**Exercise** Reconfigure `sched_context` with the following periodic scheduling parameters, + (budget = `0.9 * US_IN_S`, period = `1 * US_IN_S`). + + ```c + //TODO reconfigure sched_context to be periodic +``` +
    +Quick solution +```c + error = seL4_SchedControl_Configure(sched_control, sched_context, 0.9 * US_IN_S, 1 * US_IN_S, 0, 0); + ZF_LOGF_IF(error != seL4_NoError, "Failed to configure schedcontext"); +``` +
    + + +By completing this task successfully, the output will not change, but the rate that the output is +printed will slow: each subsequent line should be output once the period has elapsed. You should now +be able to see the loop where the `mcs.c` process and `spinner.c` process alternate, until the `mcs.c` +process blocks, at which point `"Yield"` is emitted by `spinner.c` every second, as shown below: + +``` +Yield +Tick 0 +Yield +Tick 1 +Yield +Tick 2 +Yield +Tick 3 +Yield +Tick 4 +Yield +Tick 5 +Yield +Tick 6 +Yield +Tick 7 +Yield +Tick 8 +Yield +Yield +Yield +``` +Before you completed this task, the scheduling context was round-robin, and so was +schedulable immediately after the call to `seL4_Yield`. +By changing +the scheduling parameters of `sched_context` to periodic parameters (budget < period), each time +`seL4_Yield()` is called the available budget in the scheduling context is abandoned, causing the +thread to sleep until the next replenishment, determined by the period. + +### Unbinding scheduling contexts + +You can cease a threads execution by unbinding the scheduling context. +Unlike *suspending* a thread via `seL4_TCB_Suspend`, unbinding will not change the thread state. Using suspend +cancels any system calls in process (e.g IPC) and renders the thread unschedulable by changing the +thread state. Unbinding a scheduling context does not alter the thread state, but merely removes the thread +from the scheduler queues. + +**Exercise** Unbind `sched_context` to stop the spinner process from running. +```c + //TODO unbind sched_context to stop yielding thread +``` +
    +Quick solution +```c + error = seL4_SchedContext_Unbind(sched_context); + ZF_LOGF_IF(error, "Failed to unbind sched_context"); +``` +
    + + +On success, you should see the output from the yielding thread stop. + +### Sporadic threads + +Your next task is to use a different process, `sender` to experiment with sporadic tasks. The +`sender` process is ready to run, and just needs a scheduling context in order to do so. + +**Exercise** First, bind `sched_context` to `sender_tcb`. + + ```c + //TODO bind sched_context to sender_tcb +``` +
    +Quick solution +```c + error = seL4_SchedContext_Bind(sched_context, sender_tcb); + ZF_LOGF_IF(error != seL4_NoError, "Failed to bind schedcontext"); +``` +
    + +The output should look like the following: +``` +... +Tock 3 +Tock 4 +Tock 5 +Tock 6 +``` + +Note the rate of the output: currently, you should see 2 lines come out at a time, with roughly +a second break between (the period of the scheduling context you set earlier). This is because +scheduling context only has the minimum sporadic refills (see background), and each time a context switch +occurs a refill is used up to schedule another. + +**Exercise** Reconfigure the `sched_context` to an extra 6 refills, such that all of the `Tock` output +occurs in one go. + + ```c + //TODO reconfigure sched_context to be periodic with 6 extra refills +``` +
    +Quick solution +```c + error = seL4_SchedControl_Configure(sched_control, sched_context, 0.9 * US_IN_S, 1 * US_IN_S, 6, 0); + ZF_LOGF_IF(error != seL4_NoError, "Failed to configure schedcontext"); +``` +
    + +### Passive servers + +Now look to the third process, `server.c`, which is a very basic echo server. It currently does +not have a scheduling context, and needs one to initialise. + +**Exercise** Bind `sched_context` to `server_tcb`. + + ```c + //TODO bind sched_context to server_tcb +``` +
    +Quick solution +```c + error = seL4_SchedContext_Bind(sched_context, server_tcb); + ZF_LOGF_IF(error != seL4_NoError, "Failed to bind sched_context to server_tcb"); +``` +
    + + +Now you should see the server initialise and echo the messages sent. Note the initialisation protocol: +first, you bound `sched_context` to the server. At this point, in `server.c`, the server calls +`seL4_NBSendRecv` which sends an IPC message on `endpoint`, indicating that the server is now initialised. +The output should be as follows + +``` +Tock 8 +Starting server +Wait for server +Server initialising +running +passive +echo server +Yield +``` + +The following code then converts the server to passive: + +```c + // convert to passive + error = seL4_SchedContext_Unbind(sched_context); +``` + +From this point, the server runs on the `mcs` process's scheduling context. + +### Timeout Faults + +But before we discuss timeout faults, we must first discuss the differences +between configuring a fault endpoint on the master vs the MCS kernel. There is a +minor difference in the way that the kernel is informed of the cap to a fault +endpoint, between the master and MCS kernels. + +Regardless though, on both versions of the kernel, to inform the kernel of the +fault endpoint for a thread, call the usual `seL4_TCB_SetSpace()`. + +#### Configuring a fault endpoint on the MCS kernel: + +On the MCS kernel the cap given to the kernel must be a cap to an object in +the CSpace of the thread which is *calling the syscall* (`seL4_TCB_Configure()`) +to give the cap to the kernel. + +This calling thread may be the handler thread, or some other thread which +manages both the handler thread and the faulting thread. Or in an oddly designed +system, it might be the faulting thread itself if the faulting thread is allowed +to configure its own fault endpoint. + +The reason for this difference is merely that it is faster to lookup the fault +endpoint this way since it is looked up only once at the time it is configured. + +#### Configuring a fault endpoint on the Master kernel: + +On the Master kernel the cap given to the kernel must be a cap to an object in +the CSpace of the *faulting thread*. + +On the Master kernel, the fault endpoint cap is looked up from within the CSpace +of the faulting thread everytime a fault occurs. + +#### Exercise: + +**Exercise** Set the data field of `sched_context` using `seL4_SchedControl_Configure` and set a 1s period, 500 µs +budget and 0 extra refills. + +```c + // reconfigure sched_context with 1s period, 500 microsecond budget, 0 extra refills and data of 5. +``` +
    +Quick solution +```c + error = seL4_SchedControl_Configure(sched_control, sched_context, 500, US_IN_S, 0, 5); + ZF_LOGF_IF(error != seL4_NoError, "Failed to configure sched_context"); +``` +
    +The code then binds the scheduling context back to `spinner_tcb`, which starts yielding again. + +**Exercise** set the timeout fault endpoint for `spinner_tcb`. + + +```c + //TODO set endpoint as the timeout fault handler for spinner_tcb +``` +
    +Quick solution +```c +``` +
    + + +When the `spinner` faults, you should see the following output: + +``` +Received timeout fault +Success! +``` + +### Further exercises + +That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, +to become more familiar with the MCS extensions. + +* Set up a passive server with a timeout fault handlers, with policies for clients that exhaust their budget. +* Experiment with notification binding on a passive server, by binding both a notification object to the +server TCB and an SC to the notification object. + +Next tutorial: Dynamic libraries diff --git a/TutorialsReworked/seL4Kernel/faults.md b/TutorialsReworked/seL4Kernel/faults.md index 0661f5215f..b2e1091f7d 100644 --- a/TutorialsReworked/seL4Kernel/faults.md +++ b/TutorialsReworked/seL4Kernel/faults.md @@ -335,4 +335,4 @@ Finally, to have the `faulter` thread wake up and try to execute again, we If you'd like to challenge yourself, make sure to set up the fault handling on both versions of the kernel: master and MCS. -Next tutorial: Dynamic libraries +Next tutorial: MCS diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index bbd620a84e..9d990b27b9 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -72,7 +72,7 @@
  • Getting started
  • The seL4 kernel
    • diff --git a/index.md b/index.md index 34b8221502..7c0114d88e 100644 --- a/index.md +++ b/index.md @@ -83,7 +83,7 @@ This documentation site is for cooperatively developing and sharing documentatio
    • Getting started
    • The seL4 kernel
      • From a311549bf14acaf9c1847510eac864ba4507fced Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 11 Mar 2024 13:44:06 +1100 Subject: [PATCH 010/103] add how-to page Signed-off-by: Birgit Brecknell --- TutorialsReworked/CAmkES/camkes2.md | 24 ++++ TutorialsReworked/DynamicLibraries/timer.md | 5 - .../{mcs.md => MCS/mcs-extensions.md} | 6 +- TutorialsReworked/Resources/how-to.md | 120 ++++++++++++++++++ TutorialsReworked/seL4Kernel/faults.md | 10 +- TutorialsReworked/seL4Kernel/interrupts.md | 8 +- TutorialsReworked/seL4Kernel/ipc.md | 5 + TutorialsReworked/seL4Kernel/untyped.md | 2 +- _includes/nav-sidebar.html | 88 +++++++------ index.md | 11 +- 10 files changed, 219 insertions(+), 60 deletions(-) rename TutorialsReworked/{mcs.md => MCS/mcs-extensions.md} (98%) create mode 100644 TutorialsReworked/Resources/how-to.md diff --git a/TutorialsReworked/CAmkES/camkes2.md b/TutorialsReworked/CAmkES/camkes2.md index e69de29bb2..0819cd8e1a 100644 --- a/TutorialsReworked/CAmkES/camkes2.md +++ b/TutorialsReworked/CAmkES/camkes2.md @@ -0,0 +1,24 @@ +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut hello-camkes-1 +# building the tutorial exercise +cd hello-camkes-1_build +ninja +``` +
        +Hint: tutorial solutions +
        +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut hello-camkes-1 +``` +
        + +**TBD: There are no solutions for CAmkES 1-3!!!!** + +Next tutorial: CAmkES 3 diff --git a/TutorialsReworked/DynamicLibraries/timer.md b/TutorialsReworked/DynamicLibraries/timer.md index c8e66131c3..ab15f6fc35 100644 --- a/TutorialsReworked/DynamicLibraries/timer.md +++ b/TutorialsReworked/DynamicLibraries/timer.md @@ -43,11 +43,6 @@ Answers are also available in drop down menus under each section. -## Prerequisites - -1. [Set up your machine](https://docs.sel4.systems/HostDependencies). -1. [dynamic-3](https://docs.sel4.systems/Tutorials/dynamic-3) - ## Exercises Once you initialise and run the tutorials, you will see the following output: diff --git a/TutorialsReworked/mcs.md b/TutorialsReworked/MCS/mcs-extensions.md similarity index 98% rename from TutorialsReworked/mcs.md rename to TutorialsReworked/MCS/mcs-extensions.md index 1e04ab19bb..e99e66eaf6 100644 --- a/TutorialsReworked/mcs.md +++ b/TutorialsReworked/MCS/mcs-extensions.md @@ -368,7 +368,7 @@ endpoint, between the master and MCS kernels. Regardless though, on both versions of the kernel, to inform the kernel of the fault endpoint for a thread, call the usual `seL4_TCB_SetSpace()`. -#### Configuring a fault endpoint on the MCS kernel: +#### Configuring a fault endpoint on the MCS kernel On the MCS kernel the cap given to the kernel must be a cap to an object in the CSpace of the thread which is *calling the syscall* (`seL4_TCB_Configure()`) @@ -382,7 +382,7 @@ to configure its own fault endpoint. The reason for this difference is merely that it is faster to lookup the fault endpoint this way since it is looked up only once at the time it is configured. -#### Configuring a fault endpoint on the Master kernel: +#### Configuring a fault endpoint on the Master kernel On the Master kernel the cap given to the kernel must be a cap to an object in the CSpace of the *faulting thread*. @@ -436,4 +436,4 @@ to become more familiar with the MCS extensions. * Experiment with notification binding on a passive server, by binding both a notification object to the server TCB and an SC to the notification object. -Next tutorial: Dynamic libraries +Next tutorial: Dynamic libraries diff --git a/TutorialsReworked/Resources/how-to.md b/TutorialsReworked/Resources/how-to.md new file mode 100644 index 0000000000..a3403125f2 --- /dev/null +++ b/TutorialsReworked/Resources/how-to.md @@ -0,0 +1,120 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +# How to: A quick solutions guide +This guide provides links to tutorial solutions as quick references for seL4 calls and methods. + +## The seL4 kernel + +### [Capabilities](../seL4Kernel/capabilities) + + - [Calculate the size of a CSpace](../seL4Kernel/capabilities#how-big-is-your-cspace) + - [Copy a capability between CSlots](../seL4Kernel/capabilities#copy-a-capability-between-cslots) + - [Delete a capability](../seL4Kernel/capabilities#how-do-you-delete-capabilities) + - [Suspend a thread](../seL4Kernel/capabilities#invoking-capabilities) + +### [Untyped](../seL4Kernel/untyped) + + - [Create an untyped capability](../seL4Kernel/untyped#create-an-untyped-capability) + - [Create a TCB object](../seL4Kernel/untyped#create-a-tcb-object) + - [Create an endpoint object](../seL4Kernel/untyped#create-an-endpoint-object) + - [Create a notification object](../seL4Kernel/untyped#create-a-notification-object) + - [Delete an object](../seL4Kernel/untyped#delete-the-objects) + +### [Mapping](../seL4Kernel/mapping) +- [Map a page directory](../seL4Kernel/mapping#map-a-page-directory) +- [Map a page table](../seL4Kernel/mapping#map-a-page-table) +- [Remap a page](../seL4Kernel/mapping#remap-a-page) +- [Unmap a page](../seL4Kernel/mapping#unmapping-pages) + +### [Threads](../seL4Kernel/threads) +- [Configure a TCB](../seL4Kernel/threads#configure-a-tcb) +- [Change the priority of a thread](../seL4Kernel/threads#change-priority-via-sel4_tcb_setpriority) +- [Set initial register state](../seL4Kernel/threads#set-initial-register-state) +- [Start the thread](../seL4Kernel/threads#start-the-thread) +- [Set the arguments of a thread](../seL4Kernel/threads#passing-arguments) +- [Resolve a fault](../seL4Kernel/threads#resolving-a-fault) + +### [IPC](../seL4Kernel/ipc) + - [Use capability transfer to send the badged capability]( +seL4Kernel/ipc#use-capability-transfer-to-send-the-badged-capability) + - [Get a message](../seL4Kernel/ipc#get-a-message) + - [Reply and wait](../seL4Kernel/ipc#reply-and-wait) + - [Save a reply and store reply capabilities](../seL4Kernel/ipc#save-a-reply-and-store-reply-capabilities) + +### [Notifications](../seL4Kernel/notifications) + - [Set up shared memory](../seL4Kernel/notifications#set-up-shared-memory) + - [Signalling](../seL4Kernel/notifications#signal-the-producers-to-go) + - [Differentiate signals](../seL4Kernel/notifications#differentiate-signals) + +### [Interrupts](../seL4Kernel/interrupts) + - [Invoke IRQ control](../seL4Kernel/interrupts#invoke-irq-control) + - [Set NTFN](../seL4Kernel/interrupts#set-ntfn) + - [Acknowledge an interrupt](../seL4Kernel/interrupts#acknowledge-an-interrupt) + +### [Fault handling](../seL4Kernel/faults) + - [Set up an endpoint for thread fault IPC messages](../seL4Kernel/faults#setting-up-the-endpoint-to-be-used-for-thread-fault-ipc-messages) + - [Receive an IPC message from the kernel](../seL4Kernel/faults#receiving-the-ipc-message-from-the-kernel) + - [Get information about a thread fault](../seL4Kernel/faults#finding-out-information-about-the-generated-thread-fault) + - [Handle a thread fault](../seL4Kernel/faults#handling-a-thread-fault) + - [Resume a faulting thread](../seL4Kernel/faults#resuming-a-faulting-thread) + +## [MCS Extensions](../MCS/mcs-extensions) + - [Set up a periodic thread](../MCS/mcs-extensionsperiodic-threads) + - [Unbind a scheduling context](../MCS/mcs-extensionsunbinding-scheduling-contexts) + - [Experiment with sporadic tasks](../MCS/mcs-extensionssporadic-threads) + - [Use passive servers](../MCS/mcs-extensionspassive-servers) + - [Configure fault endpoints](../MCS/mcs-extensionsconfiguring-a-fault-endpoint-on-the-mcs-kernel) + +## Dynamic libraries + - [Initiliasation & threading](../DynamicLibraries/initialisation) + - [Obtain BootInfo](../DynamicLibraries/initialisation#obtain-bootinfo) + - [Initialise simple](../DynamicLibraries/initialisation#initialise-simple) + - [Use simple to print BootInfo](../DynamicLibraries/initialisation#use-simple-to-print-bootinfo) + - [Initialise an allocator](../DynamicLibraries/initialisation#initialise-an-allocator) + - [Obtain a generic allocation interface (vka)](../DynamicLibraries/initialisation#obtain-a-generic-allocation-interface-vka) + - [Find the CSpace root cap](../DynamicLibraries/initialisation#find-the-cspace-root-cap) + - [Find the VSpace root cap](../DynamicLibraries/initialisation#find-the-vspace-root-cap) + - [Allocate a TCB Object](../DynamicLibraries/initialisation#allocate-a-tcb-object) + - [Configure the new TCB](../DynamicLibraries/initialisation#configure-the-new-tcb) + - [Name the new TCB](../DynamicLibraries/initialisation#name-the-new-tcb) + - [Set the instruction pointer](../DynamicLibraries/initialisation#set-the-instruction-pointer) + - [Write the registers](../DynamicLibraries/initialisation#write-the-registers) + - [Start the new thread](../DynamicLibraries/initialisation#start-the-new-thread) + - [IPC](../DynamicLibraries/ipc) + - [Allocate an IPC buffer](../DynamicLibraries/ipc#allocate-an-ipc-buffer) + - [Allocate a page table](../DynamicLibraries/ipc#allocate-a-page-table) + - [Map a page table](../DynamicLibraries/ipc#map-a-page-table) + - [Map a page](../DynamicLibraries/ipc#map-a-page) + - [Allocate an endpoint](../DynamicLibraries/ipc#allocate-an-endpoint) + - [Badge an endpoint](../DynamicLibraries/ipc#badge-an-endpoint) + - [Set a message register](../DynamicLibraries/ipc#message-registers) + - [Send and wait for a reply](../DynamicLibraries/ipc#ipc) + - [Receive a reply](../DynamicLibraries/ipc#receive-a-reply) + - [Receive an IPC](../DynamicLibraries/ipc#receive-an-ipc) + - [Validate a message](../DynamicLibraries/ipc#validate-the-message) + - [Write the message registers](../DynamicLibraries/ipc#write-the-message-registers) + - [Reply to a message](../DynamicLibraries/ipc#reply-to-a-message) +- [Processes & Elf loading](../DynamicLibraries/processes) + - [Create a VSpace object](../DynamicLibraries/processes#virtual-memory-management) + - [Configure a process](../DynamicLibraries/processes#configure-a-process) + - [Get a cspacepath](../DynamicLibraries/processes#get-a-cspacepath) + - [Badge a capability](../DynamicLibraries/processes#badge-a-capability) + - [Spawn a process](../DynamicLibraries/processes#spawn-a-process) + - [Receive a message](../DynamicLibraries/processes#receive-a-message) + - [Send a reply](../DynamicLibraries/processes#send-a-reply) + - [Initiate communications by using seL4_Call](../DynamicLibraries/processes#client-call) + - [Timer](../DynamicLibraries/timer) + - [Allocate a notification object](../DynamicLibraries/timer#allocate-a-notification-object) + - [Initialise a timer](../DynamicLibraries/timer#initialise-the-timer) + - [Use a timer](../DynamicLibraries/timer#use-the-timer) + - [Handle an interrupt](../DynamicLibraries/timer#handle-the-interrupt) + - [Destroy a timer](../DynamicLibraries/timer#destroy-the-timer) + + +## CAmkES +TBD + diff --git a/TutorialsReworked/seL4Kernel/faults.md b/TutorialsReworked/seL4Kernel/faults.md index b2e1091f7d..b8ba0cad43 100644 --- a/TutorialsReworked/seL4Kernel/faults.md +++ b/TutorialsReworked/seL4Kernel/faults.md @@ -279,7 +279,7 @@ the CSpace of the `faulter` thread: 0); ``` -### Receiving the IPC message from the kernel: +### Receiving the IPC message from the kernel The kernel will deliver the IPC message to any thread waiting on the fault endpoint. To wait for a fault IPC message simply `seL4_Recv()`, the same way @@ -289,7 +289,7 @@ you'd wait for any other IPC message: foreign_faulter_capfault_cap = seL4_GetMR(seL4_CapFault_Addr); ``` -### Finding out information about the generated thread fault: +### Finding out information about the generated thread fault In the thread fault IPC message, the kernel will send information about the fault including the capability address whose access triggered the thread fault. @@ -301,7 +301,7 @@ In our example here, our sample code generated a Cap Fault, so according to the seL4 manual, we can find out the cap fault address using at offset `seL4_CapFault_Addr` in the IPC message, as you see above in the code snippet. -### Handling a thread fault: +### Handling a thread fault Now that we know the cap address that generated a fault in the `faulting` thread, we can "handle" the fault by putting a random cap into that slot and then when @@ -321,7 +321,7 @@ So here we'll copy an endpoint cap into the faulting slot: seL4_AllRights); ``` -### Resuming a faulting thread: +### Resuming a faulting thread Finally, to have the `faulter` thread wake up and try to execute again, we `seL4_Reply()` to it: @@ -335,4 +335,4 @@ Finally, to have the `faulter` thread wake up and try to execute again, we If you'd like to challenge yourself, make sure to set up the fault handling on both versions of the kernel: master and MCS. -Next tutorial: MCS +Next tutorial: MCS diff --git a/TutorialsReworked/seL4Kernel/interrupts.md b/TutorialsReworked/seL4Kernel/interrupts.md index 34632204a7..c18e7a5a0e 100644 --- a/TutorialsReworked/seL4Kernel/interrupts.md +++ b/TutorialsReworked/seL4Kernel/interrupts.md @@ -57,9 +57,6 @@ For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This ca -## Outcomes - - ## Background ### IRQControl @@ -140,6 +137,8 @@ main@timer.c:78 [Cond failed: error] The timer driver we are using emits an interrupt in the `TTC0_TIMER1_IRQ` number. +### Invoke IRQ control + **Exercise** Invoke `irq_control`, which contains the `seL4_IRQControl` capability, the place the `IRQHandler` capability for `TTC0_TIMER1_IRQ` into the `irq_handler` CSlot. @@ -165,6 +164,7 @@ Undelivered IRQ: 42 This is a warning message from the kernel that an IRQ was recieved for irq number 42, but no notification capability is set to sent a signal to. +### Set NTFN **Exercise** Now set the notification capability (`ntfn`) by invoking the irq handler. ``` @@ -188,6 +188,8 @@ Only one interrupt is delivered, as the interrupt has not been acknowledged. The programmed to emit an interrupt every millisecond, so we need to count 2000 interrupts before replying to the client. +### Acknowledge an interrupt + **Exercise** Acknowledge the interrupt after handling it in the timer driver. ``` diff --git a/TutorialsReworked/seL4Kernel/ipc.md b/TutorialsReworked/seL4Kernel/ipc.md index ae8314e0fd..4856ed5f48 100644 --- a/TutorialsReworked/seL4Kernel/ipc.md +++ b/TutorialsReworked/seL4Kernel/ipc.md @@ -208,6 +208,8 @@ uses the badged endpoint, such that the server can identify the client. However, currently send the badged capability! We have provided code to badge the endpoint capability, and reply to the client. +### Using capability transfer to send the badged capability + **Exercise** Your task is to set up the cap transfer such that the client successfully receives the badged endpoint. @@ -255,6 +257,7 @@ Depending on timing, the messages may be different, the result is the same: the This is because one of the clients has hit the else case, where the badge is set, and the server does not respond, or wait for new messages from this point. +### Getting a message **Exercise** Your next task is to implement the echo part of the server. ```c @@ -281,6 +284,7 @@ the This is because the server does not reply to the client, and continues to spin in a loop repeating the last message. +### Using reply and wait **Exercise** Update the code to reply to the clients after printing the message. ```c @@ -313,6 +317,7 @@ over lazy ``` +### Saving a reply and storing reply capabilities **Exercise** Currently each client is scheduled for its full timeslice until it is preempted. Alter your server to only print one message from each client, alternating. You will need to use [`seL4_CNode_SaveCaller`](https://docs.sel4.systems/ApiDoc.html#save-caller) to save the reply diff --git a/TutorialsReworked/seL4Kernel/untyped.md b/TutorialsReworked/seL4Kernel/untyped.md index 1f366ec11a..5ae254d22b 100644 --- a/TutorialsReworked/seL4Kernel/untyped.md +++ b/TutorialsReworked/seL4Kernel/untyped.md @@ -243,7 +243,7 @@ This error happens because we are trying to create an untyped of size 0. On success, the tutorial will progress further, printing "Failed to set priority" -### Create a TCB Object +### Create a TCB object The priority check is failing as `child_tcb` is an empty CSlot. diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index 9d990b27b9..5c56e36038 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -68,47 +68,51 @@ {% if page_url[1] == "TutorialsReworked" %} - -
      • MCS
      • +
      • MCS
      • +
      • Dynamic libraries
      • +
      • Resources
      • +
      From cb2fc679bf5cf0965056b1c825a030ba9f5f097c Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 11 Mar 2024 14:58:54 +1100 Subject: [PATCH 011/103] add camkes 1 and 2 (incomplete) Signed-off-by: Birgit Brecknell --- TutorialsReworked/CAmkES/camkes1.md | 46 +++- TutorialsReworked/CAmkES/camkes2.md | 411 +++++++++++++++++++++++++++- _includes/nav-sidebar.html | 2 + index.md | 4 +- 4 files changed, 451 insertions(+), 12 deletions(-) diff --git a/TutorialsReworked/CAmkES/camkes1.md b/TutorialsReworked/CAmkES/camkes1.md index 5730b24252..03649e2865 100644 --- a/TutorialsReworked/CAmkES/camkes1.md +++ b/TutorialsReworked/CAmkES/camkes1.md @@ -38,8 +38,6 @@ All tutorials come with complete solutions. To get solutions run: ``` -**TBD: There are no solutions for CAmkES 1-3!!!!** - ## Background @@ -152,12 +150,18 @@ assembly { composition { component EmptyComponent empty; // TODO remove the empty component, and define an Echo and a Client component -assembly { +``` +
      +Quick solution +``` + assembly { composition { component EmptyComponent empty; component Client client; component Echo echo; ``` +
      + **Exercise** Now add a connection from `client.hello` to `echo.hello`. @@ -166,8 +170,13 @@ assembly { * hint 2: look at * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application */ - connection seL4RPCCall hello_con(from client.hello, to echo.hello); ``` +
      +Quick solution +``` + connection seL4RPCCall hello_con(from client.hello, to echo.hello); +``` +
      **Exercise** Define the interface for hello in `interfaces/HelloSimple.idl4`. @@ -180,6 +189,12 @@ procedure HelloSimple { */ }; ``` +
      +Quick solution +``` + void say_hello(in string str); +``` +
      **Exercise** Implement the RPC hello function. @@ -201,10 +216,15 @@ procedure HelloSimple { * hint 6: make the function print out a mesage using printf * hint 7: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application */ +``` +
      +Quick solution +``` void hello_say_hello(const char *str) { printf("Component %s saying: %s\n", get_instance_name(), str); } ``` +
      **Exercise** Invoke the RPC function in `components/Client/src/client.c`. ```c @@ -229,18 +249,30 @@ int run(void) { * hint 4: so the function would be: hello_say_hello() * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application */ - char *shello = "hello world"; - hello_say_hello(shello); - printf("After the client\n"); return 0; } ``` +
      +Quick solution +``` + char *shello = "hello world"; + hello_say_hello(shello); +``` +
      ### TASK 5 Here you define the callee-side invocation functions for the Hello interface exposed by Echo. +**Can't find a solution---------------------------------------------------------** + +
      +Quick solution +``` +``` +
      + ## Done Now build and run the project, if it compiles: Congratulations! Be sure to read up on the keywords and diff --git a/TutorialsReworked/CAmkES/camkes2.md b/TutorialsReworked/CAmkES/camkes2.md index 0819cd8e1a..889435e413 100644 --- a/TutorialsReworked/CAmkES/camkes2.md +++ b/TutorialsReworked/CAmkES/camkes2.md @@ -1,3 +1,13 @@ +# CAmkES Tutorial 2 +This tutorial is an introduction to +CAmkES: bootstrapping a basic static CAmkES application, describing its +components, and linking them together. + +Learn how to: +- Represent and implement events in CAmkES. +- Use Dataports. + + ## Initialising ```sh @@ -5,9 +15,9 @@ # # Follow these instructions to initialise the tutorial # initialising the build directory with a tutorial exercise -./init --tut hello-camkes-1 +./init --tut hello-camkes-2 # building the tutorial exercise -cd hello-camkes-1_build +cd hello-camkes-2_build ninja ```
      @@ -15,10 +25,403 @@ ninja
      All tutorials come with complete solutions. To get solutions run: ``` -./init --solution --tut hello-camkes-1 +./init --solution --tut hello-camkes-2 +``` +
      + + +## Walkthrough + Bear in mind, this article will be going through the +tutorial steps in the order that the user is led through them in the +slide presentation, except where several similar tasks are coalesced to +avoid duplication. Additionally, if a tasks step covers material that +has already been touched on, it will be omitted from this article. + +### TASK 1 + Here you're declaring the events that will be bounced +back and forth in this tutorial. An event is a signal is sent over a +Notification connection. + +You are strongly advised to read the manual section on Events here: +. + + ''Ensure that when declaring the consumes and emits keywords between + the Client.camkes and Echo.camkes files, you match them up so that + you're not emitting on both sides of a single interface, or consuming + on both sides of an interface.'' + +
      +Quick solution +``` ```
      -**TBD: There are no solutions for CAmkES 1-3!!!!** + +### TASK 10, 11, 14, 15, 22, 25 + Recall that CAmkES prefixes the name +of the interface instance to the function being called across that +interface? This is the same phenomenon, but for events; in the case of a +connection over which events are sent, there is no API, but rather +CAmkES will generate \_emit() and \_wait() functions to enable the +application to transparently interact with these events. + +
      +Quick solution +```c + /* TASK 10: emit event to signal that the data is available */ + /* hint 1: use the function _emit + * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events + */ + + echo_emit(); +``` +
      +
      +Quick solution +```c + /* TASK 11: wait to get an event back signalling that the reply data is avaialble */ + /* hint 1: use the function _wait + * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events + */ + + client_wait(); +``` +
      + + + +
      +Quick solution +```c + /* TASK 14: emit event to signal that the data is available */ + /* hint 1: we've already done this before */ + + echo_emit(); +``` +
      + +
      +Quick solution +```c + /* TASK 15: wait to get an event back signalling that data has been read */ + /* hint 1: we've already done this before */ + + client_wait(); +``` +
      + +
      +Quick solution +```c + /* TASK 22: notify the client that there is new data available for it */ + /* hint 1: use the function _emit + * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events + */ + + client_emit(); +``` +
      + +
      +Quick solution +```c + /* TASK 25: notify the client that we are done reading the data */ + /* hint 1: use the function _emit + * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events + */ + + client_emit(); +``` +
      + + +### TASK 18, 21, 24 + One way to handle notifications in CAmkES is to +use callbacks when they are raised. CAmkES generates functions that +handle the registration of callbacks for each notification interface +instance. These steps help you to become familiar with this approach. + +
      +Quick solution +```c + /* this function is invoked to initialise the echo event interface before it + * becomes active. */ + /* TASK 17: replace "echo" with the actual name of the "consumes" event interface */ + /* hint 1: use the interface name as defined in Echo.camkes. + * For example if you defined it as "consumes TheEvent c_event" then you would use "c_event". + */ + void echo__init(void) { + /* TASK 18: register the first callback handler for this interface */ + /* hint 1: use the function _reg_callback() + * hint 2: register the function "callback_handler_1" + * hint 3: pass NULL as the extra argument to the callback + * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events + */ + + int error = echo_reg_callback(callback_handler_1, NULL); + ZF_LOGF_IF(error != 0, "Failed to register callback"); + } +``` +
      + +
      +Quick solution +```c + /* TASK 21: register the second callback for this event. */ + /* hint 1: use the function _reg_callback() + * hint 2: register the function "callback_handler_2" + * hint 3: pass NULL as the extra argument to the callback + * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events + */ + + int error = echo_reg_callback(callback_handler_2, NULL); + ZF_LOGF_IF(error != 0, "Failed to register callback"); +``` +
      + +
      +Quick solution +```c + /* TASK 24: register the original callback handler for this event */ + /* hint 1: use the function _reg_callback() + * hint 2: register the function "callback_handler_1" + * hint 3: pass NULL as the extra argument to the callback + * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events + */ + + int error = echo_reg_callback(callback_handler_1, NULL); + ZF_LOGF_IF(error != 0, "Failed to register callback"); +``` +
      + +------------------------------------------------------------------------ + +### TASK 2, 4 + Dataports are typed shared memory mappings. In your +CAmkES ADL specification, you state what C data type you'll be using to +access the data in the shared memory -- so you can specify a C struct +type, etc. + +The really neat part is more that CAmkES provides access control for +accessing these shared memory mappings: if a shared mem mapping is such +that one party writes and the other reads and never writes, we can tell +CAmkES about this access constraint in ADL. + +So in TASKs 2 and 4, you're first being led to create the "Dataport" +interface instances on each of the components that will be participating +in the shared mem communication. We will then link them together using a +"seL4SharedData" connector later on. + +
      +Quick solution +``` +``` +
      + +
      +Quick solution +``` +``` +
      + +### TASK 6 + And here we are: we're about to specify connections +between the shared memory pages in each client, and tell CAmkES to link +these using shared underlying Frame objects. Fill out this step, and +proceed. + +
      +Quick solution +``` +``` +
      + +### TASK 9, 12, 13 + These steps are asking you to write some C code +to access and manipulate the data in the shared memory mapping +(Dataport) of the client. Follow through to the next step. + +
      +Quick solution +```c + /* TASK 9: copy strings to an untyped dataport */ + /* hint 1: use the "Buf" dataport as defined in the Client.camkes file + * hint 2: to access the dataport use the interface name as defined in Client.camkes. + * For example if you defined it as "dataport Buf d" then you would use "d" to refer to the dataport in C. + * hint 3: first write the number of strings (NUM_STRINGS) to the dataport + * hint 4: then copy all the strings from "s_arr" to the dataport. + * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports + */ + + int *n = (int*)d; + *n = NUM_STRINGS; + char *str = (char*)(n + 1); + for (int i = 0; i < NUM_STRINGS; i++) { + strcpy(str, s_arr[i]); + str += strlen(str) + 1; + } + +``` +
      + +
      +Quick solution +``` + /* TASK 12: read the reply data from a typed dataport */ + /* hint 1: use the "str_buf_t" dataport as defined in the Client.camkes file + * hint 2: to access the dataport use the interface name as defined in Client.camkes. + * For example if you defined it as "dataport str_buf_t d_typed" then you would use "d_typed" to refer to the dataport in C. + * hint 3: for the definition of "str_buf_t" see "str_buf.h". + * hint 4: use the "n" field to determine the number of strings in the dataport + * hint 5: print out the specified number of strings from the "str" field + * hint 6: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports + */ + + for (int i = 0; i < d_typed->n; i++) { + printf("%s: string %d (%p): \"%s\"\n", get_instance_name(), i, d_typed->str[i], d_typed->str[i]); + } +``` +
      + +
      +Quick solution +``` + /* TASK 13: send the data over again, this time using two dataports, one + * untyped dataport containing the data, and one typed dataport containing + * dataport pointers pointing to data in the untyped, dataport. + */ + /* hint 1: for the untyped dataport use the "Buf" dataport as defined in the Client.camkes file + * hint 2: for the typed dataport use the "ptr_buf_t" dataport as defined in the Client.camkes file + * hint 3: for the definition of "ptr_buf_t" see "str_buf.h". + * hint 4: copy all the strings from "s_arr" into the untyped dataport + * hint 5: use the "n" field of the typed dataport to specify the number of dataport pointers (NUM_STRINGS) + * hint 6: use the "ptr" field of the typed dataport to store the dataport pointers + * hint 7: use the function "dataport_wrap_ptr()" to create a dataport pointer from a regular pointer + * hint 8: the dataport pointers should point into the untyped dataport + * hint 9: for more information about dataport pointers see: https://github.com/seL4/camkes-tool/blob/master/docs/index.md + */ + + d_ptrs->n = NUM_STRINGS; + str = (char*)d; + for (int i = 0; i < NUM_STRINGS; i++) { + strcpy(str, s_arr[i]); + d_ptrs->ptr[i] = dataport_wrap_ptr(str); + str += strlen(str) + 1; + } +``` +
      + +### TASK 19, 20, 23 + And these steps are asking you to write some C +code to access and manipulate the data in the shared memory mapping +(Dataport) of the server. + +
      +Quick solution +```c + /* TASK 19: read some data from the untyped dataport */ + /* hint 1: use the "Buf" dataport as defined in the Echo.camkes file + * hint 2: to access the dataport use the interface name as defined in Echo.camkes. + * For example if you defined it as "dataport Buf d" then you would use "d" to refer to the dataport in C. + * hint 3: first read the number of strings from the dataport + * hint 4: then print each string from the dataport + * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports + */ + + int *n = (int*)d; + char *str = (char*)(n + 1); + for (int i = 0; i < *n; i++) { + printf("%s: saying (%p): \"%s\"\n", get_instance_name(), str, str); + str += strlen(str) + 1; + } +``` +
      + +
      +Quick solution +```c + /* TASK 20: put a modified copy of the data from the untyped dataport into the typed dataport */ + /* hint 1: modify each string by making it upper case, use the function "uppercase" + * hint 2: read from the "Buf" dataport as above + * hint 3: write to the "str_buf_t" dataport as defined in the Echo.camkes file + * hint 4: to access the dataport use the interface name as defined in Echo.camkes. + * For example if you defined it as "dataport str_buf_t d_typed" then you would use "d_typed" to refer to the dataport in C. + * hint 5: for the definition of "str_buf_t" see "str_buf.h" + * hint 6: use the "n" field to specify the number of strings in the dataport + * hint 7: copy the specified number of strings from the "Buf" dataport to the "str" field + * hint 8: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports + * hint 9: you could combine this TASK with the previous one in a single loop if you want + */ + + n = (int*)d; + str = (char*)(n + 1); + for (int i = 0, j = *n - 1; i < *n; i++, j--) { + strncpy(d_typed->str[j], str, STR_LEN); + uppercase(d_typed->str[j]); + str += strlen(str) + 1; + } + d_typed->n = *n; +``` +
      + +
      +Quick solution +```c + /* TASK 23: read some data from the dataports. specifically: + * read a dataport pointer from one of the typed dataports, then use + * that pointer to access data in the untyped dataport. + */ + /* hint 1: for the untyped dataport use the "Buf" dataport as defined in the Echo.camkes file + * hint 2: for the typed dataport use the "ptr_buf_t" dataport as defined in the Echo.camkes file + * hint 3: for the definition of "ptr_buf_t" see "str_buf.h". + * hint 4: the "n" field of the typed dataport specifies the number of dataport pointers + * hint 5: the "ptr" field of the typed dataport contains the dataport pointers + * hint 6: use the function "dataport_unwrap_ptr()" to create a regular pointer from a dataport pointer + * hint 7: for more information about dataport pointers see: https://github.com/seL4/camkes-tool/blob/master/docs/index.md + * hint 8: print out the string pointed to by each dataport pointer + */ + + char *str; + for (int i = 0; i < d_ptrs->n; i++) { + str = dataport_unwrap_ptr(d_ptrs->ptr[i]); + printf("%s: dptr saying (%p): \"%s\"\n", get_instance_name(), str, str); + } +``` +
      + +### TASK 7 + This is an introduction to CAmkES attributes: you're +being asked to set the priority of the components. + +
      +Quick solution +``` +``` +
      + +### TASK 8, 16 + This is where we specify the data access constraints +for the Dataports in a shared memory connection. We then go about +attempting to violate those constraints to see how CAmkES has truly met +our constraints when mapping those Dataports. + +
      +Quick solution +``` +``` +
      + +
      +Quick solution +``` +``` +
      + +## Done! + Congratulations: be sure to read up on the keywords and +structure of ADL: it's key to understanding CAmkES. And well done on +writing your first CAmkES application. + + Next tutorial: CAmkES 3 diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index 5c56e36038..12e11f8a6a 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -108,6 +108,8 @@
    • CAmkES VM
    • CAmkES Cross VM Connectors
    +
  • Microkit
  • +
  • Rust
  • Resources
    • seL4 Manual
    • diff --git a/index.md b/index.md index 49126b729a..98e53b9f92 100644 --- a/index.md +++ b/index.md @@ -119,7 +119,9 @@ This documentation site is for cooperatively developing and sharing documentatio
    • CAmkES VM
    • CAmkES Cross VM Connectors
    -
  • Resources
  • +
  • Microkit
  • +
  • Rust
  • +
  • Resources
    • seL4 Manual
    • API references
    • From 90077341bb01e7f4b875582ab57aa1e082af3aea Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 11 Mar 2024 19:00:22 +1100 Subject: [PATCH 012/103] update camkes 1 and 2 (incomplete) Signed-off-by: Birgit Brecknell --- TutorialsReworked/CAmkES/camkes1.md | 8 ++- TutorialsReworked/CAmkES/camkes2.md | 71 +++++++++++++++++++++++---- TutorialsReworked/Resources/how-to.md | 30 +++++++++-- 3 files changed, 93 insertions(+), 16 deletions(-) diff --git a/TutorialsReworked/CAmkES/camkes1.md b/TutorialsReworked/CAmkES/camkes1.md index 03649e2865..33f78469a4 100644 --- a/TutorialsReworked/CAmkES/camkes1.md +++ b/TutorialsReworked/CAmkES/camkes1.md @@ -141,7 +141,7 @@ the second one was named `a2`? Then in order to call on that second ## Exercises - +### Define instance in the composition section of the ADL **Exercise** First modify `hello-1.camkes`. Define instances of `Echo` and `Client` in the `composition` section of the ADL. @@ -162,7 +162,7 @@ assembly { ``` - +### Add a connection **Exercise** Now add a connection from `client.hello` to `echo.hello`. ``` @@ -178,6 +178,8 @@ assembly { ``` +### Define an interface + **Exercise** Define the interface for hello in `interfaces/HelloSimple.idl4`. ```c @@ -196,6 +198,7 @@ procedure HelloSimple { ``` +### Implement a RPC function **Exercise** Implement the RPC hello function. ```c @@ -226,6 +229,7 @@ void hello_say_hello(const char *str) { ``` +### Invoke a RPC function **Exercise** Invoke the RPC function in `components/Client/src/client.c`. ```c /* diff --git a/TutorialsReworked/CAmkES/camkes2.md b/TutorialsReworked/CAmkES/camkes2.md index 889435e413..49c406c91f 100644 --- a/TutorialsReworked/CAmkES/camkes2.md +++ b/TutorialsReworked/CAmkES/camkes2.md @@ -1,7 +1,5 @@ # CAmkES Tutorial 2 -This tutorial is an introduction to -CAmkES: bootstrapping a basic static CAmkES application, describing its -components, and linking them together. +This tutorial describes CAmkES in greater detail, building on [Tutorial 1](camkes1). Learn how to: - Represent and implement events in CAmkES. @@ -30,13 +28,6 @@ All tutorials come with complete solutions. To get solutions run: -## Walkthrough - Bear in mind, this article will be going through the -tutorial steps in the order that the user is led through them in the -slide presentation, except where several similar tasks are coalesced to -avoid duplication. Additionally, if a tasks step covers material that -has already been touched on, it will be omitted from this article. - ### TASK 1 Here you're declaring the events that will be bounced back and forth in this tutorial. An event is a signal is sent over a @@ -50,9 +41,17 @@ You are strongly advised to read the manual section on Events here: you're not emitting on both sides of a single interface, or consuming on both sides of an interface.'' +#### Specify an events interface
      Quick solution ``` + /* TASK 1: the event interfaces */ + /* hint 1: specify 2 interfaces: one "emits" and one "consumes" + * hint 2: you can use an arbitrary string as the interface type (it doesn't get used) + * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events + */ + emits TheEvent echo; + consumes TheEvent client; ```
      @@ -65,6 +64,7 @@ connection over which events are sent, there is no API, but rather CAmkES will generate \_emit() and \_wait() functions to enable the application to transparently interact with these events. +#### Emit event to signal that the data is available
      Quick solution ```c @@ -76,6 +76,7 @@ application to transparently interact with these events. echo_emit(); ```
      +
      Quick solution ```c @@ -215,12 +216,29 @@ in the shared mem communication. We will then link them together using a
      Quick solution ``` + /* TASK 2: the dataport interfaces */ + /* hint 1: specify 3 interfaces: one of type "Buf", one of type "str_buf_t" and one of type "ptr_buf_t" + * hint 2: for the definition of these types see "str_buf.h". + * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports + */ + + dataport Buf d; + dataport str_buf_t d_typed; + dataport ptr_buf_t d_ptrs; ```
      Quick solution ``` + /* TASK 4: the dataport interfaces */ + /* hint 1: specify 3 interfaces: one of type "Buf", one of type "str_buf_t" and one of type "ptr_buf_t" + * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports + */ + + dataport Buf d; + dataport str_buf_t d_typed; + dataport ptr_buf_t d_ptrs; ```
      @@ -233,6 +251,15 @@ proceed.
      Quick solution ``` + /* TASK 6: Dataport connections */ + /* hint 1: connect the corresponding dataport interfaces of the components to each other + * hint 2: use seL4SharedData as the connector + * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports + */ + + connection seL4SharedData data_conn(from client.d, to echo.d); + connection seL4SharedData typed_data_conn(from client.d_typed, to echo.d_typed); + connection seL4SharedData ptr_data_conn(from client.d_ptrs, to echo.d_ptrs); ```
      @@ -396,6 +423,13 @@ being asked to set the priority of the components.
      Quick solution ``` + /* TASK 7: set component priorities */ + /* hint 1: component priority is specified as an attribute with the name .priority + * hint 2: the highest priority is represented by 255, the lowest by 0 + */ + + client.priority = 255; + echo.priority = 254; ```
      @@ -408,12 +442,29 @@ our constraints when mapping those Dataports.
      Quick solution ``` + /* TASK 8: restrict access to dataports */ + /* hint 1: use attribute ._access for each component and interface + * hint 2: appropriate values for the to_access and from_access attributes are: "R" or "W" + * hint 4: make the "Buf" dataport read only for the Echo component + * hint 3: make the "str_buf_t" dataport read only for the Client component + */ + + echo.d_access = "R"; + client.d_access = "W"; + echo.d_typed_access = "W"; + client.d_typed_access = "R"; ```
      Quick solution ``` + /* TASK 16: test the read and write permissions on the dataport. + * When we try to write to a read-only dataport, we will get a VM fault. + */ + /* hint 1: try to assign a value to a field of the "str_buf_t" dataport */ + + d_typed->n = 0; ```
      diff --git a/TutorialsReworked/Resources/how-to.md b/TutorialsReworked/Resources/how-to.md index a3403125f2..167c33d365 100644 --- a/TutorialsReworked/Resources/how-to.md +++ b/TutorialsReworked/Resources/how-to.md @@ -113,8 +113,30 @@ seL4Kernel/ipc#use-capability-transfer-to-send-the-badged-capability) - [Use a timer](../DynamicLibraries/timer#use-the-timer) - [Handle an interrupt](../DynamicLibraries/timer#handle-the-interrupt) - [Destroy a timer](../DynamicLibraries/timer#destroy-the-timer) - - -## CAmkES -TBD + - ## [CAmkES](../CAmkES/) + - [A basic CAmkES application](../CAmkES/camkes1) + - [Define instance in the composition section of the ADL](../CAmkES/camkes1#define-instance-in-the-composition-section-of-the-adl) + - [Add a connection](../CAmkES/camkes1#add-a-connection) + - [Define an interface](../CAmkES/camkes1#define-an-interface) + - [Implement a RPC function](../CAmkES/camkes1#implement-a-rpc-function) + - [Invoke a RPC function](../CAmkES/camkes1#invoke-a-rpc-function) + - [Events in CAmkES](../CAmkES/camkes2) + - [Specify an events interface](../CAmkES/camkes2#specify-an-events-interface) + - +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 +(../CAmkES/camkes2 From 8f11ebd4ac55362cd4466f0d85189d7a649ffa74 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Wed, 13 Mar 2024 17:19:25 +1100 Subject: [PATCH 013/103] add and update camkes 2 & 3 tuts Signed-off-by: Birgit Brecknell --- TutorialsReworked/CAmkES/camkes2.md | 52 ++- TutorialsReworked/CAmkES/camkes3.md | 443 ++++++++++++++++++++++++++ TutorialsReworked/Resources/how-to.md | 46 ++- 3 files changed, 498 insertions(+), 43 deletions(-) diff --git a/TutorialsReworked/CAmkES/camkes2.md b/TutorialsReworked/CAmkES/camkes2.md index 49c406c91f..4e747f87a0 100644 --- a/TutorialsReworked/CAmkES/camkes2.md +++ b/TutorialsReworked/CAmkES/camkes2.md @@ -1,5 +1,5 @@ # CAmkES Tutorial 2 -This tutorial describes CAmkES in greater detail, building on [Tutorial 1](camkes1). +This tutorial shows how to build events in CAmkES. Learn how to: - Represent and implement events in CAmkES. @@ -64,7 +64,7 @@ connection over which events are sent, there is no API, but rather CAmkES will generate \_emit() and \_wait() functions to enable the application to transparently interact with these events. -#### Emit event to signal that the data is available +#### Signal that the data is available
      Quick solution ```c @@ -72,45 +72,44 @@ application to transparently interact with these events. /* hint 1: use the function _emit * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events */ - echo_emit(); ```
      +#### Wait for data to become available
      Quick solution ```c - /* TASK 11: wait to get an event back signalling that the reply data is avaialble */ + /* TASK 11: wait to get an event back signalling that the reply data is available */ /* hint 1: use the function _wait * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events */ - client_wait(); ```
      - +#### Signal that data is available
      Quick solution ```c /* TASK 14: emit event to signal that the data is available */ /* hint 1: we've already done this before */ - echo_emit(); ```
      +#### Wait for data to be read
      Quick solution ```c /* TASK 15: wait to get an event back signalling that data has been read */ /* hint 1: we've already done this before */ - client_wait(); ```
      +#### Signal that data is available
      Quick solution ```c @@ -118,11 +117,11 @@ application to transparently interact with these events. /* hint 1: use the function _emit * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events */ - client_emit(); ```
      +#### Signal that data has been read
      Quick solution ```c @@ -130,7 +129,6 @@ application to transparently interact with these events. /* hint 1: use the function _emit * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events */ - client_emit(); ```
      @@ -142,6 +140,7 @@ use callbacks when they are raised. CAmkES generates functions that handle the registration of callbacks for each notification interface instance. These steps help you to become familiar with this approach. +#### Register a callback handler
      Quick solution ```c @@ -158,13 +157,13 @@ instance. These steps help you to become familiar with this approach. * hint 3: pass NULL as the extra argument to the callback * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events */ - int error = echo_reg_callback(callback_handler_1, NULL); ZF_LOGF_IF(error != 0, "Failed to register callback"); } ```
      +#### Register another callback handler
      Quick solution ```c @@ -174,12 +173,12 @@ instance. These steps help you to become familiar with this approach. * hint 3: pass NULL as the extra argument to the callback * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events */ - int error = echo_reg_callback(callback_handler_2, NULL); ZF_LOGF_IF(error != 0, "Failed to register callback"); ```
      +#### Register a callback handler
      Quick solution ```c @@ -189,7 +188,6 @@ instance. These steps help you to become familiar with this approach. * hint 3: pass NULL as the extra argument to the callback * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events */ - int error = echo_reg_callback(callback_handler_1, NULL); ZF_LOGF_IF(error != 0, "Failed to register callback"); ``` @@ -213,6 +211,7 @@ interface instances on each of the components that will be participating in the shared mem communication. We will then link them together using a "seL4SharedData" connector later on. +#### Specify dataport interfaces
      Quick solution ``` @@ -221,13 +220,13 @@ in the shared mem communication. We will then link them together using a * hint 2: for the definition of these types see "str_buf.h". * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports */ - dataport Buf d; dataport str_buf_t d_typed; dataport ptr_buf_t d_ptrs; ```
      +#### Specify dataport interfaces
      Quick solution ``` @@ -235,7 +234,6 @@ in the shared mem communication. We will then link them together using a /* hint 1: specify 3 interfaces: one of type "Buf", one of type "str_buf_t" and one of type "ptr_buf_t" * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports */ - dataport Buf d; dataport str_buf_t d_typed; dataport ptr_buf_t d_ptrs; @@ -248,6 +246,7 @@ between the shared memory pages in each client, and tell CAmkES to link these using shared underlying Frame objects. Fill out this step, and proceed. +#### Specify dataport connections
      Quick solution ``` @@ -256,7 +255,6 @@ proceed. * hint 2: use seL4SharedData as the connector * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports */ - connection seL4SharedData data_conn(from client.d, to echo.d); connection seL4SharedData typed_data_conn(from client.d_typed, to echo.d_typed); connection seL4SharedData ptr_data_conn(from client.d_ptrs, to echo.d_ptrs); @@ -268,6 +266,7 @@ proceed. to access and manipulate the data in the shared memory mapping (Dataport) of the client. Follow through to the next step. +#### Copy strings to an untyped dataport
      Quick solution ```c @@ -279,7 +278,6 @@ to access and manipulate the data in the shared memory mapping * hint 4: then copy all the strings from "s_arr" to the dataport. * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports */ - int *n = (int*)d; *n = NUM_STRINGS; char *str = (char*)(n + 1); @@ -287,10 +285,10 @@ to access and manipulate the data in the shared memory mapping strcpy(str, s_arr[i]); str += strlen(str) + 1; } - ```
      +#### Read the reply data from a typed dataport
      Quick solution ``` @@ -303,13 +301,13 @@ to access and manipulate the data in the shared memory mapping * hint 5: print out the specified number of strings from the "str" field * hint 6: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports */ - for (int i = 0; i < d_typed->n; i++) { printf("%s: string %d (%p): \"%s\"\n", get_instance_name(), i, d_typed->str[i], d_typed->str[i]); } ```
      +# Send data using dataports
      Quick solution ``` @@ -327,7 +325,6 @@ to access and manipulate the data in the shared memory mapping * hint 8: the dataport pointers should point into the untyped dataport * hint 9: for more information about dataport pointers see: https://github.com/seL4/camkes-tool/blob/master/docs/index.md */ - d_ptrs->n = NUM_STRINGS; str = (char*)d; for (int i = 0; i < NUM_STRINGS; i++) { @@ -343,6 +340,7 @@ to access and manipulate the data in the shared memory mapping code to access and manipulate the data in the shared memory mapping (Dataport) of the server. +#### Read data from an untyped dataport
      Quick solution ```c @@ -354,7 +352,6 @@ code to access and manipulate the data in the shared memory mapping * hint 4: then print each string from the dataport * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports */ - int *n = (int*)d; char *str = (char*)(n + 1); for (int i = 0; i < *n; i++) { @@ -364,6 +361,7 @@ code to access and manipulate the data in the shared memory mapping ```
      +#### Put data into a typed dataport
      Quick solution ```c @@ -379,7 +377,6 @@ code to access and manipulate the data in the shared memory mapping * hint 8: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports * hint 9: you could combine this TASK with the previous one in a single loop if you want */ - n = (int*)d; str = (char*)(n + 1); for (int i = 0, j = *n - 1; i < *n; i++, j--) { @@ -391,6 +388,7 @@ code to access and manipulate the data in the shared memory mapping ```
      +#### Read data from a typed dataport
      Quick solution ```c @@ -407,7 +405,6 @@ code to access and manipulate the data in the shared memory mapping * hint 7: for more information about dataport pointers see: https://github.com/seL4/camkes-tool/blob/master/docs/index.md * hint 8: print out the string pointed to by each dataport pointer */ - char *str; for (int i = 0; i < d_ptrs->n; i++) { str = dataport_unwrap_ptr(d_ptrs->ptr[i]); @@ -420,14 +417,14 @@ code to access and manipulate the data in the shared memory mapping This is an introduction to CAmkES attributes: you're being asked to set the priority of the components. +#### Set component priorities
      Quick solution ``` /* TASK 7: set component priorities */ /* hint 1: component priority is specified as an attribute with the name .priority - * hint 2: the highest priority is represented by 255, the lowest by 0 - */ - + * hint 2: the highest priority is represented by 255, the lowest by 0 + */ client.priority = 255; echo.priority = 254; ``` @@ -439,6 +436,7 @@ for the Dataports in a shared memory connection. We then go about attempting to violate those constraints to see how CAmkES has truly met our constraints when mapping those Dataports. +#### Restrict access to dataports
      Quick solution ``` @@ -448,7 +446,6 @@ our constraints when mapping those Dataports. * hint 4: make the "Buf" dataport read only for the Echo component * hint 3: make the "str_buf_t" dataport read only for the Client component */ - echo.d_access = "R"; client.d_access = "W"; echo.d_typed_access = "W"; @@ -456,6 +453,7 @@ our constraints when mapping those Dataports. ```
      +#### Test the read and write permissions on the dataport
      Quick solution ``` diff --git a/TutorialsReworked/CAmkES/camkes3.md b/TutorialsReworked/CAmkES/camkes3.md index e69de29bb2..2f7de071cf 100644 --- a/TutorialsReworked/CAmkES/camkes3.md +++ b/TutorialsReworked/CAmkES/camkes3.md @@ -0,0 +1,443 @@ +# CAmkES Timer Tutorial + +This tutorial guides you through setting up a sample timer driver component in +CAmkES and using it to delay for 2 seconds. For this tutorial, we will be using +the ZYNQ7000 ARM-based platform. This platform can be simulated via QEMU so it +is not a problem if you do not have access to the actual physical board. + +The tutorial also has two parts to it. The first part will teach you how to +manually define hardware details to configure the hardware component and +initialise hardware resources. The second part will teach you how to use a +CAmkES connector to initialise hardware resources automatically for you. + +The solutions to this tutorial primarily uses the method of manually defining +hardware details. The solutions to the second part are also included, albeit +commented out. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut hello-camkes-timer +# building the tutorial exercise +cd hello-camkes-timer_build +ninja +``` +
      +Hint: tutorial solutions +
      +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut hello-camkes-timer +``` +
      + + +## Exercises - Part 1 + +### TASK 1 + +Start in `hello-camkes-timer.camkes`. + +Instantiate some components. You're already given one component instance +- `client`. You need to instantiate additional components, a timer driver and +a component instance representing the timer hardware itself. Look +in `components/Timer/Timer.camkes` for the definitions of the components. + +Once you open the file, you will notice three different components. The `Timer` +and `Timerbase` components represents the timer driver and the timer hardware +respectively. The `TimerDTB` component represents both the timer driver and the +timer hardware. This component is meant to be used with the `seL4DTBHardware` +CAmkES connector to automatically initialise hardware resources. The second +part of the tutorial will go into more detail about the `TimerDTB` component +and the `seL4DTBHardware` connector. + +For now, instantiate the `Timer` and `Timerbase` components. + +Note the lines `connection seL4RPCCall hello_timer(from client.hello, to +timer.hello);` and `timer.sem_value = 0;` in the `hello-camkes-timer.camkes` +file. They assume that the name of the timer ''driver'' will be `timer`. If you +wish to call your driver something else, you'll have to change these lines. + +
      +Quick solution +``` + /* Part 1, TASK 1: component instances */ + /* hint 1: one hardware component and one driver component + * hint 2: look at + * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application + */ + component Timerbase timerbase; + component Timer timer; +``` +
      + +### TASK 2 + +Connect the timer driver component (`Timer`) to the timer hardware component +(`Timerbase`). The timer hardware component exposes two interfaces which must +be connected to the timer driver. One of these represents memory-mapped +registers. The other represents an interrupt. + +
      +Quick solution +``` + /* Part 1, TASK 2: connections */ + /* hint 1: use seL4HardwareMMIO to connect device memory + * hint 2: use seL4HardwareInterrupt to connect interrupt + * hint 3: look at + * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application + */ + connection seL4HardwareMMIO timer_mem(from timer.reg, to timerbase.reg); + connection seL4HardwareInterrupt timer_irq(from timerbase.irq, to timer.irq); +``` +
      + +### TASK 3 + +Configure the timer hardware component instance with device-specific info. The +physical address of the timer's memory-mapped registers, and its IRQ number +must both be configured. + +
      +Quick solution +``` + /* Part 1, TASK 3: hardware resources */ + /* Timer and Timerbase: + * hint 1: find out the device memory address and IRQ number from the hardware data sheet + * hint 2: look at + * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#hardware-components + */ + timerbase.reg_paddr = 0xF8001000; // paddr of mmio registers + timerbase.reg_size = 0x1000; // size of mmio registers + timerbase.irq_irq_number = 42; // timer irq number +``` +
      + +### TASK 4 + +Now open `components/Timer/src/timer.c`. + +We'll start by completing the `irq_handle` function, which is called in +response to each timer interrupt. Note the name of this function. It follows +the naming convention `_handle`, where `` is the name of +an IRQ interface connected with `seL4HardwareInterrupt`. When an interrupt is +received on the interface ``, the function `_handle` will +be called. + +The implementation of the timer driver is located inside a different folder and +can be found in the `projects/sel4-tutorials/zynq_timer_driver` folder from the +root of the projects directory, i.e. where the `.repo` folder can be found and +where the initial `repo init` command was executed. + +This task is to call the `timer_handle_irq` function from the supply driver to +inform the driver that an interrupt has occurred. + +
      +Quick solution +```c + /* Part 1, TASK 4: call into the supplied driver to handle the interrupt. */ + /* hint: timer_handle_irq + */ + timer_handle_irq(&timer_drv); +``` +
      + +### TASK 5 + +Stop the timer from running. The `timer_stop` function will be helpful here. + +
      +Quick solution +```c + /* Part 1, TASK 5: stop the timer. */ + /* hint: timer_stop + */ + timer_stop(&timer_drv); +``` +
      + +### TASK 6 + +The interrupt now needs to be acknowledged. + +CAmkES generates the seL4-specific code for ack-ing an interrupt and provides a +function `_acknowldege` for IRQ interfaces (specifically those +connected with `seL4HardwareInterrupt`). + +
      +Quick solution +```c + /* Part 1, TASK 6: acknowledge the interrupt */ + /* hint 1: use the function _acknowledge() + */ + error = irq_acknowledge(); + ZF_LOGF_IF(error != 0, "failed to acknowledge interrupt"); +``` +
      + +### TASK 7 + +Now we'll complete `hello__init` - a function which is called once +before the component's interfaces start running. + +We need to initialise a handle to the timer driver for this device, and store a +handle to the driver in the global variable `timer_drv`. + +
      +Quick solution +```c + /* Part 1, TASK 7: call into the supplied driver to get the timer handler */ + /* hint1: timer_init + * hint2: The timer ID is supplied as a #define in this file + * hint3: The register's variable name is the same name as the dataport in the Timer component + */ + int error = timer_init(&timer_drv, DEFAULT_TIMER_ID, reg); + assert(error == 0); +``` +
      + +### TASK 8 + +After initialising the timer, we now need to start the timer. Do so by calling +`timer_start` and passing the handle to the driver. + +
      +Quick solution +```c + /* Part 1, TASK 8: start the timer + * hint: timer_start + */ + error = timer_start(&timer_drv); + assert(error == 0); +``` +
      + +### TASK 9 + +Note that this task is to understand the existing code. You won't have +to modify anything for this task. + +Implement the `timer_inf` RPC interface. This interface is defined in +`interfaces/timer.camkes`, and contains a single method, `sleep`, which +should return after a given number of seconds. in +`components/Timer/Timer.camkes`, we can see that the `timer_inf` interface +exposed by the `Timer` component is called `hello`. Thus, the function we +need to implement is called `hello_sleep`. + +
      +Quick solution +```c + /* part 1, TASK 9: implement the rpc function. */ + /* hint 1: the name of the function to implement is a composition of an interface name and a function name: + * i.e.: _ + * hint 2: the interfaces available are defined by the component, e.g. in components/timer/timer.camkes + * hint 3: the function name is defined by the interface definition, e.g. in interfaces/timer.camkes + * hint 4: so the function would be: hello_sleep() + * hint 5: the camkes 'int' type maps to 'int' in c + * hint 6: invoke a function in supplied driver the to set up the timer + * hint 7: look at https://github.com/sel4/camkes-tool/blob/master/docs/index.md#creating-an-application + */ + void hello_sleep(int sec) { + int error = 0; + /* Part 1, TASK 10: invoke a function in the supplied driver to set a timeout */ + /* hint1: timer_set_timeout + * hint2: periodic should be set to false + */ + error = timer_set_timeout(&timer_drv, sec * NS_IN_SECOND, false); + assert(error == 0); + error = sem_wait(); + ZF_LOGF_IF(error != 0, "failed to wait on semaphore"); + } +``` +
      + +### TASK 10 + +Tell the timer to interrupt after the given number of seconds. The +`timer_set_timeout` function from the included driver will help. Note that it +expects its time argument to be given in nanoseconds. + +Note the existing code in `hello_sleep`. It waits on a binary semaphore. +`irq_handle` will be called on another thread when the timer interrupt occurs, +and that function will post to the binary semaphore, unblocking us and allowing +the function to return after the delay. + +Expect the following output with a 2 second delay between the last 2 +lines: +``` +Starting the client +------Sleep for 2 seconds------ +After the client: wakeup +``` +
      +Quick solution +```c + * Part 1, TASK 10: invoke a function in the supplied driver to set a timeout */ + /* hint1: timer_set_timeout + * hint2: periodic should be set to false + */ + error = timer_set_timeout(&timer_drv, sec * NS_IN_SECOND, false); + assert(error == 0); +``` +
      + +## Exercises - Part 2 + +Now that you've learnt how to manually define the hardware details of a +hardware component to initialise hardware resources, this part of the tutorial +will teach you how to use the `seL4DTBHardware` connector to do that +automatically. + +The connector requires a devicetree blob which describes an ARM platform. +Additionally, the blob's interrupt fields also need to follow the same format +of the ARM GIC v1 and v2. There are devicetree source files bundled with the +kernel, look in the `tools/dts/` folder of the kernel sources. If a suitable +devicetree blob is not available for your platform, then do not proceed with +the tutorial. + +### TASK 1 + +Navigate to the `hello-camkes-timer.camkes` file. + +Remove the `Timerbase` and `Timer` component instantiations and instantiate a +`TimerDTB` component instead. Also change the `connection seL4RPCCall +hello_timer(from client.hello, to timer.hello);` and `timer.sem_value = 0;` +lines if necessary. +
      +Quick solution +``` + /* Part 2, TASK 1: component instances */ + /* hint 1: a single TimerDTB component + * hint 2: look at + * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application + */ + component TimerDTB timer; +``` +
      + +### TASK 2 + +Remove the `seL4HardwareMMIO` and `seL4HardwareInterrupt` connections. Connect +the two interfaces inside the `TimerDTB` component with the `seL4DTBHardware` +connector. +
      +Quick solution +``` + /* Part 2, TASK 2: connections */ + /* hint 1: connect the dummy_source and timer interfaces + * hint 2: the dummy_source should be the 'from' end + * hint 3: look at + * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application + */ + connection seL4DTBHardware timer_dtb(from timer.dummy_source, to timer.tmr); +``` +
      + +### TASK 3 + +Before opening `components/Timer/Timer.camkes`, remove the `Timerbase` settings +inside the configurations block. + +Configure the `TimerDTB` component to pass in the correct DTB path to a timer +to the connector and also initialise the interrupt resources for the timer. +This will allow the connector to read a device node from the devicetree blob +and grab the necessary data to initialise hardware resources. More +specifically, it reads the registers field and optionally the interrupts field +to allocate memory and interrupts. +
      +Quick solution +``` + /* Part 2, TASK 3: hardware resources */ + /* TimerDTB: + * hint 1: look in the DTB/DTS for the path of a timer + * hint 2: set the 'dtb' setting for the tmr interface in the TimerDTB component, + * e.g. foo.dtb = dtb({"path" : "/bar"}); + * hint 3: set the 'generate_interrupts' setting to 1 + */ + tmr.dtb = dtb({"path" : "/amba/timer@f8001000"}); // path of the timer in the DTB + tmr.generate_interrupts = 1; // tell seL4DTBHardware to init interrupts +``` +
      + +### TASK 4 + +Move to `components/TimerDTB/src/timerdtb.c`. + +Similar to part one, we'll start with the `tmr_irq_handle` function. This +function is called in response to a timer interrupt. The name of the function +has a special meaning and the meaning is unique to the `seL4DTBHardware` +connector. + +The IRQ handling functions of the connector follows the naming convention +`_irq_handle`, where `` is the name of the +interface of the 'to' end in an instance of a `seL4DTBHardware` connection. +Also notice that it takes a `ps_irq_t *` type. This is because, for a given +device, there may be multiple interrupts associated with the device. A +`ps_irq_t` struct is given to the IRQ handling function and it contains +information about the interrupt, allowing the handler to differentiate between +the numerous interrupts of a device. + +Likewise with part one, the implementation of the timer driver is in the +included driver in `timer_driver` and the task here is to call +`timer_handle_irq`. +
      +Quick solution +```c + /* Part 2, TASK 4: call into the supplied driver to handle the interrupt. */ + /* hint: timer_handle_irq + */ + timer_handle_irq(&timer_drv); +``` +
      + +### TASK 5 + +The timer needs to be stopped, the task here is the same as part one's task 5. +
      +Quick solution +```c + /* Part 2, TASK 5: stop the timer. */ + /* hint: timer_stop + */ + timer_stop(&timer_drv); +``` +
      + +### TASK 6 + +Again, the interrupt now has to be acknowledged. + +For the `seL4DTBHardware` connector, CAmkES also generates and provides a +function to acknowledge interrupts. This function follows a similar naming +convention to the IRQ handler above, `_irq_acknowledge` also +takes in a `ps_irq_t *` argument. Similarly, the `ps_irq_t *` argument helps +CAmkES to differentiate between the possibly many interrupts of a device that +you wish to acknowledge. +
      +Quick solution +``` + /* Part 2, TASK 7: call into the supplied driver to get the timer handler */ + /* hint1: timer_init + * hint2: The timer ID is supplied as a #define in this file + * hint3: The register's name is follows the format of _, + * where "interface name" is the name of the + * interface where you set the path of the DTB (foo.dtb = dtb({...})) + * and "register number" is the index of the register block in the device + * node in the devicetree blob + */ + int error = timer_init(&timer_drv, DEFAULT_TIMER_ID, tmr_0); + assert(error == 0); +``` +
      + +### TASK 7 - 10 + +Task 7 to 10 are the exact same as the tasks in part one. + +You should also expect the same output as the first part. + +Next tutorial: CAmkES VM diff --git a/TutorialsReworked/Resources/how-to.md b/TutorialsReworked/Resources/how-to.md index 167c33d365..bbeb2badd5 100644 --- a/TutorialsReworked/Resources/how-to.md +++ b/TutorialsReworked/Resources/how-to.md @@ -122,21 +122,35 @@ seL4Kernel/ipc#use-capability-transfer-to-send-the-badged-capability) - [Invoke a RPC function](../CAmkES/camkes1#invoke-a-rpc-function) - [Events in CAmkES](../CAmkES/camkes2) - [Specify an events interface](../CAmkES/camkes2#specify-an-events-interface) + - [Wait for data to become available](../CAmkES/camkes2#wait-for-data-to-become-available) + - [Signal that data is available](../CAmkES/camkes2#signal-that-data-is-available) + - [Register a callback handler](../CAmkES/camkes2#register-a-callback-handler) + - [Specify dataport interfaces](../CAmkES/camkes2#specify-an-events-interface) + - [Specify dataport connections](../CAmkES/camkes2#specify-dataport-connections) + - [Copy strings to an untyped dataport](../CAmkES/camkes2#copy-strings-to-an-untyped-dataport) + - [Read the reply data from a typed dataport](../CAmkES/camkes2#read-the-reply-data-from-a-typed-dataport) + - [Send data using dataports](../CAmkES/camkes2#send-data-using-dataports) + - [Read data from an untyped dataport](../CAmkES/camkes2#read-data-from-an-untyped-dataport) + - [Put data into a typed dataport](../CAmkES/camkes2#put-data-into-a-typed-dataport) + - [Read data from a typed dataport](../CAmkES/camkes2#read-data-from-a-typed-dataport) + - [Set component priorities](../CAmkES/camkes2#set-component-priorities) + - [Restrict access to dataports](../CAmkES/camkes2#restrict-access-to-dataports) + - [Test the read and write permissions on the dataport](../CAmkES/camkes2#test-the-read-and-write-permissions-on-the-dataport) + - [CAmkES Timer](../CAmkES/camkes) + - [Instantiate a Timer and Timerbase](../CAmkES/camkes3#task-1) + - [Connect a timer driver component](../CAmkES/camkes3#task-2) + - [Configure a timer hardware component instance](../CAmkES/camkes3#task-3) + - [Call into a supplied driver to handle the interrupt](../CAmkES/camkes3#task-4) + - [Stop a timer](../CAmkES/camkes3#task-5) + - [Acknowledge an interrupt](../CAmkES/camkes3#task-6) + - [Get a timer handler](../CAmkES/camkes3#task-7) + - [Start a timer](../CAmkES/camkes3#task-8) + - [Implement a RPC interface](../CAmkES/camkes3#task-9) + - [Set a timer interrupt](../CAmkES/camkes3#task-10) + - [Instantiate a TimerDTB component](../CAmkES/camkes3#task-1-1) + - [Connect interfaces using the seL4DTBHardware connector](../CAmkES/camkes3#task-2-1) + - [Configure the `TimerDTB` component](../CAmkES/camkes3#task-3-1) - -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 -(../CAmkES/camkes2 +(../CAmkES/camkes3 +(../CAmkES/camkes3 From a18f827858bd701005d8229d9c30d06f98d662cb Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 15 Mar 2024 11:17:08 +1100 Subject: [PATCH 014/103] update camkes tuts Signed-off-by: Birgit Brecknell --- TutorialsReworked/CAmkES/camkes-cross-vm.md | 504 +++++++++++++++++ TutorialsReworked/CAmkES/camkes-vm.md | 534 +++++++++++++++++++ TutorialsReworked/CAmkES/camkes1.md | 4 +- TutorialsReworked/CAmkES/camkes2.md | 11 +- TutorialsReworked/CAmkES/camkes3.md | 8 +- TutorialsReworked/CAmkES/hello-camkes.md | 2 +- TutorialsReworked/seL4Kernel/capabilities.md | 10 +- TutorialsReworked/seL4Kernel/hello-world.md | 11 +- _includes/nav-sidebar.html | 6 +- 9 files changed, 1074 insertions(+), 16 deletions(-) diff --git a/TutorialsReworked/CAmkES/camkes-cross-vm.md b/TutorialsReworked/CAmkES/camkes-cross-vm.md index e69de29bb2..59d7cdc796 100644 --- a/TutorialsReworked/CAmkES/camkes-cross-vm.md +++ b/TutorialsReworked/CAmkES/camkes-cross-vm.md @@ -0,0 +1,504 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + + +# CAmkES VM: Cross VM Connectors + +This tutorial provides an introduction to using the cross virtual machine (VM) connector mechanisms +provided by seL4 and Camkes in order to connect processes in a guest Linux instance to Camkes components. + +In this tutorial you will learn how to: + +* Configure processes in a Linux guest VM to communicate with CAmkES components + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut camkes-vm-crossvm +# building the tutorial exercise +cd camkes-vm-crossvm +ninja +``` +
      +Hint: tutorial solutions +
      +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut camkes-vm-crossvm +``` +
      + +## Background + +In order to connect guest Linux instances to CAmkES components, +three additional kernel modules must be installed in the guest. +These modules are included in the root filesystem by default: + +- `dataport`: facilitates setting up shared memory between the guest +and CAmkES components. +- `consumes_event`: allows a process in the guest to wait or poll +for an event sent by a CAmkES component. +- `emits_event`: allows a process to emit an event to a CAmkES component. + +Each type of module can be statically assigned to one or more file descriptors to associate that +file descriptor with a specific instance of an interface. `ioctl` can then be used to +manipulate that file descriptor and use the module. + +### Dataports + +Dataports are the mechanism which allows guests and components to share memory. +The dataport initialisation process is as follows: + +- The guest process uses `ioctl` on on the file associated with the dataport and specify a + page-aligned size for the shared memory. +- The dataport kernel module in the guest then allocates a page-aligned buffer of the requested size, + and makes a hypercall to the VMM, with the guest physical address and id of the data port. + The ID is derived from the file on which `ioctl` was called. +- The virtual machine manager (VMM) then modifies the guest's address space, creating the shared memory region. + between a camkes component and the guest. +- Linux processes can then map this memory into their own address space by calling `mmap` on the file + associated with the dataport. + +### Emitting Events + +Guest processes can emit events by using `ioctl` on files associated with the event interface. +This results in the `emits_event` kernel module in the guest making a +making a hypercall to the VMM, which triggers the event and resumes the guest. + +### Consuming Events + +Linux process can wait or poll for an event by calling `poll` +on the file associated with that event, using the timeout argument to +specify whether or not it should block. The event it polls for is +`POLLIN`. When the VMM receives an event destined for the guest, it places +the event id in some memory shared between the VMM and the +`consumes_event` kernel module, and then injects an interrupt into the +guest. The `consumes_event` kernel module is registered to handle this +interrupt, which reads the event ID from shared memory, and wakes a +thread blocked on the corresponding event file. If no threads are +blocked on the file, some state is set in the module such that the next +time a process waits on that file, it returns immediately and clears the +state, mimicking the behaviour of notifications. + +## Exercises + +In this tutorial you will +create a program that runs in the guest, and sends a string +to a CAmkES component to output. To achieve this, the guest program will write a string +to a shared buffer between itself and a CAmkES component. When its ready +for the string to be printed, it will emit an event, received by the +CAmkES component. The CAmkES component will print the string, then send +an event to the guest process so the guest knows it's safe to send a new +string. + +### Add modules to the guest + +There is a library in `projects/camkes/vm-linux/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/libs` +containing Linux system call wrappers, and some utility programs in +`projects/camkes/vm-linux/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/pkgs/{dataport,consumes_event,emits_event}` +which initialize and interact with cross VM connections. To build and use these modules in your rootfs the vm-linux +project provides an overlay target you can use. + +**Exercise** First add the `dataport`, `consumes_event` and `emits_event` kernel modules to the rootfs in the guest. + +Start by replacing the line: + +```cmake +AddToFileServer("rootfs.cpio" ${default_rootfs_file}) +``` + +in the target applications `CMakeLists.txt` file with the following: + +```cmake +set(CAmkESVMDefaultBuildrootOverlay ON CACHE BOOL "" FORCE) +AddOverlayDirToRootfs(default_buildroot_overlay ${default_rootfs_file} "buildroot" "rootfs_install" + rootfs_file rootfs_target) +AddToFileServer("rootfs.cpio" ${rootfs_file}) +``` + +### Define interfaces in the VMM + +**Exercise** Update the CAmkES file, `crossvm_tutorial.camkes` by replacing the Init0 component definition: + +```c +component Init0 { + VM_INIT_DEF() +} +``` + +with the following definition: + +```c +component Init0 { + VM_INIT_DEF() + + // this is the data port for shared memory between the component and guest process + dataport Buf(4096) data; + // this event tells the component that there is data ready to print + emits DoPrint do_print; + // this event tells the guest process that priting is complete + consumes DonePrinting done_printing; + // this mutex protects access to shared state between the VMM and the guest Linux + has mutex cross_vm_event_mutex; +} +``` + +These interfaces will eventually be made visible to processes running in +the guest linux. The mutex is used to protect access to shared state +between the VMM and guest. + +### Define the component interface + +**Exercise** Define the print server component by adding the following to +the `crossvm_tutorial.camkes` file, after the `Init0` definition: +```c +component PrintServer { + control; + dataport Buf(4096) data; + consumes DoPrint do_print; + emits DonePrinting done_printing; +} +``` + +### Instantiate the print server + +**Exercise** Replace the `composition` definition: + +```c + composition { + VM_COMPOSITION_DEF() + VM_PER_VM_COMP_DEF(0) + } +``` + +with the following: + +```c + composition { + VM_COMPOSITION_DEF() + VM_PER_VM_COMP_DEF(0) + + component PrintServer print_server; + connection seL4Notification conn_do_print(from vm0.do_print, + to print_server.do_print); + connection seL4Notification conn_done_printing(from print_server.done_printing, + to vm0.done_printing); + + connection seL4SharedDataWithCaps conn_data(from print_server.data, + to vm0.data); + } +``` + +The [seL4SharedDataWithCaps][] +connector is a dataport connector much like `seL4SharedData`. +However, the `to` side of the connection also receives access to +the capabilities to the frames backing the dataport, which is required +for cross VM dataports, as the VMM must be able to establish shared memory +at runtime by inserting new mappings into the guest's address space. + +[seL4SharedDataWithCaps]: https://docs.sel4.systems/projects/camkes/seL4SharedDataWithCaps.html + +**Exercise** Interfaces connected with [seL4SharedDataWithCaps][] must be +configured with an integer specifying the ID and size of the dataport. + Do this now by modifying `crossvm_tutorial.camkes` with the following +two lines in the configuration section: + +```c + configuration { + ... + // Add the following 2 lines: + vm0.data_id = 1; // ids must be contiguous, starting from 1 + vm0.data_size = 4096; + } +``` + +### Implement the print server + +**Exercise** Add the file `components/print_server.c` with the following contents: +```c +#include +#include + +int run(void) { + + while (1) { + // wait for the next event + do_print_wait(); + + printf("%s\n", (char*)data); + + // signal that we are done printing + done_printing_emit(); + } + + return 0; +} +``` + +This provides a very simple component definition that loops forever, printing a string from +shared memory whenever an event is received then emitting an event. +The example code assumes that the shared buffer will contain a valid, null-terminated c string, which is not + something you should do in practice. + +### Implement the VMM side of the connection +Create another c file that tells the VMM about the cross VM connections. + This file must define 3 functions which initialize each type of cross vm interface: + +- `cross_vm_dataports_init` +- `cross_vm_emits_events_init` +- `cross_vm_consumes_events_init` + +**Exercise** Add a file `src/cross_vm.c` with the following contents: + +```c +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this is defined in the dataport's glue code +extern dataport_caps_handle_t data_handle; + +// Array of dataport handles at positions corresponding to handle ids from spec +static dataport_caps_handle_t *dataports[] = { + NULL, // entry 0 is NULL so ids correspond with indices + &data_handle, +}; + +// Array of consumed event callbacks and ids +static camkes_consumes_event_t consumed_events[] = { + { .id = 1, .reg_callback = done_printing_reg_callback }, +}; + +// Array of emitted event emit functions +static camkes_emit_fn emitted_events[] = { + NULL, // entry 0 is NULL so ids correspond with indices + do_print_emit, +}; + +// mutex to protect shared event context +static camkes_mutex_t cross_vm_event_mutex = (camkes_mutex_t) { + .lock = cross_vm_event_mutex_lock, + .unlock = cross_vm_event_mutex_unlock, +}; + +int cross_vm_dataports_init(vmm_t *vmm) { + return cross_vm_dataports_init_common(vmm, dataports, sizeof(dataports)/sizeof(dataports[0])); +} + +int cross_vm_emits_events_init(vmm_t *vmm) { + return cross_vm_emits_events_init_common(vmm, emitted_events, + sizeof(emitted_events)/sizeof(emitted_events[0])); +} + +int cross_vm_consumes_events_init(vmm_t *vmm, vspace_t *vspace, seL4_Word irq_badge) { + return cross_vm_consumes_events_init_common(vmm, vspace, &cross_vm_event_mutex, + consumed_events, sizeof(consumed_events)/sizeof(consumed_events[0]), irq_badge); +} +``` + +### Update the build system + +**Exercise** Make the following changes in `CMakeLists.txt` by firstly replacing the declaration of Init0: + +```cmake +DeclareCAmkESVM(Init0) +``` + +with the following declaration: + +```cmake +# Retrieve Init0 cross vm src files +file(GLOB init0_extra src/*.c) +# Declare VM component: Init0 +DeclareCAmkESVM(Init0 + EXTRA_SOURCES ${init0_extra} + EXTRA_LIBS crossvm +) +``` + +Also add a declaration for a PrintServer component: + +```cmake +# Declare the CAmkES PrintServer component +DeclareCAmkESComponent(PrintServer SOURCES components/print_server.c) +``` + +This extends the definition of the Init component with the `cross_vm connector` source and the crossvm +library, and defines the new CAmkES component `PrintServer`. + +### Add interfaces to the Guest + +**Exercise** Create the following `camkes_init` shell script that is executed as Linux is initialized: + +```bash +#!/bin/sh +# Initialises linux-side of cross vm connections. + +# Dataport sizes must match those in the camkes spec. +# For each argument to dataport_init, the nth pair +# corresponds to the dataport with id n. +dataport_init /dev/camkes_data 4096 + +# The nth argument to event_init corresponds to the +# event with id n according to the camkes vmm. +consumes_event_init /dev/camkes_done_printing +emits_event_init /dev/camkes_do_print +``` + +Each of these commands creates device nodes associated with a particular +Linux kernel module supporting cross VM communication. Each command +takes a list of device nodes to create, which must correspond to the IDs +assigned to interfaces in `crossvm_tutorial.camkes` and `cross_vm.c`. The +`dataport_init` command must also be passed the size of each dataport. + +These changes will cause device nodes to be created which correspond to +the interfaces you added to the VMM component. + +### Create a process + +Now make a process that uses the device nodes to communicate with the +print server. + +**Exercise** First create a new directory: +``` +mkdir -p pkgs/print_client +``` + +with the following file `pkgs/print_client/print_client.c`: + +```c +#include +#include + +#include +#include +#include +#include + +#include "dataport.h" +#include "consumes_event.h" +#include "emits_event.h" + +int main(int argc, char *argv[]) { + + int data_fd = open("/dev/camkes_data", O_RDWR); + assert(data_fd >= 0); + + int do_print_fd = open("/dev/camkes_do_print", O_RDWR); + assert(do_print_fd >= 0); + + int done_printing_fd = open("/dev/camkes_done_printing", O_RDWR); + assert(done_printing_fd >= 0); + + char *data = (char*)dataport_mmap(data_fd); + assert(data != MAP_FAILED); + + ssize_t dataport_size = dataport_get_size(data_fd); + assert(dataport_size > 0); + + for (int i = 1; i < argc; i++) { + strncpy(data, argv[i], dataport_size); + emits_event_emit(do_print_fd); + consumes_event_wait(done_printing_fd); + } + + close(data_fd); + close(do_print_fd); + close(done_printing_fd); + + return 0; +} +``` + +This program prints each of its arguments on a separate line, by sending +each argument to the print server one at a time. + +**Exercise** Create `pkgs/print_client/CMakeLists.txt` for our client program: + +```cmake +cmake_minimum_required(VERSION 3.8.2) + +project(print_client C) + +file(READ ${CMAKE_MODULE_PATH_FILE} module_path) +list(APPEND CMAKE_MODULE_PATH ${module_path}) +find_package(camkes-vm-linux REQUIRED) +add_subdirectory(${CAMKES_VM_LINUX_DIR}/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/libs/camkes camkes) + +add_executable(print_client print_client.c) +target_link_libraries(print_client camkeslinux) +``` + +**Exercise** Update our the VM apps `CMakeLists.txt`. Below the line: + +```cmake +AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel) +``` + +add the `ExternalProject` declaration to include the print application: + +```cmake +# Get Custom toolchain for 32 bit Linux +include(cross_compiling) +FindCustomPollyToolchain(LINUX_32BIT_TOOLCHAIN "linux-gcc-32bit-pic") +# Declare our print server app external project +include(ExternalProject) +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/module_path "${CMAKE_MODULE_PATH}") +ExternalProject_Add(print_client-app + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/pkgs/print_client + BINARY_DIR ${CMAKE_BINARY_DIR}/print_client-app + BUILD_ALWAYS ON + STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/print_client-app-stamp + EXCLUDE_FROM_ALL + INSTALL_COMMAND "" + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_TOOLCHAIN_FILE=${LINUX_32BIT_TOOLCHAIN} + -DCMAKE_MODULE_PATH_FILE=${CMAKE_CURRENT_BINARY_DIR}/module_path +) +# Add the print client app to our overlay ('default_buildroot_overlay') +AddExternalProjFilesToOverlay(print_client-app ${CMAKE_BINARY_DIR}/print_client-app default_buildroot_overlay "usr/sbin" + FILES print_client) +``` + +Directly below this we also want to add our `camkes_init` script into the overlay. We place this into the VMs `init.d` directory so +the script is run on start up: + +```cmake +AddFileToOverlayDir("S90camkes_init" ${CMAKE_CURRENT_LIST_DIR}/camkes_init "etc/init.d" default_buildroot_overlay) +``` + +That's it. Build and run the system, and you should see the following output: + +``` +... +Creating dataport node /dev/camkes_data +Allocating 4096 bytes for /dev/camkes_data +Creating consuming event node /dev/camkes_done_printing +Creating emitting event node /dev/camkes_do_print + +Welcome to Buildroot +buildroot login: root +Password: +# print_client hello world +[ 12.730073] dataport received mmap for minor 1 +hello +world +``` + diff --git a/TutorialsReworked/CAmkES/camkes-vm.md b/TutorialsReworked/CAmkES/camkes-vm.md index e69de29bb2..07e9e3f3bc 100644 --- a/TutorialsReworked/CAmkES/camkes-vm.md +++ b/TutorialsReworked/CAmkES/camkes-vm.md @@ -0,0 +1,534 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# CAmkES VM: Adding a Linux Guest + +This tutorial provides an introduction to creating VM guests and applications on seL4 using CAmkES. + +You will become familiar with: + +* Creating, configuring and building guest Linux VM components in CAmkES. +* Building and installing your own Linux VM user-level programs and kernel modules. + +## Initialising + +```sh +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code +# +# Follow these instructions to initialise the tutorial +# initialising the build directory with a tutorial exercise +./init --tut camkes-vm-linux +# building the tutorial exercise +cd camkes-vm-linux +ninja +``` +
      +Hint: tutorial solutions +
      +All tutorials come with complete solutions. To get solutions run: +``` +./init --solution --tut camkes-vm-linux +``` +
      + + +## Background + +This tutorial is set up with a basic CAmkES VM configuration for you to build upon. +The starting application should boot a single, very basic Linux guest. + +To build the tutorial, run: + +```sh +# In build directory +ninja +``` + +You can boot the tutorial on an x86 hardware platform with a multiboot boot loader, +or use the [QEMU](https://www.qemu.org) simulator. **Note if you are using QEMU +it is important to ensure that your host machine has VT-x support and [KVM](https://www.linux-kvm.org/page/Main_Page) +installed. You also need to ensure you have enabled nested virtulisation with KVM guests as described +[here](https://www.linux-kvm.org/page/Nested_Guests).** + +To simulate the image you can run the provided simulation script with some additional parameters: + +```sh +# In the build directory +# You will need to set up a tap device first: +# ip tuntap add tap0 mode tap +# ip addr add 10.0.120.100/24 dev tap0 +# ip link set dev tap0 up +sudo ./simulate --machine q35,accel=kvm,kernel-irqchip=split --mem-size 2G --extra-cpu-opts "+vmx" --extra-qemu-args="-enable-kvm -device intel-iommu,intremap=off -net nic,model=e1000 -net tap,script=no,ifname=tap0" +``` + +When first simulating the image you should see the following login prompt: +``` +Welcome to Buildroot +buildroot login: +``` + +You can login with the username `root` and the password `root`. + +The Linux guest was built using [buildroot](https://buildroot.org/), which +creates a compatible kernel and minimal root filesystem containing busybox and a in-memory file system (a ramdisk). + +## VM Components + +Each VM component has its own assembly implementation, where the guest environment is configured. +The provided VM configuration is defined in `vm_tutorial.camkes`: + +``` +import ; + +#include + +#define VM_GUEST_CMDLINE "earlyprintk=ttyS0,115200 console=ttyS0,115200 i8042.nokbd=y i8042.nomux=y \ +i8042.noaux=y io_delay=udelay noisapnp pci=nomsi debug root=/dev/mem" + +component Init0 { + VM_INIT_DEF() +} + +assembly { + composition { + VM_COMPOSITION_DEF() + VM_PER_VM_COMP_DEF(0) + } + + configuration { + VM_CONFIGURATION_DEF() + VM_PER_VM_CONFIG_DEF(0) + + vm0.simple_untyped23_pool = 20; + vm0.heap_size = 0x2000000; + vm0.guest_ram_mb = 128; + vm0.kernel_cmdline = VM_GUEST_CMDLINE; + vm0.kernel_image = "bzimage"; + vm0.kernel_relocs = "bzimage"; + vm0.initrd_image = "rootfs.cpio"; + vm0.iospace_domain = 0x0f; + } +} +``` + +Most of the work here is done by five C preprocessor macros: +`VM_INIT_DEF`, `VM_COMPOSITION_DEF`, `VM_PER_VM_COMP_DEF`, +`VM_CONFIGURATION_DEF`, `VM_PER_VM_CONFIG_DEF`. + +These are all defined in `projects/camkes/vm/components/VM/configurations/vm.h`, +and are concerned with specifying and configuring components that all +VM(M)s need. + +The `Init0` component corresponds to a single guest. Because of some rules +in the cpp macros, the *Ith* guest in your system must be defined as a +component named `InitI`. `InitI` components will be instantiated in the +composition section by the `VM_PER_VM_COMP_DEF` macro with instance +names `vmI`. The `vm0` component instance being configured above is an +instance of `Init0`. The C source code for`InitI` components is in +`projects/camkes/vm/components/Init/src`. This source will be used for components +named `InitI` for *I* in `0..VM_NUM_VM - 1`. + +The values of `vm0.kernel_cmdline`, `vm0.kernel_image` and `vm0.initrd_image` are all +strings specifying: + - boot arguments to the guest Linux, + - the name of the guest Linux kernel image file, + - and the name of the guest Linux initrd file (the root filesystem to use during system initialization). + +The kernel command-line is defined in the `VM_GUEST_CMDLINE` macro. The kernel image +and rootfs names are defined in the applications `CMakeLists.txt` file. +These are the names of files in a CPIO archive that gets created by the build system, and +linked into the VMM. In the simple configuration for thie tutorial, the VMM uses +the `bzimage` and `rootfs.cpio` names to find the appropriate files +in this archive. + +To see how the `Init` component and CPIO archive are definied within the build system, +look at the app's `CMakeList.txt`: + +```cmake +include(${SEL4_TUTORIALS_DIR}/settings.cmake) +sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR}) + +cmake_minimum_required(VERSION 3.8.2) + +project(vm-app C ASM) +include(ExternalProject) +find_package(camkes-vm REQUIRED) +include(${CAMKES_VM_SETTINGS_PATH}) +camkes_x86_vm_setup_x86_vm_environment() +include(${CAMKES_VM_HELPERS_PATH}) +find_package(camkes-vm-linux REQUIRED) +include(${CAMKES_VM_LINUX_HELPERS_PATH}) + + +# Include CAmkES VM helper functions + + + + +# Declare VM component: Init0 +DeclareCAmkESVM(Init0) + +# Get Default Linux VM files +GetArchDefaultLinuxKernelFile("32" default_kernel_file) +GetArchDefaultLinuxRootfsFile("32" default_rootfs_file) + +# Decompress Linux Kernel image and add to file server +DecompressLinuxKernel(extract_linux_kernel decompressed_kernel ${default_kernel_file}) + +AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel) + + + +# Add rootfs images into file server +AddToFileServer("rootfs.cpio" ${default_rootfs_file}) + + + +# Initialise CAmkES Root Server with addition CPP includes +DeclareCAmkESVMRootServer(vm_tutorial.camkes) +GenerateCAmkESRootserver() + +``` + +The file `projects/camkes/vm/camkes_vm_helpers.cmake` provides helper functions for the VM projects, +including `DeclareCAmkESVM(Init0)`, which is used to define the `Init0` VM component. +Each Init component requires a corresponding `DeclareCAmkESVM` function. + +`GetArchDefaultLinuxKernelFile` (defined in `projects/camkes/vm-linux/vm-linux-helpers.cmake`) +is a helper function that retrieves the location of an architectural specific VM image provided +in the `projects/vm-linux` folder, which contains some tools for building new linux kernel +and root filesystem images, as well as the images that these tools +produce. A fresh checkout of this project will contain some pre-built +images (`bzimage` and `rootfs.cpio`), to speed up build times. + +`DecompressLinuxKernel` is used to extract the vmlinux image, which `AddToFileServer` then places +in the fileserver along with the rootfs. + +## Adding to the guest + +In the simple buildroot guest image, the +initrd (rootfs.cpio) is also the filesystem you get access to after +logging in. To make new programs available to the guest you need to add them to the +rootfs.cpio archive. Similarly, to make new kernel modules available to +the guest they must be added to the rootfs.cpio archive also. + +In this tutorial you will install new programs into the guest VM. + +### vm-linux-helpers.cmake + +The `projects/camkes/vm-linux` directory contains CMake helpers to +overlay rootfs.cpio archives with a desired set of programs, modules +and scripts. + +#### `AddFileToOverlayDir(filename file_location root_location overlay_name)` +This helper allows you to overlay specific files onto a rootfs image. The caller specifies +the file they wish to install in the rootfs image (`file_location`), the name they want the file +to be called in the rootfs (`filename`) and the location they want the file to installed in the +rootfs (`root_location`), e.g "usr/bin". Lastly the caller passes in a unique target name for the overlay +(`overlay_name`). You can repeatedly call this helper with different files for a given target to build +up a set of files to be installed on a rootfs image. + +#### `AddOverlayDirToRootfs(rootfs_overlay rootfs_image rootfs_distro rootfs_overlay_mode output_rootfs_location target_name)` +This helper allows you to install a defined overlay target onto a given rootfs image. The caller specifies +the rootfs overlay target name (`rootfs_overlay`), the rootfs image they wish to install their files onto +(`rootfs_image`), the distribution of their rootfs image (`rootfs_distro`, only 'buildroot' and 'debian' is +supported) and the output location of their overlayed rootfs image (`output_rootfs_location`). Lastly the caller +specifies how the files will be installed into their rootfs image through `rootfs_overlay_mode`. These modes include: +* `rootfs_install`: The files are installed onto the rootfs image. This is useful if the rootfs image is the filesystem +your guest VM is using when it boots. However this won't be useful if your VM will be booting from disk since the installed files +won't be present after the VM boots. +* `overlay`: The files are mounted as an overlayed filesystem (overlayfs). This is useful if you are booting from disk and don't wish to +install the artifacts permanently onto the VM. The downside to this is that writes to the overlayed root do not persist between boots. This +mode is benefitial for debugging purposes and live VM images. +* `fs_install`: The files are permanently installed on the VM's file system, after the root has been mounted. +#### `AddExternalProjFilesToOverlay(external_target external_install_dir overlay_target overlay_root_location)` +This helper allows you to add files generated from an external CMake project to an overlay target. This is mainly a wrapper around +`AddOverlayDirToRootfs` which in addition creates a target for the generated file in the external project. The caller passes the external +project target (`external_target`), the external projects install directory (`external_install_dir`), the overlay target you want to add the +file to (`overlay_target`) and the location you wish to install the file within the rootfs image (`overlay_root_location`). + +### linux-source-helpers.cmake + +#### `DownloadLinux(linux_major linux_minor linux_md5 linux_out_dir linux_out_target)` +This is a helper function for downloading the linux source. This is needed if we wish to build our own kernel modules. + +#### `ConfigureLinux(linux_dir linux_config_location linux_symvers_location configure_linux_target)` +This helper function is used for configuring downloaded linux source with a given Kbuild defconfig (`linux_config_location`) +and symvers file (`linux_symvers_location`). + +## Exercises + +### Adding a program + +This exercise guides you through adding a new program to the Linux guest user-level environment. + +First, make a new directory: +```bash +mkdir -p pkg/hello +``` +Then a simple C program in `pkg/hello/hello.c`: +```c +#include + +int main(int argc, char *argv[]) { + printf("Hello, World!\n"); + return 0; +} +``` +Then create a build file for the program at `pkg/hello/CMakeLists.txt`: + +```cmake +cmake_minimum_required(VERSION 3.8.2) + +project(hello C) + +add_executable(hello hello.c) + +target_link_libraries(hello -static) +``` +Now integrate the new program with the build system. +Update the VM apps `CMakeLists.txt` to declare the hello application as an +external project and add it to our overlay. + Do this by replacing the line `AddToFileServer("rootfs.cpio" ${default_rootfs_file})` with the following: + +```cmake +# Get Custom toolchain for 32 bit Linux +include(cross_compiling) +FindCustomPollyToolchain(LINUX_32BIT_TOOLCHAIN "linux-gcc-32bit-pic") +# Declare our hello app external project +ExternalProject_Add(hello-app + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/pkg/hello + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/hello-app + BUILD_ALWAYS ON + STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/hello-app-stamp + EXCLUDE_FROM_ALL + INSTALL_COMMAND "" + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_TOOLCHAIN_FILE=${LINUX_32BIT_TOOLCHAIN} +) +# Add the hello world app to our overlay ('vm-overlay') +AddExternalProjFilesToOverlay(hello-app ${CMAKE_CURRENT_BINARY_DIR}/hello-app vm-overlay "usr/sbin" + FILES hello) +# Add the overlay directory to our default rootfs image +AddOverlayDirToRootfs(vm-overlay ${default_rootfs_file} "buildroot" "rootfs_install" + rootfs_file rootfs_target) +AddToFileServer("rootfs.cpio" ${rootfs_file} DEPENDS rootfs_target) +``` +Now rebuild the project... + +```sh +# In build directory +ninja +``` +..and run it (use `root` as username and password). +You should be able to use the new program. + +``` +Welcome to Buildroot +buildroot login: root +Password: +# hello +Hello, World! +``` + +## Adding a kernel module + +The next exercise guides you through the addition of a new kernel module that provides +guest to VMM communication. This is a very simply module: you'll create a special file +associated with the new module, which when written to causes the VMM to print message. + +First, make a new directory: +``` +mkdir -p modules/poke +``` +Then create the following file for the module in `modules/poke/poke.c`. +```c +#include +#include +#include +#include + +#include +#include +#include + +#define DEVICE_NAME "poke" + +static int major_number; + +static ssize_t poke_write(struct file *f, const char __user*b, size_t s, loff_t *o) { + printk("hi\n"); // TODO replace with hypercall + return s; +} + +struct file_operations fops = { + .write = poke_write, +}; + +static int __init poke_init(void) { + major_number = register_chrdev(0, DEVICE_NAME, &fops); + printk(KERN_INFO "%s initialized with major number %dn", DEVICE_NAME, major_number); + return 0; +} + +static void __exit poke_exit(void) { + unregister_chrdev(major_number, DEVICE_NAME); + printk(KERN_INFO"%s exitn", DEVICE_NAME); +} + +module_init(poke_init); +module_exit(poke_exit); +``` +Now add a Makefile for building the module in `modules/poke/Makefile`: + +```make +obj-m += poke.o + +all: + make -C $(KHEAD) M=$(PWD) modules + +clean: + make -C $(KHEAD) M=$(PWD) clean +``` + +Create a `modules/CMakeLists.txt` to define the new Linux module with the following content: +```cmake +cmake_minimum_required(VERSION 3.8.2) + +if(NOT MODULE_HELPERS_FILE) + message(FATAL_ERROR "MODULE_HELPERS_FILE is not defined") +endif() + +include("${MODULE_HELPERS_FILE}") + +DefineLinuxModule(${CMAKE_CURRENT_LIST_DIR}/poke poke-module poke-target KERNEL_DIR ${LINUX_KERNEL_DIR}) +``` +Update the VM `CMakeLists.txt` file to declare the new poke module as an +external project and add it to the overlay. + +At the top of the file include our linux helpers, add the following: + +```cmake +include(${CAMKES_VM_LINUX_SOURCE_HELPERS_PATH}) +``` +Below the includes (before `AddOverlayDirToRootfs` that was added in the first exercise **Adding a program**) add: +```cmake +# Setup Linux Sources +GetDefaultLinuxMajor(linux_major) +GetDefaultLinuxMinor(linux_minor) +GetDefaultLinuxMd5(linux_md5) +# Download and Configure our Linux sources +DownloadLinux(${linux_major} ${linux_minor} ${linux_md5} vm_linux_extract_dir download_vm_linux) +set(linux_config "${CAMKES_VM_LINUX_DIR}/linux_configs/${linux_major}.${linux_minor}/32/config") +set(linux_symvers "${CAMKES_VM_LINUX_DIR}/linux_configs/${linux_major}.${linux_minor}/32/Module.symvers") +ConfigureLinux(${vm_linux_extract_dir} ${linux_config} ${linux_symvers} configure_vm_linux + DEPENDS download_vm_linux +) +# Add the external poke module project +ExternalProject_Add(poke-module + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/modules + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/poke-module + BUILD_ALWAYS ON + STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/poke-module-stamp + EXCLUDE_FROM_ALL + INSTALL_COMMAND "" + DEPENDS download_vm_linux configure_vm_linux + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_TOOLCHAIN_FILE=${LINUX_32BIT_TOOLCHAIN} + -DLINUX_KERNEL_DIR=${vm_linux_extract_dir} + -DMODULE_HELPERS_FILE=${CAMKES_VM_LINUX_DIR}/linux-module-helpers.cmake +) +# Add our module binary to the overlay +AddExternalProjFilesToOverlay(poke-module ${CMAKE_CURRENT_BINARY_DIR}/poke-module vm-overlay "lib/modules/4.8.16/kernel/drivers/vmm" + FILES poke.ko) +``` + +Write a custom init script that loads the new module during initialization. +Create a file called `init` in our tutorial directory with the following: + +```bash +#!/bin/sh +# devtmpfs does not get automounted for initramfs +/bin/mount -t devtmpfs devtmpfs /dev +exec 0/dev/console +exec 2>/dev/console + +insmod /lib/modules/4.8.16/kernel/drivers/vmm/poke.ko +exec /sbin/init $* +``` +Now update our the VM apps `CMakeLists.txt` file to add the new init script to the +overlay. After our call to `AddExternalProjFilesToOverlay` and before `AddOverlayDirToRootfs` for the poke module add the following: + +```cmake +AddFileToOverlayDir("init" ${CMAKE_CURRENT_LIST_DIR}/init "." vm-overlay) +``` +and give the script executable permissions: +```bash +chmod +x init +``` +Rebuild the project: + +```sh +# In build directory +ninja +``` +Run the following commands to see the module being used: + +``` +Welcome to Buildroot +buildroot login: root +Password: +# grep poke /proc/devices # figure out the major number of our driver +246 poke +# mknod /dev/poke c 246 0 # create the special file +# echo > /dev/poke # write to the file +[ 57.389643] hi +-sh: write error: Bad address # the shell complains, but our module is being invoked! +``` + +### Create a hypercall + +In `modules/poke/poke.c`, replace `printk("hi\n");` with `kvm_hypercall1(4, 0);`. +The choice of 4 is because 0..3 are already used by existing hypercalls. + +Then register a handler for this hypercall in `projects/camkes/vm/components/Init/src/main.c`:. +Add a new function at the top of the file: + +```c +static int poke_handler(vm_vcpu_t *vm_vcpu) { + printf("POKE!!!\n"); + return 0; +} +``` + +In the function `main_continued` register \`poke_handler\`: + +```c +vm_reg_new_vmcall_handler(&vm, poke_handler, 4); // <--- added + +/* Now go run the event loop */ +vmm_run(&vm); +``` + +Rebuild the project and try out the hypercall + module: + +```sh +# In build directory +ninja +``` +``` +Welcome to Buildroot +buildroot login: root +Password: +# mknod /dev/poke c 246 0 +# echo > /dev/poke +POKE!!! +``` +Next tutorial: CAmkES cross VM diff --git a/TutorialsReworked/CAmkES/camkes1.md b/TutorialsReworked/CAmkES/camkes1.md index 33f78469a4..36fb900279 100644 --- a/TutorialsReworked/CAmkES/camkes1.md +++ b/TutorialsReworked/CAmkES/camkes1.md @@ -5,7 +5,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- -# CAmkES Tutorial 1 +# CAmkES Tutorial 1: Introduction to CAmkES This tutorial is an introduction to CAmkES: bootstrapping a basic static CAmkES application, describing its components, and linking them together. @@ -283,5 +283,5 @@ Now build and run the project, if it compiles: Congratulations! Be sure to read structure of ADL: it's key to understanding CAmkES. And well done on writing your first CAmkES application. -Next tutorial: CAmkES 2 +Next tutorial: CAmkES 2: Events diff --git a/TutorialsReworked/CAmkES/camkes2.md b/TutorialsReworked/CAmkES/camkes2.md index 4e747f87a0..3d27c578ac 100644 --- a/TutorialsReworked/CAmkES/camkes2.md +++ b/TutorialsReworked/CAmkES/camkes2.md @@ -1,4 +1,11 @@ -# CAmkES Tutorial 2 +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# CAmkES Tutorial 2: Events This tutorial shows how to build events in CAmkES. Learn how to: @@ -473,4 +480,4 @@ writing your first CAmkES application. -Next tutorial: CAmkES 3 +Next tutorial: CAmkES 3: Timer diff --git a/TutorialsReworked/CAmkES/camkes3.md b/TutorialsReworked/CAmkES/camkes3.md index 2f7de071cf..b06d45690c 100644 --- a/TutorialsReworked/CAmkES/camkes3.md +++ b/TutorialsReworked/CAmkES/camkes3.md @@ -1,3 +1,9 @@ +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- # CAmkES Timer Tutorial This tutorial guides you through setting up a sample timer driver component in @@ -440,4 +446,4 @@ Task 7 to 10 are the exact same as the tasks in part one. You should also expect the same output as the first part. -Next tutorial: CAmkES VM +Next tutorial: CAmkES VM diff --git a/TutorialsReworked/CAmkES/hello-camkes.md b/TutorialsReworked/CAmkES/hello-camkes.md index d24b3832a4..e78a550980 100644 --- a/TutorialsReworked/CAmkES/hello-camkes.md +++ b/TutorialsReworked/CAmkES/hello-camkes.md @@ -188,4 +188,4 @@ Hello CAmkES World structure of ADL: it's key to understanding CAmkES. And well done on building and running your first CAmkES application. -Next tutorial: CAmkES 1 +Next tutorial: CAmkES 1: Introduction to CAmkES diff --git a/TutorialsReworked/seL4Kernel/capabilities.md b/TutorialsReworked/seL4Kernel/capabilities.md index e22267ce47..c4bb661f95 100644 --- a/TutorialsReworked/seL4Kernel/capabilities.md +++ b/TutorialsReworked/seL4Kernel/capabilities.md @@ -9,8 +9,7 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. This tutorial provides a basic introduction to seL4 capabilities. -By the end of this tutorial, you should be familiar with: - +You will learn: 1. The jargon CNode, CSpace, CSlot. 2. Know how to invoke a capability. 3. Know how to delete and copy CSlots. @@ -32,9 +31,11 @@ ninja Hint: tutorial solutions
      All tutorials come with complete solutions. To get solutions run: + ``` ./init --solution --tut capabilities ``` + Answers are also available in drop down menus under each section.
      @@ -241,9 +242,11 @@ The third line stating the number of slots in the CSpace, is incorrect, and your ```
      Quick solution + ```c size_t initial_cnode_object_size_bytes = initial_cnode_object_size * (1u << seL4_SlotBits); ``` +
      ### Copy a capability between CSlots @@ -277,12 +280,14 @@ The error occurs as the existing code tries to set the priority of the initial t ```
      Quick solution + ```c /* use seL4_CNode_Copy to make another copy of the initial TCB capability to the last slot in the CSpace */ error = seL4_CNode_Copy(seL4_CapInitThreadCNode, last_slot, seL4_WordBits, seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits, seL4_AllRights); ZF_LOGF_IF(error, "Failed to copy cap!"); ``` +
      On success, you will now see the output: @@ -348,6 +353,7 @@ main@main.c:56 Failed to suspend current thread ```
      Quick solution + ```c // suspend the current thread seL4_TCB_Suspend(seL4_CapInitThreadTCB); diff --git a/TutorialsReworked/seL4Kernel/hello-world.md b/TutorialsReworked/seL4Kernel/hello-world.md index 3547daa7ca..4443711290 100644 --- a/TutorialsReworked/seL4Kernel/hello-world.md +++ b/TutorialsReworked/seL4Kernel/hello-world.md @@ -7,7 +7,7 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. # Hello, world! -In this tutorial you will +In this tutorial you will: - Run Hello, World! to ensure your setup is working correctly - Become familiar with the jargon *root task* - Build and simulate a seL4 project @@ -23,7 +23,7 @@ When the root task starts there are no available drivers, however a minimal C li The tutorial is already set up to print "Hello, world!", so at this point all you need to do is build and run the tutorial. -### Initialise the build directory +### Initialising ``` cd sel4-tutorials-manifest @@ -35,13 +35,15 @@ This step creates two new directories in `sel4-tutorials-manifest`, namely `hell Hint: tutorial solutions
      All tutorials come with complete solutions. To get solutions run: + ``` ./init --solution --tut hello-world ``` + This will generate another `hello-world` directory and `hello-world_build` directory, with unique names, e.g. `hello-world44h1po5q` and `hello-world44h1po5q_build`.
      -We will now use two terminals, as described in [Setting up your machine](setting-up#mapping-a-container). +We will now use two terminals, as described in [Setting up your machine](https://docs.sel4.systems/Tutorials/seL4Kernel/setting-up#mapping-a-container). - Terminal A is just a normal terminal, and is used for git operations, editing (e.g., vim, emacs), and other normal operations. - Terminal B is running in a container, and is only used for compilation. @@ -188,12 +190,11 @@ int main(int argc, char *argv[]) { ``` Once you have made your change, use Terminal B to rebuild the project: -*Hint:* Remember to exit the QEMU siumator before rerunning the project with `ctrl-A,x`. *And* exit the container using `ctrl-D` +*Hint:* Remember to exit the QEMU siumator before rerunning the project with `ctrl-A,x`. Then rebuild using ninja and run the simulator again: ``` ninja -container ./simulate ``` diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index 12e11f8a6a..c1e33b6e3e 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -102,9 +102,9 @@
    • CAmkES
    • From d63b96f87e1dac197e21202f207e0f8089fd948f Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 15 Mar 2024 11:54:58 +1100 Subject: [PATCH 015/103] add tutorials overview page Signed-off-by: Birgit Brecknell --- TutorialsReworked/GettingStarted/about-seL4.md | 2 +- TutorialsReworked/GettingStarted/overview.md | 12 ++++++++++++ TutorialsReworked/seL4Kernel/overview.md | 9 ++------- _includes/nav-sidebar.html | 1 + index.md | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 TutorialsReworked/GettingStarted/overview.md diff --git a/TutorialsReworked/GettingStarted/about-seL4.md b/TutorialsReworked/GettingStarted/about-seL4.md index b22bb2a8d9..7e3df33206 100644 --- a/TutorialsReworked/GettingStarted/about-seL4.md +++ b/TutorialsReworked/GettingStarted/about-seL4.md @@ -41,5 +41,5 @@ memory object, which allocates the memory for the object, initialises it, and re Because sel4 is small, a lot more needs to be done in user space and there are a lot more choices about how to do that. We'll start by building a simple system using the seL4 Microkit, which is a software development kit for building static systems on seL4.

      - Next tutorial: seL4 microkit tutorial + Next: Get started with the seL4 microkit tutorial

      \ No newline at end of file diff --git a/TutorialsReworked/GettingStarted/overview.md b/TutorialsReworked/GettingStarted/overview.md new file mode 100644 index 0000000000..b644b150c0 --- /dev/null +++ b/TutorialsReworked/GettingStarted/overview.md @@ -0,0 +1,12 @@ +We have developed a series of tutorials to introduce seL4 and +developing systems on seL4. + +The tutorials are split into a number of broad categories: + +- [About seL4](about) and [Getting started with the Microkit tutorial](microkit) are introductions to seL4 concepts +- The [seL4 Kernel tutorials] are a deep dive into seL4 concepts +- [MCS] introduces seL4 MCS extensions +- [Dynamic Libraries] covers the libraries found in `seL4_libs` +- [CAmkES], a platform for building componentised systems for embedded platforms +- [Microkit], an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4 +- [Rust], crates for supporting the use of Rust in seL4 userspace diff --git a/TutorialsReworked/seL4Kernel/overview.md b/TutorialsReworked/seL4Kernel/overview.md index ce8982d496..616ce76f7b 100644 --- a/TutorialsReworked/seL4Kernel/overview.md +++ b/TutorialsReworked/seL4Kernel/overview.md @@ -23,15 +23,10 @@ architecture. Suggested resources for these include: - [Instruction Set Architecture (wikipedia)](https://en.wikipedia.org/wiki/Instruction_set_architecture)

      Resources

      -We recommend having access to the seL4 manual and the API references. +We recommend having access to the seL4 manual and the API references. +The How to page provides links to tutorial solutions as quick references for seL4 calls and methods. -

      Getting help

      -* [FAQ](https://docs.sel4.systems/FrequentlyAskedQuestions) -* [Debugging guide](https://docs.sel4.systems/DebuggingGuide.html) -* [seL4 Discourse forum](https://sel4.discourse.group) -* [Developer's mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) -* [Mattermost Channel](https://mattermost.trustworthy.systems/sel4-external/)

      Next tutorial: Setting up your machine diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index c1e33b6e3e..d805773d84 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -71,6 +71,7 @@

      {% endif %} From e293afc5cdd921448a4f0ad6da92241fd26076ed Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 15 Mar 2024 13:15:30 +1100 Subject: [PATCH 017/103] add more resources Signed-off-by: Birgit Brecknell --- TutorialsReworked/GettingStarted/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TutorialsReworked/GettingStarted/overview.md b/TutorialsReworked/GettingStarted/overview.md index 01368a657f..40aa091f8b 100644 --- a/TutorialsReworked/GettingStarted/overview.md +++ b/TutorialsReworked/GettingStarted/overview.md @@ -6,7 +6,7 @@ The tutorials are split into a number of broad categories: - [About seL4](about-seL4) and [Getting started with the Microkit tutorial](microkit) introduce seL4 concepts. - The [seL4 Kernel tutorials](../seL4Kernel/overview.md) are a deep dive into seL4 concepts. - [MCS](../MCS/mcs-extensions) introduces seL4 MCS extensions. -- [Dynamic Libraries](../DynamicLibraries/initialisation.md) covers the libraries found in `seL4_libs`. +- [Dynamic Libraries](../DynamicLibraries/initialisation.md) covers the libraries that have been developed for rapidly prototyping systems on seL4. - [CAmkES](../CAmkES/hello-camkes.md) is a platform for building componentised systems for embedded platforms. - [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](../GettingStarted/microkit) section.) - [Rust](https://github.com/seL4/rust-sel4) provide crates for supporting the use of Rust in seL4 userspace. From 84168b02428aa950c76a4d63c70997d1ba0bbf0d Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 15 Mar 2024 14:05:31 +1100 Subject: [PATCH 018/103] replace old tut files with new Signed-off-by: Birgit Brecknell --- .../camkes-vm-crossvm.md | 0 .../camkes-vm-linux.md | 0 {Tutorials => Tutorials-old}/capabilities.md | 0 {Tutorials => Tutorials-old}/dynamic-1.md | 0 {Tutorials => Tutorials-old}/dynamic-2.md | 0 {Tutorials => Tutorials-old}/dynamic-3.md | 0 {Tutorials => Tutorials-old}/dynamic-4.md | 0 .../fault-handlers.md | 0 .../hello-camkes-0.md | 0 .../hello-camkes-1.md | 0 .../hello-camkes-2.md | 0 .../hello-camkes-timer.md | 0 {Tutorials => Tutorials-old}/hello-world.md | 0 {Tutorials => Tutorials-old}/index.md | 0 {Tutorials => Tutorials-old}/interrupts.md | 0 {Tutorials => Tutorials-old}/ipc.md | 0 {Tutorials => Tutorials-old}/mapping.md | 0 {Tutorials => Tutorials-old}/mcs.md | 0 {Tutorials => Tutorials-old}/notifications.md | 0 {Tutorials => Tutorials-old}/threads.md | 0 {Tutorials => Tutorials-old}/untyped.md | 0 .../CAmkES/camkes-cross-vm.md | 0 .../CAmkES/camkes-vm.md | 0 .../CAmkES/camkes1.md | 0 .../CAmkES/camkes2.md | 0 .../CAmkES/camkes3.md | 0 .../CAmkES/hello-camkes.md | 0 .../DynamicLibraries/initialisation.md | 0 .../DynamicLibraries/ipc.md | 0 .../DynamicLibraries/processes.md | 0 .../DynamicLibraries/timer.md | 0 .../GettingStarted/about-seL4.md | 0 .../GettingStarted/microkit.md | 0 .../GettingStarted/overview.md | 0 .../MCS/mcs-extensions.md | 0 .../Resources/how-to.md | 0 .../seL4Kernel/capabilities.md | 2 +- .../seL4Kernel/faults.md | 0 .../seL4Kernel/hello-world.md | 0 .../seL4Kernel/interrupts.md | 0 .../seL4Kernel/ipc.md | 0 .../seL4Kernel/mapping.md | 2 +- .../seL4Kernel/notifications.md | 0 .../seL4Kernel/overview.md | 0 .../seL4Kernel/setting-up.md | 0 .../seL4Kernel/threads.md | 2 +- .../seL4Kernel/untyped.md | 2 +- _includes/nav-sidebar.html | 13 +--- index.md | 71 +++++++------------ 49 files changed, 32 insertions(+), 60 deletions(-) rename {Tutorials => Tutorials-old}/camkes-vm-crossvm.md (100%) rename {Tutorials => Tutorials-old}/camkes-vm-linux.md (100%) rename {Tutorials => Tutorials-old}/capabilities.md (100%) rename {Tutorials => Tutorials-old}/dynamic-1.md (100%) rename {Tutorials => Tutorials-old}/dynamic-2.md (100%) rename {Tutorials => Tutorials-old}/dynamic-3.md (100%) rename {Tutorials => Tutorials-old}/dynamic-4.md (100%) rename {Tutorials => Tutorials-old}/fault-handlers.md (100%) rename {Tutorials => Tutorials-old}/hello-camkes-0.md (100%) rename {Tutorials => Tutorials-old}/hello-camkes-1.md (100%) rename {Tutorials => Tutorials-old}/hello-camkes-2.md (100%) rename {Tutorials => Tutorials-old}/hello-camkes-timer.md (100%) rename {Tutorials => Tutorials-old}/hello-world.md (100%) rename {Tutorials => Tutorials-old}/index.md (100%) rename {Tutorials => Tutorials-old}/interrupts.md (100%) rename {Tutorials => Tutorials-old}/ipc.md (100%) rename {Tutorials => Tutorials-old}/mapping.md (100%) rename {Tutorials => Tutorials-old}/mcs.md (100%) rename {Tutorials => Tutorials-old}/notifications.md (100%) rename {Tutorials => Tutorials-old}/threads.md (100%) rename {Tutorials => Tutorials-old}/untyped.md (100%) rename {TutorialsReworked => Tutorials}/CAmkES/camkes-cross-vm.md (100%) rename {TutorialsReworked => Tutorials}/CAmkES/camkes-vm.md (100%) rename {TutorialsReworked => Tutorials}/CAmkES/camkes1.md (100%) rename {TutorialsReworked => Tutorials}/CAmkES/camkes2.md (100%) rename {TutorialsReworked => Tutorials}/CAmkES/camkes3.md (100%) rename {TutorialsReworked => Tutorials}/CAmkES/hello-camkes.md (100%) rename {TutorialsReworked => Tutorials}/DynamicLibraries/initialisation.md (100%) rename {TutorialsReworked => Tutorials}/DynamicLibraries/ipc.md (100%) rename {TutorialsReworked => Tutorials}/DynamicLibraries/processes.md (100%) rename {TutorialsReworked => Tutorials}/DynamicLibraries/timer.md (100%) rename {TutorialsReworked => Tutorials}/GettingStarted/about-seL4.md (100%) rename {TutorialsReworked => Tutorials}/GettingStarted/microkit.md (100%) rename {TutorialsReworked => Tutorials}/GettingStarted/overview.md (100%) rename {TutorialsReworked => Tutorials}/MCS/mcs-extensions.md (100%) rename {TutorialsReworked => Tutorials}/Resources/how-to.md (100%) rename {TutorialsReworked => Tutorials}/seL4Kernel/capabilities.md (99%) rename {TutorialsReworked => Tutorials}/seL4Kernel/faults.md (100%) rename {TutorialsReworked => Tutorials}/seL4Kernel/hello-world.md (100%) rename {TutorialsReworked => Tutorials}/seL4Kernel/interrupts.md (100%) rename {TutorialsReworked => Tutorials}/seL4Kernel/ipc.md (100%) rename {TutorialsReworked => Tutorials}/seL4Kernel/mapping.md (99%) rename {TutorialsReworked => Tutorials}/seL4Kernel/notifications.md (100%) rename {TutorialsReworked => Tutorials}/seL4Kernel/overview.md (100%) rename {TutorialsReworked => Tutorials}/seL4Kernel/setting-up.md (100%) rename {TutorialsReworked => Tutorials}/seL4Kernel/threads.md (99%) rename {TutorialsReworked => Tutorials}/seL4Kernel/untyped.md (99%) diff --git a/Tutorials/camkes-vm-crossvm.md b/Tutorials-old/camkes-vm-crossvm.md similarity index 100% rename from Tutorials/camkes-vm-crossvm.md rename to Tutorials-old/camkes-vm-crossvm.md diff --git a/Tutorials/camkes-vm-linux.md b/Tutorials-old/camkes-vm-linux.md similarity index 100% rename from Tutorials/camkes-vm-linux.md rename to Tutorials-old/camkes-vm-linux.md diff --git a/Tutorials/capabilities.md b/Tutorials-old/capabilities.md similarity index 100% rename from Tutorials/capabilities.md rename to Tutorials-old/capabilities.md diff --git a/Tutorials/dynamic-1.md b/Tutorials-old/dynamic-1.md similarity index 100% rename from Tutorials/dynamic-1.md rename to Tutorials-old/dynamic-1.md diff --git a/Tutorials/dynamic-2.md b/Tutorials-old/dynamic-2.md similarity index 100% rename from Tutorials/dynamic-2.md rename to Tutorials-old/dynamic-2.md diff --git a/Tutorials/dynamic-3.md b/Tutorials-old/dynamic-3.md similarity index 100% rename from Tutorials/dynamic-3.md rename to Tutorials-old/dynamic-3.md diff --git a/Tutorials/dynamic-4.md b/Tutorials-old/dynamic-4.md similarity index 100% rename from Tutorials/dynamic-4.md rename to Tutorials-old/dynamic-4.md diff --git a/Tutorials/fault-handlers.md b/Tutorials-old/fault-handlers.md similarity index 100% rename from Tutorials/fault-handlers.md rename to Tutorials-old/fault-handlers.md diff --git a/Tutorials/hello-camkes-0.md b/Tutorials-old/hello-camkes-0.md similarity index 100% rename from Tutorials/hello-camkes-0.md rename to Tutorials-old/hello-camkes-0.md diff --git a/Tutorials/hello-camkes-1.md b/Tutorials-old/hello-camkes-1.md similarity index 100% rename from Tutorials/hello-camkes-1.md rename to Tutorials-old/hello-camkes-1.md diff --git a/Tutorials/hello-camkes-2.md b/Tutorials-old/hello-camkes-2.md similarity index 100% rename from Tutorials/hello-camkes-2.md rename to Tutorials-old/hello-camkes-2.md diff --git a/Tutorials/hello-camkes-timer.md b/Tutorials-old/hello-camkes-timer.md similarity index 100% rename from Tutorials/hello-camkes-timer.md rename to Tutorials-old/hello-camkes-timer.md diff --git a/Tutorials/hello-world.md b/Tutorials-old/hello-world.md similarity index 100% rename from Tutorials/hello-world.md rename to Tutorials-old/hello-world.md diff --git a/Tutorials/index.md b/Tutorials-old/index.md similarity index 100% rename from Tutorials/index.md rename to Tutorials-old/index.md diff --git a/Tutorials/interrupts.md b/Tutorials-old/interrupts.md similarity index 100% rename from Tutorials/interrupts.md rename to Tutorials-old/interrupts.md diff --git a/Tutorials/ipc.md b/Tutorials-old/ipc.md similarity index 100% rename from Tutorials/ipc.md rename to Tutorials-old/ipc.md diff --git a/Tutorials/mapping.md b/Tutorials-old/mapping.md similarity index 100% rename from Tutorials/mapping.md rename to Tutorials-old/mapping.md diff --git a/Tutorials/mcs.md b/Tutorials-old/mcs.md similarity index 100% rename from Tutorials/mcs.md rename to Tutorials-old/mcs.md diff --git a/Tutorials/notifications.md b/Tutorials-old/notifications.md similarity index 100% rename from Tutorials/notifications.md rename to Tutorials-old/notifications.md diff --git a/Tutorials/threads.md b/Tutorials-old/threads.md similarity index 100% rename from Tutorials/threads.md rename to Tutorials-old/threads.md diff --git a/Tutorials/untyped.md b/Tutorials-old/untyped.md similarity index 100% rename from Tutorials/untyped.md rename to Tutorials-old/untyped.md diff --git a/TutorialsReworked/CAmkES/camkes-cross-vm.md b/Tutorials/CAmkES/camkes-cross-vm.md similarity index 100% rename from TutorialsReworked/CAmkES/camkes-cross-vm.md rename to Tutorials/CAmkES/camkes-cross-vm.md diff --git a/TutorialsReworked/CAmkES/camkes-vm.md b/Tutorials/CAmkES/camkes-vm.md similarity index 100% rename from TutorialsReworked/CAmkES/camkes-vm.md rename to Tutorials/CAmkES/camkes-vm.md diff --git a/TutorialsReworked/CAmkES/camkes1.md b/Tutorials/CAmkES/camkes1.md similarity index 100% rename from TutorialsReworked/CAmkES/camkes1.md rename to Tutorials/CAmkES/camkes1.md diff --git a/TutorialsReworked/CAmkES/camkes2.md b/Tutorials/CAmkES/camkes2.md similarity index 100% rename from TutorialsReworked/CAmkES/camkes2.md rename to Tutorials/CAmkES/camkes2.md diff --git a/TutorialsReworked/CAmkES/camkes3.md b/Tutorials/CAmkES/camkes3.md similarity index 100% rename from TutorialsReworked/CAmkES/camkes3.md rename to Tutorials/CAmkES/camkes3.md diff --git a/TutorialsReworked/CAmkES/hello-camkes.md b/Tutorials/CAmkES/hello-camkes.md similarity index 100% rename from TutorialsReworked/CAmkES/hello-camkes.md rename to Tutorials/CAmkES/hello-camkes.md diff --git a/TutorialsReworked/DynamicLibraries/initialisation.md b/Tutorials/DynamicLibraries/initialisation.md similarity index 100% rename from TutorialsReworked/DynamicLibraries/initialisation.md rename to Tutorials/DynamicLibraries/initialisation.md diff --git a/TutorialsReworked/DynamicLibraries/ipc.md b/Tutorials/DynamicLibraries/ipc.md similarity index 100% rename from TutorialsReworked/DynamicLibraries/ipc.md rename to Tutorials/DynamicLibraries/ipc.md diff --git a/TutorialsReworked/DynamicLibraries/processes.md b/Tutorials/DynamicLibraries/processes.md similarity index 100% rename from TutorialsReworked/DynamicLibraries/processes.md rename to Tutorials/DynamicLibraries/processes.md diff --git a/TutorialsReworked/DynamicLibraries/timer.md b/Tutorials/DynamicLibraries/timer.md similarity index 100% rename from TutorialsReworked/DynamicLibraries/timer.md rename to Tutorials/DynamicLibraries/timer.md diff --git a/TutorialsReworked/GettingStarted/about-seL4.md b/Tutorials/GettingStarted/about-seL4.md similarity index 100% rename from TutorialsReworked/GettingStarted/about-seL4.md rename to Tutorials/GettingStarted/about-seL4.md diff --git a/TutorialsReworked/GettingStarted/microkit.md b/Tutorials/GettingStarted/microkit.md similarity index 100% rename from TutorialsReworked/GettingStarted/microkit.md rename to Tutorials/GettingStarted/microkit.md diff --git a/TutorialsReworked/GettingStarted/overview.md b/Tutorials/GettingStarted/overview.md similarity index 100% rename from TutorialsReworked/GettingStarted/overview.md rename to Tutorials/GettingStarted/overview.md diff --git a/TutorialsReworked/MCS/mcs-extensions.md b/Tutorials/MCS/mcs-extensions.md similarity index 100% rename from TutorialsReworked/MCS/mcs-extensions.md rename to Tutorials/MCS/mcs-extensions.md diff --git a/TutorialsReworked/Resources/how-to.md b/Tutorials/Resources/how-to.md similarity index 100% rename from TutorialsReworked/Resources/how-to.md rename to Tutorials/Resources/how-to.md diff --git a/TutorialsReworked/seL4Kernel/capabilities.md b/Tutorials/seL4Kernel/capabilities.md similarity index 99% rename from TutorialsReworked/seL4Kernel/capabilities.md rename to Tutorials/seL4Kernel/capabilities.md index c4bb661f95..25d30b45c2 100644 --- a/TutorialsReworked/seL4Kernel/capabilities.md +++ b/Tutorials/seL4Kernel/capabilities.md @@ -17,7 +17,7 @@ You will learn: ## Initialising ```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/TutorialsReworked/seL4Kernel/setting-ip#get-the-code +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/seL4Kernel/setting-ip#get-the-code # # Follow these instructions to initialise the tutorial # initialising the build directory with a tutorial exercise diff --git a/TutorialsReworked/seL4Kernel/faults.md b/Tutorials/seL4Kernel/faults.md similarity index 100% rename from TutorialsReworked/seL4Kernel/faults.md rename to Tutorials/seL4Kernel/faults.md diff --git a/TutorialsReworked/seL4Kernel/hello-world.md b/Tutorials/seL4Kernel/hello-world.md similarity index 100% rename from TutorialsReworked/seL4Kernel/hello-world.md rename to Tutorials/seL4Kernel/hello-world.md diff --git a/TutorialsReworked/seL4Kernel/interrupts.md b/Tutorials/seL4Kernel/interrupts.md similarity index 100% rename from TutorialsReworked/seL4Kernel/interrupts.md rename to Tutorials/seL4Kernel/interrupts.md diff --git a/TutorialsReworked/seL4Kernel/ipc.md b/Tutorials/seL4Kernel/ipc.md similarity index 100% rename from TutorialsReworked/seL4Kernel/ipc.md rename to Tutorials/seL4Kernel/ipc.md diff --git a/TutorialsReworked/seL4Kernel/mapping.md b/Tutorials/seL4Kernel/mapping.md similarity index 99% rename from TutorialsReworked/seL4Kernel/mapping.md rename to Tutorials/seL4Kernel/mapping.md index 68802d07a3..7c37a17376 100644 --- a/TutorialsReworked/seL4Kernel/mapping.md +++ b/Tutorials/seL4Kernel/mapping.md @@ -15,7 +15,7 @@ By the end of this tutorial, you should be familiar with: ## Initialising ```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/TutorialsReworked/seL4Kernel/setting-ip#get-the-code +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/seL4Kernel/setting-ip#get-the-code # # Follow these instructions to initialise the tutorial # initialising the build directory with a tutorial exercise diff --git a/TutorialsReworked/seL4Kernel/notifications.md b/Tutorials/seL4Kernel/notifications.md similarity index 100% rename from TutorialsReworked/seL4Kernel/notifications.md rename to Tutorials/seL4Kernel/notifications.md diff --git a/TutorialsReworked/seL4Kernel/overview.md b/Tutorials/seL4Kernel/overview.md similarity index 100% rename from TutorialsReworked/seL4Kernel/overview.md rename to Tutorials/seL4Kernel/overview.md diff --git a/TutorialsReworked/seL4Kernel/setting-up.md b/Tutorials/seL4Kernel/setting-up.md similarity index 100% rename from TutorialsReworked/seL4Kernel/setting-up.md rename to Tutorials/seL4Kernel/setting-up.md diff --git a/TutorialsReworked/seL4Kernel/threads.md b/Tutorials/seL4Kernel/threads.md similarity index 99% rename from TutorialsReworked/seL4Kernel/threads.md rename to Tutorials/seL4Kernel/threads.md index ecdfe92e6f..5014a728b5 100644 --- a/TutorialsReworked/seL4Kernel/threads.md +++ b/Tutorials/seL4Kernel/threads.md @@ -19,7 +19,7 @@ In this tutorial, you will ## Initialising ```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/TutorialsReworked/seL4Kernel/setting-ip#get-the-code +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/seL4Kernel/setting-ip#get-the-code # # Follow these instructions to initialise the tutorial # initialising the build directory with a tutorial exercise diff --git a/TutorialsReworked/seL4Kernel/untyped.md b/Tutorials/seL4Kernel/untyped.md similarity index 99% rename from TutorialsReworked/seL4Kernel/untyped.md rename to Tutorials/seL4Kernel/untyped.md index 5ae254d22b..d2fd36ba9c 100644 --- a/TutorialsReworked/seL4Kernel/untyped.md +++ b/Tutorials/seL4Kernel/untyped.md @@ -16,7 +16,7 @@ By the end of this tutorial, you should be familiar with: ## Initialising ```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/TutorialsReworked/seL4Kernel/setting-ip#get-the-code +# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/seL4Kernel/setting-ip#get-the-code # # Follow these instructions to initialise the tutorial # initialising the build directory with a tutorial exercise diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index c8abcbbff6..8f2bfa6668 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -56,18 +56,6 @@ {% if page_url[1] == "Tutorials" %} - -{% endif %} - - -{% if page_url[1] == "TutorialsReworked" %} {% endif %} + \ No newline at end of file diff --git a/index.md b/index.md index 21d7f6fb75..abdf829913 100644 --- a/index.md +++ b/index.md @@ -46,7 +46,6 @@ This documentation site is for cooperatively developing and sharing documentatio

      Projects

      List and details of all the projects that make up the seL4 platform.

      -
      • seL4 kernel
      • L4.verified
      • @@ -60,64 +59,48 @@ This documentation site is for cooperatively developing and sharing documentatio
      -

      Tutorials

      -

      Tutorials and other material to learn about seL4.

      - - -
      - - - - From c9aaf6210f0bb9c555df66282a670c944515f4a1 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 15 Mar 2024 14:35:49 +1100 Subject: [PATCH 019/103] change Getting Started to Working with seL4 Signed-off-by: Birgit Brecknell --- Hardware/HiKey/index.md | 12 ++++++------ Hardware/VMware/index.md | 4 ++-- Hardware/jetsontk1.md | 6 +++--- SuggestedProjects.md | 2 +- Tutorials/{GettingStarted/overview.md => index.md} | 0 GettingStarted.md => Working-with-seL4.md | 4 ++-- _data/sidebar.yml | 8 ++++---- _includes/header.html | 4 ++-- index.md | 6 +++--- projects/buildsystem/index.md | 4 ++-- projects/sel4/documentation.md | 2 +- projects/sel4/frequently-asked-questions.md | 2 +- 12 files changed, 27 insertions(+), 27 deletions(-) rename Tutorials/{GettingStarted/overview.md => index.md} (100%) rename GettingStarted.md => Working-with-seL4.md (98%) diff --git a/Hardware/HiKey/index.md b/Hardware/HiKey/index.md index 2b74590f93..1317f9cf2f 100644 --- a/Hardware/HiKey/index.md +++ b/Hardware/HiKey/index.md @@ -23,7 +23,7 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. - One HiKey Board. See [Hikey 96Board](http://www.96boards.org/products/ce/hikey/) - Fully working development environment. See - [Getting started](/GettingStarted) + [Working with seL4](/Working-with-seL4) ### Getting Started The Hikey board is based around the @@ -87,12 +87,12 @@ gedit LinaroPkg/platforms.config BUILDFLAGS=-DSERIAL_BASE=0xF8015000 ATF_BUILDFLAGS=CONSOLE_BASE=PL011_UART0_BASE CRASH_CONSOLE_BASE=PL011_UART0_BASE ``` -## 5. Patching the UEFI for the Hikey +## 5. Patching the UEFI for the Hikey Obtain the patch from [edk2.patch](edk2.patch) and follow the below steps. ```bash -cd linaro-edk2 -patch -p1 < ~/Downloads/edk2.patch +cd linaro-edk2 +patch -p1 < ~/Downloads/edk2.patch # Then return to the main directory hikey-flash ``` @@ -206,8 +206,8 @@ sudo minicom -s 7. Three terminals are then required for the following commands ```bash -# In the first terminal -ls +# In the first terminal +ls # Note the next ttyUSBY that is observed, in addition to the current ttyUSBX # In the third terminal diff --git a/Hardware/VMware/index.md b/Hardware/VMware/index.md index 5ce4187429..23ac8866c7 100644 --- a/Hardware/VMware/index.md +++ b/Hardware/VMware/index.md @@ -14,7 +14,7 @@ and for a Linux host machine. May work on Mac host machine, won't work for Windows host (although general idea should be similar). This guide assumes that your project is all set up and configured to -build for x86. Read [Getting started](/GettingStarted) otherwise. +build for x86. Read [Working with seL4](/Working-with-seL4) otherwise. ## Setting up a VM @@ -55,7 +55,7 @@ There are three options for the serial port set up). You'll want to apt-get install socat and then run something like: ```bash -#!/bin/bash +#!/bin/bash while true; do socat -d -d UNIX-CONNECT:/tmp/vsock,forever PTY:link=/dev/tty99 done diff --git a/Hardware/jetsontk1.md b/Hardware/jetsontk1.md index 5f7d1e981f..c3cb126aed 100644 --- a/Hardware/jetsontk1.md +++ b/Hardware/jetsontk1.md @@ -20,10 +20,10 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. The [Jetson TK1](http://www.nvidia.com/object/jetson-tk1-embedded-dev-kit.html) is a affordable embedded system developed by NVIDIA. It runs seL4. We will explain how to run seL4 on the Tegra. - + ### Pre-Requisites * One Tegra Board. See [Jetson TK1](http://www.nvidia.com/object/jetson-tk1-embedded-dev-kit.html) -* The development environment fully working. See [Getting started](/GettingStarted) +* The development environment fully working. See [Working with seL4](/Working-with-seL4) ## Getting Started To get started, check out the @@ -94,7 +94,7 @@ to boot in nonsecure (HYP) mode. This also enables kvm if you boot Linux. To go back to secure mode booting do -``` +``` setenv bootm_boot_mode sec saveenv ``` diff --git a/SuggestedProjects.md b/SuggestedProjects.md index f043015288..8e253983da 100644 --- a/SuggestedProjects.md +++ b/SuggestedProjects.md @@ -6,7 +6,7 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. # Suggested Projects -After trying the existing projects (especially those listed on [Getting started](GettingStarted)) +After trying the existing projects (e.g. the [Tutorials](Tutorials)) a good way to learn the intricacies of programming on top of seL4 is to do the exercises in the [UNSW Advanced diff --git a/Tutorials/GettingStarted/overview.md b/Tutorials/index.md similarity index 100% rename from Tutorials/GettingStarted/overview.md rename to Tutorials/index.md diff --git a/GettingStarted.md b/Working-with-seL4.md similarity index 98% rename from GettingStarted.md rename to Working-with-seL4.md index 19b46c9e9e..e1ba843ba2 100644 --- a/GettingStarted.md +++ b/Working-with-seL4.md @@ -5,9 +5,9 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -# Getting Started +# Working with seL4 -This page is a quick start for working with seL4 and its ecosystem. +This page provides an overview on working with seL4 and its ecosystem. ## Background and terminology diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 398790862c..d7c287b8a9 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -2,11 +2,11 @@ # Copyright 2020 seL4 Project a Series of LF Projects, LLC. toc: - - title: Getting Started - url: /GettingStarted.html + - title: Working with seL4 + url: /Working-with-seL4.html subfolderitems: - - page: Getting Started - url: /GettingStarted.html + - page: Working with seL4 + url: /Working-with-seL4.html - page: seL4 Documentation url: /projects/sel4/documentation.html - page: seL4 FAQ diff --git a/_includes/header.html b/_includes/header.html index 7ad4305701..be14b39a87 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -16,10 +16,10 @@ diff --git a/index.md b/index.md index abdf829913..586fc509b2 100644 --- a/index.md +++ b/index.md @@ -14,16 +14,16 @@ This documentation site is for cooperatively developing and sharing documentatio
      -

      Getting started

      +

      Working with seL4

      Information about working with seL4 and its ecosystem

      diff --git a/projects/buildsystem/index.md b/projects/buildsystem/index.md index 5423b99bd5..5d669d2bc7 100644 --- a/projects/buildsystem/index.md +++ b/projects/buildsystem/index.md @@ -35,9 +35,9 @@ the actual build. It is assumed that * CMake of an appropriate version is installed - * You are using the Ninja CMake generator + * You are using the Ninja CMake generator * You understand how to checkout projects using the repo tool as described on the - [Getting started](/GettingStarted) page + [Working with seL4](/Working-with-seL4) page * You have the [required dependencies](/HostDependencies) installed to build your project. diff --git a/projects/sel4/documentation.md b/projects/sel4/documentation.md index 8e9c22e610..f01ee8227d 100644 --- a/projects/sel4/documentation.md +++ b/projects/sel4/documentation.md @@ -11,7 +11,7 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. - [Technical overview paper](https://trustworthy.systems/publications/nictaabstracts/Klein_AEMSKH_14.abstract) - [L4 Microkernels: The Lessons from 20 Years of Research and Deployment](https://trustworthy.systems/publications/nictaabstracts/Heiser_Elphinstone_16.abstract), a retrospective explaining how we got to where we are; -- [Getting started](/GettingStarted) +- [Working with seL4](/Working-with-seL4) - [Trustworthy Systems seL4 research project pages](https://trustworthy.systems/projects/seL4/) - [UNSW Advanced OS lecture slides](https://www.cse.unsw.edu.au/~cs9242/14/lectures/), especialy the Introduction and diff --git a/projects/sel4/frequently-asked-questions.md b/projects/sel4/frequently-asked-questions.md index fab555f597..24956a7c42 100644 --- a/projects/sel4/frequently-asked-questions.md +++ b/projects/sel4/frequently-asked-questions.md @@ -627,7 +627,7 @@ There are two recommended ways to do this. processes, but is generally more low-level. For build instructions, and how to get started, see the -[Getting started](/GettingStarted) page. +[Working with seL4](/Working-with-seL4) page. Also, UNSW's [Advanced Operating Systems course](https://www.cse.unsw.edu.au/~cs9242) has an extensive project component that builds an OS on top of seL4. If you have access to an [Odroid-C2](https://www.hardkernel.com/shop/odroid-c2/), you should be able to do the project work yourself as a way of From 442aacb1e540a65b00dbe9127527615ff0ae42d4 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 15 Mar 2024 15:12:23 +1100 Subject: [PATCH 020/103] work on redirect for tutorial landing page Signed-off-by: Birgit Brecknell --- Tutorials/GettingStarted/overview.md | 23 +++++++++++++++++++++ Tutorials/index.md | 30 +++++++--------------------- _includes/nav-sidebar.html | 1 - index.md | 3 +-- 4 files changed, 31 insertions(+), 26 deletions(-) create mode 100644 Tutorials/GettingStarted/overview.md diff --git a/Tutorials/GettingStarted/overview.md b/Tutorials/GettingStarted/overview.md new file mode 100644 index 0000000000..40aa091f8b --- /dev/null +++ b/Tutorials/GettingStarted/overview.md @@ -0,0 +1,23 @@ +We have developed a series of tutorials to introduce seL4 and +developing systems on seL4. + +The tutorials are split into a number of broad categories: + +- [About seL4](about-seL4) and [Getting started with the Microkit tutorial](microkit) introduce seL4 concepts. +- The [seL4 Kernel tutorials](../seL4Kernel/overview.md) are a deep dive into seL4 concepts. +- [MCS](../MCS/mcs-extensions) introduces seL4 MCS extensions. +- [Dynamic Libraries](../DynamicLibraries/initialisation.md) covers the libraries that have been developed for rapidly prototyping systems on seL4. +- [CAmkES](../CAmkES/hello-camkes.md) is a platform for building componentised systems for embedded platforms. +- [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](../GettingStarted/microkit) section.) +- [Rust](https://github.com/seL4/rust-sel4) provide crates for supporting the use of Rust in seL4 userspace. + +

      Resources

      +Additional resources to assist with learning: +- The [seL4 manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf) +- [API references](../../projects/sel4/api-doc) +- The [How to](../Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. +- [FAQs](../../projects/sel4/frequently-asked-questions) +- [Debugging guide](../../projects/sel4-tutorials/debugging-guide) +- [Discourse forum](https://sel4.discourse.group/) +- [Developer mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) +- [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/channels/web-doc-revamp) diff --git a/Tutorials/index.md b/Tutorials/index.md index 40aa091f8b..c64a317ef7 100644 --- a/Tutorials/index.md +++ b/Tutorials/index.md @@ -1,23 +1,7 @@ -We have developed a series of tutorials to introduce seL4 and -developing systems on seL4. - -The tutorials are split into a number of broad categories: - -- [About seL4](about-seL4) and [Getting started with the Microkit tutorial](microkit) introduce seL4 concepts. -- The [seL4 Kernel tutorials](../seL4Kernel/overview.md) are a deep dive into seL4 concepts. -- [MCS](../MCS/mcs-extensions) introduces seL4 MCS extensions. -- [Dynamic Libraries](../DynamicLibraries/initialisation.md) covers the libraries that have been developed for rapidly prototyping systems on seL4. -- [CAmkES](../CAmkES/hello-camkes.md) is a platform for building componentised systems for embedded platforms. -- [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](../GettingStarted/microkit) section.) -- [Rust](https://github.com/seL4/rust-sel4) provide crates for supporting the use of Rust in seL4 userspace. - -

      Resources

      -Additional resources to assist with learning: -- The [seL4 manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf) -- [API references](../../projects/sel4/api-doc) -- The [How to](../Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. -- [FAQs](../../projects/sel4/frequently-asked-questions) -- [Debugging guide](../../projects/sel4-tutorials/debugging-guide) -- [Discourse forum](https://sel4.discourse.group/) -- [Developer mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) -- [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/channels/web-doc-revamp) + +The redirect will only work once deployed. For testing click [here](/Tutorials/GettingStarted/overview.md) \ No newline at end of file diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index 8f2bfa6668..df9b2fa5cf 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -54,7 +54,6 @@
    {% endif %} - {% if page_url[1] == "Tutorials" %}
    -

    TutorialsOld

    -

    Tutorials

    +

    Tutorials

    Tutorials and other material to learn about seL4.

    • Getting started
    • From ce25b3f23aabcf4a9754ab6b3ffcc602528e4835 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 18 Mar 2024 11:09:04 +1100 Subject: [PATCH 021/103] organise front page, navbar and how-to page Signed-off-by: Birgit Brecknell --- Tutorials/GettingStarted/overview.md | 23 ---- Tutorials/Resources/how-to.md | 172 ++++++++++++++------------- Tutorials/index.md | 38 ++++-- _includes/nav-sidebar.html | 66 +++++----- index.md | 89 ++++---------- 5 files changed, 180 insertions(+), 208 deletions(-) delete mode 100644 Tutorials/GettingStarted/overview.md diff --git a/Tutorials/GettingStarted/overview.md b/Tutorials/GettingStarted/overview.md deleted file mode 100644 index 40aa091f8b..0000000000 --- a/Tutorials/GettingStarted/overview.md +++ /dev/null @@ -1,23 +0,0 @@ -We have developed a series of tutorials to introduce seL4 and -developing systems on seL4. - -The tutorials are split into a number of broad categories: - -- [About seL4](about-seL4) and [Getting started with the Microkit tutorial](microkit) introduce seL4 concepts. -- The [seL4 Kernel tutorials](../seL4Kernel/overview.md) are a deep dive into seL4 concepts. -- [MCS](../MCS/mcs-extensions) introduces seL4 MCS extensions. -- [Dynamic Libraries](../DynamicLibraries/initialisation.md) covers the libraries that have been developed for rapidly prototyping systems on seL4. -- [CAmkES](../CAmkES/hello-camkes.md) is a platform for building componentised systems for embedded platforms. -- [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](../GettingStarted/microkit) section.) -- [Rust](https://github.com/seL4/rust-sel4) provide crates for supporting the use of Rust in seL4 userspace. - -

      Resources

      -Additional resources to assist with learning: -- The [seL4 manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf) -- [API references](../../projects/sel4/api-doc) -- The [How to](../Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. -- [FAQs](../../projects/sel4/frequently-asked-questions) -- [Debugging guide](../../projects/sel4-tutorials/debugging-guide) -- [Discourse forum](https://sel4.discourse.group/) -- [Developer mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) -- [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/channels/web-doc-revamp) diff --git a/Tutorials/Resources/how-to.md b/Tutorials/Resources/how-to.md index bbeb2badd5..9975779210 100644 --- a/Tutorials/Resources/how-to.md +++ b/Tutorials/Resources/how-to.md @@ -69,88 +69,92 @@ seL4Kernel/ipc#use-capability-transfer-to-send-the-badged-capability) - [Use passive servers](../MCS/mcs-extensionspassive-servers) - [Configure fault endpoints](../MCS/mcs-extensionsconfiguring-a-fault-endpoint-on-the-mcs-kernel) -## Dynamic libraries - - [Initiliasation & threading](../DynamicLibraries/initialisation) - - [Obtain BootInfo](../DynamicLibraries/initialisation#obtain-bootinfo) - - [Initialise simple](../DynamicLibraries/initialisation#initialise-simple) - - [Use simple to print BootInfo](../DynamicLibraries/initialisation#use-simple-to-print-bootinfo) - - [Initialise an allocator](../DynamicLibraries/initialisation#initialise-an-allocator) - - [Obtain a generic allocation interface (vka)](../DynamicLibraries/initialisation#obtain-a-generic-allocation-interface-vka) - - [Find the CSpace root cap](../DynamicLibraries/initialisation#find-the-cspace-root-cap) - - [Find the VSpace root cap](../DynamicLibraries/initialisation#find-the-vspace-root-cap) - - [Allocate a TCB Object](../DynamicLibraries/initialisation#allocate-a-tcb-object) - - [Configure the new TCB](../DynamicLibraries/initialisation#configure-the-new-tcb) - - [Name the new TCB](../DynamicLibraries/initialisation#name-the-new-tcb) - - [Set the instruction pointer](../DynamicLibraries/initialisation#set-the-instruction-pointer) - - [Write the registers](../DynamicLibraries/initialisation#write-the-registers) - - [Start the new thread](../DynamicLibraries/initialisation#start-the-new-thread) - - [IPC](../DynamicLibraries/ipc) - - [Allocate an IPC buffer](../DynamicLibraries/ipc#allocate-an-ipc-buffer) - - [Allocate a page table](../DynamicLibraries/ipc#allocate-a-page-table) - - [Map a page table](../DynamicLibraries/ipc#map-a-page-table) - - [Map a page](../DynamicLibraries/ipc#map-a-page) - - [Allocate an endpoint](../DynamicLibraries/ipc#allocate-an-endpoint) - - [Badge an endpoint](../DynamicLibraries/ipc#badge-an-endpoint) - - [Set a message register](../DynamicLibraries/ipc#message-registers) - - [Send and wait for a reply](../DynamicLibraries/ipc#ipc) - - [Receive a reply](../DynamicLibraries/ipc#receive-a-reply) - - [Receive an IPC](../DynamicLibraries/ipc#receive-an-ipc) - - [Validate a message](../DynamicLibraries/ipc#validate-the-message) - - [Write the message registers](../DynamicLibraries/ipc#write-the-message-registers) - - [Reply to a message](../DynamicLibraries/ipc#reply-to-a-message) -- [Processes & Elf loading](../DynamicLibraries/processes) - - [Create a VSpace object](../DynamicLibraries/processes#virtual-memory-management) - - [Configure a process](../DynamicLibraries/processes#configure-a-process) - - [Get a cspacepath](../DynamicLibraries/processes#get-a-cspacepath) - - [Badge a capability](../DynamicLibraries/processes#badge-a-capability) - - [Spawn a process](../DynamicLibraries/processes#spawn-a-process) - - [Receive a message](../DynamicLibraries/processes#receive-a-message) - - [Send a reply](../DynamicLibraries/processes#send-a-reply) - - [Initiate communications by using seL4_Call](../DynamicLibraries/processes#client-call) - - [Timer](../DynamicLibraries/timer) - - [Allocate a notification object](../DynamicLibraries/timer#allocate-a-notification-object) - - [Initialise a timer](../DynamicLibraries/timer#initialise-the-timer) - - [Use a timer](../DynamicLibraries/timer#use-the-timer) - - [Handle an interrupt](../DynamicLibraries/timer#handle-the-interrupt) - - [Destroy a timer](../DynamicLibraries/timer#destroy-the-timer) - - ## [CAmkES](../CAmkES/) - - [A basic CAmkES application](../CAmkES/camkes1) - - [Define instance in the composition section of the ADL](../CAmkES/camkes1#define-instance-in-the-composition-section-of-the-adl) - - [Add a connection](../CAmkES/camkes1#add-a-connection) - - [Define an interface](../CAmkES/camkes1#define-an-interface) - - [Implement a RPC function](../CAmkES/camkes1#implement-a-rpc-function) - - [Invoke a RPC function](../CAmkES/camkes1#invoke-a-rpc-function) - - [Events in CAmkES](../CAmkES/camkes2) - - [Specify an events interface](../CAmkES/camkes2#specify-an-events-interface) - - [Wait for data to become available](../CAmkES/camkes2#wait-for-data-to-become-available) - - [Signal that data is available](../CAmkES/camkes2#signal-that-data-is-available) - - [Register a callback handler](../CAmkES/camkes2#register-a-callback-handler) - - [Specify dataport interfaces](../CAmkES/camkes2#specify-an-events-interface) - - [Specify dataport connections](../CAmkES/camkes2#specify-dataport-connections) - - [Copy strings to an untyped dataport](../CAmkES/camkes2#copy-strings-to-an-untyped-dataport) - - [Read the reply data from a typed dataport](../CAmkES/camkes2#read-the-reply-data-from-a-typed-dataport) - - [Send data using dataports](../CAmkES/camkes2#send-data-using-dataports) - - [Read data from an untyped dataport](../CAmkES/camkes2#read-data-from-an-untyped-dataport) - - [Put data into a typed dataport](../CAmkES/camkes2#put-data-into-a-typed-dataport) - - [Read data from a typed dataport](../CAmkES/camkes2#read-data-from-a-typed-dataport) - - [Set component priorities](../CAmkES/camkes2#set-component-priorities) - - [Restrict access to dataports](../CAmkES/camkes2#restrict-access-to-dataports) - - [Test the read and write permissions on the dataport](../CAmkES/camkes2#test-the-read-and-write-permissions-on-the-dataport) - - [CAmkES Timer](../CAmkES/camkes) - - [Instantiate a Timer and Timerbase](../CAmkES/camkes3#task-1) - - [Connect a timer driver component](../CAmkES/camkes3#task-2) - - [Configure a timer hardware component instance](../CAmkES/camkes3#task-3) - - [Call into a supplied driver to handle the interrupt](../CAmkES/camkes3#task-4) - - [Stop a timer](../CAmkES/camkes3#task-5) - - [Acknowledge an interrupt](../CAmkES/camkes3#task-6) - - [Get a timer handler](../CAmkES/camkes3#task-7) - - [Start a timer](../CAmkES/camkes3#task-8) - - [Implement a RPC interface](../CAmkES/camkes3#task-9) - - [Set a timer interrupt](../CAmkES/camkes3#task-10) - - [Instantiate a TimerDTB component](../CAmkES/camkes3#task-1-1) - - [Connect interfaces using the seL4DTBHardware connector](../CAmkES/camkes3#task-2-1) - - [Configure the `TimerDTB` component](../CAmkES/camkes3#task-3-1) - - -(../CAmkES/camkes3 -(../CAmkES/camkes3 +## [Dynamic libraries](../DynamicLibraries/initialisation) +### [Initiliasation & threading](../DynamicLibraries/initialisation) + - [Obtain BootInfo](../DynamicLibraries/initialisation#obtain-bootinfo) + - [Initialise simple](../DynamicLibraries/initialisation#initialise-simple) + - [Use simple to print BootInfo](../DynamicLibraries/initialisation#use-simple-to-print-bootinfo) + - [Initialise an allocator](../DynamicLibraries/initialisation#initialise-an-allocator) + - [Obtain a generic allocation interface (vka)](../DynamicLibraries/initialisation#obtain-a-generic-allocation-interface-vka) + - [Find the CSpace root cap](../DynamicLibraries/initialisation#find-the-cspace-root-cap) + - [Find the VSpace root cap](../DynamicLibraries/initialisation#find-the-vspace-root-cap) + - [Allocate a TCB Object](../DynamicLibraries/initialisation#allocate-a-tcb-object) + - [Configure the new TCB](../DynamicLibraries/initialisation#configure-the-new-tcb) + - [Name the new TCB](../DynamicLibraries/initialisation#name-the-new-tcb) + - [Set the instruction pointer](../DynamicLibraries/initialisation#set-the-instruction-pointer) + - [Write the registers](../DynamicLibraries/initialisation#write-the-registers) + - [Start the new thread](../DynamicLibraries/initialisation#start-the-new-thread) + +### [IPC](../DynamicLibraries/ipc) + - [Allocate an IPC buffer](../DynamicLibraries/ipc#allocate-an-ipc-buffer) + - [Allocate a page table](../DynamicLibraries/ipc#allocate-a-page-table) + - [Map a page table](../DynamicLibraries/ipc#map-a-page-table) + - [Map a page](../DynamicLibraries/ipc#map-a-page) + - [Allocate an endpoint](../DynamicLibraries/ipc#allocate-an-endpoint) + - [Badge an endpoint](../DynamicLibraries/ipc#badge-an-endpoint) + - [Set a message register](../DynamicLibraries/ipc#message-registers) + - [Send and wait for a reply](../DynamicLibraries/ipc#ipc) + - [Receive a reply](../DynamicLibraries/ipc#receive-a-reply) + - [Receive an IPC](../DynamicLibraries/ipc#receive-an-ipc) + - [Validate a message](../DynamicLibraries/ipc#validate-the-message) + - [Write the message registers](../DynamicLibraries/ipc#write-the-message-registers) + - [Reply to a message](../DynamicLibraries/ipc#reply-to-a-message) + +### [Processes & Elf loading](../DynamicLibraries/processes) + - [Create a VSpace object](../DynamicLibraries/processes#virtual-memory-management) + - [Configure a process](../DynamicLibraries/processes#configure-a-process) + - [Get a cspacepath](../DynamicLibraries/processes#get-a-cspacepath) + - [Badge a capability](../DynamicLibraries/processes#badge-a-capability) + - [Spawn a process](../DynamicLibraries/processes#spawn-a-process) + - [Receive a message](../DynamicLibraries/processes#receive-a-message) + - [Send a reply](../DynamicLibraries/processes#send-a-reply) + - [Initiate communications by using seL4_Call](../DynamicLibraries/processes#client-call) + +### [Timer](../DynamicLibraries/timer) + - [Allocate a notification object](../DynamicLibraries/timer#allocate-a-notification-object) + - [Initialise a timer](../DynamicLibraries/timer#initialise-the-timer) + - [Use a timer](../DynamicLibraries/timer#use-the-timer) + - [Handle an interrupt](../DynamicLibraries/timer#handle-the-interrupt) + - [Destroy a timer](../DynamicLibraries/timer#destroy-the-timer) + +## [CAmkES](../CAmkES/) + +### [A basic CAmkES application](../CAmkES/camkes1) + - [Define instance in the composition section of the ADL](../CAmkES/camkes1#define-instance-in-the-composition-section-of-the-adl) + - [Add a connection](../CAmkES/camkes1#add-a-connection) + - [Define an interface](../CAmkES/camkes1#define-an-interface) + - [Implement a RPC function](../CAmkES/camkes1#implement-a-rpc-function) + - [Invoke a RPC function](../CAmkES/camkes1#invoke-a-rpc-function) + +### [Events in CAmkES](../CAmkES/camkes2) + - [Specify an events interface](../CAmkES/camkes2#specify-an-events-interface) + - [Wait for data to become available](../CAmkES/camkes2#wait-for-data-to-become-available) + - [Signal that data is available](../CAmkES/camkes2#signal-that-data-is-available) + - [Register a callback handler](../CAmkES/camkes2#register-a-callback-handler) + - [Specify dataport interfaces](../CAmkES/camkes2#specify-an-events-interface) + - [Specify dataport connections](../CAmkES/camkes2#specify-dataport-connections) + - [Copy strings to an untyped dataport](../CAmkES/camkes2#copy-strings-to-an-untyped-dataport) + - [Read the reply data from a typed dataport](../CAmkES/camkes2#read-the-reply-data-from-a-typed-dataport) + - [Send data using dataports](../CAmkES/camkes2#send-data-using-dataports) + - [Read data from an untyped dataport](../CAmkES/camkes2#read-data-from-an-untyped-dataport) + - [Put data into a typed dataport](../CAmkES/camkes2#put-data-into-a-typed-dataport) + - [Read data from a typed dataport](../CAmkES/camkes2#read-data-from-a-typed-dataport) + - [Set component priorities](../CAmkES/camkes2#set-component-priorities) + - [Restrict access to dataports](../CAmkES/camkes2#restrict-access-to-dataports) + - [Test the read and write permissions on the dataport](../CAmkES/camkes2#test-the-read-and-write-permissions-on-the-dataport) + +### [CAmkES Timer](../CAmkES/camkes) + - [Instantiate a Timer and Timerbase](../CAmkES/camkes3#task-1) + - [Connect a timer driver component](../CAmkES/camkes3#task-2) + - [Configure a timer hardware component instance](../CAmkES/camkes3#task-3) + - [Call into a supplied driver to handle the interrupt](../CAmkES/camkes3#task-4) + - [Stop a timer](../CAmkES/camkes3#task-5) + - [Acknowledge an interrupt](../CAmkES/camkes3#task-6) + - [Get a timer handler](../CAmkES/camkes3#task-7) + - [Start a timer](../CAmkES/camkes3#task-8) + - [Implement a RPC interface](../CAmkES/camkes3#task-9) + - [Set a timer interrupt](../CAmkES/camkes3#task-10) + - [Instantiate a TimerDTB component](../CAmkES/camkes3#task-1-1) + - [Connect interfaces using the seL4DTBHardware connector](../CAmkES/camkes3#task-2-1) + - [Configure the TimerDTB component](../CAmkES/camkes3#task-3-1) diff --git a/Tutorials/index.md b/Tutorials/index.md index c64a317ef7..b4acbc43e3 100644 --- a/Tutorials/index.md +++ b/Tutorials/index.md @@ -1,7 +1,31 @@ - -The redirect will only work once deployed. For testing click [here](/Tutorials/GettingStarted/overview.md) \ No newline at end of file +--- +toc: true +layout: project +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +# Tutorials about seL4 + +We have developed a series of tutorials to introduce seL4 and +developing systems on seL4. + +The tutorials are split into a number of broad categories: + +- [About seL4](about-seL4) and [Getting started with the Microkit tutorial](microkit) introduce seL4 concepts. +- The [seL4 Kernel tutorials](../seL4Kernel/overview.md) are a deep dive into seL4 concepts. +- [MCS](../MCS/mcs-extensions) introduces seL4 MCS extensions. +- [Dynamic Libraries](../DynamicLibraries/initialisation.md) covers the libraries that have been developed for rapidly prototyping systems on seL4. +- [CAmkES](../CAmkES/hello-camkes.md) is a platform for building componentised systems for embedded platforms. +- [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](../GettingStarted/microkit) section.) +- [Rust](https://github.com/seL4/rust-sel4) provide crates for supporting the use of Rust in seL4 userspace. + +

      Resources

      +Additional resources to assist with learning: +- The [seL4 manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf) +- [API references](../../projects/sel4/api-doc) +- The [How to](../Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. +- [FAQs](../../projects/sel4/frequently-asked-questions) +- [Debugging guide](../../projects/sel4-tutorials/debugging-guide) +- [Discourse forum](https://sel4.discourse.group/) +- [Developer mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) +- [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/channels/web-doc-revamp) diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index df9b2fa5cf..f3942a2f87 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -55,55 +55,63 @@ {% endif %} {% if page_url[1] == "Tutorials" %} + {% if page_url[2] contains "" %} + {% assign url = "../" %} + {% endif %}
    - -
    -

    Projects

    -

    List and details of all the projects that make up the seL4 platform.

    - -
    +

    Projects

    +

    List and details of all the projects that make up the seL4 platform.

    + +
    + +
    +
    +

    How to: A quick solutions guide

    +

    Links to tutorial solutions as quick references for seL4 calls and methods.

    +
    + +
    \ No newline at end of file From dae73c84edaf2e5e35b625daaeac971b42a95f27 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 18 Mar 2024 11:31:44 +1100 Subject: [PATCH 022/103] fix trailing whitespace Signed-off-by: Birgit Brecknell --- Tutorials/CAmkES/camkes-cross-vm.md | 3 +-- Tutorials/CAmkES/camkes1.md | 3 +-- index.md | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Tutorials/CAmkES/camkes-cross-vm.md b/Tutorials/CAmkES/camkes-cross-vm.md index 59d7cdc796..2aa11d174e 100644 --- a/Tutorials/CAmkES/camkes-cross-vm.md +++ b/Tutorials/CAmkES/camkes-cross-vm.md @@ -500,5 +500,4 @@ Password: [ 12.730073] dataport received mmap for minor 1 hello world -``` - +``` \ No newline at end of file diff --git a/Tutorials/CAmkES/camkes1.md b/Tutorials/CAmkES/camkes1.md index 36fb900279..5a2e25683b 100644 --- a/Tutorials/CAmkES/camkes1.md +++ b/Tutorials/CAmkES/camkes1.md @@ -283,5 +283,4 @@ Now build and run the project, if it compiles: Congratulations! Be sure to read structure of ADL: it's key to understanding CAmkES. And well done on writing your first CAmkES application. -Next tutorial: CAmkES 2: Events - +Next tutorial: CAmkES 2: Events \ No newline at end of file diff --git a/index.md b/index.md index 7d2e597cb0..4e8fde6999 100644 --- a/index.md +++ b/index.md @@ -60,7 +60,7 @@ This documentation site is for cooperatively developing and sharing documentatio

    Tutorials

    -

    Tutorials and other material to learn about seL4.

    +

    Tutorials and other material to learn about seL4.

    How to: A quick solutions guide

    From 4bfd6d98383348a8a499382fd55eb5b640bb14ec Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 22 Mar 2024 11:14:10 +1100 Subject: [PATCH 023/103] fix broken links Signed-off-by: Birgit Brecknell --- Tutorials/index.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Tutorials/index.md b/Tutorials/index.md index b4acbc43e3..2d9a5b22ee 100644 --- a/Tutorials/index.md +++ b/Tutorials/index.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: overview SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- @@ -9,23 +9,24 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. We have developed a series of tutorials to introduce seL4 and developing systems on seL4. +

    Categories

    The tutorials are split into a number of broad categories: -- [About seL4](about-seL4) and [Getting started with the Microkit tutorial](microkit) introduce seL4 concepts. -- The [seL4 Kernel tutorials](../seL4Kernel/overview.md) are a deep dive into seL4 concepts. -- [MCS](../MCS/mcs-extensions) introduces seL4 MCS extensions. -- [Dynamic Libraries](../DynamicLibraries/initialisation.md) covers the libraries that have been developed for rapidly prototyping systems on seL4. -- [CAmkES](../CAmkES/hello-camkes.md) is a platform for building componentised systems for embedded platforms. -- [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](../GettingStarted/microkit) section.) +- [About seL4](GettingStarted/about-seL4) and [Getting started with the Microkit tutorial](GettingStarted/microkit) introduce seL4 concepts. +- The [seL4 Kernel tutorials](seL4Kernel/overview.md) are a deep dive into seL4 concepts. +- [MCS](MCS/mcs-extensions) introduces seL4 MCS extensions. +- [Dynamic Libraries](DynamicLibraries/initialisation.md) covers the libraries that have been developed for rapidly prototyping systems on seL4. +- [CAmkES](CAmkES/hello-camkes.md) is a platform for building componentised systems for embedded platforms. +- [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](GettingStarted/microkit) section.) - [Rust](https://github.com/seL4/rust-sel4) provide crates for supporting the use of Rust in seL4 userspace.

    Resources

    Additional resources to assist with learning: - The [seL4 manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf) -- [API references](../../projects/sel4/api-doc) -- The [How to](../Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. -- [FAQs](../../projects/sel4/frequently-asked-questions) -- [Debugging guide](../../projects/sel4-tutorials/debugging-guide) +- [API references](projects/sel4/api-doc) +- The [How to](Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. +- [FAQs](projects/sel4/frequently-asked-questions) +- [Debugging guide](projects/sel4-tutorials/debugging-guide) - [Discourse forum](https://sel4.discourse.group/) - [Developer mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) - [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/channels/web-doc-revamp) From 1769b62f43ee21fb14b172364585856ab73a2270 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 22 Mar 2024 11:36:08 +1100 Subject: [PATCH 024/103] add layout for tutorial pages Signed-off-by: Birgit Brecknell --- Tutorials/CAmkES/camkes-cross-vm.md | 2 +- Tutorials/CAmkES/camkes-vm.md | 2 +- Tutorials/CAmkES/camkes1.md | 2 +- Tutorials/CAmkES/camkes2.md | 2 +- Tutorials/CAmkES/camkes3.md | 2 +- Tutorials/CAmkES/hello-camkes.md | 2 +- Tutorials/DynamicLibraries/initialisation.md | 2 +- Tutorials/DynamicLibraries/ipc.md | 2 +- Tutorials/DynamicLibraries/processes.md | 2 +- Tutorials/DynamicLibraries/timer.md | 2 +- Tutorials/GettingStarted/about-seL4.md | 2 +- Tutorials/GettingStarted/microkit.md | 2 +- Tutorials/MCS/mcs-extensions.md | 2 +- Tutorials/Resources/how-to.md | 2 +- Tutorials/seL4Kernel/capabilities.md | 2 +- Tutorials/seL4Kernel/faults.md | 2 +- Tutorials/seL4Kernel/hello-world.md | 2 +- Tutorials/seL4Kernel/interrupts.md | 2 +- Tutorials/seL4Kernel/ipc.md | 2 +- Tutorials/seL4Kernel/mapping.md | 2 +- Tutorials/seL4Kernel/notifications.md | 2 +- Tutorials/seL4Kernel/overview.md | 2 +- Tutorials/seL4Kernel/setting-up.md | 2 +- Tutorials/seL4Kernel/threads.md | 2 +- Tutorials/seL4Kernel/untyped.md | 2 +- _layouts/overview.html | 28 +++++++++++++++++ _layouts/tutorial.html | 32 ++++++++++++++++++++ 27 files changed, 85 insertions(+), 25 deletions(-) create mode 100644 _layouts/overview.html create mode 100644 _layouts/tutorial.html diff --git a/Tutorials/CAmkES/camkes-cross-vm.md b/Tutorials/CAmkES/camkes-cross-vm.md index 2aa11d174e..f65c5b72ea 100644 --- a/Tutorials/CAmkES/camkes-cross-vm.md +++ b/Tutorials/CAmkES/camkes-cross-vm.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/CAmkES/camkes-vm.md b/Tutorials/CAmkES/camkes-vm.md index 07e9e3f3bc..915a62078f 100644 --- a/Tutorials/CAmkES/camkes-vm.md +++ b/Tutorials/CAmkES/camkes-vm.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/CAmkES/camkes1.md b/Tutorials/CAmkES/camkes1.md index 5a2e25683b..7e7732a2a9 100644 --- a/Tutorials/CAmkES/camkes1.md +++ b/Tutorials/CAmkES/camkes1.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/CAmkES/camkes2.md b/Tutorials/CAmkES/camkes2.md index 3d27c578ac..d4494f206e 100644 --- a/Tutorials/CAmkES/camkes2.md +++ b/Tutorials/CAmkES/camkes2.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/CAmkES/camkes3.md b/Tutorials/CAmkES/camkes3.md index b06d45690c..8bdca9d08b 100644 --- a/Tutorials/CAmkES/camkes3.md +++ b/Tutorials/CAmkES/camkes3.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/CAmkES/hello-camkes.md b/Tutorials/CAmkES/hello-camkes.md index e78a550980..62bd3e783f 100644 --- a/Tutorials/CAmkES/hello-camkes.md +++ b/Tutorials/CAmkES/hello-camkes.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/DynamicLibraries/initialisation.md b/Tutorials/DynamicLibraries/initialisation.md index 5054d01966..05e467cf44 100644 --- a/Tutorials/DynamicLibraries/initialisation.md +++ b/Tutorials/DynamicLibraries/initialisation.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/DynamicLibraries/ipc.md b/Tutorials/DynamicLibraries/ipc.md index 0c056ee083..d97d5f7e97 100644 --- a/Tutorials/DynamicLibraries/ipc.md +++ b/Tutorials/DynamicLibraries/ipc.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/DynamicLibraries/processes.md b/Tutorials/DynamicLibraries/processes.md index 5a0d1e28a4..ddd16acbda 100644 --- a/Tutorials/DynamicLibraries/processes.md +++ b/Tutorials/DynamicLibraries/processes.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/DynamicLibraries/timer.md b/Tutorials/DynamicLibraries/timer.md index ab15f6fc35..b760d5cef3 100644 --- a/Tutorials/DynamicLibraries/timer.md +++ b/Tutorials/DynamicLibraries/timer.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/GettingStarted/about-seL4.md b/Tutorials/GettingStarted/about-seL4.md index 7e3df33206..f9727896de 100644 --- a/Tutorials/GettingStarted/about-seL4.md +++ b/Tutorials/GettingStarted/about-seL4.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: overview SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/GettingStarted/microkit.md b/Tutorials/GettingStarted/microkit.md index 89de82b981..0003ac8a30 100644 --- a/Tutorials/GettingStarted/microkit.md +++ b/Tutorials/GettingStarted/microkit.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: overview SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/MCS/mcs-extensions.md b/Tutorials/MCS/mcs-extensions.md index e99e66eaf6..047d83d1d4 100644 --- a/Tutorials/MCS/mcs-extensions.md +++ b/Tutorials/MCS/mcs-extensions.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/Resources/how-to.md b/Tutorials/Resources/how-to.md index 9975779210..37f2369ead 100644 --- a/Tutorials/Resources/how-to.md +++ b/Tutorials/Resources/how-to.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/capabilities.md b/Tutorials/seL4Kernel/capabilities.md index 25d30b45c2..c4a44aea50 100644 --- a/Tutorials/seL4Kernel/capabilities.md +++ b/Tutorials/seL4Kernel/capabilities.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/faults.md b/Tutorials/seL4Kernel/faults.md index b8ba0cad43..e7558dbd80 100644 --- a/Tutorials/seL4Kernel/faults.md +++ b/Tutorials/seL4Kernel/faults.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/hello-world.md b/Tutorials/seL4Kernel/hello-world.md index 4443711290..61f539877d 100644 --- a/Tutorials/seL4Kernel/hello-world.md +++ b/Tutorials/seL4Kernel/hello-world.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/interrupts.md b/Tutorials/seL4Kernel/interrupts.md index c18e7a5a0e..015ae570e6 100644 --- a/Tutorials/seL4Kernel/interrupts.md +++ b/Tutorials/seL4Kernel/interrupts.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/ipc.md b/Tutorials/seL4Kernel/ipc.md index 4856ed5f48..2fa50eb349 100644 --- a/Tutorials/seL4Kernel/ipc.md +++ b/Tutorials/seL4Kernel/ipc.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/mapping.md b/Tutorials/seL4Kernel/mapping.md index 7c37a17376..320fa60955 100644 --- a/Tutorials/seL4Kernel/mapping.md +++ b/Tutorials/seL4Kernel/mapping.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/notifications.md b/Tutorials/seL4Kernel/notifications.md index 142a3b6fe7..b8baa5177b 100644 --- a/Tutorials/seL4Kernel/notifications.md +++ b/Tutorials/seL4Kernel/notifications.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/overview.md b/Tutorials/seL4Kernel/overview.md index 616ce76f7b..dfaa2fe556 100644 --- a/Tutorials/seL4Kernel/overview.md +++ b/Tutorials/seL4Kernel/overview.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/setting-up.md b/Tutorials/seL4Kernel/setting-up.md index e28fc657c6..3ece8a8f39 100644 --- a/Tutorials/seL4Kernel/setting-up.md +++ b/Tutorials/seL4Kernel/setting-up.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/threads.md b/Tutorials/seL4Kernel/threads.md index 5014a728b5..7692f9e615 100644 --- a/Tutorials/seL4Kernel/threads.md +++ b/Tutorials/seL4Kernel/threads.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/seL4Kernel/untyped.md b/Tutorials/seL4Kernel/untyped.md index d2fd36ba9c..94ca65687f 100644 --- a/Tutorials/seL4Kernel/untyped.md +++ b/Tutorials/seL4Kernel/untyped.md @@ -1,6 +1,6 @@ --- toc: true -layout: project +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- diff --git a/_layouts/overview.html b/_layouts/overview.html new file mode 100644 index 0000000000..50a4f2d197 --- /dev/null +++ b/_layouts/overview.html @@ -0,0 +1,28 @@ +--- +layout: basic +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. +--- + +
    + +
    + {{ content }} +
    + +{% assign url = page.url | split: "/" %} +{% capture project_name %} +{% if page.project %} +{{page.project}} +{% elsif url[1] == "projects" %} +{{url[2]}} +{% endif %} +{% endcapture %} + +{% assign project_name = project_name | strip %} +{% assign project = site.data.projects[project_name] %} + +
    diff --git a/_layouts/tutorial.html b/_layouts/tutorial.html new file mode 100644 index 0000000000..80f4ce0310 --- /dev/null +++ b/_layouts/tutorial.html @@ -0,0 +1,32 @@ +--- +layout: basic +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. +--- + +
    + +
    + {{ content }} +
    + +{% assign url = page.url | split: "/" %} +{% capture project_name %} +{% if page.project %} +{{page.project}} +{% elsif url[1] == "projects" %} +{{url[2]}} +{% endif %} +{% endcapture %} + +{% assign project_name = project_name | strip %} +{% assign project = site.data.projects[project_name] %} + + {% if page.toc %} + {% include toc-sidebar.html %} + {% endif %} + +
    From 98b162c6d97238d9d9b14f74ccae04d57cbb76db Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 19 Apr 2024 11:02:04 +1000 Subject: [PATCH 025/103] update setting up instructions Signed-off-by: Birgit Brecknell --- Tutorials/seL4Kernel/setting-up.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tutorials/seL4Kernel/setting-up.md b/Tutorials/seL4Kernel/setting-up.md index 3ece8a8f39..b8a742c00e 100644 --- a/Tutorials/seL4Kernel/setting-up.md +++ b/Tutorials/seL4Kernel/setting-up.md @@ -7,7 +7,7 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. # Setting up your machine **Overview** -- Set up your machine - install dependencies required to run seL4 +- Set up your machine - install dependencies required to run seL4`` - Run seL4test on a simulator - Gain awareness of terminology used for seL4 From 7071759bf6df241fbbff75ad141a5cb6b0af67a1 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Wed, 24 Apr 2024 18:41:10 +1000 Subject: [PATCH 026/103] rename tutorials to match tutorials repo Signed-off-by: Birgit Brecknell --- ...amkes-cross-vm.md => camkes-vm-crossvm.md} | 0 .../{camkes-vm.md => camkes-vm-linux.md} | 1 - .../{hello-camkes.md => hello-camkes-0.md} | 0 .../CAmkES/{camkes1.md => hello-camkes-1.md} | 2 +- .../CAmkES/{camkes2.md => hello-camkes-2.md} | 2 +- .../{camkes3.md => hello-camkes-timer.md} | 0 .../{initialisation.md => dynamic-1.md} | 3 +- .../DynamicLibraries/{ipc.md => dynamic-2.md} | 1 - .../{processes.md => dynamic-3.md} | 6 +- .../{timer.md => dynamic-4.md} | 0 Tutorials/Resources/how-to.md | 180 +++++++++--------- Tutorials/index.md | 4 +- Tutorials/seL4Kernel/capabilities.md | 4 + .../{faults.md => fault-handlers.md} | 0 14 files changed, 101 insertions(+), 102 deletions(-) rename Tutorials/CAmkES/{camkes-cross-vm.md => camkes-vm-crossvm.md} (100%) rename Tutorials/CAmkES/{camkes-vm.md => camkes-vm-linux.md} (99%) rename Tutorials/CAmkES/{hello-camkes.md => hello-camkes-0.md} (100%) rename Tutorials/CAmkES/{camkes1.md => hello-camkes-1.md} (99%) rename Tutorials/CAmkES/{camkes2.md => hello-camkes-2.md} (99%) rename Tutorials/CAmkES/{camkes3.md => hello-camkes-timer.md} (100%) rename Tutorials/DynamicLibraries/{initialisation.md => dynamic-1.md} (99%) rename Tutorials/DynamicLibraries/{ipc.md => dynamic-2.md} (99%) rename Tutorials/DynamicLibraries/{processes.md => dynamic-3.md} (99%) rename Tutorials/DynamicLibraries/{timer.md => dynamic-4.md} (100%) rename Tutorials/seL4Kernel/{faults.md => fault-handlers.md} (100%) diff --git a/Tutorials/CAmkES/camkes-cross-vm.md b/Tutorials/CAmkES/camkes-vm-crossvm.md similarity index 100% rename from Tutorials/CAmkES/camkes-cross-vm.md rename to Tutorials/CAmkES/camkes-vm-crossvm.md diff --git a/Tutorials/CAmkES/camkes-vm.md b/Tutorials/CAmkES/camkes-vm-linux.md similarity index 99% rename from Tutorials/CAmkES/camkes-vm.md rename to Tutorials/CAmkES/camkes-vm-linux.md index 915a62078f..2f4d7f2ceb 100644 --- a/Tutorials/CAmkES/camkes-vm.md +++ b/Tutorials/CAmkES/camkes-vm-linux.md @@ -20,7 +20,6 @@ You will become familiar with: # For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code # # Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise ./init --tut camkes-vm-linux # building the tutorial exercise cd camkes-vm-linux diff --git a/Tutorials/CAmkES/hello-camkes.md b/Tutorials/CAmkES/hello-camkes-0.md similarity index 100% rename from Tutorials/CAmkES/hello-camkes.md rename to Tutorials/CAmkES/hello-camkes-0.md diff --git a/Tutorials/CAmkES/camkes1.md b/Tutorials/CAmkES/hello-camkes-1.md similarity index 99% rename from Tutorials/CAmkES/camkes1.md rename to Tutorials/CAmkES/hello-camkes-1.md index 7e7732a2a9..767f4a8253 100644 --- a/Tutorials/CAmkES/camkes1.md +++ b/Tutorials/CAmkES/hello-camkes-1.md @@ -162,7 +162,7 @@ assembly { ``` -### Add a connection +**### Add a connection** **Exercise** Now add a connection from `client.hello` to `echo.hello`. ``` diff --git a/Tutorials/CAmkES/camkes2.md b/Tutorials/CAmkES/hello-camkes-2.md similarity index 99% rename from Tutorials/CAmkES/camkes2.md rename to Tutorials/CAmkES/hello-camkes-2.md index d4494f206e..3d95ecd943 100644 --- a/Tutorials/CAmkES/camkes2.md +++ b/Tutorials/CAmkES/hello-camkes-2.md @@ -314,7 +314,7 @@ to access and manipulate the data in the shared memory mapping ``` -# Send data using dataports +### Send data using dataports
    Quick solution ``` diff --git a/Tutorials/CAmkES/camkes3.md b/Tutorials/CAmkES/hello-camkes-timer.md similarity index 100% rename from Tutorials/CAmkES/camkes3.md rename to Tutorials/CAmkES/hello-camkes-timer.md diff --git a/Tutorials/DynamicLibraries/initialisation.md b/Tutorials/DynamicLibraries/dynamic-1.md similarity index 99% rename from Tutorials/DynamicLibraries/initialisation.md rename to Tutorials/DynamicLibraries/dynamic-1.md index 05e467cf44..1725dc3fc9 100644 --- a/Tutorials/DynamicLibraries/initialisation.md +++ b/Tutorials/DynamicLibraries/dynamic-1.md @@ -130,6 +130,7 @@ You need to initialize it with some default state before using it. ```
    Quick solution + ```c simple_default_init_bootinfo(&simple, info); ``` @@ -436,11 +437,11 @@ On successful completion this task, the output should not change. * hint 2: we want the new thread to run the function "thread_2" */ ``` +
    Quick solution ```c sel4utils_set_instruction_pointer(®s, (seL4_Word)thread_2); - ```
    diff --git a/Tutorials/DynamicLibraries/ipc.md b/Tutorials/DynamicLibraries/dynamic-2.md similarity index 99% rename from Tutorials/DynamicLibraries/ipc.md rename to Tutorials/DynamicLibraries/dynamic-2.md index d97d5f7e97..e97777445c 100644 --- a/Tutorials/DynamicLibraries/ipc.md +++ b/Tutorials/DynamicLibraries/dynamic-2.md @@ -609,7 +609,6 @@ Complete them and proceed to the next step. ```c ZF_LOGF_IF(sender_badge != EP_BADGE, "Badge on the endpoint was not what was expected.\n"); - ZF_LOGF_IF(seL4_MessageInfo_get_length(tag) != 1, "Length of the data send from root thread was not what was expected.\n" "\tHow many registers did you set with seL4_SetMR, within the root thread?\n"); diff --git a/Tutorials/DynamicLibraries/processes.md b/Tutorials/DynamicLibraries/dynamic-3.md similarity index 99% rename from Tutorials/DynamicLibraries/processes.md rename to Tutorials/DynamicLibraries/dynamic-3.md index ddd16acbda..f28b3cdb9f 100644 --- a/Tutorials/DynamicLibraries/processes.md +++ b/Tutorials/DynamicLibraries/dynamic-3.md @@ -163,11 +163,10 @@ thread. Quick solution ```c sel4utils_process_t new_process; - sel4utils_process_config_t config = process_config_default_simple(&simple, APP_IMAGE_NAME, APP_PRIORITY); error = sel4utils_configure_process_custom(&new_process, &vka, &vspace, config); ZF_LOGF_IFERR(error, "Failed to spawn a new thread.\n" - "\tsel4utils_configure_process expands an ELF file into our VSpace.\n" +"\tsel4utils_configure_process expands an ELF file into our VSpace.\n" "\tBe sure you've properly configured a VSpace manager using sel4utils_bootstrap_vspace_with_bootinfo.\n" "\tBe sure you've passed the correct component name for the new thread!\n"); ``` @@ -267,7 +266,6 @@ free slot that the VKA library found for us. ```c new_ep_cap = sel4utils_mint_cap_to_process(&new_process, ep_cap_path, seL4_AllRights, EP_BADGE); - ZF_LOGF_IF(new_ep_cap == 0, "Failed to mint a badged copy of the IPC endpoint into the new thread's CSpace.\n" "\tsel4utils_mint_cap_to_process takes a cspacepath_t: double check what you passed.\n"); ``` @@ -324,7 +322,6 @@ communicate with us, we can let it run. Complete this step and proceed. char string_args[argc][WORD_STRING_SIZE]; char* argv[argc]; sel4utils_create_word_args(string_args, argv, argc, new_ep_cap); - error = sel4utils_spawn_process_v(&new_process, &vka, &vspace, argc, (char**) &argv, 1); ZF_LOGF_IFERR(error, "Failed to spawn and start the new thread.\n" "\tVerify: the new thread is being executed in the root thread's VSpace.\n" @@ -374,7 +371,6 @@ Then we verify the fidelity of the data that was transmitted. /* make sure it is what we expected */ ZF_LOGF_IF(sender_badge != EP_BADGE, "The badge we received from the new thread didn't match our expectation.\n"); - ZF_LOGF_IF(seL4_MessageInfo_get_length(tag) != 1, "Response data from the new process was not the length expected.\n" "\tHow many registers did you set with seL4_SetMR within the new process?\n"); diff --git a/Tutorials/DynamicLibraries/timer.md b/Tutorials/DynamicLibraries/dynamic-4.md similarity index 100% rename from Tutorials/DynamicLibraries/timer.md rename to Tutorials/DynamicLibraries/dynamic-4.md diff --git a/Tutorials/Resources/how-to.md b/Tutorials/Resources/how-to.md index 37f2369ead..8e9db7b2e7 100644 --- a/Tutorials/Resources/how-to.md +++ b/Tutorials/Resources/how-to.md @@ -55,12 +55,12 @@ seL4Kernel/ipc#use-capability-transfer-to-send-the-badged-capability) - [Set NTFN](../seL4Kernel/interrupts#set-ntfn) - [Acknowledge an interrupt](../seL4Kernel/interrupts#acknowledge-an-interrupt) -### [Fault handling](../seL4Kernel/faults) - - [Set up an endpoint for thread fault IPC messages](../seL4Kernel/faults#setting-up-the-endpoint-to-be-used-for-thread-fault-ipc-messages) - - [Receive an IPC message from the kernel](../seL4Kernel/faults#receiving-the-ipc-message-from-the-kernel) - - [Get information about a thread fault](../seL4Kernel/faults#finding-out-information-about-the-generated-thread-fault) - - [Handle a thread fault](../seL4Kernel/faults#handling-a-thread-fault) - - [Resume a faulting thread](../seL4Kernel/faults#resuming-a-faulting-thread) +### [Fault handling](../seL4Kernel/fault-handlers) + - [Set up an endpoint for thread fault IPC messages](../seL4Kernel/fault-handlers#setting-up-the-endpoint-to-be-used-for-thread-fault-ipc-messages) + - [Receive an IPC message from the kernel](../seL4Kernel/fault-handlers#receiving-the-ipc-message-from-the-kernel) + - [Get information about a thread fault](../seL4Kernel/fault-handlers#finding-out-information-about-the-generated-thread-fault) + - [Handle a thread fault](../seL4Kernel/fault-handlers#handling-a-thread-fault) + - [Resume a faulting thread](../seL4Kernel/fault-handlers#resuming-a-faulting-thread) ## [MCS Extensions](../MCS/mcs-extensions) - [Set up a periodic thread](../MCS/mcs-extensionsperiodic-threads) @@ -69,92 +69,92 @@ seL4Kernel/ipc#use-capability-transfer-to-send-the-badged-capability) - [Use passive servers](../MCS/mcs-extensionspassive-servers) - [Configure fault endpoints](../MCS/mcs-extensionsconfiguring-a-fault-endpoint-on-the-mcs-kernel) -## [Dynamic libraries](../DynamicLibraries/initialisation) - -### [Initiliasation & threading](../DynamicLibraries/initialisation) - - [Obtain BootInfo](../DynamicLibraries/initialisation#obtain-bootinfo) - - [Initialise simple](../DynamicLibraries/initialisation#initialise-simple) - - [Use simple to print BootInfo](../DynamicLibraries/initialisation#use-simple-to-print-bootinfo) - - [Initialise an allocator](../DynamicLibraries/initialisation#initialise-an-allocator) - - [Obtain a generic allocation interface (vka)](../DynamicLibraries/initialisation#obtain-a-generic-allocation-interface-vka) - - [Find the CSpace root cap](../DynamicLibraries/initialisation#find-the-cspace-root-cap) - - [Find the VSpace root cap](../DynamicLibraries/initialisation#find-the-vspace-root-cap) - - [Allocate a TCB Object](../DynamicLibraries/initialisation#allocate-a-tcb-object) - - [Configure the new TCB](../DynamicLibraries/initialisation#configure-the-new-tcb) - - [Name the new TCB](../DynamicLibraries/initialisation#name-the-new-tcb) - - [Set the instruction pointer](../DynamicLibraries/initialisation#set-the-instruction-pointer) - - [Write the registers](../DynamicLibraries/initialisation#write-the-registers) - - [Start the new thread](../DynamicLibraries/initialisation#start-the-new-thread) - -### [IPC](../DynamicLibraries/ipc) - - [Allocate an IPC buffer](../DynamicLibraries/ipc#allocate-an-ipc-buffer) - - [Allocate a page table](../DynamicLibraries/ipc#allocate-a-page-table) - - [Map a page table](../DynamicLibraries/ipc#map-a-page-table) - - [Map a page](../DynamicLibraries/ipc#map-a-page) - - [Allocate an endpoint](../DynamicLibraries/ipc#allocate-an-endpoint) - - [Badge an endpoint](../DynamicLibraries/ipc#badge-an-endpoint) - - [Set a message register](../DynamicLibraries/ipc#message-registers) - - [Send and wait for a reply](../DynamicLibraries/ipc#ipc) - - [Receive a reply](../DynamicLibraries/ipc#receive-a-reply) - - [Receive an IPC](../DynamicLibraries/ipc#receive-an-ipc) - - [Validate a message](../DynamicLibraries/ipc#validate-the-message) - - [Write the message registers](../DynamicLibraries/ipc#write-the-message-registers) - - [Reply to a message](../DynamicLibraries/ipc#reply-to-a-message) - -### [Processes & Elf loading](../DynamicLibraries/processes) - - [Create a VSpace object](../DynamicLibraries/processes#virtual-memory-management) - - [Configure a process](../DynamicLibraries/processes#configure-a-process) - - [Get a cspacepath](../DynamicLibraries/processes#get-a-cspacepath) - - [Badge a capability](../DynamicLibraries/processes#badge-a-capability) - - [Spawn a process](../DynamicLibraries/processes#spawn-a-process) - - [Receive a message](../DynamicLibraries/processes#receive-a-message) - - [Send a reply](../DynamicLibraries/processes#send-a-reply) - - [Initiate communications by using seL4_Call](../DynamicLibraries/processes#client-call) - -### [Timer](../DynamicLibraries/timer) - - [Allocate a notification object](../DynamicLibraries/timer#allocate-a-notification-object) - - [Initialise a timer](../DynamicLibraries/timer#initialise-the-timer) - - [Use a timer](../DynamicLibraries/timer#use-the-timer) - - [Handle an interrupt](../DynamicLibraries/timer#handle-the-interrupt) - - [Destroy a timer](../DynamicLibraries/timer#destroy-the-timer) +## [Dynamic libraries](../DynamicLibraries/dynamic-1) + +### [Initiliasation & threading](../DynamicLibraries/dynamic-1) + - [Obtain BootInfo](../DynamicLibraries/dynamic-1#obtain-bootinfo) + - [Initialise simple](../DynamicLibraries/dynamic-1#initialise-simple) + - [Use simple to print BootInfo](../DynamicLibraries/dynamic-1#use-simple-to-print-bootinfo) + - [Initialise an allocator](../DynamicLibraries/dynamic-1#initialise-an-allocator) + - [Obtain a generic allocation interface (vka)](../DynamicLibraries/dynamic-1#obtain-a-generic-allocation-interface-vka) + - [Find the CSpace root cap](../DynamicLibraries/dynamic-1#find-the-cspace-root-cap) + - [Find the VSpace root cap](../DynamicLibraries/dynamic-1#find-the-vspace-root-cap) + - [Allocate a TCB Object](../DynamicLibraries/dynamic-1#allocate-a-tcb-object) + - [Configure the new TCB](../DynamicLibraries/dynamic-1#configure-the-new-tcb) + - [Name the new TCB](../DynamicLibraries/dynamic-1#name-the-new-tcb) + - [Set the instruction pointer](../DynamicLibraries/dynamic-1#set-the-instruction-pointer) + - [Write the registers](../DynamicLibraries/dynamic-1#write-the-registers) + - [Start the new thread](../DynamicLibraries/dynamic-1#start-the-new-thread) + +### [IPC](../DynamicLibraries/dynamic-2) + - [Allocate an IPC buffer](../DynamicLibraries/dynamic-2#allocate-an-ipc-buffer) + - [Allocate a page table](../DynamicLibraries/dynamic-2#allocate-a-page-table) + - [Map a page table](../DynamicLibraries/dynamic-2#map-a-page-table) + - [Map a page](../DynamicLibraries/dynamic-2#map-a-page) + - [Allocate an endpoint](../DynamicLibraries/dynamic-2#allocate-an-endpoint) + - [Badge an endpoint](../DynamicLibraries/dynamic-2#badge-an-endpoint) + - [Set a message register](../DynamicLibraries/dynamic-2#message-registers) + - [Send and wait for a reply](../DynamicLibraries/dynamic-2#ipc) + - [Receive a reply](../DynamicLibraries/dynamic-2#receive-a-reply) + - [Receive an IPC](../DynamicLibraries/dynamic-2#receive-an-ipc) + - [Validate a message](../DynamicLibraries/dynamic-2#validate-the-message) + - [Write the message registers](../DynamicLibraries/dynamic-2#write-the-message-registers) + - [Reply to a message](../DynamicLibraries/dynamic-2#reply-to-a-message) + +### [Processes & Elf loading](../DynamicLibraries/dynamic-3) + - [Create a VSpace object](../DynamicLibraries/dynamic-3#virtual-memory-management) + - [Configure a process](../DynamicLibraries/dynamic-3#configure-a-process) + - [Get a cspacepath](../DynamicLibraries/dynamic-3#get-a-cspacepath) + - [Badge a capability](../DynamicLibraries/dynamic-3#badge-a-capability) + - [Spawn a process](../DynamicLibraries/dynamic-3#spawn-a-process) + - [Receive a message](../DynamicLibraries/dynamic-3#receive-a-message) + - [Send a reply](../DynamicLibraries/dynamic-3#send-a-reply) + - [Initiate communications by using seL4_Call](../DynamicLibraries/dynamic-3#client-call) + +### [Timer](../DynamicLibraries/dynamic-4) + - [Allocate a notification object](../DynamicLibraries/dynamic-4#allocate-a-notification-object) + - [Initialise a timer](../DynamicLibraries/dynamic-4#initialise-the-timer) + - [Use a timer](../DynamicLibraries/dynamic-4#use-the-timer) + - [Handle an interrupt](../DynamicLibraries/dynamic-4#handle-the-interrupt) + - [Destroy a timer](../DynamicLibraries/dynamic-4#destroy-the-timer) ## [CAmkES](../CAmkES/) -### [A basic CAmkES application](../CAmkES/camkes1) - - [Define instance in the composition section of the ADL](../CAmkES/camkes1#define-instance-in-the-composition-section-of-the-adl) - - [Add a connection](../CAmkES/camkes1#add-a-connection) - - [Define an interface](../CAmkES/camkes1#define-an-interface) - - [Implement a RPC function](../CAmkES/camkes1#implement-a-rpc-function) - - [Invoke a RPC function](../CAmkES/camkes1#invoke-a-rpc-function) - -### [Events in CAmkES](../CAmkES/camkes2) - - [Specify an events interface](../CAmkES/camkes2#specify-an-events-interface) - - [Wait for data to become available](../CAmkES/camkes2#wait-for-data-to-become-available) - - [Signal that data is available](../CAmkES/camkes2#signal-that-data-is-available) - - [Register a callback handler](../CAmkES/camkes2#register-a-callback-handler) - - [Specify dataport interfaces](../CAmkES/camkes2#specify-an-events-interface) - - [Specify dataport connections](../CAmkES/camkes2#specify-dataport-connections) - - [Copy strings to an untyped dataport](../CAmkES/camkes2#copy-strings-to-an-untyped-dataport) - - [Read the reply data from a typed dataport](../CAmkES/camkes2#read-the-reply-data-from-a-typed-dataport) - - [Send data using dataports](../CAmkES/camkes2#send-data-using-dataports) - - [Read data from an untyped dataport](../CAmkES/camkes2#read-data-from-an-untyped-dataport) - - [Put data into a typed dataport](../CAmkES/camkes2#put-data-into-a-typed-dataport) - - [Read data from a typed dataport](../CAmkES/camkes2#read-data-from-a-typed-dataport) - - [Set component priorities](../CAmkES/camkes2#set-component-priorities) - - [Restrict access to dataports](../CAmkES/camkes2#restrict-access-to-dataports) - - [Test the read and write permissions on the dataport](../CAmkES/camkes2#test-the-read-and-write-permissions-on-the-dataport) +### [A basic CAmkES application](../CAmkES/hello-camkes-1) + - [Define instance in the composition section of the ADL](../CAmkES/hello-camkes-1#define-instance-in-the-composition-section-of-the-adl) + - [Add a connection](../CAmkES/hello-camkes-1#add-a-connection) + - [Define an interface](../CAmkES/hello-camkes-1#define-an-interface) + - [Implement a RPC function](../CAmkES/hello-camkes-1#implement-a-rpc-function) + - [Invoke a RPC function](../CAmkES/hello-camkes-1#invoke-a-rpc-function) + +### [Events in CAmkES](../CAmkES/hello-camkes-2) + - [Specify an events interface](../CAmkES/hello-camkes-2#specify-an-events-interface) + - [Wait for data to become available](../CAmkES/hello-camkes-2#wait-for-data-to-become-available) + - [Signal that data is available](../CAmkES/hello-camkes-2#signal-that-data-is-available) + - [Register a callback handler](../CAmkES/hello-camkes-2#register-a-callback-handler) + - [Specify dataport interfaces](../CAmkES/hello-camkes-2#specify-an-events-interface) + - [Specify dataport connections](../CAmkES/hello-camkes-2#specify-dataport-connections) + - [Copy strings to an untyped dataport](../CAmkES/hello-camkes-2#copy-strings-to-an-untyped-dataport) + - [Read the reply data from a typed dataport](../CAmkES/hello-camkes-2#read-the-reply-data-from-a-typed-dataport) + - [Send data using dataports](../CAmkES/hello-camkes-2#send-data-using-dataports) + - [Read data from an untyped dataport](../CAmkES/hello-camkes-2#read-data-from-an-untyped-dataport) + - [Put data into a typed dataport](../CAmkES/hello-camkes-2#put-data-into-a-typed-dataport) + - [Read data from a typed dataport](../CAmkES/hello-camkes-2#read-data-from-a-typed-dataport) + - [Set component priorities](../CAmkES/hello-camkes-2#set-component-priorities) + - [Restrict access to dataports](../CAmkES/hello-camkes-2#restrict-access-to-dataports) + - [Test the read and write permissions on the dataport](../CAmkES/hello-camkes-2#test-the-read-and-write-permissions-on-the-dataport) ### [CAmkES Timer](../CAmkES/camkes) - - [Instantiate a Timer and Timerbase](../CAmkES/camkes3#task-1) - - [Connect a timer driver component](../CAmkES/camkes3#task-2) - - [Configure a timer hardware component instance](../CAmkES/camkes3#task-3) - - [Call into a supplied driver to handle the interrupt](../CAmkES/camkes3#task-4) - - [Stop a timer](../CAmkES/camkes3#task-5) - - [Acknowledge an interrupt](../CAmkES/camkes3#task-6) - - [Get a timer handler](../CAmkES/camkes3#task-7) - - [Start a timer](../CAmkES/camkes3#task-8) - - [Implement a RPC interface](../CAmkES/camkes3#task-9) - - [Set a timer interrupt](../CAmkES/camkes3#task-10) - - [Instantiate a TimerDTB component](../CAmkES/camkes3#task-1-1) - - [Connect interfaces using the seL4DTBHardware connector](../CAmkES/camkes3#task-2-1) - - [Configure the TimerDTB component](../CAmkES/camkes3#task-3-1) + - [Instantiate a Timer and Timerbase](../CAmkES/hello-camkes-timer#task-1) + - [Connect a timer driver component](../CAmkES/hello-camkes-timer#task-2) + - [Configure a timer hardware component instance](../CAmkES/hello-camkes-timer#task-3) + - [Call into a supplied driver to handle the interrupt](../CAmkES/hello-camkes-timer#task-4) + - [Stop a timer](../CAmkES/hello-camkes-timer#task-5) + - [Acknowledge an interrupt](../CAmkES/hello-camkes-timer#task-6) + - [Get a timer handler](../CAmkES/hello-camkes-timer#task-7) + - [Start a timer](../CAmkES/hello-camkes-timer#task-8) + - [Implement a RPC interface](../CAmkES/hello-camkes-timer#task-9) + - [Set a timer interrupt](../CAmkES/hello-camkes-timer#task-10) + - [Instantiate a TimerDTB component](../CAmkES/hello-camkes-timer#task-1-1) + - [Connect interfaces using the seL4DTBHardware connector](../CAmkES/hello-camkes-timer#task-2-1) + - [Configure the TimerDTB component](../CAmkES/hello-camkes-timer#task-3-1) diff --git a/Tutorials/index.md b/Tutorials/index.md index 2d9a5b22ee..2c2f159101 100644 --- a/Tutorials/index.md +++ b/Tutorials/index.md @@ -15,8 +15,8 @@ The tutorials are split into a number of broad categories: - [About seL4](GettingStarted/about-seL4) and [Getting started with the Microkit tutorial](GettingStarted/microkit) introduce seL4 concepts. - The [seL4 Kernel tutorials](seL4Kernel/overview.md) are a deep dive into seL4 concepts. - [MCS](MCS/mcs-extensions) introduces seL4 MCS extensions. -- [Dynamic Libraries](DynamicLibraries/initialisation.md) covers the libraries that have been developed for rapidly prototyping systems on seL4. -- [CAmkES](CAmkES/hello-camkes.md) is a platform for building componentised systems for embedded platforms. +- [Dynamic Libraries](DynamicLibraries/dynamic-1) covers the libraries that have been developed for rapidly prototyping systems on seL4. +- [CAmkES](CAmkES/hello-camkes-0) is a platform for building componentised systems for embedded platforms. - [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](GettingStarted/microkit) section.) - [Rust](https://github.com/seL4/rust-sel4) provide crates for supporting the use of Rust in seL4 userspace. diff --git a/Tutorials/seL4Kernel/capabilities.md b/Tutorials/seL4Kernel/capabilities.md index c4a44aea50..fbd2cd5461 100644 --- a/Tutorials/seL4Kernel/capabilities.md +++ b/Tutorials/seL4Kernel/capabilities.md @@ -1,5 +1,9 @@ --- toc: true +title: Capabilities +tutorial: capabilities +tutorial-order: mechanisms-1 +description: an introduction to capabilities in the seL4 kernel API. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/seL4Kernel/faults.md b/Tutorials/seL4Kernel/fault-handlers.md similarity index 100% rename from Tutorials/seL4Kernel/faults.md rename to Tutorials/seL4Kernel/fault-handlers.md From 438d54aacc952db99298964cbdc2df4f40e1aed9 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 10 May 2024 13:08:38 +1000 Subject: [PATCH 027/103] add tests for including tutorial.md Signed-off-by: Birgit Brecknell --- Tutorials/MCS/{mcs-extensions.md => mcs.md} | 0 Tutorials/Resources/how-to.md | 2 +- Tutorials/index.md | 2 +- Tutorials/seL4Kernel/hello-world.md | 204 +------------------- 4 files changed, 7 insertions(+), 201 deletions(-) rename Tutorials/MCS/{mcs-extensions.md => mcs.md} (100%) diff --git a/Tutorials/MCS/mcs-extensions.md b/Tutorials/MCS/mcs.md similarity index 100% rename from Tutorials/MCS/mcs-extensions.md rename to Tutorials/MCS/mcs.md diff --git a/Tutorials/Resources/how-to.md b/Tutorials/Resources/how-to.md index 8e9db7b2e7..d2ac75d74a 100644 --- a/Tutorials/Resources/how-to.md +++ b/Tutorials/Resources/how-to.md @@ -62,7 +62,7 @@ seL4Kernel/ipc#use-capability-transfer-to-send-the-badged-capability) - [Handle a thread fault](../seL4Kernel/fault-handlers#handling-a-thread-fault) - [Resume a faulting thread](../seL4Kernel/fault-handlers#resuming-a-faulting-thread) -## [MCS Extensions](../MCS/mcs-extensions) +## [MCS Extensions](../MCS/mcs) - [Set up a periodic thread](../MCS/mcs-extensionsperiodic-threads) - [Unbind a scheduling context](../MCS/mcs-extensionsunbinding-scheduling-contexts) - [Experiment with sporadic tasks](../MCS/mcs-extensionssporadic-threads) diff --git a/Tutorials/index.md b/Tutorials/index.md index 2c2f159101..15fb25580f 100644 --- a/Tutorials/index.md +++ b/Tutorials/index.md @@ -14,7 +14,7 @@ The tutorials are split into a number of broad categories: - [About seL4](GettingStarted/about-seL4) and [Getting started with the Microkit tutorial](GettingStarted/microkit) introduce seL4 concepts. - The [seL4 Kernel tutorials](seL4Kernel/overview.md) are a deep dive into seL4 concepts. -- [MCS](MCS/mcs-extensions) introduces seL4 MCS extensions. +- [MCS](MCS/mcs) introduces seL4 MCS extensions. - [Dynamic Libraries](DynamicLibraries/dynamic-1) covers the libraries that have been developed for rapidly prototyping systems on seL4. - [CAmkES](CAmkES/hello-camkes-0) is a platform for building componentised systems for embedded platforms. - [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](GettingStarted/microkit) section.) diff --git a/Tutorials/seL4Kernel/hello-world.md b/Tutorials/seL4Kernel/hello-world.md index 61f539877d..df1711d74c 100644 --- a/Tutorials/seL4Kernel/hello-world.md +++ b/Tutorials/seL4Kernel/hello-world.md @@ -1,208 +1,14 @@ --- toc: true +title: Hello, World! +tutorial: hello-world +tutorial-order: 0-hello +description: an introduction to seL4 projects and tutorials. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- - -# Hello, world! -In this tutorial you will: -- Run Hello, World! to ensure your setup is working correctly -- Become familiar with the jargon *root task* -- Build and simulate a seL4 project -- Have a basic understanding of the role of the `CMakeLists.txt` file in applications - -## Building your first program - -seL4 is a microkernel, not an operating system, and as a result only provides very minimal services. -After the kernel boots, an initial thread called the *root task* is started, which is then responsible for - setting up the user-level system. -When the root task starts there are no available drivers, however a minimal C library is provided. - -The tutorial is already set up to print "Hello, world!", so at this point -all you need to do is build and run the tutorial. - -### Initialising - -``` -cd sel4-tutorials-manifest -./init --tut hello-world -``` -This step creates two new directories in `sel4-tutorials-manifest`, namely `hello-world` and `hello-world_build` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: - -``` -./init --solution --tut hello-world -``` - -This will generate another `hello-world` directory and `hello-world_build` directory, with unique names, e.g. `hello-world44h1po5q` and `hello-world44h1po5q_build`. -
    - -We will now use two terminals, as described in [Setting up your machine](https://docs.sel4.systems/Tutorials/seL4Kernel/setting-up#mapping-a-container). - - - Terminal A is just a normal terminal, and is used for git operations, editing (e.g., vim, emacs), and other normal operations. - - Terminal B is running in a container, and is only used for compilation. - -This gives you the flexibility to use all the normal tools you are used to, while having the seL4 dependencies separated from your machine. - -### Create a container -Open a new terminal, Terminal B, to run a container. - -Create a container: -``` -container -``` - -### Build the program - -``` -cd sel4-tutorials-manifest/hello-world_build -``` - -Next, build the program in Terminal B using ninja - -``` -ninja -``` - - -If successful, you should see the final ninja rule passing, e.g.: -``` -[150/150] objcopy kernel into bootable elf -``` - - - -### Run Hello, World using QEMU -The final image can be run *inside* the container using the command: - -``` -./simulate -``` - -This will run the result on an instance of the [QEMU](https://www.qemu.org) simulator. -If everything has worked, you should see: - -``` -Booting all finished, dropped to user space -Hello, World! -``` - -After that output, there should be a capability violation and a stack dump, -because the program hasn't properly cleaned up after itself yet. (This will come in later examples.) - -`Ctrl-A, X` will terminate QEMU. - -## Looking at the sources -To look at the sources, open a new terminal, Terminal A: - -``` -cd sel4-tutorials-manifest/hello-world -ls -``` - -In your tutorial directory, you will find the following files: - * `CMakeLists.txt` - the file that incorporates the root task into the wider seL4 build system. - * `src/main.c` - the single source file for the initial task. - * `hello-world.md` - A generated README for the tutorial. - -### `CMakeLists.txt` - -Every application and library in an seL4 project requires a `CMakeLists.txt` file in order to be - incorporated into the project build system. - -```cmake -/*-- set build_file --*/ -include(${SEL4_TUTORIALS_DIR}/settings.cmake) -sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR}) - -cmake_minimum_required(VERSION 3.7.2) -# declare the hello-world CMake project and the languages it is written in (just C) -project(hello-world C ASM) - -# In future tutorials, these setup steps will be replaced with -# sel4_tutorials_setup_roottask_tutorial_environment() -find_package(seL4 REQUIRED) -find_package(elfloader-tool REQUIRED) -find_package(musllibc REQUIRED) -find_package(util_libs REQUIRED) -find_package(seL4_libs REQUIRED) - -sel4_import_kernel() -elfloader_import_project() - -# This sets up environment build flags and imports musllibc and runtime libraries. -musllibc_setup_build_environment_with_sel4runtime() -sel4_import_libsel4() -util_libs_import_libraries() -sel4_libs_import_libraries() -sel4_tutorials_import_libsel4tutorials() - -# Name the executable and list source files required to build it -add_executable(hello-world src/main.c) - -# List of libraries to link with the application. -target_link_libraries(hello-world - sel4runtime sel4 - muslc utils sel4tutorials - sel4muslcsys sel4platsupport sel4utils sel4debug) - -# Tell the build system that this application is the root task. -include(rootserver) -DeclareRootserver(hello-world) -/*- endset -*/ -/*? build_file ?*/ -``` - -### `main.c` -The main C is a very typical C file. For a basic root server application, the only requirement is that -a `main` function is provided. - -```c -#include - -/*-- filter TaskContent("hello-world", TaskContentType.ALL) -*/ -int main(int argc, char *argv[]) { - printf("Hello, World!\n"); - - return 0; -} -/*- endfilter --*/ -``` - -## Making a change -Test making a change to `main.c` by adding a second printf to output `"Second hello\n"`. - -```c -/*-- filter TaskContent("hello-world-mod", TaskContentType.COMPLETED) -*/ -int main(int argc, char *argv[]) { - printf("Hello, World!\n"); - - printf("Second hello\n"); - return 0; -} -/*- endfilter --*/ -``` -Once you have made your change, use Terminal B to rebuild the project: - -*Hint:* Remember to exit the QEMU siumator before rerunning the project with `ctrl-A,x`. - -Then rebuild using ninja and run the simulator again: -``` -ninja -./simulate -``` - -On success, you should see the following: - -``` -Hello, World! -Second hello -``` +{% include tutorial.md %} Next tutorial: Capabilities \ No newline at end of file From 5fbdc58037223e786c20e7260e2b2d6fee65eef1 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 13 May 2024 10:16:23 +1000 Subject: [PATCH 028/103] revert docsite tutorial files to include tutes from tutorials repo Signed-off-by: Birgit Brecknell --- Tutorials/CAmkES/camkes-vm-crossvm.md | 504 +---------------- Tutorials/CAmkES/camkes-vm-linux.md | 534 +----------------- Tutorials/CAmkES/hello-camkes-0.md | 192 +------ Tutorials/CAmkES/hello-camkes-1.md | 287 +--------- Tutorials/CAmkES/hello-camkes-2.md | 484 +--------------- Tutorials/CAmkES/hello-camkes-timer.md | 449 +-------------- Tutorials/DynamicLibraries/dynamic-1.md | 576 +------------------ Tutorials/DynamicLibraries/dynamic-2.md | 721 +----------------------- Tutorials/DynamicLibraries/dynamic-3.md | 458 +-------------- Tutorials/DynamicLibraries/dynamic-4.md | 228 +------- Tutorials/MCS/mcs.md | 440 +-------------- Tutorials/seL4Kernel/capabilities.md | 373 +----------- Tutorials/seL4Kernel/fault-handlers.md | 337 +---------- Tutorials/seL4Kernel/interrupts.md | 213 +------ Tutorials/seL4Kernel/ipc.md | 367 +----------- Tutorials/seL4Kernel/mapping.md | 241 +------- Tutorials/seL4Kernel/notifications.md | 223 +------- Tutorials/seL4Kernel/threads.md | 492 +--------------- Tutorials/seL4Kernel/untyped.md | 357 +----------- 19 files changed, 119 insertions(+), 7357 deletions(-) diff --git a/Tutorials/CAmkES/camkes-vm-crossvm.md b/Tutorials/CAmkES/camkes-vm-crossvm.md index f65c5b72ea..3fc835fb72 100644 --- a/Tutorials/CAmkES/camkes-vm-crossvm.md +++ b/Tutorials/CAmkES/camkes-vm-crossvm.md @@ -1,503 +1,11 @@ --- toc: true +title: Camkes Cross-VM communication +tutorial: camkes-vm-crossvm +tutorial-order: vm-2 layout: tutorial +description: walkthrough of adding communication between Linux guests in separate VMs. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- - - -# CAmkES VM: Cross VM Connectors - -This tutorial provides an introduction to using the cross virtual machine (VM) connector mechanisms -provided by seL4 and Camkes in order to connect processes in a guest Linux instance to Camkes components. - -In this tutorial you will learn how to: - -* Configure processes in a Linux guest VM to communicate with CAmkES components - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut camkes-vm-crossvm -# building the tutorial exercise -cd camkes-vm-crossvm -ninja -``` -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut camkes-vm-crossvm -``` -
    - -## Background - -In order to connect guest Linux instances to CAmkES components, -three additional kernel modules must be installed in the guest. -These modules are included in the root filesystem by default: - -- `dataport`: facilitates setting up shared memory between the guest -and CAmkES components. -- `consumes_event`: allows a process in the guest to wait or poll -for an event sent by a CAmkES component. -- `emits_event`: allows a process to emit an event to a CAmkES component. - -Each type of module can be statically assigned to one or more file descriptors to associate that -file descriptor with a specific instance of an interface. `ioctl` can then be used to -manipulate that file descriptor and use the module. - -### Dataports - -Dataports are the mechanism which allows guests and components to share memory. -The dataport initialisation process is as follows: - -- The guest process uses `ioctl` on on the file associated with the dataport and specify a - page-aligned size for the shared memory. -- The dataport kernel module in the guest then allocates a page-aligned buffer of the requested size, - and makes a hypercall to the VMM, with the guest physical address and id of the data port. - The ID is derived from the file on which `ioctl` was called. -- The virtual machine manager (VMM) then modifies the guest's address space, creating the shared memory region. - between a camkes component and the guest. -- Linux processes can then map this memory into their own address space by calling `mmap` on the file - associated with the dataport. - -### Emitting Events - -Guest processes can emit events by using `ioctl` on files associated with the event interface. -This results in the `emits_event` kernel module in the guest making a -making a hypercall to the VMM, which triggers the event and resumes the guest. - -### Consuming Events - -Linux process can wait or poll for an event by calling `poll` -on the file associated with that event, using the timeout argument to -specify whether or not it should block. The event it polls for is -`POLLIN`. When the VMM receives an event destined for the guest, it places -the event id in some memory shared between the VMM and the -`consumes_event` kernel module, and then injects an interrupt into the -guest. The `consumes_event` kernel module is registered to handle this -interrupt, which reads the event ID from shared memory, and wakes a -thread blocked on the corresponding event file. If no threads are -blocked on the file, some state is set in the module such that the next -time a process waits on that file, it returns immediately and clears the -state, mimicking the behaviour of notifications. - -## Exercises - -In this tutorial you will -create a program that runs in the guest, and sends a string -to a CAmkES component to output. To achieve this, the guest program will write a string -to a shared buffer between itself and a CAmkES component. When its ready -for the string to be printed, it will emit an event, received by the -CAmkES component. The CAmkES component will print the string, then send -an event to the guest process so the guest knows it's safe to send a new -string. - -### Add modules to the guest - -There is a library in `projects/camkes/vm-linux/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/libs` -containing Linux system call wrappers, and some utility programs in -`projects/camkes/vm-linux/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/pkgs/{dataport,consumes_event,emits_event}` -which initialize and interact with cross VM connections. To build and use these modules in your rootfs the vm-linux -project provides an overlay target you can use. - -**Exercise** First add the `dataport`, `consumes_event` and `emits_event` kernel modules to the rootfs in the guest. - -Start by replacing the line: - -```cmake -AddToFileServer("rootfs.cpio" ${default_rootfs_file}) -``` - -in the target applications `CMakeLists.txt` file with the following: - -```cmake -set(CAmkESVMDefaultBuildrootOverlay ON CACHE BOOL "" FORCE) -AddOverlayDirToRootfs(default_buildroot_overlay ${default_rootfs_file} "buildroot" "rootfs_install" - rootfs_file rootfs_target) -AddToFileServer("rootfs.cpio" ${rootfs_file}) -``` - -### Define interfaces in the VMM - -**Exercise** Update the CAmkES file, `crossvm_tutorial.camkes` by replacing the Init0 component definition: - -```c -component Init0 { - VM_INIT_DEF() -} -``` - -with the following definition: - -```c -component Init0 { - VM_INIT_DEF() - - // this is the data port for shared memory between the component and guest process - dataport Buf(4096) data; - // this event tells the component that there is data ready to print - emits DoPrint do_print; - // this event tells the guest process that priting is complete - consumes DonePrinting done_printing; - // this mutex protects access to shared state between the VMM and the guest Linux - has mutex cross_vm_event_mutex; -} -``` - -These interfaces will eventually be made visible to processes running in -the guest linux. The mutex is used to protect access to shared state -between the VMM and guest. - -### Define the component interface - -**Exercise** Define the print server component by adding the following to -the `crossvm_tutorial.camkes` file, after the `Init0` definition: -```c -component PrintServer { - control; - dataport Buf(4096) data; - consumes DoPrint do_print; - emits DonePrinting done_printing; -} -``` - -### Instantiate the print server - -**Exercise** Replace the `composition` definition: - -```c - composition { - VM_COMPOSITION_DEF() - VM_PER_VM_COMP_DEF(0) - } -``` - -with the following: - -```c - composition { - VM_COMPOSITION_DEF() - VM_PER_VM_COMP_DEF(0) - - component PrintServer print_server; - connection seL4Notification conn_do_print(from vm0.do_print, - to print_server.do_print); - connection seL4Notification conn_done_printing(from print_server.done_printing, - to vm0.done_printing); - - connection seL4SharedDataWithCaps conn_data(from print_server.data, - to vm0.data); - } -``` - -The [seL4SharedDataWithCaps][] -connector is a dataport connector much like `seL4SharedData`. -However, the `to` side of the connection also receives access to -the capabilities to the frames backing the dataport, which is required -for cross VM dataports, as the VMM must be able to establish shared memory -at runtime by inserting new mappings into the guest's address space. - -[seL4SharedDataWithCaps]: https://docs.sel4.systems/projects/camkes/seL4SharedDataWithCaps.html - -**Exercise** Interfaces connected with [seL4SharedDataWithCaps][] must be -configured with an integer specifying the ID and size of the dataport. - Do this now by modifying `crossvm_tutorial.camkes` with the following -two lines in the configuration section: - -```c - configuration { - ... - // Add the following 2 lines: - vm0.data_id = 1; // ids must be contiguous, starting from 1 - vm0.data_size = 4096; - } -``` - -### Implement the print server - -**Exercise** Add the file `components/print_server.c` with the following contents: -```c -#include -#include - -int run(void) { - - while (1) { - // wait for the next event - do_print_wait(); - - printf("%s\n", (char*)data); - - // signal that we are done printing - done_printing_emit(); - } - - return 0; -} -``` - -This provides a very simple component definition that loops forever, printing a string from -shared memory whenever an event is received then emitting an event. -The example code assumes that the shared buffer will contain a valid, null-terminated c string, which is not - something you should do in practice. - -### Implement the VMM side of the connection -Create another c file that tells the VMM about the cross VM connections. - This file must define 3 functions which initialize each type of cross vm interface: - -- `cross_vm_dataports_init` -- `cross_vm_emits_events_init` -- `cross_vm_consumes_events_init` - -**Exercise** Add a file `src/cross_vm.c` with the following contents: - -```c -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// this is defined in the dataport's glue code -extern dataport_caps_handle_t data_handle; - -// Array of dataport handles at positions corresponding to handle ids from spec -static dataport_caps_handle_t *dataports[] = { - NULL, // entry 0 is NULL so ids correspond with indices - &data_handle, -}; - -// Array of consumed event callbacks and ids -static camkes_consumes_event_t consumed_events[] = { - { .id = 1, .reg_callback = done_printing_reg_callback }, -}; - -// Array of emitted event emit functions -static camkes_emit_fn emitted_events[] = { - NULL, // entry 0 is NULL so ids correspond with indices - do_print_emit, -}; - -// mutex to protect shared event context -static camkes_mutex_t cross_vm_event_mutex = (camkes_mutex_t) { - .lock = cross_vm_event_mutex_lock, - .unlock = cross_vm_event_mutex_unlock, -}; - -int cross_vm_dataports_init(vmm_t *vmm) { - return cross_vm_dataports_init_common(vmm, dataports, sizeof(dataports)/sizeof(dataports[0])); -} - -int cross_vm_emits_events_init(vmm_t *vmm) { - return cross_vm_emits_events_init_common(vmm, emitted_events, - sizeof(emitted_events)/sizeof(emitted_events[0])); -} - -int cross_vm_consumes_events_init(vmm_t *vmm, vspace_t *vspace, seL4_Word irq_badge) { - return cross_vm_consumes_events_init_common(vmm, vspace, &cross_vm_event_mutex, - consumed_events, sizeof(consumed_events)/sizeof(consumed_events[0]), irq_badge); -} -``` - -### Update the build system - -**Exercise** Make the following changes in `CMakeLists.txt` by firstly replacing the declaration of Init0: - -```cmake -DeclareCAmkESVM(Init0) -``` - -with the following declaration: - -```cmake -# Retrieve Init0 cross vm src files -file(GLOB init0_extra src/*.c) -# Declare VM component: Init0 -DeclareCAmkESVM(Init0 - EXTRA_SOURCES ${init0_extra} - EXTRA_LIBS crossvm -) -``` - -Also add a declaration for a PrintServer component: - -```cmake -# Declare the CAmkES PrintServer component -DeclareCAmkESComponent(PrintServer SOURCES components/print_server.c) -``` - -This extends the definition of the Init component with the `cross_vm connector` source and the crossvm -library, and defines the new CAmkES component `PrintServer`. - -### Add interfaces to the Guest - -**Exercise** Create the following `camkes_init` shell script that is executed as Linux is initialized: - -```bash -#!/bin/sh -# Initialises linux-side of cross vm connections. - -# Dataport sizes must match those in the camkes spec. -# For each argument to dataport_init, the nth pair -# corresponds to the dataport with id n. -dataport_init /dev/camkes_data 4096 - -# The nth argument to event_init corresponds to the -# event with id n according to the camkes vmm. -consumes_event_init /dev/camkes_done_printing -emits_event_init /dev/camkes_do_print -``` - -Each of these commands creates device nodes associated with a particular -Linux kernel module supporting cross VM communication. Each command -takes a list of device nodes to create, which must correspond to the IDs -assigned to interfaces in `crossvm_tutorial.camkes` and `cross_vm.c`. The -`dataport_init` command must also be passed the size of each dataport. - -These changes will cause device nodes to be created which correspond to -the interfaces you added to the VMM component. - -### Create a process - -Now make a process that uses the device nodes to communicate with the -print server. - -**Exercise** First create a new directory: -``` -mkdir -p pkgs/print_client -``` - -with the following file `pkgs/print_client/print_client.c`: - -```c -#include -#include - -#include -#include -#include -#include - -#include "dataport.h" -#include "consumes_event.h" -#include "emits_event.h" - -int main(int argc, char *argv[]) { - - int data_fd = open("/dev/camkes_data", O_RDWR); - assert(data_fd >= 0); - - int do_print_fd = open("/dev/camkes_do_print", O_RDWR); - assert(do_print_fd >= 0); - - int done_printing_fd = open("/dev/camkes_done_printing", O_RDWR); - assert(done_printing_fd >= 0); - - char *data = (char*)dataport_mmap(data_fd); - assert(data != MAP_FAILED); - - ssize_t dataport_size = dataport_get_size(data_fd); - assert(dataport_size > 0); - - for (int i = 1; i < argc; i++) { - strncpy(data, argv[i], dataport_size); - emits_event_emit(do_print_fd); - consumes_event_wait(done_printing_fd); - } - - close(data_fd); - close(do_print_fd); - close(done_printing_fd); - - return 0; -} -``` - -This program prints each of its arguments on a separate line, by sending -each argument to the print server one at a time. - -**Exercise** Create `pkgs/print_client/CMakeLists.txt` for our client program: - -```cmake -cmake_minimum_required(VERSION 3.8.2) - -project(print_client C) - -file(READ ${CMAKE_MODULE_PATH_FILE} module_path) -list(APPEND CMAKE_MODULE_PATH ${module_path}) -find_package(camkes-vm-linux REQUIRED) -add_subdirectory(${CAMKES_VM_LINUX_DIR}/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/libs/camkes camkes) - -add_executable(print_client print_client.c) -target_link_libraries(print_client camkeslinux) -``` - -**Exercise** Update our the VM apps `CMakeLists.txt`. Below the line: - -```cmake -AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel) -``` - -add the `ExternalProject` declaration to include the print application: - -```cmake -# Get Custom toolchain for 32 bit Linux -include(cross_compiling) -FindCustomPollyToolchain(LINUX_32BIT_TOOLCHAIN "linux-gcc-32bit-pic") -# Declare our print server app external project -include(ExternalProject) -file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/module_path "${CMAKE_MODULE_PATH}") -ExternalProject_Add(print_client-app - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/pkgs/print_client - BINARY_DIR ${CMAKE_BINARY_DIR}/print_client-app - BUILD_ALWAYS ON - STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/print_client-app-stamp - EXCLUDE_FROM_ALL - INSTALL_COMMAND "" - CMAKE_ARGS - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_TOOLCHAIN_FILE=${LINUX_32BIT_TOOLCHAIN} - -DCMAKE_MODULE_PATH_FILE=${CMAKE_CURRENT_BINARY_DIR}/module_path -) -# Add the print client app to our overlay ('default_buildroot_overlay') -AddExternalProjFilesToOverlay(print_client-app ${CMAKE_BINARY_DIR}/print_client-app default_buildroot_overlay "usr/sbin" - FILES print_client) -``` - -Directly below this we also want to add our `camkes_init` script into the overlay. We place this into the VMs `init.d` directory so -the script is run on start up: - -```cmake -AddFileToOverlayDir("S90camkes_init" ${CMAKE_CURRENT_LIST_DIR}/camkes_init "etc/init.d" default_buildroot_overlay) -``` - -That's it. Build and run the system, and you should see the following output: - -``` -... -Creating dataport node /dev/camkes_data -Allocating 4096 bytes for /dev/camkes_data -Creating consuming event node /dev/camkes_done_printing -Creating emitting event node /dev/camkes_do_print - -Welcome to Buildroot -buildroot login: root -Password: -# print_client hello world -[ 12.730073] dataport received mmap for minor 1 -hello -world -``` \ No newline at end of file +{% include tutorial.md %} diff --git a/Tutorials/CAmkES/camkes-vm-linux.md b/Tutorials/CAmkES/camkes-vm-linux.md index 2f4d7f2ceb..9c8a032c8a 100644 --- a/Tutorials/CAmkES/camkes-vm-linux.md +++ b/Tutorials/CAmkES/camkes-vm-linux.md @@ -1,533 +1,13 @@ --- toc: true +title: Camkes VM Linux +tutorial: camkes-vm-linux +tutorial-order: vm-1 layout: tutorial +description: using Linux as a guest in the Camkes VM. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- +{% include tutorial.md %} -# CAmkES VM: Adding a Linux Guest - -This tutorial provides an introduction to creating VM guests and applications on seL4 using CAmkES. - -You will become familiar with: - -* Creating, configuring and building guest Linux VM components in CAmkES. -* Building and installing your own Linux VM user-level programs and kernel modules. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -./init --tut camkes-vm-linux -# building the tutorial exercise -cd camkes-vm-linux -ninja -``` -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut camkes-vm-linux -``` -
    - - -## Background - -This tutorial is set up with a basic CAmkES VM configuration for you to build upon. -The starting application should boot a single, very basic Linux guest. - -To build the tutorial, run: - -```sh -# In build directory -ninja -``` - -You can boot the tutorial on an x86 hardware platform with a multiboot boot loader, -or use the [QEMU](https://www.qemu.org) simulator. **Note if you are using QEMU -it is important to ensure that your host machine has VT-x support and [KVM](https://www.linux-kvm.org/page/Main_Page) -installed. You also need to ensure you have enabled nested virtulisation with KVM guests as described -[here](https://www.linux-kvm.org/page/Nested_Guests).** - -To simulate the image you can run the provided simulation script with some additional parameters: - -```sh -# In the build directory -# You will need to set up a tap device first: -# ip tuntap add tap0 mode tap -# ip addr add 10.0.120.100/24 dev tap0 -# ip link set dev tap0 up -sudo ./simulate --machine q35,accel=kvm,kernel-irqchip=split --mem-size 2G --extra-cpu-opts "+vmx" --extra-qemu-args="-enable-kvm -device intel-iommu,intremap=off -net nic,model=e1000 -net tap,script=no,ifname=tap0" -``` - -When first simulating the image you should see the following login prompt: -``` -Welcome to Buildroot -buildroot login: -``` - -You can login with the username `root` and the password `root`. - -The Linux guest was built using [buildroot](https://buildroot.org/), which -creates a compatible kernel and minimal root filesystem containing busybox and a in-memory file system (a ramdisk). - -## VM Components - -Each VM component has its own assembly implementation, where the guest environment is configured. -The provided VM configuration is defined in `vm_tutorial.camkes`: - -``` -import ; - -#include - -#define VM_GUEST_CMDLINE "earlyprintk=ttyS0,115200 console=ttyS0,115200 i8042.nokbd=y i8042.nomux=y \ -i8042.noaux=y io_delay=udelay noisapnp pci=nomsi debug root=/dev/mem" - -component Init0 { - VM_INIT_DEF() -} - -assembly { - composition { - VM_COMPOSITION_DEF() - VM_PER_VM_COMP_DEF(0) - } - - configuration { - VM_CONFIGURATION_DEF() - VM_PER_VM_CONFIG_DEF(0) - - vm0.simple_untyped23_pool = 20; - vm0.heap_size = 0x2000000; - vm0.guest_ram_mb = 128; - vm0.kernel_cmdline = VM_GUEST_CMDLINE; - vm0.kernel_image = "bzimage"; - vm0.kernel_relocs = "bzimage"; - vm0.initrd_image = "rootfs.cpio"; - vm0.iospace_domain = 0x0f; - } -} -``` - -Most of the work here is done by five C preprocessor macros: -`VM_INIT_DEF`, `VM_COMPOSITION_DEF`, `VM_PER_VM_COMP_DEF`, -`VM_CONFIGURATION_DEF`, `VM_PER_VM_CONFIG_DEF`. - -These are all defined in `projects/camkes/vm/components/VM/configurations/vm.h`, -and are concerned with specifying and configuring components that all -VM(M)s need. - -The `Init0` component corresponds to a single guest. Because of some rules -in the cpp macros, the *Ith* guest in your system must be defined as a -component named `InitI`. `InitI` components will be instantiated in the -composition section by the `VM_PER_VM_COMP_DEF` macro with instance -names `vmI`. The `vm0` component instance being configured above is an -instance of `Init0`. The C source code for`InitI` components is in -`projects/camkes/vm/components/Init/src`. This source will be used for components -named `InitI` for *I* in `0..VM_NUM_VM - 1`. - -The values of `vm0.kernel_cmdline`, `vm0.kernel_image` and `vm0.initrd_image` are all -strings specifying: - - boot arguments to the guest Linux, - - the name of the guest Linux kernel image file, - - and the name of the guest Linux initrd file (the root filesystem to use during system initialization). - -The kernel command-line is defined in the `VM_GUEST_CMDLINE` macro. The kernel image -and rootfs names are defined in the applications `CMakeLists.txt` file. -These are the names of files in a CPIO archive that gets created by the build system, and -linked into the VMM. In the simple configuration for thie tutorial, the VMM uses -the `bzimage` and `rootfs.cpio` names to find the appropriate files -in this archive. - -To see how the `Init` component and CPIO archive are definied within the build system, -look at the app's `CMakeList.txt`: - -```cmake -include(${SEL4_TUTORIALS_DIR}/settings.cmake) -sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR}) - -cmake_minimum_required(VERSION 3.8.2) - -project(vm-app C ASM) -include(ExternalProject) -find_package(camkes-vm REQUIRED) -include(${CAMKES_VM_SETTINGS_PATH}) -camkes_x86_vm_setup_x86_vm_environment() -include(${CAMKES_VM_HELPERS_PATH}) -find_package(camkes-vm-linux REQUIRED) -include(${CAMKES_VM_LINUX_HELPERS_PATH}) - - -# Include CAmkES VM helper functions - - - - -# Declare VM component: Init0 -DeclareCAmkESVM(Init0) - -# Get Default Linux VM files -GetArchDefaultLinuxKernelFile("32" default_kernel_file) -GetArchDefaultLinuxRootfsFile("32" default_rootfs_file) - -# Decompress Linux Kernel image and add to file server -DecompressLinuxKernel(extract_linux_kernel decompressed_kernel ${default_kernel_file}) - -AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel) - - - -# Add rootfs images into file server -AddToFileServer("rootfs.cpio" ${default_rootfs_file}) - - - -# Initialise CAmkES Root Server with addition CPP includes -DeclareCAmkESVMRootServer(vm_tutorial.camkes) -GenerateCAmkESRootserver() - -``` - -The file `projects/camkes/vm/camkes_vm_helpers.cmake` provides helper functions for the VM projects, -including `DeclareCAmkESVM(Init0)`, which is used to define the `Init0` VM component. -Each Init component requires a corresponding `DeclareCAmkESVM` function. - -`GetArchDefaultLinuxKernelFile` (defined in `projects/camkes/vm-linux/vm-linux-helpers.cmake`) -is a helper function that retrieves the location of an architectural specific VM image provided -in the `projects/vm-linux` folder, which contains some tools for building new linux kernel -and root filesystem images, as well as the images that these tools -produce. A fresh checkout of this project will contain some pre-built -images (`bzimage` and `rootfs.cpio`), to speed up build times. - -`DecompressLinuxKernel` is used to extract the vmlinux image, which `AddToFileServer` then places -in the fileserver along with the rootfs. - -## Adding to the guest - -In the simple buildroot guest image, the -initrd (rootfs.cpio) is also the filesystem you get access to after -logging in. To make new programs available to the guest you need to add them to the -rootfs.cpio archive. Similarly, to make new kernel modules available to -the guest they must be added to the rootfs.cpio archive also. - -In this tutorial you will install new programs into the guest VM. - -### vm-linux-helpers.cmake - -The `projects/camkes/vm-linux` directory contains CMake helpers to -overlay rootfs.cpio archives with a desired set of programs, modules -and scripts. - -#### `AddFileToOverlayDir(filename file_location root_location overlay_name)` -This helper allows you to overlay specific files onto a rootfs image. The caller specifies -the file they wish to install in the rootfs image (`file_location`), the name they want the file -to be called in the rootfs (`filename`) and the location they want the file to installed in the -rootfs (`root_location`), e.g "usr/bin". Lastly the caller passes in a unique target name for the overlay -(`overlay_name`). You can repeatedly call this helper with different files for a given target to build -up a set of files to be installed on a rootfs image. - -#### `AddOverlayDirToRootfs(rootfs_overlay rootfs_image rootfs_distro rootfs_overlay_mode output_rootfs_location target_name)` -This helper allows you to install a defined overlay target onto a given rootfs image. The caller specifies -the rootfs overlay target name (`rootfs_overlay`), the rootfs image they wish to install their files onto -(`rootfs_image`), the distribution of their rootfs image (`rootfs_distro`, only 'buildroot' and 'debian' is -supported) and the output location of their overlayed rootfs image (`output_rootfs_location`). Lastly the caller -specifies how the files will be installed into their rootfs image through `rootfs_overlay_mode`. These modes include: -* `rootfs_install`: The files are installed onto the rootfs image. This is useful if the rootfs image is the filesystem -your guest VM is using when it boots. However this won't be useful if your VM will be booting from disk since the installed files -won't be present after the VM boots. -* `overlay`: The files are mounted as an overlayed filesystem (overlayfs). This is useful if you are booting from disk and don't wish to -install the artifacts permanently onto the VM. The downside to this is that writes to the overlayed root do not persist between boots. This -mode is benefitial for debugging purposes and live VM images. -* `fs_install`: The files are permanently installed on the VM's file system, after the root has been mounted. -#### `AddExternalProjFilesToOverlay(external_target external_install_dir overlay_target overlay_root_location)` -This helper allows you to add files generated from an external CMake project to an overlay target. This is mainly a wrapper around -`AddOverlayDirToRootfs` which in addition creates a target for the generated file in the external project. The caller passes the external -project target (`external_target`), the external projects install directory (`external_install_dir`), the overlay target you want to add the -file to (`overlay_target`) and the location you wish to install the file within the rootfs image (`overlay_root_location`). - -### linux-source-helpers.cmake - -#### `DownloadLinux(linux_major linux_minor linux_md5 linux_out_dir linux_out_target)` -This is a helper function for downloading the linux source. This is needed if we wish to build our own kernel modules. - -#### `ConfigureLinux(linux_dir linux_config_location linux_symvers_location configure_linux_target)` -This helper function is used for configuring downloaded linux source with a given Kbuild defconfig (`linux_config_location`) -and symvers file (`linux_symvers_location`). - -## Exercises - -### Adding a program - -This exercise guides you through adding a new program to the Linux guest user-level environment. - -First, make a new directory: -```bash -mkdir -p pkg/hello -``` -Then a simple C program in `pkg/hello/hello.c`: -```c -#include - -int main(int argc, char *argv[]) { - printf("Hello, World!\n"); - return 0; -} -``` -Then create a build file for the program at `pkg/hello/CMakeLists.txt`: - -```cmake -cmake_minimum_required(VERSION 3.8.2) - -project(hello C) - -add_executable(hello hello.c) - -target_link_libraries(hello -static) -``` -Now integrate the new program with the build system. -Update the VM apps `CMakeLists.txt` to declare the hello application as an -external project and add it to our overlay. - Do this by replacing the line `AddToFileServer("rootfs.cpio" ${default_rootfs_file})` with the following: - -```cmake -# Get Custom toolchain for 32 bit Linux -include(cross_compiling) -FindCustomPollyToolchain(LINUX_32BIT_TOOLCHAIN "linux-gcc-32bit-pic") -# Declare our hello app external project -ExternalProject_Add(hello-app - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/pkg/hello - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/hello-app - BUILD_ALWAYS ON - STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/hello-app-stamp - EXCLUDE_FROM_ALL - INSTALL_COMMAND "" - CMAKE_ARGS - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_TOOLCHAIN_FILE=${LINUX_32BIT_TOOLCHAIN} -) -# Add the hello world app to our overlay ('vm-overlay') -AddExternalProjFilesToOverlay(hello-app ${CMAKE_CURRENT_BINARY_DIR}/hello-app vm-overlay "usr/sbin" - FILES hello) -# Add the overlay directory to our default rootfs image -AddOverlayDirToRootfs(vm-overlay ${default_rootfs_file} "buildroot" "rootfs_install" - rootfs_file rootfs_target) -AddToFileServer("rootfs.cpio" ${rootfs_file} DEPENDS rootfs_target) -``` -Now rebuild the project... - -```sh -# In build directory -ninja -``` -..and run it (use `root` as username and password). -You should be able to use the new program. - -``` -Welcome to Buildroot -buildroot login: root -Password: -# hello -Hello, World! -``` - -## Adding a kernel module - -The next exercise guides you through the addition of a new kernel module that provides -guest to VMM communication. This is a very simply module: you'll create a special file -associated with the new module, which when written to causes the VMM to print message. - -First, make a new directory: -``` -mkdir -p modules/poke -``` -Then create the following file for the module in `modules/poke/poke.c`. -```c -#include -#include -#include -#include - -#include -#include -#include - -#define DEVICE_NAME "poke" - -static int major_number; - -static ssize_t poke_write(struct file *f, const char __user*b, size_t s, loff_t *o) { - printk("hi\n"); // TODO replace with hypercall - return s; -} - -struct file_operations fops = { - .write = poke_write, -}; - -static int __init poke_init(void) { - major_number = register_chrdev(0, DEVICE_NAME, &fops); - printk(KERN_INFO "%s initialized with major number %dn", DEVICE_NAME, major_number); - return 0; -} - -static void __exit poke_exit(void) { - unregister_chrdev(major_number, DEVICE_NAME); - printk(KERN_INFO"%s exitn", DEVICE_NAME); -} - -module_init(poke_init); -module_exit(poke_exit); -``` -Now add a Makefile for building the module in `modules/poke/Makefile`: - -```make -obj-m += poke.o - -all: - make -C $(KHEAD) M=$(PWD) modules - -clean: - make -C $(KHEAD) M=$(PWD) clean -``` - -Create a `modules/CMakeLists.txt` to define the new Linux module with the following content: -```cmake -cmake_minimum_required(VERSION 3.8.2) - -if(NOT MODULE_HELPERS_FILE) - message(FATAL_ERROR "MODULE_HELPERS_FILE is not defined") -endif() - -include("${MODULE_HELPERS_FILE}") - -DefineLinuxModule(${CMAKE_CURRENT_LIST_DIR}/poke poke-module poke-target KERNEL_DIR ${LINUX_KERNEL_DIR}) -``` -Update the VM `CMakeLists.txt` file to declare the new poke module as an -external project and add it to the overlay. - -At the top of the file include our linux helpers, add the following: - -```cmake -include(${CAMKES_VM_LINUX_SOURCE_HELPERS_PATH}) -``` -Below the includes (before `AddOverlayDirToRootfs` that was added in the first exercise **Adding a program**) add: -```cmake -# Setup Linux Sources -GetDefaultLinuxMajor(linux_major) -GetDefaultLinuxMinor(linux_minor) -GetDefaultLinuxMd5(linux_md5) -# Download and Configure our Linux sources -DownloadLinux(${linux_major} ${linux_minor} ${linux_md5} vm_linux_extract_dir download_vm_linux) -set(linux_config "${CAMKES_VM_LINUX_DIR}/linux_configs/${linux_major}.${linux_minor}/32/config") -set(linux_symvers "${CAMKES_VM_LINUX_DIR}/linux_configs/${linux_major}.${linux_minor}/32/Module.symvers") -ConfigureLinux(${vm_linux_extract_dir} ${linux_config} ${linux_symvers} configure_vm_linux - DEPENDS download_vm_linux -) -# Add the external poke module project -ExternalProject_Add(poke-module - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/modules - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/poke-module - BUILD_ALWAYS ON - STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/poke-module-stamp - EXCLUDE_FROM_ALL - INSTALL_COMMAND "" - DEPENDS download_vm_linux configure_vm_linux - CMAKE_ARGS - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_TOOLCHAIN_FILE=${LINUX_32BIT_TOOLCHAIN} - -DLINUX_KERNEL_DIR=${vm_linux_extract_dir} - -DMODULE_HELPERS_FILE=${CAMKES_VM_LINUX_DIR}/linux-module-helpers.cmake -) -# Add our module binary to the overlay -AddExternalProjFilesToOverlay(poke-module ${CMAKE_CURRENT_BINARY_DIR}/poke-module vm-overlay "lib/modules/4.8.16/kernel/drivers/vmm" - FILES poke.ko) -``` - -Write a custom init script that loads the new module during initialization. -Create a file called `init` in our tutorial directory with the following: - -```bash -#!/bin/sh -# devtmpfs does not get automounted for initramfs -/bin/mount -t devtmpfs devtmpfs /dev -exec 0/dev/console -exec 2>/dev/console - -insmod /lib/modules/4.8.16/kernel/drivers/vmm/poke.ko -exec /sbin/init $* -``` -Now update our the VM apps `CMakeLists.txt` file to add the new init script to the -overlay. After our call to `AddExternalProjFilesToOverlay` and before `AddOverlayDirToRootfs` for the poke module add the following: - -```cmake -AddFileToOverlayDir("init" ${CMAKE_CURRENT_LIST_DIR}/init "." vm-overlay) -``` -and give the script executable permissions: -```bash -chmod +x init -``` -Rebuild the project: - -```sh -# In build directory -ninja -``` -Run the following commands to see the module being used: - -``` -Welcome to Buildroot -buildroot login: root -Password: -# grep poke /proc/devices # figure out the major number of our driver -246 poke -# mknod /dev/poke c 246 0 # create the special file -# echo > /dev/poke # write to the file -[ 57.389643] hi --sh: write error: Bad address # the shell complains, but our module is being invoked! -``` - -### Create a hypercall - -In `modules/poke/poke.c`, replace `printk("hi\n");` with `kvm_hypercall1(4, 0);`. -The choice of 4 is because 0..3 are already used by existing hypercalls. - -Then register a handler for this hypercall in `projects/camkes/vm/components/Init/src/main.c`:. -Add a new function at the top of the file: - -```c -static int poke_handler(vm_vcpu_t *vm_vcpu) { - printf("POKE!!!\n"); - return 0; -} -``` - -In the function `main_continued` register \`poke_handler\`: - -```c -vm_reg_new_vmcall_handler(&vm, poke_handler, 4); // <--- added - -/* Now go run the event loop */ -vmm_run(&vm); -``` - -Rebuild the project and try out the hypercall + module: - -```sh -# In build directory -ninja -``` -``` -Welcome to Buildroot -buildroot login: root -Password: -# mknod /dev/poke c 246 0 -# echo > /dev/poke -POKE!!! -``` -Next tutorial: CAmkES cross VM +Next tutorial: CAmkES Cross VM diff --git a/Tutorials/CAmkES/hello-camkes-0.md b/Tutorials/CAmkES/hello-camkes-0.md index 62bd3e783f..1ed57a311e 100644 --- a/Tutorials/CAmkES/hello-camkes-0.md +++ b/Tutorials/CAmkES/hello-camkes-0.md @@ -1,191 +1,13 @@ --- toc: true +title: Camkes +tutorial: hello-camkes-0 +tutorial-order: camkes-0 layout: tutorial +description: an introduction to Camkes concepts. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- +{% include tutorial.md %} - -# CAmkES Tutorial: Introduction - -This tutorial is an introduction to CAmkES. This will involve introducing the CAmkES syntax, bootstrapping a basic -static CAmkES application and describing its components. - -Note that it's possible to successfully complete the CAmkES tutorial without having read the manual, however highly -recommended that you familiarise yourself with the [CAmkES manual](https://github.com/seL4/camkes-tool/blob/master/docs/index.md). - - -Outcomes: -- Understand the structure of a CAmkES application, as a described, well-defined, static system. -- Understand the file-layout of a CAmkES ADL project. -- Become acquainted with the basics of creating a practical CAmkES application. - -## Background - -The fundamentals of CAmkES are the component, the interface and the connection. Components are logical -groupings of code and resources. They communicate with other component instances via well-defined -interfaces which must be statically defined, over communication channels. - -### Component - -As briefly described above, we identify a component as a functional grouping of code and resources. We -use the term component in CAmkES to refer to the *type* of our functional grouping (see the Component section in the [manual](https://github.com/seL4/camkes-tool/blob/master/docs/index.md#component)). -An example of this in concrete CAmkES syntax can be seen below: - -```c -component foo { - control; - uses MyInterface a; - attribute Int b; -} -``` - -Disregarding the items defined within the component (we will unpack these in a later tutorial), we defined a component above -whose *type* is `foo`. We later can use our `foo` type to define a component *instance*. -For example, the statement `component foo bar` refers to a component instance `bar` whose type is -`foo`. - -### Describing a static system: Assembly, Composition and Configuration - -In CAmkES, we will commonly see the use of three hierarchical elements, being `assembly`, `composition` and `configuration`. We use these concepts -to build upon a well-defined static system. We firstly use the term 'assembly' to refer to a complete description of our static system. In the CAmkES ADL (Architecture Description Language), -we employ the term `assembly` as a top-level element that will encapsulate our system definition. Each CAmkES project must contain -at least one `assembly` definition. An example of using the `assembly` term in CAmkES can be seen below: - -```c -assembly { - composition { - component foo bar; - } - - configuration { - bar.b = 0; - } -} -``` - -In the above example we can also see the use of the `composition` and `configuration` elements. The `composition` element is -used as a container to encapsulate our component and connector instantiations. Above we declare an instance of -our `foo` component and we appropriately called it `bar`. The `configuration` element is also used to describe settings and attribute -assignments in our given system. - -## Creating your first CAmkES application - -In this tutorial we will create a simple 'Hello World' example within the CAmkES. This will invole creating a CAmkES component that will -print "Hello CAmkES World" when it starts up. - -### Looking at the sources - -In the tutorial directory, you will find the following files: -* `CMakeLists.txt` - the file that defines how to build our CAmkES application -* `client.c` - the single source file for our 'Hello World' client component -* `hello.camkes` - Our CAmkES file describing our static system - -#### `client.c` - -For this tutorial we require our component to simply print "Hello CAmkES World". We define this in -a typical C file `client.c`: - -```c -/* - * CAmkES tutorial part 0: just a component. - */ - -#include - -/* generated header for our component */ -#include - -/* run the control thread */ -int run(void) { - printf("Hello CAmkES World\n"); - return 0; -} -``` - -Note above that in the source code of `client.c` instead of typically using `main`, we place -our runtime code in the function `int run(void)`. `run` is the entry point -of a CAmkES component. - -#### `hello.camkes` - -The `hello.camkes` file is where we form our description of a static CAmkES system. Our `.camkes` -files are written using the CAmkES syntax. Employing the concepts discussed in the background -section, we define the following: - -```c -/* - * CAmkES tutorial part 0: just a component. - */ - -component Client { - control; -} - -assembly { - composition { - component Client client; - } -} -``` - -In the source above we create a minimal static system with a single component instance. We define -our component `Client` and declare an instance of that component in our system. - -#### `CMakeLists.txt` - -Every CAmkES project requires a `CMakeLists.txt` file to be incorporated in the seL4 build system. Our tutorial -directory should contain the following `CMakeLists.txt` file: - -```cmake - -include(${SEL4_TUTORIALS_DIR}/settings.cmake) -sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR}) - -cmake_minimum_required(VERSION 3.7.2) - -project(hello-camkes-0 C ASM) - -find_package(camkes-tool REQUIRED) -camkes_tool_setup_camkes_build_environment() - -DeclareCAmkESComponent(Client SOURCES client.c) - -DeclareCAmkESRootserver(hello.camkes) - -GenerateCAmkESRootserver() -``` - -Our `CMakeLists.txt` file declares our `Client` component, linking it with our `client.c` source -file. In addition it declares the CAmkES Root Server using our `hello.camkes` system description. - -### Building your first CAmkES system - -At this point all you need to do is build and run the tutorial: - - -```sh -# In build directory -ninja -``` - -If build successfully, we can run our system as follows: - - -```sh -# In build directory -./simulate -``` - -and should see the following once the system has booted: - -``` -Hello CAmkES World -``` - -## Done - Congratulations: be sure to read up on the keywords and -structure of ADL: it's key to understanding CAmkES. And well done on -building and running your first CAmkES application. - -Next tutorial: CAmkES 1: Introduction to CAmkES +Next tutorial: CAmkES 1: Introduction to CAmkES diff --git a/Tutorials/CAmkES/hello-camkes-1.md b/Tutorials/CAmkES/hello-camkes-1.md index 767f4a8253..f981d02ef9 100644 --- a/Tutorials/CAmkES/hello-camkes-1.md +++ b/Tutorials/CAmkES/hello-camkes-1.md @@ -1,286 +1,13 @@ --- toc: true +title: Camkes 1 +tutorial: hello-camkes-1 +tutorial-order: camkes-1 layout: tutorial +description: an introduction to Camkes concepts. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- +{% include tutorial.md %} -# CAmkES Tutorial 1: Introduction to CAmkES -This tutorial is an introduction to -CAmkES: bootstrapping a basic static CAmkES application, describing its -components, and linking them together. - -Outcomes: -1. Understand the structure of a CAmkES application, as a described, -well-defined, static system. -2. Understand the file-layout of a CAmkES ADL project. -3. Become acquainted with the basics of creating a practical CAmkES application. - - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut hello-camkes-1 -# building the tutorial exercise -cd hello-camkes-1_build -ninja -``` -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut hello-camkes-1 -``` -
    - - -## Background - -The fundamentals of CAmkES are the component, the interface and the connection. - -### Components - -*Components* are logical -groupings of code and resources. They communicate with other component -instances via well-defined interfaces which must be statically defined, -over communication channels. This tutorial will lead you through the -construction of a CAmkES application with two components: an Echo -server, and its Client that makes calls to it. These components are -defined when you initialise your build repository, found in -the following camkes file: - -- `hello-camkes-1/hello-1.camkes` - -Find the Component manual section here: - - -### Connections - - The second fundamental component of CAmkES applications -is the *Connection*: a connection is the representation of a method of -communication between two software components in CAmkES. The underlying -implementation may be shared memory, synchronous IPC, notifications or -some other implementation-provided means. In this particular tutorial, -we are using synchronous IPC. In implementation terms, this boils down -to the `seL4_Call` syscall on seL4. - -Find the "Connection" keyword manual section here: - - -### Interfaces - - All communications over a CAmkES connection must be well -defined: static systems' communications should be able to be reasoned -about at build time. All the function calls which will be delivered over -a communication channel then, also are well defined, and logically -grouped so as to provide clear directional understanding of all -transmissions over a connection. Components are connected together in -CAmkES, yes -- but the interfaces that are exposed over each connection -for calling by other components, are also described. - -There are different -kinds of interfaces: --Dataports, --Procedural interfaces, --and Notifications. - -This tutorial will lead you through the construction of a Procedural -interface, which is an interface over which function calls are made -according to a well-defined pre-determined API. The keyword for this -kind of interface in CAmkES is `procedure`. The definition of this -Procedure interface may be found here: -`hello-camkes-1/interfaces/HelloSimple.idl4` - -Find the "Procedure" keyword definition here: - - -### Component source - - Based on the ADL, CAmkES generates boilerplate which -conforms to your system's architecture, and enables you to fill in the -spaces with your program's logic. The two generated files in this -tutorial application are, in accordance with the Components we have -defined: - -- `hello-camkes-1/components/Echo/src/echo.c` -- `hello-camkes-1/components/Client/src/client.c` - -Now when it comes to invoking the functions that were defined in the -Interface specification -(`hello-camkes-1/interfaces/HelloSimple.idl4`), -you must prefix the API function name with the name of the Interface -instance that you are exposing over the particular connection. - -The reason for this is because it is possible for one component to -expose an interface multiple times, with each instance of that interface -referring to a different function altogether. For example, if a -composite device, such as a network card with with a serial interface -integrated into it, exposes two instances of a procedural interface that -has a particular procedure named `send()` -- how will the caller of -`send()` know whether his `send()` is the one that is exposed over the -NIC connection, or the serial connection? - -The same component provides both. Therefore, CAmkES prefixes the -instances of functions in an Interface with the Interface-instance's -name. In the dual-function NIC device's case, it might have a -`provides serial` and a `provides nic`. -When a caller wants to call for the NIC-send, it would call, -nic_send(), and when a caller wants to invoke the Serial-send, it would -call, "serial_send()". - -So if the `Hello` interface is provided once by `Echo` as `a`, you would -call for the `a` instance of Echo's `Hello` by calling for `a_hello()`. -But what if Echo had provided 2 instances of the `Hello` interface, and -the second one was named `a2`? Then in order to call on that second -`Hello` interface instance on Echo, you would call `a2_hello()`. - -## Exercises - -### Define instance in the composition section of the ADL -**Exercise** First modify `hello-1.camkes`. Define instances of `Echo` and `Client` in the -`composition` section of the ADL. - -``` -assembly { - composition { - component EmptyComponent empty; - // TODO remove the empty component, and define an Echo and a Client component -``` -
    -Quick solution -``` - assembly { - composition { - component EmptyComponent empty; - component Client client; - component Echo echo; -``` -
    - -**### Add a connection** -**Exercise** Now add a connection from `client.hello` to `echo.hello`. - -``` - /* hint 1: use seL4RPCCall as the connector (or you could use seL4RPC if you prefer) - * hint 2: look at - * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application - */ -``` -
    -Quick solution -``` - connection seL4RPCCall hello_con(from client.hello, to echo.hello); -``` -
    - -### Define an interface - -**Exercise** Define the interface for hello in `interfaces/HelloSimple.idl4`. - -```c -/* Simple RPC interface */ -procedure HelloSimple { - /* TODO define RPC functions */ - /* hint 1: define at least one function that takes a string as input parameter. call it say_hello. no return value - * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application - */ -}; -``` -
    -Quick solution -``` - void say_hello(in string str); -``` -
    - -### Implement a RPC function -**Exercise** Implement the RPC hello function. - -```c -/* - * CAmkES tutorial part 1: components with RPC. Server part. - */ -#include - -/* generated header for our component */ -#include -/* TASK 5: implement the RPC function. */ -/* hint 1: the name of the function to implement is a composition of an interface name and a function name: - * i.e.: _ - * hint 2: the interfaces available are defined by the component, e.g. in hello-1.camkes - * hint 3: the function name is defined by the interface definition, e.g. in interfaces/HelloSimple.idl4 - * hint 4: so the function would be: hello_say_hello() - * hint 5: the CAmkES 'string' type maps to 'const char *' in C - * hint 6: make the function print out a mesage using printf - * hint 7: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application - */ -``` -
    -Quick solution -``` -void hello_say_hello(const char *str) { - printf("Component %s saying: %s\n", get_instance_name(), str); -} -``` -
    - -### Invoke a RPC function -**Exercise** Invoke the RPC function in `components/Client/src/client.c`. -```c -/* - * CAmkES tutorial part 1: components with RPC. Client part. - */ - -#include - -/* generated header for our component */ -#include - -/* run the control thread */ -int run(void) { - printf("Starting the client\n"); - printf("-------------------\n"); - /* TODO: invoke the RPC function */ - /* hint 1: the name of the function to invoke is a composition of an interface name and a function name: - * i.e.: _ - * hint 2: the interfaces available are defined by the component, e.g. in hello-1.camkes - * hint 3: the function name is defined by the interface definition, e.g. in interfaces/HelloSimple.idl4 - * hint 4: so the function would be: hello_say_hello() - * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application - */ - printf("After the client\n"); - return 0; -} -``` -
    -Quick solution -``` - char *shello = "hello world"; - hello_say_hello(shello); -``` -
    - -### TASK 5 - Here you define the callee-side invocation functions for -the Hello interface exposed by Echo. - -**Can't find a solution---------------------------------------------------------** - -
    -Quick solution -``` -``` -
    - -## Done - -Now build and run the project, if it compiles: Congratulations! Be sure to read up on the keywords and -structure of ADL: it's key to understanding CAmkES. And well done on -writing your first CAmkES application. - -Next tutorial: CAmkES 2: Events \ No newline at end of file +Next tutorial: CAmkES 2: Events \ No newline at end of file diff --git a/Tutorials/CAmkES/hello-camkes-2.md b/Tutorials/CAmkES/hello-camkes-2.md index 3d95ecd943..935e1896f6 100644 --- a/Tutorials/CAmkES/hello-camkes-2.md +++ b/Tutorials/CAmkES/hello-camkes-2.md @@ -1,483 +1,13 @@ --- toc: true +title: Camkes 2 +tutorial: hello-camkes-2 +tutorial-order: camkes-2 layout: tutorial +description: an introduction to Camkes concepts. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- +{% include tutorial.md %} -# CAmkES Tutorial 2: Events -This tutorial shows how to build events in CAmkES. - -Learn how to: -- Represent and implement events in CAmkES. -- Use Dataports. - - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut hello-camkes-2 -# building the tutorial exercise -cd hello-camkes-2_build -ninja -``` -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut hello-camkes-2 -``` -
    - - -### TASK 1 - Here you're declaring the events that will be bounced -back and forth in this tutorial. An event is a signal is sent over a -Notification connection. - -You are strongly advised to read the manual section on Events here: -. - - ''Ensure that when declaring the consumes and emits keywords between - the Client.camkes and Echo.camkes files, you match them up so that - you're not emitting on both sides of a single interface, or consuming - on both sides of an interface.'' - -#### Specify an events interface -
    -Quick solution -``` - /* TASK 1: the event interfaces */ - /* hint 1: specify 2 interfaces: one "emits" and one "consumes" - * hint 2: you can use an arbitrary string as the interface type (it doesn't get used) - * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events - */ - emits TheEvent echo; - consumes TheEvent client; -``` -
    - - -### TASK 10, 11, 14, 15, 22, 25 - Recall that CAmkES prefixes the name -of the interface instance to the function being called across that -interface? This is the same phenomenon, but for events; in the case of a -connection over which events are sent, there is no API, but rather -CAmkES will generate \_emit() and \_wait() functions to enable the -application to transparently interact with these events. - -#### Signal that the data is available -
    -Quick solution -```c - /* TASK 10: emit event to signal that the data is available */ - /* hint 1: use the function _emit - * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events - */ - echo_emit(); -``` -
    - -#### Wait for data to become available -
    -Quick solution -```c - /* TASK 11: wait to get an event back signalling that the reply data is available */ - /* hint 1: use the function _wait - * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events - */ - client_wait(); -``` -
    - -#### Signal that data is available -
    -
    -Quick solution -```c - /* TASK 14: emit event to signal that the data is available */ - /* hint 1: we've already done this before */ - echo_emit(); -``` -
    - -#### Wait for data to be read -
    -Quick solution -```c - /* TASK 15: wait to get an event back signalling that data has been read */ - /* hint 1: we've already done this before */ - client_wait(); -``` -
    - -#### Signal that data is available -
    -Quick solution -```c - /* TASK 22: notify the client that there is new data available for it */ - /* hint 1: use the function _emit - * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events - */ - client_emit(); -``` -
    - -#### Signal that data has been read -
    -Quick solution -```c - /* TASK 25: notify the client that we are done reading the data */ - /* hint 1: use the function _emit - * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events - */ - client_emit(); -``` -
    - - -### TASK 18, 21, 24 - One way to handle notifications in CAmkES is to -use callbacks when they are raised. CAmkES generates functions that -handle the registration of callbacks for each notification interface -instance. These steps help you to become familiar with this approach. - -#### Register a callback handler -
    -Quick solution -```c - /* this function is invoked to initialise the echo event interface before it - * becomes active. */ - /* TASK 17: replace "echo" with the actual name of the "consumes" event interface */ - /* hint 1: use the interface name as defined in Echo.camkes. - * For example if you defined it as "consumes TheEvent c_event" then you would use "c_event". - */ - void echo__init(void) { - /* TASK 18: register the first callback handler for this interface */ - /* hint 1: use the function _reg_callback() - * hint 2: register the function "callback_handler_1" - * hint 3: pass NULL as the extra argument to the callback - * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events - */ - int error = echo_reg_callback(callback_handler_1, NULL); - ZF_LOGF_IF(error != 0, "Failed to register callback"); - } -``` -
    - -#### Register another callback handler -
    -Quick solution -```c - /* TASK 21: register the second callback for this event. */ - /* hint 1: use the function _reg_callback() - * hint 2: register the function "callback_handler_2" - * hint 3: pass NULL as the extra argument to the callback - * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events - */ - int error = echo_reg_callback(callback_handler_2, NULL); - ZF_LOGF_IF(error != 0, "Failed to register callback"); -``` -
    - -#### Register a callback handler -
    -Quick solution -```c - /* TASK 24: register the original callback handler for this event */ - /* hint 1: use the function _reg_callback() - * hint 2: register the function "callback_handler_1" - * hint 3: pass NULL as the extra argument to the callback - * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events - */ - int error = echo_reg_callback(callback_handler_1, NULL); - ZF_LOGF_IF(error != 0, "Failed to register callback"); -``` -
    - ------------------------------------------------------------------------- - -### TASK 2, 4 - Dataports are typed shared memory mappings. In your -CAmkES ADL specification, you state what C data type you'll be using to -access the data in the shared memory -- so you can specify a C struct -type, etc. - -The really neat part is more that CAmkES provides access control for -accessing these shared memory mappings: if a shared mem mapping is such -that one party writes and the other reads and never writes, we can tell -CAmkES about this access constraint in ADL. - -So in TASKs 2 and 4, you're first being led to create the "Dataport" -interface instances on each of the components that will be participating -in the shared mem communication. We will then link them together using a -"seL4SharedData" connector later on. - -#### Specify dataport interfaces -
    -Quick solution -``` - /* TASK 2: the dataport interfaces */ - /* hint 1: specify 3 interfaces: one of type "Buf", one of type "str_buf_t" and one of type "ptr_buf_t" - * hint 2: for the definition of these types see "str_buf.h". - * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports - */ - dataport Buf d; - dataport str_buf_t d_typed; - dataport ptr_buf_t d_ptrs; -``` -
    - -#### Specify dataport interfaces -
    -Quick solution -``` - /* TASK 4: the dataport interfaces */ - /* hint 1: specify 3 interfaces: one of type "Buf", one of type "str_buf_t" and one of type "ptr_buf_t" - * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports - */ - dataport Buf d; - dataport str_buf_t d_typed; - dataport ptr_buf_t d_ptrs; -``` -
    - -### TASK 6 - And here we are: we're about to specify connections -between the shared memory pages in each client, and tell CAmkES to link -these using shared underlying Frame objects. Fill out this step, and -proceed. - -#### Specify dataport connections -
    -Quick solution -``` - /* TASK 6: Dataport connections */ - /* hint 1: connect the corresponding dataport interfaces of the components to each other - * hint 2: use seL4SharedData as the connector - * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports - */ - connection seL4SharedData data_conn(from client.d, to echo.d); - connection seL4SharedData typed_data_conn(from client.d_typed, to echo.d_typed); - connection seL4SharedData ptr_data_conn(from client.d_ptrs, to echo.d_ptrs); -``` -
    - -### TASK 9, 12, 13 - These steps are asking you to write some C code -to access and manipulate the data in the shared memory mapping -(Dataport) of the client. Follow through to the next step. - -#### Copy strings to an untyped dataport -
    -Quick solution -```c - /* TASK 9: copy strings to an untyped dataport */ - /* hint 1: use the "Buf" dataport as defined in the Client.camkes file - * hint 2: to access the dataport use the interface name as defined in Client.camkes. - * For example if you defined it as "dataport Buf d" then you would use "d" to refer to the dataport in C. - * hint 3: first write the number of strings (NUM_STRINGS) to the dataport - * hint 4: then copy all the strings from "s_arr" to the dataport. - * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports - */ - int *n = (int*)d; - *n = NUM_STRINGS; - char *str = (char*)(n + 1); - for (int i = 0; i < NUM_STRINGS; i++) { - strcpy(str, s_arr[i]); - str += strlen(str) + 1; - } -``` -
    - -#### Read the reply data from a typed dataport -
    -Quick solution -``` - /* TASK 12: read the reply data from a typed dataport */ - /* hint 1: use the "str_buf_t" dataport as defined in the Client.camkes file - * hint 2: to access the dataport use the interface name as defined in Client.camkes. - * For example if you defined it as "dataport str_buf_t d_typed" then you would use "d_typed" to refer to the dataport in C. - * hint 3: for the definition of "str_buf_t" see "str_buf.h". - * hint 4: use the "n" field to determine the number of strings in the dataport - * hint 5: print out the specified number of strings from the "str" field - * hint 6: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports - */ - for (int i = 0; i < d_typed->n; i++) { - printf("%s: string %d (%p): \"%s\"\n", get_instance_name(), i, d_typed->str[i], d_typed->str[i]); - } -``` -
    - -### Send data using dataports -
    -Quick solution -``` - /* TASK 13: send the data over again, this time using two dataports, one - * untyped dataport containing the data, and one typed dataport containing - * dataport pointers pointing to data in the untyped, dataport. - */ - /* hint 1: for the untyped dataport use the "Buf" dataport as defined in the Client.camkes file - * hint 2: for the typed dataport use the "ptr_buf_t" dataport as defined in the Client.camkes file - * hint 3: for the definition of "ptr_buf_t" see "str_buf.h". - * hint 4: copy all the strings from "s_arr" into the untyped dataport - * hint 5: use the "n" field of the typed dataport to specify the number of dataport pointers (NUM_STRINGS) - * hint 6: use the "ptr" field of the typed dataport to store the dataport pointers - * hint 7: use the function "dataport_wrap_ptr()" to create a dataport pointer from a regular pointer - * hint 8: the dataport pointers should point into the untyped dataport - * hint 9: for more information about dataport pointers see: https://github.com/seL4/camkes-tool/blob/master/docs/index.md - */ - d_ptrs->n = NUM_STRINGS; - str = (char*)d; - for (int i = 0; i < NUM_STRINGS; i++) { - strcpy(str, s_arr[i]); - d_ptrs->ptr[i] = dataport_wrap_ptr(str); - str += strlen(str) + 1; - } -``` -
    - -### TASK 19, 20, 23 - And these steps are asking you to write some C -code to access and manipulate the data in the shared memory mapping -(Dataport) of the server. - -#### Read data from an untyped dataport -
    -Quick solution -```c - /* TASK 19: read some data from the untyped dataport */ - /* hint 1: use the "Buf" dataport as defined in the Echo.camkes file - * hint 2: to access the dataport use the interface name as defined in Echo.camkes. - * For example if you defined it as "dataport Buf d" then you would use "d" to refer to the dataport in C. - * hint 3: first read the number of strings from the dataport - * hint 4: then print each string from the dataport - * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports - */ - int *n = (int*)d; - char *str = (char*)(n + 1); - for (int i = 0; i < *n; i++) { - printf("%s: saying (%p): \"%s\"\n", get_instance_name(), str, str); - str += strlen(str) + 1; - } -``` -
    - -#### Put data into a typed dataport -
    -Quick solution -```c - /* TASK 20: put a modified copy of the data from the untyped dataport into the typed dataport */ - /* hint 1: modify each string by making it upper case, use the function "uppercase" - * hint 2: read from the "Buf" dataport as above - * hint 3: write to the "str_buf_t" dataport as defined in the Echo.camkes file - * hint 4: to access the dataport use the interface name as defined in Echo.camkes. - * For example if you defined it as "dataport str_buf_t d_typed" then you would use "d_typed" to refer to the dataport in C. - * hint 5: for the definition of "str_buf_t" see "str_buf.h" - * hint 6: use the "n" field to specify the number of strings in the dataport - * hint 7: copy the specified number of strings from the "Buf" dataport to the "str" field - * hint 8: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports - * hint 9: you could combine this TASK with the previous one in a single loop if you want - */ - n = (int*)d; - str = (char*)(n + 1); - for (int i = 0, j = *n - 1; i < *n; i++, j--) { - strncpy(d_typed->str[j], str, STR_LEN); - uppercase(d_typed->str[j]); - str += strlen(str) + 1; - } - d_typed->n = *n; -``` -
    - -#### Read data from a typed dataport -
    -Quick solution -```c - /* TASK 23: read some data from the dataports. specifically: - * read a dataport pointer from one of the typed dataports, then use - * that pointer to access data in the untyped dataport. - */ - /* hint 1: for the untyped dataport use the "Buf" dataport as defined in the Echo.camkes file - * hint 2: for the typed dataport use the "ptr_buf_t" dataport as defined in the Echo.camkes file - * hint 3: for the definition of "ptr_buf_t" see "str_buf.h". - * hint 4: the "n" field of the typed dataport specifies the number of dataport pointers - * hint 5: the "ptr" field of the typed dataport contains the dataport pointers - * hint 6: use the function "dataport_unwrap_ptr()" to create a regular pointer from a dataport pointer - * hint 7: for more information about dataport pointers see: https://github.com/seL4/camkes-tool/blob/master/docs/index.md - * hint 8: print out the string pointed to by each dataport pointer - */ - char *str; - for (int i = 0; i < d_ptrs->n; i++) { - str = dataport_unwrap_ptr(d_ptrs->ptr[i]); - printf("%s: dptr saying (%p): \"%s\"\n", get_instance_name(), str, str); - } -``` -
    - -### TASK 7 - This is an introduction to CAmkES attributes: you're -being asked to set the priority of the components. - -#### Set component priorities -
    -Quick solution -``` - /* TASK 7: set component priorities */ - /* hint 1: component priority is specified as an attribute with the name .priority - * hint 2: the highest priority is represented by 255, the lowest by 0 - */ - client.priority = 255; - echo.priority = 254; -``` -
    - -### TASK 8, 16 - This is where we specify the data access constraints -for the Dataports in a shared memory connection. We then go about -attempting to violate those constraints to see how CAmkES has truly met -our constraints when mapping those Dataports. - -#### Restrict access to dataports -
    -Quick solution -``` - /* TASK 8: restrict access to dataports */ - /* hint 1: use attribute ._access for each component and interface - * hint 2: appropriate values for the to_access and from_access attributes are: "R" or "W" - * hint 4: make the "Buf" dataport read only for the Echo component - * hint 3: make the "str_buf_t" dataport read only for the Client component - */ - echo.d_access = "R"; - client.d_access = "W"; - echo.d_typed_access = "W"; - client.d_typed_access = "R"; -``` -
    - -#### Test the read and write permissions on the dataport -
    -Quick solution -``` - /* TASK 16: test the read and write permissions on the dataport. - * When we try to write to a read-only dataport, we will get a VM fault. - */ - /* hint 1: try to assign a value to a field of the "str_buf_t" dataport */ - - d_typed->n = 0; -``` -
    - -## Done! - Congratulations: be sure to read up on the keywords and -structure of ADL: it's key to understanding CAmkES. And well done on -writing your first CAmkES application. - - - -Next tutorial: CAmkES 3: Timer +Next tutorial: CAmkES 3: Timer diff --git a/Tutorials/CAmkES/hello-camkes-timer.md b/Tutorials/CAmkES/hello-camkes-timer.md index 8bdca9d08b..021b449d5f 100644 --- a/Tutorials/CAmkES/hello-camkes-timer.md +++ b/Tutorials/CAmkES/hello-camkes-timer.md @@ -1,449 +1,14 @@ --- toc: true +title: Camkes 3 +tutorial: hello-camkes-timer +tutorial-order: camkes-3 layout: tutorial +description: introduce Camkes hardware components. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -# CAmkES Timer Tutorial +{% include tutorial.md %} -This tutorial guides you through setting up a sample timer driver component in -CAmkES and using it to delay for 2 seconds. For this tutorial, we will be using -the ZYNQ7000 ARM-based platform. This platform can be simulated via QEMU so it -is not a problem if you do not have access to the actual physical board. -The tutorial also has two parts to it. The first part will teach you how to -manually define hardware details to configure the hardware component and -initialise hardware resources. The second part will teach you how to use a -CAmkES connector to initialise hardware resources automatically for you. - -The solutions to this tutorial primarily uses the method of manually defining -hardware details. The solutions to the second part are also included, albeit -commented out. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut hello-camkes-timer -# building the tutorial exercise -cd hello-camkes-timer_build -ninja -``` -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut hello-camkes-timer -``` -
    - - -## Exercises - Part 1 - -### TASK 1 - -Start in `hello-camkes-timer.camkes`. - -Instantiate some components. You're already given one component instance -- `client`. You need to instantiate additional components, a timer driver and -a component instance representing the timer hardware itself. Look -in `components/Timer/Timer.camkes` for the definitions of the components. - -Once you open the file, you will notice three different components. The `Timer` -and `Timerbase` components represents the timer driver and the timer hardware -respectively. The `TimerDTB` component represents both the timer driver and the -timer hardware. This component is meant to be used with the `seL4DTBHardware` -CAmkES connector to automatically initialise hardware resources. The second -part of the tutorial will go into more detail about the `TimerDTB` component -and the `seL4DTBHardware` connector. - -For now, instantiate the `Timer` and `Timerbase` components. - -Note the lines `connection seL4RPCCall hello_timer(from client.hello, to -timer.hello);` and `timer.sem_value = 0;` in the `hello-camkes-timer.camkes` -file. They assume that the name of the timer ''driver'' will be `timer`. If you -wish to call your driver something else, you'll have to change these lines. - -
    -Quick solution -``` - /* Part 1, TASK 1: component instances */ - /* hint 1: one hardware component and one driver component - * hint 2: look at - * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application - */ - component Timerbase timerbase; - component Timer timer; -``` -
    - -### TASK 2 - -Connect the timer driver component (`Timer`) to the timer hardware component -(`Timerbase`). The timer hardware component exposes two interfaces which must -be connected to the timer driver. One of these represents memory-mapped -registers. The other represents an interrupt. - -
    -Quick solution -``` - /* Part 1, TASK 2: connections */ - /* hint 1: use seL4HardwareMMIO to connect device memory - * hint 2: use seL4HardwareInterrupt to connect interrupt - * hint 3: look at - * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application - */ - connection seL4HardwareMMIO timer_mem(from timer.reg, to timerbase.reg); - connection seL4HardwareInterrupt timer_irq(from timerbase.irq, to timer.irq); -``` -
    - -### TASK 3 - -Configure the timer hardware component instance with device-specific info. The -physical address of the timer's memory-mapped registers, and its IRQ number -must both be configured. - -
    -Quick solution -``` - /* Part 1, TASK 3: hardware resources */ - /* Timer and Timerbase: - * hint 1: find out the device memory address and IRQ number from the hardware data sheet - * hint 2: look at - * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#hardware-components - */ - timerbase.reg_paddr = 0xF8001000; // paddr of mmio registers - timerbase.reg_size = 0x1000; // size of mmio registers - timerbase.irq_irq_number = 42; // timer irq number -``` -
    - -### TASK 4 - -Now open `components/Timer/src/timer.c`. - -We'll start by completing the `irq_handle` function, which is called in -response to each timer interrupt. Note the name of this function. It follows -the naming convention `_handle`, where `` is the name of -an IRQ interface connected with `seL4HardwareInterrupt`. When an interrupt is -received on the interface ``, the function `_handle` will -be called. - -The implementation of the timer driver is located inside a different folder and -can be found in the `projects/sel4-tutorials/zynq_timer_driver` folder from the -root of the projects directory, i.e. where the `.repo` folder can be found and -where the initial `repo init` command was executed. - -This task is to call the `timer_handle_irq` function from the supply driver to -inform the driver that an interrupt has occurred. - -
    -Quick solution -```c - /* Part 1, TASK 4: call into the supplied driver to handle the interrupt. */ - /* hint: timer_handle_irq - */ - timer_handle_irq(&timer_drv); -``` -
    - -### TASK 5 - -Stop the timer from running. The `timer_stop` function will be helpful here. - -
    -Quick solution -```c - /* Part 1, TASK 5: stop the timer. */ - /* hint: timer_stop - */ - timer_stop(&timer_drv); -``` -
    - -### TASK 6 - -The interrupt now needs to be acknowledged. - -CAmkES generates the seL4-specific code for ack-ing an interrupt and provides a -function `_acknowldege` for IRQ interfaces (specifically those -connected with `seL4HardwareInterrupt`). - -
    -Quick solution -```c - /* Part 1, TASK 6: acknowledge the interrupt */ - /* hint 1: use the function _acknowledge() - */ - error = irq_acknowledge(); - ZF_LOGF_IF(error != 0, "failed to acknowledge interrupt"); -``` -
    - -### TASK 7 - -Now we'll complete `hello__init` - a function which is called once -before the component's interfaces start running. - -We need to initialise a handle to the timer driver for this device, and store a -handle to the driver in the global variable `timer_drv`. - -
    -Quick solution -```c - /* Part 1, TASK 7: call into the supplied driver to get the timer handler */ - /* hint1: timer_init - * hint2: The timer ID is supplied as a #define in this file - * hint3: The register's variable name is the same name as the dataport in the Timer component - */ - int error = timer_init(&timer_drv, DEFAULT_TIMER_ID, reg); - assert(error == 0); -``` -
    - -### TASK 8 - -After initialising the timer, we now need to start the timer. Do so by calling -`timer_start` and passing the handle to the driver. - -
    -Quick solution -```c - /* Part 1, TASK 8: start the timer - * hint: timer_start - */ - error = timer_start(&timer_drv); - assert(error == 0); -``` -
    - -### TASK 9 - -Note that this task is to understand the existing code. You won't have -to modify anything for this task. - -Implement the `timer_inf` RPC interface. This interface is defined in -`interfaces/timer.camkes`, and contains a single method, `sleep`, which -should return after a given number of seconds. in -`components/Timer/Timer.camkes`, we can see that the `timer_inf` interface -exposed by the `Timer` component is called `hello`. Thus, the function we -need to implement is called `hello_sleep`. - -
    -Quick solution -```c - /* part 1, TASK 9: implement the rpc function. */ - /* hint 1: the name of the function to implement is a composition of an interface name and a function name: - * i.e.: _ - * hint 2: the interfaces available are defined by the component, e.g. in components/timer/timer.camkes - * hint 3: the function name is defined by the interface definition, e.g. in interfaces/timer.camkes - * hint 4: so the function would be: hello_sleep() - * hint 5: the camkes 'int' type maps to 'int' in c - * hint 6: invoke a function in supplied driver the to set up the timer - * hint 7: look at https://github.com/sel4/camkes-tool/blob/master/docs/index.md#creating-an-application - */ - void hello_sleep(int sec) { - int error = 0; - /* Part 1, TASK 10: invoke a function in the supplied driver to set a timeout */ - /* hint1: timer_set_timeout - * hint2: periodic should be set to false - */ - error = timer_set_timeout(&timer_drv, sec * NS_IN_SECOND, false); - assert(error == 0); - error = sem_wait(); - ZF_LOGF_IF(error != 0, "failed to wait on semaphore"); - } -``` -
    - -### TASK 10 - -Tell the timer to interrupt after the given number of seconds. The -`timer_set_timeout` function from the included driver will help. Note that it -expects its time argument to be given in nanoseconds. - -Note the existing code in `hello_sleep`. It waits on a binary semaphore. -`irq_handle` will be called on another thread when the timer interrupt occurs, -and that function will post to the binary semaphore, unblocking us and allowing -the function to return after the delay. - -Expect the following output with a 2 second delay between the last 2 -lines: -``` -Starting the client -------Sleep for 2 seconds------ -After the client: wakeup -``` -
    -Quick solution -```c - * Part 1, TASK 10: invoke a function in the supplied driver to set a timeout */ - /* hint1: timer_set_timeout - * hint2: periodic should be set to false - */ - error = timer_set_timeout(&timer_drv, sec * NS_IN_SECOND, false); - assert(error == 0); -``` -
    - -## Exercises - Part 2 - -Now that you've learnt how to manually define the hardware details of a -hardware component to initialise hardware resources, this part of the tutorial -will teach you how to use the `seL4DTBHardware` connector to do that -automatically. - -The connector requires a devicetree blob which describes an ARM platform. -Additionally, the blob's interrupt fields also need to follow the same format -of the ARM GIC v1 and v2. There are devicetree source files bundled with the -kernel, look in the `tools/dts/` folder of the kernel sources. If a suitable -devicetree blob is not available for your platform, then do not proceed with -the tutorial. - -### TASK 1 - -Navigate to the `hello-camkes-timer.camkes` file. - -Remove the `Timerbase` and `Timer` component instantiations and instantiate a -`TimerDTB` component instead. Also change the `connection seL4RPCCall -hello_timer(from client.hello, to timer.hello);` and `timer.sem_value = 0;` -lines if necessary. -
    -Quick solution -``` - /* Part 2, TASK 1: component instances */ - /* hint 1: a single TimerDTB component - * hint 2: look at - * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application - */ - component TimerDTB timer; -``` -
    - -### TASK 2 - -Remove the `seL4HardwareMMIO` and `seL4HardwareInterrupt` connections. Connect -the two interfaces inside the `TimerDTB` component with the `seL4DTBHardware` -connector. -
    -Quick solution -``` - /* Part 2, TASK 2: connections */ - /* hint 1: connect the dummy_source and timer interfaces - * hint 2: the dummy_source should be the 'from' end - * hint 3: look at - * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application - */ - connection seL4DTBHardware timer_dtb(from timer.dummy_source, to timer.tmr); -``` -
    - -### TASK 3 - -Before opening `components/Timer/Timer.camkes`, remove the `Timerbase` settings -inside the configurations block. - -Configure the `TimerDTB` component to pass in the correct DTB path to a timer -to the connector and also initialise the interrupt resources for the timer. -This will allow the connector to read a device node from the devicetree blob -and grab the necessary data to initialise hardware resources. More -specifically, it reads the registers field and optionally the interrupts field -to allocate memory and interrupts. -
    -Quick solution -``` - /* Part 2, TASK 3: hardware resources */ - /* TimerDTB: - * hint 1: look in the DTB/DTS for the path of a timer - * hint 2: set the 'dtb' setting for the tmr interface in the TimerDTB component, - * e.g. foo.dtb = dtb({"path" : "/bar"}); - * hint 3: set the 'generate_interrupts' setting to 1 - */ - tmr.dtb = dtb({"path" : "/amba/timer@f8001000"}); // path of the timer in the DTB - tmr.generate_interrupts = 1; // tell seL4DTBHardware to init interrupts -``` -
    - -### TASK 4 - -Move to `components/TimerDTB/src/timerdtb.c`. - -Similar to part one, we'll start with the `tmr_irq_handle` function. This -function is called in response to a timer interrupt. The name of the function -has a special meaning and the meaning is unique to the `seL4DTBHardware` -connector. - -The IRQ handling functions of the connector follows the naming convention -`_irq_handle`, where `` is the name of the -interface of the 'to' end in an instance of a `seL4DTBHardware` connection. -Also notice that it takes a `ps_irq_t *` type. This is because, for a given -device, there may be multiple interrupts associated with the device. A -`ps_irq_t` struct is given to the IRQ handling function and it contains -information about the interrupt, allowing the handler to differentiate between -the numerous interrupts of a device. - -Likewise with part one, the implementation of the timer driver is in the -included driver in `timer_driver` and the task here is to call -`timer_handle_irq`. -
    -Quick solution -```c - /* Part 2, TASK 4: call into the supplied driver to handle the interrupt. */ - /* hint: timer_handle_irq - */ - timer_handle_irq(&timer_drv); -``` -
    - -### TASK 5 - -The timer needs to be stopped, the task here is the same as part one's task 5. -
    -Quick solution -```c - /* Part 2, TASK 5: stop the timer. */ - /* hint: timer_stop - */ - timer_stop(&timer_drv); -``` -
    - -### TASK 6 - -Again, the interrupt now has to be acknowledged. - -For the `seL4DTBHardware` connector, CAmkES also generates and provides a -function to acknowledge interrupts. This function follows a similar naming -convention to the IRQ handler above, `_irq_acknowledge` also -takes in a `ps_irq_t *` argument. Similarly, the `ps_irq_t *` argument helps -CAmkES to differentiate between the possibly many interrupts of a device that -you wish to acknowledge. -
    -Quick solution -``` - /* Part 2, TASK 7: call into the supplied driver to get the timer handler */ - /* hint1: timer_init - * hint2: The timer ID is supplied as a #define in this file - * hint3: The register's name is follows the format of _, - * where "interface name" is the name of the - * interface where you set the path of the DTB (foo.dtb = dtb({...})) - * and "register number" is the index of the register block in the device - * node in the devicetree blob - */ - int error = timer_init(&timer_drv, DEFAULT_TIMER_ID, tmr_0); - assert(error == 0); -``` -
    - -### TASK 7 - 10 - -Task 7 to 10 are the exact same as the tasks in part one. - -You should also expect the same output as the first part. - -Next tutorial: CAmkES VM +Next tutorial: CAmkES VM diff --git a/Tutorials/DynamicLibraries/dynamic-1.md b/Tutorials/DynamicLibraries/dynamic-1.md index 1725dc3fc9..ce60d43856 100644 --- a/Tutorials/DynamicLibraries/dynamic-1.md +++ b/Tutorials/DynamicLibraries/dynamic-1.md @@ -1,576 +1,14 @@ --- toc: true +title: Dynamic Libraries 1 +tutorial: dynamic-1 +tutorial-order: dynamic-1 layout: tutorial +description: system initialisation & threading with seL4_libs. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- +{% include tutorial.md %} -# seL4 Dynamic Libraries: initialisation & threading -This tutorial provides code examples and exercises for using the dynamic libraries -found in [`seL4_libs`](https://github.com/seL4/seL4_libs) to bootstrap a system and start a thread. - -The tutorial is useful in that -it addresses conceptual problems for two different types of developers: - -- Experienced kernel developers whose minds are pre-programmed to - think in terms of "One address space equals one process", and - begins to introduce the seL4 CSpace vs VSpace model. -- New kernel developers, for whom the tutorial will prompt them on - what to read about. - -Don't gloss over the globals declared before `main()` -- they're declared -for your benefit so you can grasp some of the basic data structures. - - -Outcomes: -- Understand the kernel's startup procedure. -- Understand that the kernel centers around certain objects and - capabilities to those objects. -- Understand that libraries exist to automate the very - fine-grained nature of the seL4 API, and get a rough idea of - some of those libraries. -- Learn how the kernel hands over control to userspace. -- Get a feel for how the seL4 API enables developers to manipulate - the objects referred to by the capabilities they encounter. -- Understand the how to spawn new threads in seL4, and the basic - idea that a thread has a TCB, VSpace and CSpace, and that you - must fill these out. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut dynamic-1 -# building the tutorial exercise -cd dynamic-1_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut dynamic-1 -``` -Answers are also available in drop down menus under each section. -
    - - - -## Exercises - -When you first run the tutorial, you should see the following output: - -``` -Booting all finished, dropped to user space -main@main.c:89 [Cond failed: info == NULL] -Failed to get bootinfo. -``` - -### Obtain BootInfo - -After bootstrapping the system, the seL4 kernel hands over control to the root task. - to an init thread. -This thread receives a structure from the kernel that describes all the -resources available on the machine. This structure is called the -BootInfo structure. It includes information on all IRQs, memory, and -IO-Ports (x86). This structure also tells the init thread where certain -important capability references are. This step is teaching you how to -obtain that structure. - -`seL4_BootInfo* platsupport_get_bootinfo(void)` is a function that returns the BootInfo structure. -It also sets up the IPC buffer so that it can perform some syscalls such as `seL4_DebugNameThread` used by `name_thread`. - -- -- - -```c - - /* TASK 1: get boot info */ - /* hint: platsupport_get_bootinfo() - * seL4_BootInfo* platsupport_get_bootinfo(void); - * @return Pointer to the bootinfo, NULL on failure - */ -} -``` -
    -Quick solution -```c - info = platsupport_get_bootinfo(); - ZF_LOGF_IF(info == NULL, "Failed to get bootinfo."); -``` -
    - -On success, you should see the following: -``` -dynamic-1: main@main.c:124 [Cond failed: allocman == NULL] - Failed to initialize alloc manager. - Memory pool sufficiently sized? - Memory pool pointer valid? -``` - -### Initialise simple - -`libsel4simple` provides an abstraction for the boot environment of a thread. -You need to initialize it with some default state before using it. -- -```c - - /* TASK 2: initialise simple object */ - /* hint: simple_default_init_bootinfo() - * void simple_default_init_bootinfo(simple_t *simple, seL4_BootInfo *bi); - * @param simple Structure for the simple interface object. This gets initialised. - * @param bi Pointer to the bootinfo describing what resources are available - */ -``` -
    -Quick solution - -```c - simple_default_init_bootinfo(&simple, info); -``` -
    - -On successful completion of this task, the output should not change. - -### Use simple to print BootInfo - -Use a `simple` function to print out the contents of the `seL4_BootInfo` function. - -```c - - /* TASK 3: print out bootinfo and other info about simple */ - /* hint: simple_print() - * void simple_print(simple_t *simple); - * @param simple Pointer to simple interface. - */ -``` -
    -Quick solution -```c - simple_print(&simple); -``` -
    - - -- - -The error message should remain, but your output should now also contain something like: - -``` -Node 0 of 1 -IOPT levels: 4294967295 -IPC buffer: 0x52c000 -Empty slots: [406 --> 4096) -sharedFrames: [0 --> 0) -userImageFrames: [16 --> 316) -userImagePaging: [12 --> 15) -untypeds: [316 --> 406) -Initial thread domain: 0 -Initial thread cnode size: -dynamic-1: main@main.c:126 [Cond failed: allocman == NULL] -``` - -### Initialise an allocator - -In seL4, memory management is delegated in large part to userspace, and -each thread manages its own page faults with a custom pager. Without -the use of the `allocman` library and the `VKA` library, you would have to -manually allocate a frame, then map the frame into a page-table, before -you could use new memory in your address space. In this tutorial you -don't go through that procedure, but you'll encounter it later. For now, -use the allocman and VKA allocation system. The allocman library -requires some initial memory to bootstrap its metadata. Complete this -step. -- - -```c - - /* TASK 4: create an allocator */ - /* hint: bootstrap_use_current_simple() - * allocman_t *bootstrap_use_current_simple(simple_t *simple, uint32_t pool_size, char *pool); - * @param simple Pointer to simple interface. - * @param pool_size Size of the initial memory pool. - * @param pool Initial memory pool. - * @return returns NULL on error - */ -``` -
    -Quick solution -```c - allocman = bootstrap_use_current_simple(&simple, ALLOCATOR_STATIC_POOL_SIZE, allocator_mem_pool); - ZF_LOGF_IF(allocman == NULL, "Failed to initialize alloc manager.\n" - "\tMemory pool sufficiently sized?\n" - "\tMemory pool pointer valid?\n"); -``` -
    - -The output should now be as follows: -``` -<> -dynamic-1: main@main.c:199 [Err seL4_InvalidCapability]: - Failed to set the priority for the new TCB object. -``` - -### Obtain a generic allocation interface (vka) - -`libsel4vka` is an seL4 type-aware object allocator that will allocate new -kernel objects for you. The term "allocate new kernel objects" in seL4 -is a more detailed process of "retyping" previously un-typed memory. -seL4 considers all memory that hasn't been explicitly earmarked for a -purpose to be "untyped", and in order to repurpose any memory into a -useful object, you must give it an seL4-specific type. This is retyping, -and the VKA library simplifies this for you, among other things. -- - -```c - - /* TASK 5: create a vka (interface for interacting with the underlying allocator) */ - /* hint: allocman_make_vka() - * void allocman_make_vka(vka_t *vka, allocman_t *alloc); - * @param vka Structure for the vka interface object. This gets initialised. - * @param alloc allocator to be used with this vka - */ -``` -
    -Quick solution -```c - allocman_make_vka(&vka, allocman); -``` -
    - -On successful completion this task, the output should not change. - -### Find the CSpace root cap - -```c - - /* TASK 6: get our cspace root cnode */ - /* hint: simple_get_cnode() - * seL4_CPtr simple_get_cnode(simple_t *simple); - * @param simple Pointer to simple interface. - * @return The cnode backing the simple interface. no failure. - */ - seL4_CPtr cspace_cap; -``` -
    -Quick solution -```c - cspace_cap = simple_get_cnode(&simple); -``` -
    - -This is where the differences between seL4 and contemporary kernels -begin to start playing out. Every kernel-object that you "retype" will -be handed to you using a capability reference. The seL4 kernel keeps -multiple trees of these capabilities. Each separate tree of capabilities -is called a "CSpace". Each thread can have its own CSpace, or a CSpace -can be shared among multiple threads. The delineations between -"Processes" aren't well-defined, since seL4 doesn't have any real -concept of "processes". It deals with threads. Sharing and isolation is -based on CSpaces (shared vs not-shared) and VSpaces (shared vs -not-shared). The "process" idea goes as far as perhaps the fact that at -the hardware level, threads sharing the same VSpace are in a traditional -sense, siblings, but logically in seL4, there is no concept of -"Processes" really. - -So you're being made to grab a reference to your thread's CSpace's root -"CNode". A CNode is one of the many blocks of capabilities that make up -a CSpace. -- - -On successful completion this task, the output should not change. - -### Find the VSpace root cap - -```c - - /* TASK 7: get our vspace root page diretory */ - /* hint: simple_get_pd() - * seL4_CPtr simple_get_pd(simple_t *simple); - * @param simple Pointer to simple interface. - * @return The vspace (PD) backing the simple interface. no failure. - */ - seL4_CPtr pd_cap; -``` -
    -Quick solution -```c - pd_cap = simple_get_pd(&simple); -``` -
    - -Just as in the previous step, you were made to grab a reference to the -root of your thread's CSpace, now you're being made to grab a reference -to the root of your thread's VSpace. -- - -On successful completion this task, the output should not change. - -### Allocate a TCB Object - -```c - - /* TASK 8: create a new TCB */ - /* hint: vka_alloc_tcb() - * int vka_alloc_tcb(vka_t *vka, vka_object_t *result); - * @param vka Pointer to vka interface. - * @param result Structure for the TCB object. This gets initialised. - * @return 0 on success - */ - vka_object_t tcb_object = {0}; -``` -
    -Quick solution -```c - error = vka_alloc_tcb(&vka, &tcb_object); - ZF_LOGF_IFERR(error, "Failed to allocate new TCB.\n" - "\tVKA given sufficient bootstrap memory?"); -``` -
    - -In order to manage the threads that are created in seL4, the seL4 kernel -keeps track of TCB (Thread Control Block) objects. Each of these -represents a schedulable executable resource. Unlike other contemporary -kernels, seL4 **doesn't** allocate a stack, virtual-address space -(VSpace) and other metadata on your behalf. This step creates a TCB, -which is a very bare-bones, primitive resource, which requires you to -still manually fill it out. - -- - -After completing this task, the errors should disappear, and you should see the following -output: -``` -main: hello world -``` - -### Configure the new TCB -```c - - /* TASK 9: initialise the new TCB */ - /* hint 1: seL4_TCB_Configure() - * int seL4_TCB_Configure(seL4_TCB _service, seL4_Word fault_ep, seL4_CNode cspace_root, seL4_Word cspace_root_data, seL4_CNode vspace_root, seL4_Word vspace_root_data, seL4_Word buffer, seL4_CPtr bufferFrame) - * @param service Capability to the TCB which is being operated on. - * @param fault_ep Endpoint which receives IPCs when this thread faults (must be in TCB's cspace). - * @param cspace_root The new CSpace root. - * @param cspace_root_data Optionally set the guard and guard size of the new root CNode. If set to zero, this parameter has no effect. - * @param vspace_root The new VSpace root. - * @param vspace_root_data Has no effect on IA-32 or ARM processors. - * @param buffer Address of the thread's IPC buffer. Must be 512-byte aligned. The IPC buffer may not cross a page boundary. - * @param bufferFrame Capability to a page containing the thread?s IPC buffer. - * @return 0 on success. - * Note: this function is generated during build. It is generated from the following definition: - * - * hint 2: use seL4_CapNull for the fault endpoint - * hint 3: use seL4_NilData for cspace and vspace data - * hint 4: we don't need an IPC buffer frame or address yet - */ -``` -
    -Quick solution -```c - error = seL4_TCB_Configure(tcb_object.cptr, seL4_CapNull, cspace_cap, seL4_NilData, pd_cap, seL4_NilData, 0, 0); - ZF_LOGF_IFERR(error, "Failed to configure the new TCB object.\n" - "\tWe're running the new thread with the root thread's CSpace.\n" - "\tWe're running the new thread in the root thread's VSpace.\n" - "\tWe will not be executing any IPC in this app.\n"); -``` -
    - -You must create a new VSpace for your new thread if you need it to -execute in its own isolated address space, and tell the kernel which -VSpace you plan for the new thread to execute in. This opens up the -option for threads to share VSpaces. In similar fashion, you must also -tell the kernel which CSpace your new thread will use -- whether it will -share a currently existing one, or whether you've created a new one for -it. That's what you're doing now. - -In this particular example, you're allowing the new thread to share your -main thread's CSpace and VSpace. - -In addition, a thread needs to have a priority set on it in order for it to run. -`seL4_TCB_SetPriority(tcb_object.cptr, seL4_CapInitThreadTCB, seL4_MaxPrio);` -will give your new thread the same priority as the current thread, allowing it -to be run the next time the seL4 scheduler is invoked. The seL4 scheduler is invoked -everytime there is a kernel timer tick. -- - -On successful completion this task, the output should not change. - -### Name the new TCB -```c - - /* TASK 10: give the new thread a name */ - /* hint: we've done thread naming before */ -``` -
    -Quick solution -```c - NAME_THREAD(tcb_object.cptr, "dynamic-1: thread_2"); -``` -
    - -This is a convenience function -- sets a name string for the TCB object. - -On successful completion this task, the output should not change. - -### Set the instruction pointer -```c - - /* - * set start up registers for the new thread: - */ - UNUSED seL4_UserContext regs = {0}; - - /* TASK 11: set instruction pointer where the thread shoud start running */ - /* hint 1: sel4utils_set_instruction_pointer() - * void sel4utils_set_instruction_pointer(seL4_UserContext *regs, seL4_Word value); - * @param regs Data structure in which to set the instruction pointer value - * @param value New instruction pointer value - * - * hint 2: we want the new thread to run the function "thread_2" - */ -``` - -
    -Quick solution -```c - sel4utils_set_instruction_pointer(®s, (seL4_Word)thread_2); -``` -
    - -Pay attention to the line that precedes this particular task -- the line -that zeroes out a new "seL4_UserContext" object. As we previously -explained, seL4 requires you to fill out the Thread Control Block -manually. That includes the new thread's initial register contents. You -can set the value of the stack pointer, the instruction pointer, and if -you want to get a little creative, you can pass some initial data to -your new thread through its registers. -- - -On successful completion this task, the output should not change. -### Set the stack pointer -```c - - /* TASK 12: set stack pointer for the new thread */ - /* hint 1: sel4utils_set_stack_pointer() - * void sel4utils_set_stack_pointer(seL4_UserContext *regs, seL4_Word value); - * @param regs Data structure in which to set the stack pointer value - * @param value New stack pointer value - * - * hint 2: remember the stack grows down! - */ -``` -
    -Quick solution -```c - sel4utils_set_stack_pointer(®s, thread_2_stack_top); -``` -
    - -This TASK is just some pointer arithmetic. The cautionary note that the -stack grows down is meant to make you think about the arithmetic. -Processor stacks push new values toward decreasing addresses, so give it -some thought. -- - -On successful completion this task, the output should not change. - -### Write the registers -```c - - /* TASK 13: actually write the TCB registers. We write 2 registers: - * instruction pointer is first, stack pointer is second. */ - /* hint: seL4_TCB_WriteRegisters() - * int seL4_TCB_WriteRegisters(seL4_TCB service, seL4_Bool resume_target, seL4_Uint8 arch_flags, seL4_Word count, seL4_UserContext *regs) - * @param service Capability to the TCB which is being operated on. - * @param resume_target The invocation should also resume the destination thread. - * @param arch_flags Architecture dependent flags. These have no meaning on either IA-32 or ARM. - * @param count The number of registers to be set. - * @param regs Data structure containing the new register values. - * @return 0 on success - */ -``` -
    -Quick solution -```c - error = seL4_TCB_WriteRegisters(tcb_object.cptr, 0, 0, 2, ®s); - ZF_LOGF_IFERR(error, "Failed to write the new thread's register set.\n" - "\tDid you write the correct number of registers? See arg4.\n"); -``` -
    - -As explained above, we've been filling out our new thread's TCB for the -last few operations, so now we're writing the values we've chosen, to -the TCB object in the kernel. -- - -On successful completion this task, the output should not change. - -### Start the new thread -```c - - /* TASK 14: start the new thread running */ - /* hint: seL4_TCB_Resume() - * int seL4_TCB_Resume(seL4_TCB service) - * @param service Capability to the TCB which is being operated on. - * @return 0 on success - */ -``` -
    -Quick solution -```c - error = seL4_TCB_Resume(tcb_object.cptr); - ZF_LOGF_IFERR(error, "Failed to start new thread.\n"); -``` -
    - -Finally, we tell the kernel that our new thread is runnable. From here, -the kernel itself will choose when to run the thread based on the -priority we gave it, and according to the kernel's configured scheduling -policy. - -- - -On successful completion this task, the output should not change. -### Print something -```c - - /* TASK 15: print something */ - /* hint: printf() */ -} -``` -
    -Quick solution -```c - printf("thread_2: hallo wereld\n"); -``` -
    - -For the sake of confirmation that our new thread was executed by the -kernel successfully, we cause it to print something to the screen. - -On success, you should see output from your new thread. - -## Links to source - -- `sel4_BootInfo`: - -- `simple_t`: - -- `vka_t`: - -- `allocman_t`: - -- `name_thread()`: - - -That's it for this tutorial. - -Next tutorial: IPC +Next tutorial: IPC diff --git a/Tutorials/DynamicLibraries/dynamic-2.md b/Tutorials/DynamicLibraries/dynamic-2.md index e97777445c..ce1486f7fe 100644 --- a/Tutorials/DynamicLibraries/dynamic-2.md +++ b/Tutorials/DynamicLibraries/dynamic-2.md @@ -1,721 +1,14 @@ --- toc: true +title: Dynamic Libraries 2 +tutorial: dynamic-2 +tutorial-order: dynamic-2 layout: tutorial +description: IPC with seL4_libs. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- +{% include tutorial.md %} -# seL4 Dynamic Libraries: IPC -The tutorial is designed to -teach the basics of seL4 IPC using Endpoint objects, and userspace -paging management. You'll be led through the process of creating a new -thread (retyping an untyped object into a TCB object), and also made to -manually do your own memory management to allocate some virtual memory -for use as the shared memory buffer between your two threads. - -Don't gloss over the globals declared before `main()` -- they're declared -for your benefit so you can grasp some of the basic data structures. - -You'll observe that the things you've already covered in the second -tutorial are filled out and you don't have to repeat them: in much the -same way, we won't be repeating conceptual explanations on this page, if -they were covered by a previous tutorial in the series. - -Learning outcomes: -- Repeat the spawning of a thread. "''If it's nice, do it twice''" - -- Caribbean folk-saying. Once again, the new thread will be - sharing its creator's VSpace and CSpace. -- Introduction to the idea of badges, and minting badged copies of - an Endpoint capability. NB: you don't mint a new copy of the - Endpoint object, but a copy of the capability that - references it. -- Basic IPC: sending and receiving: how to make two - threads communicate. -- IPC Message format, and Message Registers. seL4 binds some of - the first Message Registers to hardware registers, and the rest - are transferred in the IPC buffer. -- Understand that each thread has only one IPC buffer, which is - pointed to by its TCB. It's possible to make a thread wait on - both an Endpoint and a Notification using "Bound Notifications". -- Understand CSpace pointers, which are really just integers with - multiple indexes concatenated into one. Understanding them well - however, is important to understanding how capabilities work. Be - sure you understand the diagram on the "**CSpace example and - addressing**" slide. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut dynamic-2 -# building the tutorial exercise -cd dynamic-2_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut dynamic-2 -``` -Answers are also available in drop down menus under each section. -
    - - -## Exercises - -When you first run this tutorial, you will see a fault as follows: -``` -Booting all finished, dropped to user space -Caught cap fault in send phase at address (nil) -while trying to handle: -vm fault on data at address 0x70003c8 with status 0x6 -in thread 0xffffff801ffb5400 "rootserver" at address 0x402977 -With stack: -0x43df70: 0x0 -0x43df78: 0x0 -``` - -### Allocate an IPC buffer - -As we mentioned in passing before, threads in seL4 do their own memory -management. You implement your own Virtual Memory Manager, essentially. -To the extent that you must allocate a physical memory frame, then map -it into your thread's page directory -- and even manually allocate page -tables on your own, where necessary. - -Here's the first step in a conventional memory manager's process of -allocating memory: first allocate a physical frame. As you would expect, -you cannot directly write to or read from this frame object since it is -not mapped into any virtual address space as yet. Standard restrictions -of a MMU-utilizing kernel apply. - -- - -``` - - /* TASK 1: get a frame cap for the ipc buffer */ - /* hint: vka_alloc_frame() - * int vka_alloc_frame(vka_t *vka, uint32_t size_bits, vka_object_t *result) - * @param vka Pointer to vka interface. - * @param size_bits Frame size: 2^size_bits - * @param result Structure for the Frame object. This gets initialised. - * @return 0 on success - */ - vka_object_t ipc_frame_object; -``` -
    -Quick solution -```c - error = vka_alloc_frame(&vka, IPCBUF_FRAME_SIZE_BITS, &ipc_frame_object); - ZF_LOGF_IFERR(error, "Failed to alloc a frame for the IPC buffer.\n" - "\tThe frame size is not the number of bytes, but an exponent.\n" - "\tNB: This frame is not an immediately usable, virtually mapped page.\n") -``` -
    - -On completion, the output will not change. - -### Try to map a page - -Take note of the line of code that precedes this: the one where a -virtual address is randomly chosen for use. This is because, as we -explained before, the process is responsible for its own Virtual Memory -Management. As such, if it chooses, it can map any page in its VSpace to -physical frame. It can technically choose to do unconventional things, -like not unmap PFN #0. The control of how the address space is managed -is up to the threads that have write-capabilities to that address space. -There is both flexibility and responsibility implied here. Granted, seL4 -itself provides strong guarantees of isolation even if a thread decides -to go rogue. - -Attempt to map the frame you allocated earlier, into your VSpace. A keen -reader will pick up on the fact that it's unlikely that this will work, -since you'd need a new page table to contain the new page-table-entry. -The tutorial deliberately walks you through both the mapping of a frame -into a VSpace, and the mapping of a new page-table into a VSpace. - -- -- - -``` - - /* TASK 2: try to map the frame the first time */ - /* hint 1: seL4_ARCH_Page_Map() - * The *ARCH* versions of seL4 sys calls are abstractions over the architecture provided by libsel4utils - * this one is defined as: - * #define seL4_ARCH_Page_Map seL4_X86_Page_Map - * The signature for the underlying function is: - * int seL4_X86_Page_Map(seL4_X86_Page service, seL4_X86_PageDirectory pd, seL4_Word vaddr, seL4_CapRights rights, seL4_X86_VMAttributes attr) - * @param service Capability to the page to map. - * @param pd Capability to the VSpace which will contain the mapping. - * @param vaddr Virtual address to map the page into. - * @param rights Rights for the mapping. - * @param attr VM Attributes for the mapping. - * @return 0 on success. - * - * Note: this function is generated during build. It is generated from the following definition: - * - * hint 2: for the rights, use seL4_AllRights - * hint 3: for VM attributes use seL4_ARCH_Default_VMAttributes - * Hint 4: It is normal for this function call to fail. That means there are - * no page tables with free slots -- proceed to the next step where you'll - * be led to allocate a new empty page table and map it into the VSpace, - * before trying again. - */ -``` -
    -Quick solution -```c - error = seL4_ARCH_Page_Map(ipc_frame_object.cptr, pd_cap, ipc_buffer_vaddr, - seL4_AllRights, seL4_ARCH_Default_VMAttributes); -``` -
    - - -On completion, the output will be as follows: -``` -dynamic-2: main@main.c:260 [Err seL4_FailedLookup]: - Failed to allocate new page table. -``` - -### Allocate a page table - -So just as you previously had to manually retype a new frame to use for -your IPC buffer, you're also going to have to manually retype a new -page-table object to use as a leaf page-table in your VSpace. - -- - -``` - - /* TASK 3: create a page table */ - /* hint: vka_alloc_page_table() - * int vka_alloc_page_table(vka_t *vka, vka_object_t *result) - * @param vka Pointer to vka interface. - * @param result Structure for the PageTable object. This gets initialised. - * @return 0 on success - */ - ``` -
    -Quick solution -```c - error = vka_alloc_page_table(&vka, &pt_object); - ZF_LOGF_IFERR(error, "Failed to allocate new page table.\n"); -``` -
    - -On completion, you will see another fault. - -### Map a page table - -If you successfully retyped a new page table from an untyped memory -object, you can now map that new page table into your VSpace, and then -try again to finally map the IPC-buffer's frame object into the VSpace. - -- -- - -``` - - /* TASK 4: map the page table */ - /* hint 1: seL4_ARCH_PageTable_Map() - * The *ARCH* versions of seL4 sys calls are abstractions over the architecture provided by libsel4utils - * this one is defined as: - * #define seL4_ARCH_PageTable_Map seL4_X86_PageTable_Map - * The signature for the underlying function is: - * int seL4_X86_PageTable_Map(seL4_X86_PageTable service, seL4_X86_PageDirectory pd, seL4_Word vaddr, seL4_X86_VMAttributes attr) - * @param service Capability to the page table to map. - * @param pd Capability to the VSpace which will contain the mapping. - * @param vaddr Virtual address to map the page table into. - * @param rights Rights for the mapping. - * @param attr VM Attributes for the mapping. - * @return 0 on success. - * - * Note: this function is generated during build. It is generated from the following definition: - * - * hint 2: for VM attributes use seL4_ARCH_Default_VMAttributes - */ -``` -
    -Quick solution -```c - error = seL4_ARCH_PageTable_Map(pt_object.cptr, pd_cap, - ipc_buffer_vaddr, seL4_ARCH_Default_VMAttributes); - ZF_LOGF_IFERR(error, "Failed to map page table into VSpace.\n" - "\tWe are inserting a new page table into the top-level table.\n" - "\tPass a capability to the new page table, and not for example, the IPC buffer frame vaddr.\n") -``` -
    - -On completion, you will see another fault. - -### Map a page - -Use `seL4_ARCH_Page_Map` to map the frame in. -If everything was done correctly, there is no reason why this step -should fail. Complete it and proceed. -``` - - /* TASK 5: then map the frame in */ - /* hint 1: use seL4_ARCH_Page_Map() as above - * hint 2: for the rights, use seL4_AllRights - * hint 3: for VM attributes use seL4_ARCH_Default_VMAttributes - */ -``` -
    -Quick solution -```c - error = seL4_ARCH_Page_Map(ipc_frame_object.cptr, pd_cap, - ipc_buffer_vaddr, seL4_AllRights, seL4_ARCH_Default_VMAttributes); - ZF_LOGF_IFERR(error, "Failed again to map the IPC buffer frame into the VSpace.\n" - "\t(It's not supposed to fail.)\n" - "\tPass a capability to the IPC buffer's physical frame.\n" - "\tRevisit the first seL4_ARCH_Page_Map call above and double-check your arguments.\n"); -``` -
    - -On completion, you will see the following: -``` -main: hello world -dynamic-2: main@main.c:464 [Cond failed: seL4_MessageInfo_get_length(tag) != 1] - Response data from thread_2 was not the length expected. - How many registers did you set with seL4_SetMR within thread_2? -``` - -### Allocate an endpoint - -Now we have a (fully mapped) IPC buffer -- but no Endpoint object to -send our IPC data across. We must retype an untyped object into a kernel -Endpoint object, and then proceed. This could be done via a more -low-level approach using `seL4_Untyped_Retype()`, but instead, the -tutorial makes use of the VKA allocator. Remember that the VKA allocator -is an seL4 type-aware object allocator? So we can simply ask it for a -new object of a particular type, and it will do the low-level retyping -for us, and return a capability to a new object as requested. - -In this case, we want a new Endpoint so we can do IPC. Complete the step -and proceed. - -- - -``` - - /* TASK 6: create an endpoint */ - /* hint: vka_alloc_endpoint() - * int vka_alloc_endpoint(vka_t *vka, vka_object_t *result) - * @param vka Pointer to vka interface. - * @param result Structure for the Endpoint object. This gets initialised. - * @return 0 on success - */ -``` -
    -Quick solution -```c - error = vka_alloc_endpoint(&vka, &ep_object); - ZF_LOGF_IFERR(error, "Failed to allocate new endpoint object.\n"); -``` -
    - -On completion, the output will not change. - -### Badge an endpoint - -Badges are used to uniquely identify a message queued on an endpoint as -having come from a particular sender. Recall that in seL4, each thread -has only one IPC buffer. If multiple other threads are sending data to a -listening thread, how can that listening thread distinguish between the -data sent by each of its IPC partners? Each sender must "badge" its -capability to its target's endpoint. - -Note the distinction: the badge is not applied to the target endpoint, -but to the sender's **capability** to the target endpoint. This -enables the listening thread to mint off copies of a capability to an -Endpoint to multiple senders. Each sender is responsible for applying a -unique badge value to the capability that the listener gave it so that -the listener can identify it. - -In this step, you are badging the endpoint that you will use when -sending data to the thread you will be creating later on. The -`vka_mint_object()` call will return a new, badged copy of the -capability to the endpoint that your new thread will listen on. When you -send data to your new thread, it will receive the badge value with the -data, and know which sender you are. Complete the step and proceed. - -- -- - -``` - - /* TASK 7: make a badged copy of it in our cspace. This copy will be used to send - * an IPC message to the original cap */ - /* hint 1: vka_mint_object() - * int vka_mint_object(vka_t *vka, vka_object_t *object, cspacepath_t *result, seL4_CapRights rights, seL4_Word badge) - * @param[in] vka The allocator for the cspace. - * @param[in] object Target object for cap minting. - * @param[out] result Allocated cspacepath. - * @param[in] rights The rights for the minted cap. - * @param[in] badge The badge for the minted cap. - * @return 0 on success - * - * hint 2: for the rights, use seL4_AllRights - * hint 3: for the badge use EP_BADGE - */ -``` -
    -Quick solution -```c - error = vka_mint_object(&vka, &ep_object, &ep_cap_path, seL4_AllRights, - EP_BADGE); - ZF_LOGF_IFERR(error, "Failed to mint new badged copy of IPC endpoint.\n" - "\tseL4_Mint is the backend for vka_mint_object.\n" - "\tseL4_Mint is simply being used here to create a badged copy of the same IPC endpoint.\n" - "\tThink of a badge in this case as an IPC context cookie.\n"); -``` -
    - -On completion, the output will not change. - -### Message registers - -Here we get a formal introduction to message registers. At first glance, -you might wonder why the `sel4_SetMR()` calls don't specify a message -buffer, and seem to know which buffer to fill out -- and that would be -correct, because they do. They are operating directly on the sending -thread's IPC buffer. Recall that each thread has only one IPC buffer. Go -back and look at your call to `seL4_TCB_Configure()` in step 7 again: -you set the IPC buffer for the new thread in the last 2 arguments to -this function. Likewise, the thread that created **your** main thread -also set an IPC buffer up for you. - -So `seL4_SetMR()` and `seL4_GetMR()` simply write to and read from the IPC -buffer you designated for your thread. `MSG_DATA` is uninteresting -- can -be any value. You'll find the `seL4_MessageInfo_t` type explained in the -manuals. In short, it's a header that is embedded in each message that -specifies, among other things, the number of Message Registers that hold -meaningful data, and the number of capabilities that are going to be -transmitted in the message. - -- -- - -``` - - /* TASK 8: set the data to send. We send it in the first message register */ - /* hint 1: seL4_MessageInfo_new() - * seL4_MessageInfo_t CONST seL4_MessageInfo_new(seL4_Uint32 label, seL4_Uint32 capsUnwrapped, seL4_Uint32 extraCaps, seL4_Uint32 length) - * @param label The value of the label field - * @param capsUnwrapped The value of the capsUnwrapped field - * @param extraCaps The value of the extraCaps field - * @param length The number of message registers to send - * @return The seL4_MessageInfo_t containing the given values. - * - * seL4_MessageInfo_new() is generated during build. It can be found in: - * build/x86/pc99/libsel4/include/sel4/types_gen.h - * - * hint 2: use 0 for the first 3 fields. - * hint 3: send only 1 message register of data - * - * hint 4: seL4_SetMR() - * void seL4_SetMR(int i, seL4_Word mr) - * @param i The message register to write - * @param mr The value of the message register - * - * hint 5: send MSG_DATA - */ -``` -
    -Quick solution -```c - tag = seL4_MessageInfo_new(0, 0, 0, 1); - seL4_SetMR(0, MSG_DATA); -``` -
    - -On completion, the output should change as follows: -``` -dynamic-2: main@main.c:472 [Cond failed: msg != ~MSG_DATA] - Response data from thread_2's content was not what was expected. -``` - -### IPC - -Now that you've constructed your message and badged the endpoint that -you'll use to send it, it's time to send it. The `seL4_Call()` syscall -will send a message across an endpoint synchronously. If there is no -thread waiting at the other end of the target endpoint, the sender will -block until there is a waiter. The reason for this is because the seL4 -kernel would prefer not to buffer IPC data in the kernel address space, -so it just sleeps the sender until a receiver is ready, and then -directly copies the data. It simplifies the IPC logic. There are also -polling send operations, as well as polling receive operations in case -you don't want to be forced to block if there is no receiver on the -other end of an IPC Endpoint. - -When you send your badged data using `seL4_Call()`, our receiving thread -(which we created earlier) will pick up the data, see the badge, and -know that it was us who sent the data. Notice how the sending thread -uses the **badged** capability to the endpoint object, and the -receiving thread uses the unmodified original capability to the same -endpoint? The sender must identify itself. - -Notice also that the fact that both the sender and the receiver share -the same root CSpace, enables the receiving thread to just casually use -the original, unbadged capability without any extra work needed to make -it accessible. - -Notice however also, that while the sending thread has a capability that -grants it full rights to send data across the endpoint since it was the -one that created that capability, the receiver's capability may not -necessarily grant it sending powers (write capability) to the endpoint. -It's entirely possible that the receiver may not be able to send a -response message, if the sender doesn't want it to. - -- -- - -``` - - /* TASK 9: send and wait for a reply. */ - /* hint: seL4_Call() - * seL4_MessageInfo_t seL4_Call(seL4_CPtr dest, seL4_MessageInfo_t msgInfo) - * @param dest The capability to be invoked. - * @param msgInfo The messageinfo structure for the IPC. This specifies information about the message to send (such as the number of message registers to send). - * @return A seL4_MessageInfo_t structure. This is information about the repy message. - * - * hint 2: seL4_MessageInfo_t is generated during build. - * The type definition and generated field access functions are defined in a generated file: - * build/x86/pc99/libsel4/include/sel4/types_gen.h - * It is generated from the following definition: - */ -``` -
    -Quick solution -```c - tag = seL4_Call(ep_cap_path.capPtr, tag); -``` -
    - -On completion, you should see thread_2 fault as follows: -``` -thread_2: hallo wereld -thread_2: got a message 0 from 0 -Caught cap fault in send phase at address (nil) -while trying to handle: -vm fault on data at address (nil) with status 0x4 -in thread 0xffffff801ffb4400 "child of: 'rootserver'" at address (nil) -in thread 0xffffff801ffb4400 "child of: 'rootserver'" at address (nil) -With stack: -``` - -### Receive a reply - -While this task is out of order, since we haven't yet examined the -receive-side of the operation here, it's fairly simple anyway: this task -occurs after the receiver has sent a reply, and it shows the sender now -reading the reply from the receiver. As mentioned before, the -`seL4_GetMR()` calls are simply reading from the calling thread's -designated, single IPC buffer. - -- - -``` - - /* TASK 10: get the reply message */ - /* hint: seL4_GetMR() - * seL4_Word seL4_GetMR(int i) - * @param i The message register to retreive - * @return The message register value - */ -``` -
    -Quick solution -```c - msg = seL4_GetMR(0); -``` -
    - -On completion, the output should not change. - -### Receive an IPC - -We're now in the receiving thread. The `seL4_Recv()` syscall performs a -blocking listen on an Endpoint or Notification capability. When new data -is queued (or when the Notification is signalled), the `seL4_Recv` -operation will unqueue the data and resume execution. - -Notice how the `seL4_Recv()` operation explicitly makes allowance for -reading the badge value on the incoming message? The receiver is -explicitly interested in distinguishing the sender. - -- -- - -``` - - /* TASK 11: wait for a message to come in over the endpoint */ - /* hint 1: seL4_Recv() - * seL4_MessageInfo_t seL4_Recv(seL4_CPtr src, seL4_Word* sender) - * @param src The capability to be invoked. - * @param sender The badge of the endpoint capability that was invoked by the sender is written to this address. - * @return A seL4_MessageInfo_t structure - * - * hint 2: seL4_MessageInfo_t is generated during build. - * The type definition and generated field access functions are defined in a generated file: - * build/x86/pc99/libsel4/include/sel4/types_gen.h - */ -``` -
    -Quick solution -```c - tag = seL4_Recv(ep_object.cptr, &sender_badge); -``` -
    - -On completion, the output should change slightly: -``` -thread_2: got a message 0 from 0x61 -``` - -### Validate the message - -These two calls here are just verification of the fidelity of the -transmitted message. It's very unlikely you'll encounter an error here. -Complete them and proceed to the next step. - -- - -``` - - /* TASK 12: make sure it is what we expected */ - /* hint 1: check the badge. is it EP_BADGE? - * hint 2: we are expecting only 1 message register - * hint 3: seL4_MessageInfo_get_length() - * seL4_Uint32 CONST seL4_MessageInfo_get_length(seL4_MessageInfo_t seL4_MessageInfo) - * @param seL4_MessageInfo the seL4_MessageInfo_t to extract a field from - * @return the number of message registers delivered - * seL4_MessageInfo_get_length() is generated during build. It can be found in: - * build/x86/pc99/libsel4/include/sel4/types_gen.h - */ -``` -
    -Quick solution -```c - ZF_LOGF_IF(sender_badge != EP_BADGE, - "Badge on the endpoint was not what was expected.\n"); - ZF_LOGF_IF(seL4_MessageInfo_get_length(tag) != 1, - "Length of the data send from root thread was not what was expected.\n" - "\tHow many registers did you set with seL4_SetMR, within the root thread?\n"); -``` -
    - -On completion, the output should not change. - -### Read the message registers - -Again, just reading the data from the Message Registers. - -- - -``` - - /* TASK 13: get the message stored in the first message register */ - /* hint: seL4_GetMR() - * seL4_Word seL4_GetMR(int i) - * @param i The message register to retreive - * @return The message register value - */ -``` -
    -Quick solution -```c - msg = seL4_GetMR(0); - printf("thread_2: got a message %#" PRIxPTR " from %#" PRIxPTR "\n", msg, sender_badge); -``` -
    - -On completion, the output should change slightly: -``` -thread_2: got a message 0x6161 from 0x61 -``` - -### Write the message registers - -And writing Message Registers again. - -- - -``` - - /* TASK 14: copy the modified message back into the message register */ - /* hint: seL4_SetMR() - * void seL4_SetMR(int i, seL4_Word mr) - * @param i The message register to write - * @param mr The value of the message register - */ -``` -
    -Quick solution -```c - seL4_SetMR(0, msg); -``` -
    - -On completion, the output should not change. - -### Reply to a message - -This is a formal introduction to the `Reply` capability which is -automatically generated by the seL4 kernel, whenever an IPC message is -sent using the `seL4_Call()` syscall. This is unique to the `seL4_Call()` -syscall, and if you send data instead with the `seL4_Send()` syscall, the -seL4 kernel will not generate a Reply capability. - -The Reply capability solves the issue of a receiver getting a message -from a sender, but not having a sufficiently permissive capability to -respond to that sender. The "Reply" capability is a one-time capability -to respond to a particular sender. If a sender doesn't want to grant the -target the ability to send to it repeatedly, but would like to allow the -receiver to respond to a specific message once, it can use `seL4_Call()`, -and the seL4 kernel will facilitate this one-time permissive response. -Complete the step and pat yourself on the back. - -- -- - -``` - - /* TASK 15: send the message back */ - /* hint 1: seL4_ReplyRecv() - * seL4_MessageInfo_t seL4_ReplyRecv(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *sender) - * @param dest The capability to be invoked. - * @param msgInfo The messageinfo structure for the IPC. This specifies information about the message to send (such as the number of message registers to send) as the Reply part. - * @param sender The badge of the endpoint capability that was invoked by the sender is written to this address. This is a result of the Wait part. - * @return A seL4_MessageInfo_t structure. This is a result of the Wait part. - * - * hint 2: seL4_MessageInfo_t is generated during build. - * The type definition and generated field access functions are defined in a generated file: - * build/x86/pc99/libsel4/include/sel4/types_gen.h - * It is generated from the following definition: - */ -``` -
    -Quick solution -```c - seL4_ReplyRecv(ep_object.cptr, tag, &sender_badge); -``` -
    - -On completion, the output should change, with the fault message replaced with the following: -``` -main: got a reply: [0xffff9e9e|0xffffffffffff9e9e] -``` -That's it for this tutorial. - -Next tutorial: Processes & Elf loading +Next tutorial: Processes & Elf loading diff --git a/Tutorials/DynamicLibraries/dynamic-3.md b/Tutorials/DynamicLibraries/dynamic-3.md index f28b3cdb9f..0e90c0733a 100644 --- a/Tutorials/DynamicLibraries/dynamic-3.md +++ b/Tutorials/DynamicLibraries/dynamic-3.md @@ -1,457 +1,13 @@ --- toc: true +title: Dynamic Libraries 3 +tutorial: dynamic-3 +tutorial-order: dynamic-3 layout: tutorial +description: IPC with seL4_libs. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -# seL4 Dynamic Libraries: Processes & Elf loading +{% include tutorial.md %} -This tutorial shows how a separate ELF file can be loaded and expanded into a -VSpace, and subsequently executed, while facilitating IPC between the -two modules. It also shows how threads with different CSpaces have to -maneuver in order to pass capabilities to one another. - -Don't gloss over the globals declared before `main()` -- they're declared -for your benefit so you can grasp some of the basic data structures. -Uncomment them one by one as needed when going through the tasks. - -You'll observe that the things you've already covered in the second -tutorial are filled out and you don't have to repeat them: in much the -same way, we won't be repeating conceptual explanations on this page, if -they were covered by a previous tutorial in the series. - -Learning outcomes: -- Once again, repeat the spawning of a thread: however, this time - the two threads will only share the same vspace, but have - different CSpaces. This is an automatic side effect of the way - that sel4utils creates new "processes". -- Learn how the init thread in an seL4 system performs some types - of initialization that aren't traditionally left to userspace. -- Observe and understand the effects of creating thread that do - not share the same CSpace. -- Understand IPC across CSpace boundaries. -- Understand how minting a capability to a thread in another - CSpace works. - - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut dynamic-3 -# building the tutorial exercise -cd dynamic-3_build -ninja -``` -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut dynamic-3 -``` -Answers are also available in drop down menus under each section. -
    - - -## Exercises - -Tasks in this tutorial are in `main.c` and `app.c`. - -When you first run this tutorial, you should see the following output: - -``` -Booting all finished, dropped to user space -Node 0 of 1 -IOPT levels: 4294967295 -IPC buffer: 0x57f000 -Empty slots: [488 --> 4096) -sharedFrames: [0 --> 0) -userImageFrames: [16 --> 399) -userImagePaging: [12 --> 15) -untypeds: [399 --> 488) -Initial thread domain: 0 -Initial thread cnode size: 12 -dynamic-3: vspace_reserve_range_aligned@vspace.h:621 Not implemented -dynamic-3: main@main.c:117 [Cond failed: virtual_reservation.res == NULL] - Failed to reserve a chunk of memory. -``` - -### Virtual memory management - -Aside from receiving information about IRQs in the IRQControl object -capability, and information about available IO-Ports, and ASID -availability, and several other privileged bits of information, the init -thread is also responsible, surprisingly, for reserving certain critical -ranges of memory as being used, and unavailable for applications. - -This call to `sel4utils_bootstrap_vspace_with_bootinfo_leaky()` does -that. For an interesting look at what sorts of things the init thread -does, see: -`static int reserve_initial_task_regions(vspace_t *vspace, void *existing_frames[])`, -which is eventually called on by -`sel4utils_bootstrap_vspace_with_bootinfo_leaky()`. So while this -function may seem tedious, it's doing some important things. - -- -- - -```c - - /* TASK 1: create a vspace object to manage our vspace */ - /* hint 1: sel4utils_bootstrap_vspace_with_bootinfo_leaky() - * int sel4utils_bootstrap_vspace_with_bootinfo_leaky(vspace_t *vspace, sel4utils_alloc_data_t *data, seL4_CPtr page_directory, vka_t *vka, seL4_BootInfo *info) - * @param vspace Uninitialised vspace struct to populate. - * @param data Uninitialised vspace data struct to populate. - * @param page_directory Page directory for the new vspace. - * @param vka Initialised vka that this virtual memory allocator will use to allocate pages and pagetables. This allocator will never invoke free. - * @param info seL4 boot info - * @return 0 on succes. - */ -``` -
    -Quick solution -```c - error = sel4utils_bootstrap_vspace_with_bootinfo_leaky(&vspace, - &data, simple_get_pd(&simple), &vka, info); - ZF_LOGF_IFERR(error, "Failed to prepare root thread's VSpace for use.\n" - "\tsel4utils_bootstrap_vspace_with_bootinfo reserves important vaddresses.\n" - "\tIts failure means we can't safely use our vaddrspace.\n"); -``` -
    - - -On success, you should see a different error: - -``` -<> -halting... -``` - -### Configure a process - -`sel4utils_configure_process_custom` took a large amount of the work -out of creating a new "processs". We skipped a number of steps. Take a -look at the source for `sel4utils_configure_process_custom()` and -notice how it spawns the new thread with its own CSpace by -automatically. This will have an effect on our tutorial! It means that -the new thread we're creating will not share a CSpace with our main -thread. - -- - -```c - - /* TASK 2: use sel4utils to make a new process */ - /* hint 1: sel4utils_configure_process_custom() - * hint 2: process_config_default_simple() - * @param process Uninitialised process struct. - * @param vka Allocator to use to allocate objects. - * @param vspace Vspace allocator for the current vspace. - * @param priority Priority to configure the process to run as. - * @param image_name Name of the elf image to load from the cpio archive. - * @return 0 on success, -1 on error. - * - * hint 2: priority is in APP_PRIORITY and can be 0 to seL4_MaxPrio - * hint 3: the elf image name is in APP_IMAGE_NAME - */ -``` -
    -Quick solution -```c - sel4utils_process_t new_process; - sel4utils_process_config_t config = process_config_default_simple(&simple, APP_IMAGE_NAME, APP_PRIORITY); - error = sel4utils_configure_process_custom(&new_process, &vka, &vspace, config); - ZF_LOGF_IFERR(error, "Failed to spawn a new thread.\n" -"\tsel4utils_configure_process expands an ELF file into our VSpace.\n" - "\tBe sure you've properly configured a VSpace manager using sel4utils_bootstrap_vspace_with_bootinfo.\n" - "\tBe sure you've passed the correct component name for the new thread!\n"); -``` -
    - - -On success, you should see a different error: - -``` - dynamic-3: main@main.c:196 [Cond failed: new_ep_cap == 0] - Failed to mint a badged copy of the IPC endpoint into the new thread's CSpace. - sel4utils_mint_cap_to_process takes a cspacepath_t: double check what you passed. -``` - -### Get a `cspacepath` - -Now, in this particular case, we are making the new thread be the -sender. Recall that the sender must have a capability to the endpoint -that the receiver is listening on, in order to send to that listener. -But in this scenario, our threads do **not** share the same CSpace! -The only way the new thread will know which endpoint it needs a -capability to, is if we tell it. Furthermore, even if the new thread -knows which endpoint object we are listening on, if it doesn't have a -capability to that endpoint, it still can't send data to us. So we must -provide our new thread with both a capability to the endpoint we're -listening on, and also make sure, that that capability we give it has -sufficient privileges to send across the endpoint. - -There is a number of ways we could approach this, but in this tutorial -we decided to just pre-initialize the sender's CSpace with a sufficient -capability to enable it to send to us right from the start of its -execution. We could also have spawned the new thread as a listener -instead, and made it wait for us to send it a message with a sufficient -capability. - -So we use `vka_cspace_make_path()`, which locates one free capability -slot in the selected CSpace, and returns a handle to it, to us. We then -filled that free slot in the new thread's CSpace with a **badged** -capability to the endpoint we are listening on, so as so allow it to -send to us immediately. We could have filled the slot with an unbadged -capability, but then if we were listening for multiple senders, we -wouldn't know who was whom. - -- - -```c - - /* TASK 3: make a cspacepath for the new endpoint cap */ - /* hint 1: vka_cspace_make_path() - * void vka_cspace_make_path(vka_t *vka, seL4_CPtr slot, cspacepath_t *res) - * @param vka Vka interface to use for allocation of objects. - * @param slot A cslot allocated by the cspace alloc function - * @param res Pointer to a cspacepath struct to fill out - * - * hint 2: use the cslot of the endpoint allocated above - */ - cspacepath_t ep_cap_path; - seL4_CPtr new_ep_cap = 0; - ``` -
    -Quick solution -```c - cspacepath_t ep_cap_path; - seL4_CPtr new_ep_cap = 0; - vka_cspace_make_path(&vka, ep_object.cptr, &ep_cap_path); -``` -
    - -On success, the output should not change. - -### Badge a capability - -As discussed above, we now just mint a badged copy of a capability to -the endpoint we're listening on, into the new thread's CSpace, in the -free slot that the VKA library found for us. - -- -- - -```c - - /* TASK 4: copy the endpont cap and add a badge to the new cap */ - /* hint 1: sel4utils_mint_cap_to_process() - * seL4_CPtr sel4utils_mint_cap_to_process(sel4utils_process_t *process, cspacepath_t src, seL4_CapRights rights, seL4_Word data) - * @param process Process to copy the cap to - * @param src Path in the current cspace to copy the cap from - * @param rights The rights of the new cap - * @param data Extra data for the new cap (e.g., the badge) - * @return 0 on failure, otherwise the slot in the processes cspace. - * - * hint 2: for the rights, use seL4_AllRights - * hint 3: for the badge value use EP_BADGE - */ -``` -
    -Quick solution -```c - new_ep_cap = sel4utils_mint_cap_to_process(&new_process, ep_cap_path, - seL4_AllRights, EP_BADGE); - ZF_LOGF_IF(new_ep_cap == 0, "Failed to mint a badged copy of the IPC endpoint into the new thread's CSpace.\n" - "\tsel4utils_mint_cap_to_process takes a cspacepath_t: double check what you passed.\n"); -``` -
    - - -On success, the output should look something like: - -``` -NEW CAP SLOT: 6ac. -main: hello world -dynamic-3: main@main.c:247 [Cond failed: sender_badge != EP_BADGE] - The badge we received from the new thread didn't match our expectation -``` - -### Spawn a process - -So now that we've given the new thread everything it needs to -communicate with us, we can let it run. Complete this step and proceed. - -- - -```c - - /* TASK 5: spawn the process */ - /* hint 1: sel4utils_spawn_process_v() - * int sel4utils_spawn_process_v(sel4utils_process_t *process, vka_t *vka, vspace_t *vspace, int argc, char *argv[], int resume) - * @param process Initialised sel4utils process struct. - * @param vka Vka interface to use for allocation of frames. - * @param vspace The current vspace. - * @param argc The number of arguments. - * @param argv A pointer to an array of strings in the current vspace. - * @param resume 1 to start the process, 0 to leave suspended. - * @return 0 on success, -1 on error. - */ - /* hint 2: sel4utils_create_word_args() - * void sel4utils_create_word_args(char strings[][WORD_STRING_SIZE], char *argv[], int argc, ...) - * Create c-formatted argument list to pass to a process from arbitrarily long amount of words. - * - * @param strings empty 2d array of chars to populate with word strings. - * @param argv empty 1d array of char pointers which will be set up with pointers to - * strings in strings. - * @param argc number of words - * @param ... list of words to create arguments from. - * - */ -``` -
    -Quick solution -```c - new_ep_cap = sel4utils_mint_cap_to_process(&new_process, ep_cap_path, - seL4_AllRights, EP_BADGE); - seL4_Word argc = 1; - char string_args[argc][WORD_STRING_SIZE]; - char* argv[argc]; - sel4utils_create_word_args(string_args, argv, argc, new_ep_cap); - error = sel4utils_spawn_process_v(&new_process, &vka, &vspace, argc, (char**) &argv, 1); - ZF_LOGF_IFERR(error, "Failed to spawn and start the new thread.\n" - "\tVerify: the new thread is being executed in the root thread's VSpace.\n" - "\tIn this case, the CSpaces are different, but the VSpaces are the same.\n" - "\tDouble check your vspace_t argument.\n"); -``` -
    - -On success, you should be able to see the second process running. The output should -be as follows: - -``` -NEW CAP SLOT: 6ac. -process_2: hey hey hey -main@app.c:67 [Cond failed: msg != ~MSG_DATA] - Unexpected response from root thread. -main: hello world -dynamic-3: main@main.c:255 [Cond failed: sender_badge != EP_BADGE] - The badge we received from the new thread didn't match our expectation. -``` - -### Receive a message - -We now wait for the new thread to send us data using `seL4_Recv()`... -Then we verify the fidelity of the data that was transmitted. - -- -- - -```c - - /* TASK 6: wait for a message */ - /* hint 1: seL4_Recv() - * seL4_MessageInfo_t seL4_Recv(seL4_CPtr src, seL4_Word* sender) - * @param src The capability to be invoked. - * @param sender The badge of the endpoint capability that was invoked by the sender is written to this address. - * @return A seL4_MessageInfo_t structure - * - * hint 2: seL4_MessageInfo_t is generated during build. - * hint 3: use the badged endpoint cap that you minted above - */ -``` -
    -Quick solution -```c - tag = seL4_Recv(ep_cap_path.capPtr, &sender_badge); - /* make sure it is what we expected */ - ZF_LOGF_IF(sender_badge != EP_BADGE, - "The badge we received from the new thread didn't match our expectation.\n"); - ZF_LOGF_IF(seL4_MessageInfo_get_length(tag) != 1, - "Response data from the new process was not the length expected.\n" - "\tHow many registers did you set with seL4_SetMR within the new process?\n"); -``` -
    - - -On success, the badge error should no longer be visible. - -### Send a reply - -Another demonstration of the `sel4_Reply()` facility: we reply to the -message sent by the new thread. - -- -- - -```c - - /* TASK 7: send the modified message back */ - /* hint 1: seL4_ReplyRecv() - * seL4_MessageInfo_t seL4_ReplyRecv(seL4_CPtr dest, seL4_MessageInfo_t msgInfo, seL4_Word *sender) - * @param dest The capability to be invoked. - * @param msgInfo The messageinfo structure for the IPC. This specifies information about the message to send (such as the number of message registers to send) as the Reply part. - * @param sender The badge of the endpoint capability that was invoked by the sender is written to this address. This is a result of the Wait part. - * @return A seL4_MessageInfo_t structure. This is a result of the Wait part. - * - * hint 2: seL4_MessageInfo_t is generated during build. - * hint 3: use the badged endpoint cap that you used for Call - */ -``` -
    -Quick solution -```c - seL4_ReplyRecv(ep_cap_path.capPtr, tag, &sender_badge); -``` -
    - - -On success, the output should not change. - -### Client Call - -In the new thread, we initiate communications by using `seL4_Call()`. As -outlined above, the receiving thread replies to us using -`sel4_ReplyRecv()`. The new thread then checks the fidelity of the data -that was sent, and that's the end. - -- - -```c - - /* TASK 8: send and wait for a reply */ - /* hint 1: seL4_Call() - * seL4_MessageInfo_t seL4_Call(seL4_CPtr dest, seL4_MessageInfo_t msgInfo) - * @param dest The capability to be invoked. - * @param msgInfo The messageinfo structure for the IPC. This specifies information about the message to send (such as the number of message registers to send). - * @return A seL4_MessageInfo_t structure. This is information about the repy message. - * - * hint 2: send the endpoint cap using argv (see TASK 6 in the other main.c) - */ - ZF_LOGF_IF(argc < 1, - "Missing arguments.\n"); - seL4_CPtr ep = (seL4_CPtr) atol(argv[0]); -``` -
    -Quick solution -```c - seL4_CPtr ep = (seL4_CPtr) atol(argv[0]); - tag = seL4_Call(ep, tag); -``` -
    - -On success, you should see the following: - -``` -process_2: hey hey hey -main: got a message 0x6161 from 0x61 -process_2: got a reply: 0xffffffffffff9e9e -``` - -That's it for this tutorial. - -Next tutorial: Timer +Next tutorial: Timer diff --git a/Tutorials/DynamicLibraries/dynamic-4.md b/Tutorials/DynamicLibraries/dynamic-4.md index b760d5cef3..f3984c190e 100644 --- a/Tutorials/DynamicLibraries/dynamic-4.md +++ b/Tutorials/DynamicLibraries/dynamic-4.md @@ -1,227 +1,13 @@ --- toc: true +title: Dynamic Libraries 4 +tutorial: dynamic-4 +tutorial-order: dynamic-4 layout: tutorial +description: IPC with seL4_libs. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -# seL4 Dynamic Libraries: Timer tutorial +{% include tutorial.md %} -This tutorial demonstrates how to set up and use a basic timer driver using the -`seL4_libs` dynamic libraries. - -You'll observe that the things you've already covered in the other -tutorials are already filled out and you don't have to repeat them: in -much the same way, we won't be repeating conceptual explanations on this -page, if they were covered by a previous tutorial in the series. - -Learning outcomes: -- Allocate a notification object. -- Set up a timer provided by `util_libs`. -- Use `seL4_libs` and `util_libs` functions to manipulate timer and - handle interrupts. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut dynamic-4 -# building the tutorial exercise -cd dynamic-4_build -ninja -``` -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut dynamic-4 -``` -Answers are also available in drop down menus under each section. -
    - - -## Exercises - -Once you initialise and run the tutorials, you will see the following output: - -``` -Booting all finished, dropped to user space -Node 0 of 1 -IOPT levels: 4294967295 -IPC buffer: 0x5a1000 -Empty slots: [523 --> 4096) -sharedFrames: [0 --> 0) -userImageFrames: [16 --> 433) -userImagePaging: [12 --> 15) -untypeds: [433 --> 523) -Initial thread domain: 0 -Initial thread cnode size: 12 -timer client: hey hey hey -main: hello world -main: got a message from 0x61 to sleep 2 seconds -ltimer_get_time@ltimer.h:267 get_time not implemented -timer client wakes up: - got the current timer tick: - 0 -``` -### Allocate a notification object - -The first task is to allocate a notification object to receive -interrupts on. -```c - - /* TASK 1: create a notification object for the timer interrupt */ - /* hint: vka_alloc_notification() - * int vka_alloc_notification(vka_t *vka, vka_object_t *result) - * @param vka Pointer to vka interface. - * @param result Structure for the notification object. This gets initialised. - * @return 0 on success - * https://github.com/seL4/libsel4vka/blob/master/include/vka/object.h#L98 - */ - vka_object_t ntfn_object = {0}; -``` -
    -Quick solution -```c - error = vka_alloc_notification(&vka, &ntfn_object); - assert(error == 0); -``` -
    - -The output will not change as a result of completing this task. - -### Initialise the timer - -Use our library function `ltimer_default_init` to -initialise a timer driver. Assign it to the `timer` global variable. -```c - - /* TASK 2: call ltimer library to get the default timer */ - /* hint: ltimer_default_init, you can set NULL for the callback and token - */ - ps_io_ops_t ops = {{0}}; - error = sel4platsupport_new_malloc_ops(&ops.malloc_ops); - assert(error == 0); - error = sel4platsupport_new_io_mapper(&vspace, &vka, &ops.io_mapper); - assert(error == 0); - error = sel4platsupport_new_fdt_ops(&ops.io_fdt, &simple, &ops.malloc_ops); - assert(error == 0); - if (ntfn_object.cptr != seL4_CapNull) { - error = sel4platsupport_new_mini_irq_ops(&ops.irq_ops, &vka, &simple, &ops.malloc_ops, - ntfn_object.cptr, MASK(seL4_BadgeBits)); - assert(error == 0); - } - error = sel4platsupport_new_arch_ops(&ops, &simple, &vka); - assert(error == 0); -``` -
    -Quick solution -```c - error = ltimer_default_init(&timer, ops, NULL, NULL); - assert(error == 0); -``` -
    - -After this change, the server will output non-zero for the tick value at the end. -``` - got the current timer tick: - 1409040 -``` - -### Use the timer - -While at the end of the previous task the tutorial appears to be -working, the main thread replies immediately to the client and doesn't -wait at all. - -Consequently, the final task is to interact with the timer: set a -timeout, wait for an interrupt on the created notification, and handle -it. - -```c - - /* - * TASK 3: Start and configure the timer - * hint 1: ltimer_set_timeout - * hint 2: set period to 1 millisecond - */ -``` -
    -Quick solution -```c - error = ltimer_set_timeout(&timer, NS_IN_MS, TIMEOUT_PERIODIC); - assert(error == 0); -``` -
    - -The output will cease after the following line as a result of completing this task. -``` -main: got a message from 0x61 to sleep 2 seconds -``` - -### Handle the interrupt - -In order to receive more interrupts, you need to handle the interrupt in the driver -and acknowledge the irq. - -```c - - /* - * TASK 4: Handle the timer interrupt - * hint 1: wait for the incoming interrupt and handle it - * The loop runs for (1000 * msg) times, which is basically 1 second * msg. - * - * hint2: seL4_Wait - * hint3: sel4platsupport_irq_handle - * hint4: 'ntfn_id' should be MINI_IRQ_INTERFACE_NTFN_ID and handle_mask' should be the badge - * - */ -``` -
    -Quick solution -```c - seL4_Word badge; - seL4_Wait(ntfn_object.cptr, &badge); - sel4platsupport_irq_handle(&ops.irq_ops, MINI_IRQ_INTERFACE_NTFN_ID, badge); - count++; - if (count == 1000 * msg) { - break; - } -``` -
    - -The timer interrupts are bound to the IRQ interface initialised in Task 2, -hence when we receive an interrupt, we forward it to the interface and let it notify the timer driver. - -After this task is completed you should see a 2 second wait, then output from the - client as follows: -``` -timer client wakes up: - got the current timer tick: - 2365866120 -``` - -### Destroy the timer - -```c - - /* - * TASK 5: Stop the timer - * hint: ltimer_destroy - */ -``` -
    -Quick solution -```c - ltimer_destroy(&timer); -``` -
    - -The output should not change on successful completion of completing this task. - -That's it for this tutorial. - -Next tutorial: Hello CAmkES +Next tutorial: Hello CAmkES diff --git a/Tutorials/MCS/mcs.md b/Tutorials/MCS/mcs.md index 047d83d1d4..d7c5d29197 100644 --- a/Tutorials/MCS/mcs.md +++ b/Tutorials/MCS/mcs.md @@ -1,439 +1,13 @@ --- toc: true +title: MCS +tutorial: mcs +tutorial-order: mcs-1 +description: an introduction to the seL4 MCS extensions. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- +{% include tutorial.md %} -# MCS Extensions -This tutorial presents the features in the upcoming MCS extensions for seL4, which are currently undergoing -verification. For further context on the new features, please see the -[paper](https://trustworthy.systems/publications/csiro_full_text/Lyons_MAH_18.pdf) or [phd](https://github.com/pingerino/phd/blob/master/phd.pdf) - which provides a comprehensive background on the changes. - -Learn: -1. About the MCS new kernel API. -1. How to create and configure scheduling contexts. -2. The jargon *passive server*. -3. How to spawn round-robin and periodic threads. - - - -## Initialising - -Then initialise the tutorial: - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut mcs -# building the tutorial exercise -cd mcs_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut mcs -``` -
    - - -## Background - -The MCS extensions provide capability-based access to CPU time, and provide mechanisms to limit the upper -bound of execution of a thread. - -### Scheduling Contexts - -Scheduling contexts are a new object type in the kernel, which contain scheduling parameters amoung other -accounting details. Most importantly, scheduling contexts contain a *budget* and a *period*, which -represent an upper bound on execution time allocated: the kernel will enforce that threads cannot execute -for more than *budget* microseconds out of *period* microseconds. - -### SchedControl - -Parameters for scheduling contexts are configured by invoking `seL4_SchedControl` capabilities, one of -which is provided per CPU. The invoked `seL4_SchedControl` determines which processing core that specific -scheduling context provides access to. - -Scheduling contexts can be configured as *full* or *partial*. Full scheduling contexts have `budget == -period` and grant access to 100% of CPU time. Partial scheduling contexts grant access to an upper bound of - `budget/period` CPU time. - -The code example below configures a -scheduling context with a budget and period both equal to 1000us. Because the budget and period are equal, -the scheduling context is treated as round-robin - -```c - error = seL4_SchedControl_Configure(sched_control, sched_context, US_IN_S, US_IN_S, 0, 0); - ZF_LOGF_IF(error != seL4_NoError, "Failed to configure schedcontext"); -``` - -### SchedContext Binding - -Thread control blocks (TCBs) must have a scheduling context configured with non-zero budget and period - in order to be picked by the scheduler. This -can by invoking the scheduling context capability with the `seL4_SchedContext_Bind` invocation, or by -using `seL4_TCB_SetSchedParams`, which takes a scheduling context capability. Below is example code for -binding a TCB and a scheduling context. - -```c - error = seL4_SchedContext_Bind(sched_context, spinner_tcb); - ZF_LOGF_IF(error != seL4_NoError, "Failed to bind sched_context to round_robin_tcb"); -``` - -TCB's can only be bound to one scheduling context at a time, and vice versa. If a scheduling context has not -been configured with any time, then although the TCB has a scheduling context it will remain ineligible -for scheduling. - -### Bounding execution - -For partial scheduling contexts, an upper bound on execution is enforced by seL4 using the *sporadic server* -algorithm, which work by guaranteeing the *sliding window* constrain, meaning that during any period, the -budget cannot be exceeded. This is achieved by tracking the eligible budget in chunks called -*replenishments* (abbreviated to `refills` in the API for brevity). A replenishment is simply an amount - of time, and a timestamp from which that time can be consumed. We explain this now through an example: - -Consider a scheduling context with period *T* and budget *C*. Initially, the scheduling context has -a single replenishment of size *C* which is eligible to be used from time *t*. - -The scheduling context is scheduled at time *t* and blocks at time *t + n*. A new replenishment is then scheduled -for time *t+T* for *n*. The existing replenishment is updated to *C - n*, subtracting the amount consumed. -For further details on the sporadic server algorithm, see the -[original paper](https://dl.acm.org/citation.cfm?id=917665). - -If the replenishment data structure is full, replenishments are merged and the upper bound on execution is -reduced. For this reason, the bound on execution is configurable with the `extra_refills` parameter -on scheduling contexts. By default, scheduling contexts contain only two parameters, meaning if a -scheduling context is blocked, switched or preempted more than twice, the rest of the budget is forfeit until -the next period. `extra_refills` provides more replenishment data structures in a scheduling context. Note -that the higher the number of replenishments the more fragmentation of budget can occur, which will increase -scheduling overhead. - -`extra_refills` itself is bounded by the size of a scheduling context, which is itself configurable. -On scheduling context creation a size can be specified, and must be `> seL4_MinSchedContextBits`. The -maximum number of extra refills that can fit into a specific scheduling context size can be calculated -with the function `seL4_MaxExtraRefills()` provided in `libsel4`. - -Threads bound to scheduling contexts that do not have an available replenishment are placed into an ordered -queue of threads, and woken once their next replenishment is ready. - -### Scheduler - -The seL4 scheduler is largely unchanged: the highest priority, non-blocked thread with a configured - scheduling context that has available budget is chosen by the scheduler to run. - -### Passive servers - -The MCS extensions allow for RPC style servers to run on client TCBs' scheduling contexts. This is achived by -unbinding the scheduling context once a server is blocked on an endpoint, rendering the server *passive*. -Caller scheduling contexts are donated to the server on `seL4_Call` and returned on `seL4_ReplyRecv`. - -Passive servers can also receive scheduling contexts from their bound notification object, which is -achieved by binding a notification object using `seL4_SchedContext_Bind`. - -### Timeout faults - -Threads can register a timeout fault handler using `seL4_TCB_SetTimeoutEndpoint`. Timeout fault -handlers are optional and are raised when a thread's replenishment expires *and* they have a valid handler -registered. The timeout fault message from the kernel contains the data word which can be used to identify the -scheduling context that the thread was using when the timeout fault occurred, and the amount of time -consumed by the thread since the last fault or `seL4_SchedContext_Consumed`. - -### New invocations - -* `seL4_SchedContext_Bind` - bind a TCB or Notification capability to the invoked scheduling context. -* `seL4_SchedContext_Unbind` - unbind any objects from the invoked scheduling context. -* `seL4_SchedContext_UnbindObject`- unbind a specific object from the invoked scheduling context. -* `seL4_SchedContext_YieldTo` - if the thread running on the invoked scheduling context is -schedulable, place it at the head of the scheduling queue for its priority. For same priority threads, this -will result in the target thread being scheduled. Return the amount of time consumed by this scheduling -context since the last timeout fault, `YieldTo` or `Consumed` invocation. -* `seL4_SchedContext_Consumed` - Return the amount of time consumed by this scheduling -context since the last timeout fault, `YieldTo` or `Consumed` invocation. -* `seL4_TCB_SetTimeoutEndpoint` - Set the timeout fault endpoint for a TCB. - -### Reply objects - -The MCS API also makes the reply channel explicit: reply capabilities are now fully fledged objects -which must be provided by a thread on `seL4_Recv` operations. They are used to track the scheduling -context donation chain and return donated scheduling contexts to callers. - -Please see the [release notes](https://docs.sel4.systems/sel4_release/seL4_9.0.0-mcs) and -[manual](https://docs.sel4.systems/sel4_release/seL4_9.0.0-mcs.html) for further details - on the API changes. - -## Exercises - -In the initial state of the tutorial, the main function in `mcs.c` is running in one process, and the -following loop from `spinner.c` is running in another process: - - -``` - int i = 0; - while (1) { - printf("Yield\n"); - seL4_Yield(); - } -``` - -Both processes share the same priority. The code in `mcs.c` binds -a scheduling context (`sched_context`) to the TCB of the spinner process (`spinner_tcb)` with round-robin scheduling parameters. As a result, you should see - something like the following output, which continues uninterrupted: - -``` -Yield -Yield -Yield -``` - -### Periodic threads - -**Exercise** Reconfigure `sched_context` with the following periodic scheduling parameters, - (budget = `0.9 * US_IN_S`, period = `1 * US_IN_S`). - - ```c - //TODO reconfigure sched_context to be periodic -``` -
    -Quick solution -```c - error = seL4_SchedControl_Configure(sched_control, sched_context, 0.9 * US_IN_S, 1 * US_IN_S, 0, 0); - ZF_LOGF_IF(error != seL4_NoError, "Failed to configure schedcontext"); -``` -
    - - -By completing this task successfully, the output will not change, but the rate that the output is -printed will slow: each subsequent line should be output once the period has elapsed. You should now -be able to see the loop where the `mcs.c` process and `spinner.c` process alternate, until the `mcs.c` -process blocks, at which point `"Yield"` is emitted by `spinner.c` every second, as shown below: - -``` -Yield -Tick 0 -Yield -Tick 1 -Yield -Tick 2 -Yield -Tick 3 -Yield -Tick 4 -Yield -Tick 5 -Yield -Tick 6 -Yield -Tick 7 -Yield -Tick 8 -Yield -Yield -Yield -``` -Before you completed this task, the scheduling context was round-robin, and so was -schedulable immediately after the call to `seL4_Yield`. -By changing -the scheduling parameters of `sched_context` to periodic parameters (budget < period), each time -`seL4_Yield()` is called the available budget in the scheduling context is abandoned, causing the -thread to sleep until the next replenishment, determined by the period. - -### Unbinding scheduling contexts - -You can cease a threads execution by unbinding the scheduling context. -Unlike *suspending* a thread via `seL4_TCB_Suspend`, unbinding will not change the thread state. Using suspend -cancels any system calls in process (e.g IPC) and renders the thread unschedulable by changing the -thread state. Unbinding a scheduling context does not alter the thread state, but merely removes the thread -from the scheduler queues. - -**Exercise** Unbind `sched_context` to stop the spinner process from running. -```c - //TODO unbind sched_context to stop yielding thread -``` -
    -Quick solution -```c - error = seL4_SchedContext_Unbind(sched_context); - ZF_LOGF_IF(error, "Failed to unbind sched_context"); -``` -
    - - -On success, you should see the output from the yielding thread stop. - -### Sporadic threads - -Your next task is to use a different process, `sender` to experiment with sporadic tasks. The -`sender` process is ready to run, and just needs a scheduling context in order to do so. - -**Exercise** First, bind `sched_context` to `sender_tcb`. - - ```c - //TODO bind sched_context to sender_tcb -``` -
    -Quick solution -```c - error = seL4_SchedContext_Bind(sched_context, sender_tcb); - ZF_LOGF_IF(error != seL4_NoError, "Failed to bind schedcontext"); -``` -
    - -The output should look like the following: -``` -... -Tock 3 -Tock 4 -Tock 5 -Tock 6 -``` - -Note the rate of the output: currently, you should see 2 lines come out at a time, with roughly -a second break between (the period of the scheduling context you set earlier). This is because -scheduling context only has the minimum sporadic refills (see background), and each time a context switch -occurs a refill is used up to schedule another. - -**Exercise** Reconfigure the `sched_context` to an extra 6 refills, such that all of the `Tock` output -occurs in one go. - - ```c - //TODO reconfigure sched_context to be periodic with 6 extra refills -``` -
    -Quick solution -```c - error = seL4_SchedControl_Configure(sched_control, sched_context, 0.9 * US_IN_S, 1 * US_IN_S, 6, 0); - ZF_LOGF_IF(error != seL4_NoError, "Failed to configure schedcontext"); -``` -
    - -### Passive servers - -Now look to the third process, `server.c`, which is a very basic echo server. It currently does -not have a scheduling context, and needs one to initialise. - -**Exercise** Bind `sched_context` to `server_tcb`. - - ```c - //TODO bind sched_context to server_tcb -``` -
    -Quick solution -```c - error = seL4_SchedContext_Bind(sched_context, server_tcb); - ZF_LOGF_IF(error != seL4_NoError, "Failed to bind sched_context to server_tcb"); -``` -
    - - -Now you should see the server initialise and echo the messages sent. Note the initialisation protocol: -first, you bound `sched_context` to the server. At this point, in `server.c`, the server calls -`seL4_NBSendRecv` which sends an IPC message on `endpoint`, indicating that the server is now initialised. -The output should be as follows - -``` -Tock 8 -Starting server -Wait for server -Server initialising -running -passive -echo server -Yield -``` - -The following code then converts the server to passive: - -```c - // convert to passive - error = seL4_SchedContext_Unbind(sched_context); -``` - -From this point, the server runs on the `mcs` process's scheduling context. - -### Timeout Faults - -But before we discuss timeout faults, we must first discuss the differences -between configuring a fault endpoint on the master vs the MCS kernel. There is a -minor difference in the way that the kernel is informed of the cap to a fault -endpoint, between the master and MCS kernels. - -Regardless though, on both versions of the kernel, to inform the kernel of the -fault endpoint for a thread, call the usual `seL4_TCB_SetSpace()`. - -#### Configuring a fault endpoint on the MCS kernel - -On the MCS kernel the cap given to the kernel must be a cap to an object in -the CSpace of the thread which is *calling the syscall* (`seL4_TCB_Configure()`) -to give the cap to the kernel. - -This calling thread may be the handler thread, or some other thread which -manages both the handler thread and the faulting thread. Or in an oddly designed -system, it might be the faulting thread itself if the faulting thread is allowed -to configure its own fault endpoint. - -The reason for this difference is merely that it is faster to lookup the fault -endpoint this way since it is looked up only once at the time it is configured. - -#### Configuring a fault endpoint on the Master kernel - -On the Master kernel the cap given to the kernel must be a cap to an object in -the CSpace of the *faulting thread*. - -On the Master kernel, the fault endpoint cap is looked up from within the CSpace -of the faulting thread everytime a fault occurs. - -#### Exercise: - -**Exercise** Set the data field of `sched_context` using `seL4_SchedControl_Configure` and set a 1s period, 500 µs -budget and 0 extra refills. - -```c - // reconfigure sched_context with 1s period, 500 microsecond budget, 0 extra refills and data of 5. -``` -
    -Quick solution -```c - error = seL4_SchedControl_Configure(sched_control, sched_context, 500, US_IN_S, 0, 5); - ZF_LOGF_IF(error != seL4_NoError, "Failed to configure sched_context"); -``` -
    -The code then binds the scheduling context back to `spinner_tcb`, which starts yielding again. - -**Exercise** set the timeout fault endpoint for `spinner_tcb`. - - -```c - //TODO set endpoint as the timeout fault handler for spinner_tcb -``` -
    -Quick solution -```c -``` -
    - - -When the `spinner` faults, you should see the following output: - -``` -Received timeout fault -Success! -``` - -### Further exercises - -That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, -to become more familiar with the MCS extensions. - -* Set up a passive server with a timeout fault handlers, with policies for clients that exhaust their budget. -* Experiment with notification binding on a passive server, by binding both a notification object to the -server TCB and an SC to the notification object. - -Next tutorial: Dynamic libraries +Next tutorial: Dynamic libraries diff --git a/Tutorials/seL4Kernel/capabilities.md b/Tutorials/seL4Kernel/capabilities.md index fbd2cd5461..c7ca44aa25 100644 --- a/Tutorials/seL4Kernel/capabilities.md +++ b/Tutorials/seL4Kernel/capabilities.md @@ -9,377 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- -# Capabilities - -This tutorial provides a basic introduction to seL4 capabilities. - -You will learn: -1. The jargon CNode, CSpace, CSlot. -2. Know how to invoke a capability. -3. Know how to delete and copy CSlots. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/seL4Kernel/setting-ip#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut capabilities -# building the tutorial exercise -cd capabilities_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: - -``` -./init --solution --tut capabilities -``` - -Answers are also available in drop down menus under each section. -
    - - -## Background - -### What is a capability? - -A *capability* is a unique, unforgeable token that gives the possessor -permission to access an entity or object in system. One way to think of a -capability is as a pointer with access rights. There are three kinds of -capabilities in seL4: - -* capabilities that control access to kernel objects such as thread control blocks, -* capabilities that control access to abstract resources such as `IRQControl`, and -* untyped capabilities, that are responsible for memory ranges and allocation - from those (see also the [Untyped](untyped) tutorial). - -In seL4, capabilities to all resources controlled by the kernel are given to the root -task on initialisation. To change the state of any resource, user code can use -the kernel API, available in `libsel4` to request an operation on the resource -a specific capability points to. - -For example, the root task is provided with a capability to its own thread -control block (TCB), `seL4_CapInitThreadTCB`, a constant defined by `libsel4`. -To change the properties of the initial TCB, one can use any of the [TCB API -methods](https://docs.sel4.systems/projects/sel4/api-doc.html#sel4_tcb) on this -capability. - -Below is an example which changes the stack pointer of the root task's TCB, a -common operation in the root task if a larger stack is needed: - -```c - seL4_UserContext registers; - seL4_Word num_registers = sizeof(seL4_UserContext)/sizeof(seL4_Word); - - /* Read the registers of the TCB that the capability in seL4_CapInitThreadTCB grants access to. */ - seL4_Error error = seL4_TCB_ReadRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, ®isters); - assert(error == seL4_NoError); - - /* set new register values */ - registers.sp = new_sp; // the new stack pointer, derived by prior code. - - /* Write new values */ - error = seL4_TCB_WriteRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, ®isters); - assert(error == seL4_NoError); -``` - -The first argument of `seL4_TCB_ReadRegisters` and `seL4_TCB_WriteRegisters` -addresses the capability in slot `seL4_CapInitThreadTCB`. We will explain -addressing and slots below. The rest of the arguments are specific to the -invocations. Further documentation is available on -[TCB_ReadRegisters](https://docs.sel4.systems/projects/sel4/api-doc.html#read-registers) -and -[TCB_WriteRegisters](https://docs.sel4.systems/projects/sel4/api-doc.html#write-registers). - -### CNodes and CSlots - -A *CNode* (capability-node) is an object full of capabilities: you can think of a CNode as an array of capabilities. -We refer to slots as *CSlots* (capability-slots). In the example above, `seL4_CapInitThreadTCB` is the slot in the root -task's CNode that contains the capability to the root task's TCB. -Each CSlot in a CNode can be in the following state: - -* empty: the CNode slot contains a null capability, -* full: the slot contains a capability to a kernel resource. - -By convention the 0th CSlot is kept empty, for the same reasons as keeping NULL unmapped in - process virtual address spaces: to avoid errors when uninitialised slots are used unintentionally. - -The field `info->CNodeSizeBits` gives a measure of the size of the initial -CNode: it will have `1 << CNodeSizeBits` CSlots. A CSlot has -`1 << seL4_SlotBits` bytes, so the size of a CNode in bytes is -`1 << (CNodeSizeBits + seL4_SlotBits)`. - -### CSpaces - -A *CSpace* (capability-space) is the full range of capabilities accessible to a thread, which may be -formed of one or more CNodes. In this tutorial, we focus on the CSpace constructed for the root task -by seL4's initialisation protocol, which consists of one CNode. - -### CSpace addressing - -To refer to a capability and perform operations on it, you must *address* the -capability. There are two ways to address capabilities in the seL4 API. First is -by invocation, the second is by direct addressing. Invocation is a shorthand and -it is what we used to manipulate the registers of the root task's TCB, which we -now explain in further detail. - -#### Invocation - -Each thread has a special CNode capability installed in its TCB as its *CSpace -root*. This root can be empty (a null cap), for instance when the thread is not -authorised to invoke any capabilities at all, or it can be a capability to a -CNode. The root task always has a CSpace root capability that points to a CNode. - -In an *invocation*, a CSlot is addressed by implicitly invoking the CSpace root -of the thread that is performing the invocation. In the code example above, we -use an invocation on the `seL4_CapInitThreadTCB` CSlot to read from and write to -the registers of the TCB represented by the capability in that specific CSlot. - -```c -seL4_TCB_WriteRegisters(seL4_CapInitThreadTCB, 0, 0, num_registers, ®isters); -``` - -This implicitly looks up the `seL4_CapInitThreadTCB` CSlot in the CNode pointed to -by the CSpace root capability of the calling thread, which here is the root task. - -When it is clear by context and not otherwise relevant, we sometimes identify -the capability with the object it points to. So, instead of saying "the CNode -pointed to by the CSpace root capability", we sometimes say "the CSpace root". -If not sure, it is better to be precise. Like structs and pointers in C, objects -and capabilities are not actually interchangeable: one object can be pointed to -by multiple capabilities, and each of these capabilities could have a different -level of permissions to that object. - - -#### Direct CSpace addressing - -In contrast to invocation addressing, *direct addressing* allows you to specify -the CNode to look up in, rather than implicitly using the CSpace root. This form -of addressing is primarily used to construct and manipulate the shape of CSpaces --- potentially the CSpace of another thread. Note that direct addressing also -requires invocation: the operation occurs by invoking a CNode capability, which -itself is indexed from the CSpace root. - -The following fields are used when directly addressing CSlots: - -* *_service/root* A capability to the CNode to operate on. -* *index* The index of the CSlot in the CNode to address. -* *depth* How far to traverse the CNode before resolving the CSlot. - -For the initial, single-level CSpace, the *depth* value is always `seL4_WordBits`. For invocations, the depth is always - implicitly `seL4_WordBits`. -More on CSpace depth will be discussed in future tutorials. - -In the example below, we directly address the root task's TCB to make a copy of -it in the 0th slot in the CSpace root. [CNode -copy](https://docs.sel4.systems/projects/sel4/api-doc.html#copy) requires two -CSlots to be directly addressed: the destination CSlot, and the source CSlot. -`seL4_CapInitThreadCNode` is used in three different roles here: as source root, -as destination root, and as source slot. It is used as source and destination -root, because we are copying within the same CNode -- the CNode of the initial -thread. It is used as source slot, because within the CNode of the initial -thread, `seL4_CapInitThreadCNode` is the slot of the capability we want to copy -(and the slot `0` is the destination). - -```c - seL4_Error error = seL4_CNode_Copy( - seL4_CapInitThreadCNode, 0, seL4_WordBits, // destination root, slot, and depth - seL4_CapInitThreadCNode, seL4_CapInitThreadTCB, seL4_WordBits, // source root, slot, and depth - seL4_AllRights); - assert(error == seL4_NoError); -``` - -All [CNode invocations](https://docs.sel4.systems/projects/sel4/api-doc.html#sel4_cnode) require direct CSpace addressing. - -### Initial CSpace - -The root task has a CSpace, set up by seL4 during boot, which contains capabilities to all -resources managed by seL4. We have already seen several capabilities in the root CSpace: `seL4_CapInitThreadTCB`, - and `seL4_CapInitThreadCNode`. Both of these are specified by constants in `libsel4`, however not all initial - capabilities are statically specified. Other capabilities are described by the `seL4_BootInfo` data structure, - described in `libsel4` and initialised by seL4. `seL4_BootInfo` describes ranges of initial capabilities, - including free slots available in the initial CSpace. - -## Exercises - -The initial state of this tutorial provides you with the BootInfo structure, -and calculates the size (in slots) of the initial CNode object. - -```c -int main(int argc, char *argv[]) { - - /* parse the location of the seL4_BootInfo data structure from - the environment variables set up by the default crt0.S */ - seL4_BootInfo *info = platsupport_get_bootinfo(); - - size_t initial_cnode_object_size = BIT(info->initThreadCNodeSizeBits); - printf("Initial CNode is %zu slots in size\n", initial_cnode_object_size); -``` - -When you run the tutorial without changes, you will see something like the following output: - -``` -Booting all finished, dropped to user space -Initial CNode is 65536 slots in size -The CNode is 0 bytes in size -<> -main@main.c:33 [Cond failed: error] - Failed to set priority -``` - -By the end of the tutorial all of the output will make sense. For now, the first line is from the kernel. -The second is the `printf`, telling you the size of the initial CNode. -The third line stating the number of slots in the CSpace, is incorrect, and your first task is to fix that. - -### How big is your CSpace? - -**Exercise:** refer to the background above, and calculate the number of bytes occupied by the initial thread's CSpace. - -```c - size_t initial_cnode_object_size_bytes = 0; // TODO calculate this. - printf("The CNode is %zu bytes in size\n", initial_cnode_object_size_bytes); -``` -
    -Quick solution - -```c - size_t initial_cnode_object_size_bytes = initial_cnode_object_size * (1u << seL4_SlotBits); -``` - -
    - -### Copy a capability between CSlots - -After the output showing the number of bytes in the CSpace, you will see an error: - -``` -<> -main@main.c:33 [Cond failed: error] - Failed to set priority -``` - -The error occurs as the existing code tries to set the priority of the initial thread's TCB by - invoking the last CSlot in the CSpace, which is currently empty. seL4 then returns an error code, - and our check that the operation succeeded fails. - -**Exercise:** fix this problem by making another copy of the TCB capability into the last slot in the CNode. - -```c - seL4_CPtr first_free_slot = info->empty.start; - seL4_Error error = seL4_CNode_Copy(seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits, - seL4_CapInitThreadCNode, seL4_CapInitThreadTCB, seL4_WordBits, - seL4_AllRights); - ZF_LOGF_IF(error, "Failed to copy cap!"); - seL4_CPtr last_slot = info->empty.end - 1; - /* TODO use seL4_CNode_Copy to make another copy of the initial TCB capability to the last slot in the CSpace */ - - /* set the priority of the root task */ - error = seL4_TCB_SetPriority(last_slot, last_slot, 10); - ZF_LOGF_IF(error, "Failed to set priority"); -``` -
    -Quick solution - -```c - /* use seL4_CNode_Copy to make another copy of the initial TCB capability to the last slot in the CSpace */ - error = seL4_CNode_Copy(seL4_CapInitThreadCNode, last_slot, seL4_WordBits, - seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits, seL4_AllRights); - ZF_LOGF_IF(error, "Failed to copy cap!"); -``` - -
    -On success, you will now see the output: - -``` -<> -main@main.c:44 [Cond failed: error != seL4_FailedLookup] - first_free_slot is not empty -``` - -Which will be fixed in the next exercise. - -### How do you delete capabilities? - -The provided code checks that both `first_free_slot` and `last_slot` are empty, which of course is not -true, as you copied TCB capabilities into those CSlots. Checking if CSlots are empty is done -by a neat hack: by attempting to move the CSlots onto themselves. This should fail with an error code -`seL4_FailedLookup` if the source CSLot is empty, and an `seL4_DeleteFirst` if not. - -**Exercise:** delete both copies of the TCB capability. - -* You can either use `seL4_CNode_Delete` on the copies, or -* `seL4_CNode_Revoke` on the original capability to achieve this. - - - ```c - // TODO delete the created TCB capabilities - - // check first_free_slot is empty - error = seL4_CNode_Move(seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits, - seL4_CapInitThreadCNode, first_free_slot, seL4_WordBits); - ZF_LOGF_IF(error != seL4_FailedLookup, "first_free_slot is not empty"); - - // check last_slot is empty - error = seL4_CNode_Move(seL4_CapInitThreadCNode, last_slot, seL4_WordBits, - seL4_CapInitThreadCNode, last_slot, seL4_WordBits); - ZF_LOGF_IF(error != seL4_FailedLookup, "last_slot is not empty"); -``` -
    -Quick solution -```c - // delete the created TCB capabilities - seL4_CNode_Revoke(seL4_CapInitThreadCNode, seL4_CapInitThreadTCB, seL4_WordBits); -``` -
    - -On success, the output will now show: - -``` -<> -<> -Suspending current thread -main@main.c:56 Failed to suspend current thread -``` - -#### Invoking capabilities - -**Exercise** Use `seL4_TCB_Suspend` to try and suspend the current thread. - -```c - printf("Suspending current thread\n"); - // TODO suspend the current thread - ZF_LOGF("Failed to suspend current thread\n"); -``` -
    -Quick solution - -```c - // suspend the current thread - seL4_TCB_Suspend(seL4_CapInitThreadTCB); -``` -
    - -On success, the output will be as follows: - -``` -<> -<> -Suspending current thread -``` - -### Further exercises - -That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, -to become more familiar with CSpaces. - -* Use a data structure to track which CSlots in a CSpace are free. -* Make copies of the entire CSpace described by `seL4_BootInfo` -* Experiment with other [CNode invocations](https://docs.sel4.systems/projects/sel4/api-doc.html#sel4_cnode). - +{% include tutorial.md %} Next tutorial: Untyped diff --git a/Tutorials/seL4Kernel/fault-handlers.md b/Tutorials/seL4Kernel/fault-handlers.md index e7558dbd80..a5321f4752 100644 --- a/Tutorials/seL4Kernel/fault-handlers.md +++ b/Tutorials/seL4Kernel/fault-handlers.md @@ -1,338 +1,13 @@ --- toc: true +title: Faults +tutorial: fault-handlers +tutorial-order: mechanisms-8 layout: tutorial +description: fault (e.g virtual memory fault) handling and fault endpoints. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- - -# Fault handling -This tutorial covers fault handling in seL4 - -You will learn -1. About thread faults. -2. That a thread fault is different from a processor hardware fault. -3. About fault handlers. -4. What the kernel does to a thread which has faulted. -5. How to set the endpoint that the kernel will deliver fault messages on (master vs MCS). -6. How to resume threads after they have faulted. - - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut fault-handlers -# building the tutorial exercise -cd fault-handlers_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut fault-handlers -``` -
    - -## CapDL Loader - -This tutorial uses a the *capDL loader*, a root task which allocates statically - configured objects and capabilities. - -
    -Get CapDL -The capDL loader parses -a static description of the system and the relevant ELF binaries. -It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects -but we also use it in the tutorials to reduce redundant code. -The program that you construct will end up with its own CSpace and VSpace, which are separate -from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning -in applications loaded by the capDL loader. - -More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). - -For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. -
    - - - -## Background: What is a fault, and what is a fault handler? - -A fault handler is a separate instruction stream which the CPU can jump to in -order to rectify an anomalous condition in the current thread and then return to -the previous instruction stream. - -In seL4, faults are modeled as separately programmer-designated "fault handler" -threads. In monolithic kernels, faults are not usually delivered to a userspace -handler, but they are handled by the monolithic kernel itself. - -In general, attempting to resume execution of the faulted thread -without rectifying the anomaly will simply re-trigger the fault ad infinitum -until the anomaly is cleared away. - -## Thread faults vs other sources of faults - -There are several sources of faults in a running system; they include: -* Fault events generated by the CPU itself when it encounters anomalies in the instruction stream (aka, "processor exceptions"). -* Fault events generated by hardware in the event of some hardware anomaly (such as a machine check or non-maskable interrupt). -* Fault events generated by the seL4 kernel when it encounters anomalies in the current thread. - -This tutorial is only concerned with those fault events generated by the seL4 -kernel. We will call them "thread faults" from here onward to reduce ambiguity. - -## How does thread fault handling work? - -In seL4, when a thread generates a thread fault, the kernel will **block** the -faulting thread's execution and attempt to deliver a message across a special -endpoint associated with that thread, called its "fault handler" endpoint. - -The only special thing about the fault handler endpoint is that a thread can -only have *one* of them. Otherwise it is created and managed just the same way -as any other kind of seL4 endpoint object. - -The thread which is listening on the other end of the fault endpoint is called -the "fault handler". The kernel expects that the fault handler will correct the -anomaly that ails the faulting thread and then tell the kernel when it is safe -to try executing the faulting thread once again. - -To tell the kernel to resume execution of the faulting thread, the fault handler -can either: -* Invoke a reply operation (with `seL4_Reply()`) on the fault handler endpoint and make sure that the `label` in the `seL4_MessageInfo_t` tag is set to `0`; -* Explicitly tell the kernel to resume executing the faulting thread using `seL4_TCB_Resume()`. - -Please note that if the `handler` sets message registers in the reply message, -the kernel may interpret these as meaning something: some fault replies accept -parameters. See the seL4 manual for the reply message format for all faults. - -If the fault handler did not properly rectify the anomaly in the faulting -thread, resuming the faulting thread will simply cause the kernel to re-generate -the fault. - -## Reasons for thread faults - -Thread faults can be generated for different reasons. When a fault occurs the -kernel will pass information describing the cause of the fault as an IPC -message. At the time of writing, the following faults could be generated by -the Master version of the seL4 kernel: - -* Cap fault: A fault triggered because of an invalid cap access. -* VM fault: A fault triggered by incoherent page table state or incorrect memory accesses by a thread. -* Unknown Syscall fault: Triggered by performing a syscall invocation that is unknown to the kernel. -* Debug fault: Triggered when a breakpoint, watchpoint or single-step debug event occurs. - -In addition, the following fault types are added by the MCS kernel: - -* Timeout fault: Triggered when a thread consumes all of its budget and still has further execution to do in the current period. - -## Thread fault messages - -When a fault is generated, the kernel will deliver an IPC message across the -fault endpoint. This IPC message contains information that tells the fault -handler why the fault occured as well as surrounding contextual information -about the fault which might help the fault handler to rectify the anomaly. - -Each anomaly has its own message format because the information needed to -describe each anomaly will be different. For more information about the contents -of the IPC message sent by the seL4 kernel for each fault anomaly, please see -the [seL4 Manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf). - -The rest of this tutorial will attempt to teach the reader how to receive and -handle seL4 thread faults. - -## Setting up a fault endpoint for a thread - -In the scenario where a fault message is being delivered on a fault endpoint, -the kernel acts as the IPC "sender" and the fault handler acts as a receiver. - -This implies that when caps are being handed out to the fault endpoint object, -one cap to the object must be given to the kernel and one cap to the object must -be given to the handler. - -### Kernel end vs handler end - -Programmers specify the capability to use a fault handler for a thread when -configuring a TCB. As a result the programmer can also set a badge on the -kernel's cap to the fault endpoint object. - -When the kernel sends a fault IPC message using a badged endpoint cap, the badge -is delivered to the receiver just the same way it is delivered for any other -IPC where there is a badge on the sender's cap. - -A keen reader would probably have realized that this means that a badge on the -kernel's cap to a fault endpoint can be used to distinguish fault messages -from different faulting threads, such that a single handler can handle -faults from multiple threads. Please see the -[IPC Tutorial](https://docs.sel4.systems/Tutorials/ipc) for a refresher on how -badged fault endpoints work. - -### Differences between MCS and Master kernel - -There is a minor difference in the way that the kernel is informed of the -cap to a fault endpoint, between the master and MCS kernels. - -Regardless though, on both versions of the kernel, to inform the kernel of the -fault endpoint for a thread, call the usual `seL4_TCB_SetSpace()`. - -See the [MCS tutorial](https://docs.sel4.systems/Tutorials/mcs.html) for more information. - -## Exercises - -This tutorial has one address space set up by the CapDL loader, containing two -threads which share the same CSpace. One of the threads is a fault handler while -the other triggers a virtual memory fault. - -You will be guided through the following broad steps: -1. Badging and configuring a fault handler for the faulting thread. -2. Having the faulting thread trigger a thread fault. -3. Handling the fault in the fault handler. -4. Resuming the execution of the faulting thread. - -### Description of the tutorial program - -The tutorial features two threads in different virtual address spaces. One -thread is the "`faulter`" and the other is the "`handler`". The `faulter` is going to -generate a fault, and the `handler` will "handle" it. - -In order for the `handler` to handle the fault, the `handler` must set up a -fault-handling endpoint and tell the kernel to send all fault IPC messages -generated by the `faulter` thread to itself. This is therefore the first step we -take. - -However, we have to ensure that the fault is only triggered *after* the `handler` -thread has set up the fault-handling endpoint and is ready to receive the fault -IPC message from the kernel. - -If the `faulter` thread generates a fault and there is no thread to handle the -the IPC message, the kernel will simply suspend the `faulting` thread. - -For this reason we make the `faulter` thread `seL4_call()` the `handler` thread -across an endpoint and tell it which slot the `handler` should place the fault -handling endpoint cap into. After the `handler` has set up the handler endpoint, -the `handler` will `seL4_Reply()` to the `faulter` to let it know that it the -`handler` is ready to handle fault IPC messages. - -After that we trigger a fault in the `faulter`, handle the fault in the `handler`, -and then resume the `faulter` and that's the end of the exercise. - -### Setting up the endpoint to be used for thread fault IPC messages - -The first exercise is to configure the TCB of the faulter with a fault endpoint. -This exercise is meant to achieve two learning outcomes: -1. Explain that the end of the endpoint that is given to the kernel can be badged, and the kernel will return that badge value when it sends a fault IPC message. -2. Explain the differences between the Master and MCS kernels when it comes to telling the kernel about the fault endpoint. - -Right now the `faulter` thread is blocked on an Endpoint, waiting for the `handler` -to tell it where to put the fault handler endpoint within its own (the -`faulter`'s) CSpace (for the Master kernel). - -To set up the fault handler endpoint, we will to first badge it so that when the -kernel sends us a fault IPC message, we will be able to identify the faulter. -Fault handlers can handle faults from multiple threads, so a badge -enables handlers to identify the faulters they are handling. - -To badge the endpoint, use the `seL4_CNode_Mint()` syscall: - -```c - error = seL4_CNode_Mint( - handler_cspace_root, - badged_faulter_fault_ep_cap, - seL4_WordBits, - handler_cspace_root, - faulter_fault_ep_cap, - seL4_WordBits, - seL4_AllRights, FAULTER_BADGE_VALUE); -``` - -Since we are using the Master kernel, you will also need to copy the badged cap -into the `faulter`'s CSpace (See the [MCS tutorial](https://docs.sel4.systems/Tutorials/mcs.html) -for an explanation of the differences between the Master and MCS kernel when -configuring fault endpoints): - -```c - error = seL4_CNode_Copy( - faulter_cspace_root, - foreign_badged_faulter_empty_slot_cap, - seL4_WordBits, - handler_cspace_root, - badged_faulter_fault_ep_cap, - seL4_WordBits, - seL4_AllRights); -``` - -Finally, we tell the kernel the cap address of the fault endpoint so that the -kernel can deliver fault IPC messages to the `handler`. Since we're -using the Master kernel, we need to pass a CPtr that can be resolved from within -the CSpace of the `faulter` thread: - -```c - error = seL4_TCB_SetSpace( - faulter_tcb_cap, - foreign_badged_faulter_empty_slot_cap, - faulter_cspace_root, - 0, - faulter_vspace_root, - 0); -``` - -### Receiving the IPC message from the kernel - -The kernel will deliver the IPC message to any thread waiting on the fault -endpoint. To wait for a fault IPC message simply `seL4_Recv()`, the same way -you'd wait for any other IPC message: - -```c - foreign_faulter_capfault_cap = seL4_GetMR(seL4_CapFault_Addr); -``` - -### Finding out information about the generated thread fault - -In the thread fault IPC message, the kernel will send information about the -fault including the capability address whose access triggered the thread fault. -The seL4 manual gives detailed information on which message registers in the IPC -buffer contain information about the fault and if you're so inclined, the -libsel4 source code also has the exact code values as well. - -In our example here, our sample code generated a Cap Fault, so according to the -seL4 manual, we can find out the cap fault address using at offset -`seL4_CapFault_Addr` in the IPC message, as you see above in the code snippet. - -### Handling a thread fault - -Now that we know the cap address that generated a fault in the `faulting` thread, -we can "handle" the fault by putting a random cap into that slot and then when -the `faulter` thread re-tries to access that slot, it will succeed this time and -no thread fault will be generated. - -So here we'll copy an endpoint cap into the faulting slot: - -```c - error = seL4_CNode_Copy( - faulter_cspace_root, - foreign_faulter_capfault_cap, - seL4_WordBits, - handler_cspace_root, - sequencing_ep_cap, - seL4_WordBits, - seL4_AllRights); -``` - -### Resuming a faulting thread - -Finally, to have the `faulter` thread wake up and try to execute again, we -`seL4_Reply()` to it: - -```c - seL4_Reply(seL4_MessageInfo_new(0, 0, 0, 0)); -``` - -## Further exercises - -If you'd like to challenge yourself, make sure to set up the fault handling on -both versions of the kernel: master and MCS. +{% include tutorial.md %} Next tutorial: MCS diff --git a/Tutorials/seL4Kernel/interrupts.md b/Tutorials/seL4Kernel/interrupts.md index 015ae570e6..8b04dc03a3 100644 --- a/Tutorials/seL4Kernel/interrupts.md +++ b/Tutorials/seL4Kernel/interrupts.md @@ -1,214 +1,13 @@ --- toc: true +title: Interrupts +tutorial: interrupts +tutorial-order: mechanisms-7 layout: tutorial +description: receiving and handling interrupts. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- - -# Interrupts -This tutorial covers seL4 interrupts. - -You will learn -* The purpose of the IRQControl capability. -* How to obtain capabilities for specific interrupts. -* How to handle interrupts and their relation with notification objects. - - -# Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut interrupts -# building the tutorial exercise -cd interrupts_build -ninja -``` -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut interrupts -``` -Answers are also available in drop down menus under each section. -
    - -## CapDL Loader - -This tutorial uses a the *capDL loader*, a root task which allocates statically - configured objects and capabilities. - -
    -Get CapDL -The capDL loader parses -a static description of the system and the relevant ELF binaries. -It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects -but we also use it in the tutorials to reduce redundant code. -The program that you construct will end up with its own CSpace and VSpace, which are separate -from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning -in applications loaded by the capDL loader. - -More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). - -For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. -
    - - -## Background - -### IRQControl - -The root task is given a single capability from which capabilities to all irq numbers -in the system can be derived, `seL4_CapIRQControl`. This capability can be moved between CSpaces -and CSlots but cannot be duplicated. Revoking this capability results in all access to all -irq capabilities being removed. - -### IRQHandlers - -IRQHandler capabilities give access to a single irq and are standard seL4 capabilities: they -*can* be moved and duplicated according to system policy. IRQHandlers are obtained by -invoking the IRQControl capability, with architecture specific parameters. Below is an -example of obtaining an IRQHandler. - -```bash -// Get a capability for irq number 7 and place it in cslot 10 in a single-level cspace. -error = seL4_IRQControl_Get(seL4_IRQControl, 7, cspace_root, 10, seL4_WordBits); -``` - -There are a variety of different invocations to obtain irq capabilities which are hardware -dependent, including: - -* [`seL4_IRQControl_GetIOAPIC`](https://docs.sel4.systems/ApiDoc.html#get-io-apic) (x86) -* [`seL4_IRQControl_GetMSI`](https://docs.sel4.systems/ApiDoc.html#get-msi) (x86) -* [`seL4_IRQControl_GetTrigger`](https://docs.sel4.systems/ApiDoc.html#gettrigger) (ARM) - -### Receiving interrupts - -Interrupts are received by registering a capability to a notification object -with the IRQHandler capability for that irq, as follows: -```bash -seL4_IRQHandler_SetNotification(irq_handler, notification); -``` -On success, this call will result in signals being delivered to the notification object when -an interrupt occurs. To handle multiple interrupts on the same notification object, you -can set different badges on the notification capabilities bound to each IRQHandler. - When an interrupt arrives, -the badge of the notification object bound to that IRQHandler is bitwise orred with the data -word in the notification object. -Recall the badging technique for differentiating signals from the - [notification tutorial](https://docs.sel4.systems/Tutorials/notifications). - -Interrupts can be polled for using `seL4_Poll` or waited for using `seL4_Wait`. Either system -call results in the data word of the notification object being delivered as the badge of the -message, and the data word cleared. - -[`seL4_IRQHandler_Clear`](https://docs.sel4.systems/ApiDoc.html#clear) can be used to unbind -the notification from an IRQHandler. - -### Handling interrupts - -Once an interrupt is received and processed by the software, you can unmask the interrupt -using [`seL4_IRQHandler_Ack`](https://docs.sel4.systems/ApiDoc.html#ack) on the IRQHandler. -seL4 will not deliver any further interrupts after an IRQ is raised until that IRQHandler -has been acked. - -## Exercises - -In this tutorial you will set up interrupt handling for a provided timer driver -on the zynq7000 ARM platform. This timer driver can be located inside the -`projects/sel4-tutorials/zynq_timer_driver` folder from the root of the -projects directory, i.e. where the `.repo` folder can be found and where the -initial `repo init` command was executed. The tutorial has been set up with two -processes: `timer.c`, the timer driver and RPC server, and `client.c`, which -makes a single request. - -On successful initialisation of the tutorial, you will see the following: - -``` -timer client: hey hey hey -timer: got a message from 61 to sleep 2 seconds -<> -main@timer.c:78 [Cond failed: error] - Failed to ack irq -``` - -The timer driver we are using emits an interrupt in the `TTC0_TIMER1_IRQ` number. - -### Invoke IRQ control - -**Exercise** Invoke `irq_control`, which contains the `seL4_IRQControl` capability, -the place the `IRQHandler` capability for `TTC0_TIMER1_IRQ` into the `irq_handler` CSlot. - -``` - /* TODO invoke irq_control to put the interrupt for TTC0_TIMER1_IRQ in - cslot irq_handler (depth is seL4_WordBits) */ -``` -
    -Quick solution -```c - error = seL4_IRQControl_Get(irq_control, TTC0_TIMER1_IRQ, cnode, irq_handler, seL4_WordBits); - ZF_LOGF_IF(error, "Failed to get IRQ capability"); -``` -
    - -On success, you should see the following output, without the error message that occurred earlier, -as the irq_handle capability is now valid: - -``` -Undelivered IRQ: 42 -``` - -This is a warning message from the kernel that an IRQ was recieved for irq number 42, but no -notification capability is set to sent a signal to. - -### Set NTFN -**Exercise** Now set the notification capability (`ntfn`) by invoking the irq handler. - -``` - /* TODO set ntfn as the notification for irq_handler */ -``` -
    -Quick solution -```c - error = seL4_IRQHandler_SetNotification(irq_handler, ntfn); - ZF_LOGF_IF(error, "Failed to set notification"); -``` -
    - -Now the output will be: - -``` -Tick -``` - -Only one interrupt is delivered, as the interrupt has not been acknowledged. The timer driver is -programmed to emit an interrupt every millisecond, so we need to count 2000 interrupts -before replying to the client. - -### Acknowledge an interrupt - -**Exercise** Acknowledge the interrupt after handling it in the timer driver. - -``` - /* TODO ack the interrupt */ -``` -
    -Quick solution -```c - error = seL4_IRQHandler_Ack(irq_handler); - ZF_LOGF_IF(error, "Failed to ack irq"); -``` -
    - -Now the timer interrupts continue to come in, and the reply is delivered to the client. - -``` -timer client wakes up -``` - -That's it for this tutorial. +{% include tutorial.md %} Next tutorial: Fault handling diff --git a/Tutorials/seL4Kernel/ipc.md b/Tutorials/seL4Kernel/ipc.md index 2fa50eb349..d7494b3f3c 100644 --- a/Tutorials/seL4Kernel/ipc.md +++ b/Tutorials/seL4Kernel/ipc.md @@ -1,368 +1,13 @@ --- toc: true +title: IPC +tutorial: ipc +tutorial-order: mechanisms-5 layout: tutorial +description: overview of interprocess communication (IPC). SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -# IPC -This tutorial is about interprocess communication (IPC), the microkernel mechanism for synchronous transmission of small amounts of data. - -You will learn -1. How to use IPC to send data and capabilities between processes. -2. The jargon *cap transfer*. -3. How to to differentiate requests via badged capabilities. -4. Design protocols that use the IPC fastpath. - - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut ipc -# building the tutorial exercise -cd ipc_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut ipc -``` -Answers are also available in drop down menus under each section. -
    - -## CapDL Loader - -This tutorial uses a the *capDL loader*, a root task which allocates statically - configured objects and capabilities. - -
    -Get CapDL -The capDL loader parses -a static description of the system and the relevant ELF binaries. -It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects -but we also use it in the tutorials to reduce redundant code. -The program that you construct will end up with its own CSpace and VSpace, which are separate -from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning -in applications loaded by the capDL loader. - -More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). - -For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. -
    - -## Background - -Interprocess communication (IPC) is the microkernel mechanism for synchronous transmission of small amounts of data -and capabilities between processes. In seL4, IPC is facilitated by small kernel objects known as *endpoints*, which -act as general communication ports. Invocations on endpoint objects are used to send and receive IPC messages. - -Endpoints consist of a queue of threads waiting to send, or waiting to receive messages. To understand -this, consider an example where *n* threads are waiting for a message on an endpoint. If *n* threads -send messages on the endpoint, all *n* waiting threads will receive the message and wake up. If an *n+1*th -sender sends a message, that sender is now queued. - -### System calls - -Threads can send messages on endpoints with the system call `seL4_Send`, which blocks until the message has been -consumed by another thread. `seL4_NBSend` can also be used, which performs a polling send: the send is only -successful if a receiver is already blocked waiting for a message, and otherwise fails. To avoid a -back channel, `seL4_NBSend` does not return a result indicating if the message was sent or not. - -`seL4_Recv` can be used to receive messages, and `seL4_NBRecv` can be used to poll for messages. - -`seL4_Call` is a system call that essentially combines an `seL4_Send` and an `seL4_Recv` with one -major difference: in the receive phase, thread which uses this function is blocked on a one-time capability termed a -*reply capability*, and not the endpoint itself. In a client-server scenario, where clients use -`seL4_Call` to make requests, the server can explicitly reply to the correct client. - -The reply capability is stored internally in the thread control block (TCB) of the receiver. The system -call `seL4_Reply` invokes this capability, which sends an IPC to the client and wakes it up. `seL4_ReplyRecv` -does the same, except it sends the reply and blocks on the provided endpoint in a combined system call. - -Since TCBs have a single space to store a reply capability, if servers need to service multiple -requests (e.g saving requests to reply at a later time, after hardware operations have been completed), -[`seL4_CNode_SaveCaller`](https://docs.sel4.systems/ApiDoc.html#save-caller) can be used to save -the reply capability to an empty slot in the receivers CSpace. - -### IPC Buffer - -Each thread has a buffer (referred to as the *IPC buffer*), which contains the payload of the IPC message, -consisting of data and capabilities. Senders specify a message length and the kernel copies this (bounded) -amount between the sender and receiver IPC buffer. - -### Data transfer - -The IPC buffer contains a bounded area of message registers (MR) used to transmit data on IPC. Each -register is the machine word size, and the maximum message size is available in the -`seL4_MsgMaxLength` constant provided by `libsel4`. - -Messages can be loaded into the IPC buffer using `seL4_SetMR` and extracted using `seL4_GetMR`. -Small messages are sent in registers and do not require a copy operation. The amount of words -that fit in registers is available in the `seL4_FastMessageRegisters` constant. - -The amount of data being transferred, in terms of the number of message registers used, must be -set in as the `length` field in the `seL4_MessageInfo_t` data structure. - -### Cap transfer - -Along with data, IPC can be used to send capabilities between processes per message. This is referred to as - *cap transfer*. The number of capabilities being transferred is encoded in the `seL4_MessageInfo_t` -structure as `extraCaps`. Below is an example for sending a capability via IPC: - -```c - seL4_MessageInfo info = seL4_MessageInfo_new(0, 0, 1, 0); - seL4_SetCap(0, free_slot); - seL4_Call(endpoint, info); -``` - -To receive a capability, the receiver must specify a cspace address to place the capability in. This is -shown in the code example below: - -```c - seL4_SetCapReceivePath(cnode, badged_endpoint, seL4_WordBits); - seL4_Recv(endpoint, &sender); -``` - -The access rights of the received capability are the same as by the rights that the receiver has to the endpoint. -Note that while senders can send multiple capabilities, receivers can only receive one at a time. - -### Capability unwrapping - -seL4 can also *unwrap* capabilities on IPC. -If the n-th capability in the message refers to the endpoint through which the message -is sent, the capability is unwrapped: its badge is placed into the n-th position of the -receiver's IPC buffer (in the field `caps_or_badges`), and the kernel sets the n-th bit -(counting from the least significant) in the `capsUnwrapped` field of `seL4_MessageInfo_t`. - -### Message Info - -The `seL4_MessageInfo_t` data structure is used to encode the description of an IPC message into a single word. -It is used to describe a message to be sent to seL4, and for seL4 to describe the message that was -sent to the receiver. -It contains the following fields: - -* `length` the amount of message registers (data) in the message (`seL4_MsgMaxLength` maximum), -* `extraCaps` the number of capabilities in the message (`seL4_MsgMaxExtraCaps`) -* `capsUnwrapped` marks any capabilities unwrapped by the kernel. -* `label` data that is transferred unmodified by the kernel from sender to receiver, - -### Badges - -Along with the message the kernel additionally delivers the badge of the endpoint capability -that the sender invoked to send the message. Endpoints can be badged using -[`seL4_CNode_Mint`](https://docs.sel4.systems/ApiDoc.html#mint) or - [`seL4_CNode_Mutate`](https://docs.sel4.systems/ApiDoc.html#mutate). Once an endpoint is badged, -the badge of the endpoint is transferred to any receiver that receives messages on that endpoint. -The code example below demonstrates this: - -```c -seL4_Word badge; -seL4_Recv(endpoint, &badge); -// once a message is received, the badge value is set by seL4 to the -// badge of capability used by the sender to send the message -``` - -### Fastpath - -Fast IPC is essential to microkernel-based systems, as services are often separated from each other -for isolation, with IPC one of the core mechanisms for communication between clients and services. -Consequently, IPC has a fastpath -- a heavily optimised path in the kernel -- which allows these operations -to be very fast. In order to use the fastpath, an IPC must meet the following conditions: - -* `seL4_Call` or `seL4_ReplyRecv` must be used. -* The data in the message must fit into the `seL4_FastMessageRegisters` registers. -* The processes must have valid address spaces. -* No caps should be transferred. -* No other threads in the scheduler of higher priority than the thread unblocked by the IPC can be running. - -## Exercises - -This tutorial has several processes set up by the capDL loader, two clients and a server. All processes have -access to a single endpoint capability, which provides access to the same endpoint object. - -In this tutorial, you will construct a server which echos the contents of messages sent by clients. You -will also alter the ordering of replies from the clients to get the right message. - -When you run the tutorial, the output should be something like this: - -``` -Client 2: waiting for badged endpoint -Badged 2 -Assertion failed: seL4_MessageInfo_get_extraCaps(info) == 1 (../ipcCkQ6Ub/client_2.c: main: 22) -Client 1: waiting for badged endpoint -Badged 1 -Assertion failed: seL4_MessageInfo_get_extraCaps(info) == 1 (../ipcCkQ6Ub/client_1.c: main: 22) -``` - - -On initialisation, both clients use the following protocol: they wait on the provided endpoint for -a badged endpoint to be sent to them via cap transfer. All following messages sent by the client -uses the badged endpoint, such that the server can identify the client. However, the server does not -currently send the badged capability! We have provided code to badge the endpoint capability, and -reply to the client. - -### Using capability transfer to send the badged capability - -**Exercise** Your task is to set up the cap transfer such that the client successfully -receives the badged endpoint. - -```c - /* No badge! give this sender a badged copy of the endpoint */ - seL4_Word badge = seL4_GetMR(0); - seL4_Error error = seL4_CNode_Mint(cnode, free_slot, seL4_WordBits, - cnode, endpoint, seL4_WordBits, - seL4_AllRights, badge); - printf("Badged %lu\n", badge); - - // TODO use cap transfer to send the badged cap in the reply - - /* reply to the sender and wait for the next message */ - seL4_Reply(info); - - /* now delete the transferred cap */ - error = seL4_CNode_Delete(cnode, free_slot, seL4_WordBits); - assert(error == seL4_NoError); - - /* wait for the next message */ - info = seL4_Recv(endpoint, &sender); -``` -
    -Quick solution -```c - // use cap transfer to send the badged cap in the reply - seL4_SetCap(0, free_slot); - info = seL4_MessageInfo_new(0, 0, 1, 0); -``` -
    - -Now the output should look something like: -```bash -Booting all finished, dropped to user space -Client 2: waiting for badged endpoint -Badged 2 -Client 1: waiting for badged endpoint -Badged 1 -Client 2: received badged endpoint -Client 1: received badged endpoint -``` - -Depending on timing, the messages may be different, the result is the same: the system hangs. -This is because one of the clients has hit the else case, where the badge is set, and the server -does not respond, or wait for new messages from this point. - -### Getting a message -**Exercise** Your next task is to implement the echo part of the server. - -```c - // TODO use printf to print out the message sent by the client - // followed by a new line -``` -
    -Quick solution -```c - for (int i = 0; i < seL4_MessageInfo_get_length(info); i++) { - printf("%c", (char) seL4_GetMR(i)); - } - printf("\n"); -``` -
    - -At this point, you should see a single word output to the console in a loop. -``` -the -the -the -``` - -This is because the server does not reply to the client, and continues to spin in a loop - repeating the last message. - -### Using reply and wait -**Exercise** Update the code to reply to the clients after printing the message. - -```c - // TODO reply to the client and wait for the next message -``` -
    -Quick solution -```c - info = seL4_ReplyRecv(endpoint, info, &sender); - for (int i = 0; i < seL4_MessageInfo_get_length(info); i++) { - printf("%c", (char) seL4_GetMR(i)); - } - printf("\n"); -``` -
    - -Now the output should be something like this: - -``` -Client 2: received badged endpoint -the -brown -jumps -the -dog -Client 1: received badged endpoint -quick -fox -over -lazy -``` - -### Saving a reply and storing reply capabilities -**Exercise** Currently each client is scheduled for its full timeslice until it is preempted. Alter -your server to only print one message from each client, alternating. You will need to use -[`seL4_CNode_SaveCaller`](https://docs.sel4.systems/ApiDoc.html#save-caller) to save the reply -capability for each sender. You can use `free_slot` to store the reply capabilities. - -
    -Quick solution -```c - error = seL4_CNode_SaveCaller(cnode, free_slot, seL4_WordBits); - assert(error == 0); - info = seL4_Recv(endpoint, &sender); - for (int i = 0; i < seL4_MessageInfo_get_length(info); i++) { - printf("%c", (char) seL4_GetMR(i)); - } - printf("\n"); - - seL4_Send(free_slot, seL4_MessageInfo_new(0, 0, 0, 0)); - - info = seL4_ReplyRecv(endpoint, info, &sender); - - -``` -
    - -Depending on your approach, successful output should look something like this: -``` -Client 2: received badged endpoint -the -Client 1: received badged endpoint -quick -fox -brown -jumps -over -lazy -the -dog -``` - -### Further exercises - -That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, -to become more familiar with IPC. - -* Try using `seL4_Send` and `seL4_Recv`. -* Try the non-blocking variants, `seL4_NBSend` and `seL4_NBRecv`. +{% include tutorial.md %} Next tutorial: Notifications diff --git a/Tutorials/seL4Kernel/mapping.md b/Tutorials/seL4Kernel/mapping.md index 320fa60955..9de492e6d7 100644 --- a/Tutorials/seL4Kernel/mapping.md +++ b/Tutorials/seL4Kernel/mapping.md @@ -1,242 +1,13 @@ --- toc: true +title: Mapping +tutorial: mapping +tutorial-order: mechanisms-3 +description: virtual memory in seL4. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -# Mapping - -This tutorial provides an introduction to virtual memory management on seL4. - -By the end of this tutorial, you should be familiar with: - -1. How to map and unmap virtual memory pages in seL4. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/seL4Kernel/setting-ip#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut mapping -# building the tutorial exercise -cd mapping_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut mapping -``` -Answers are also available in drop down menus under each section. -
    - - -## Background - -### Virtual memory - -seL4 does not provide virtual memory management, beyond kernel primitives for manipulating hardware -paging structures. User-level must provide services for creating intermediate paging structures, -mapping and unmapping pages. - -Users are free to define their own address space layout with one restriction: the seL4 kernel claims -the high part of the virtual memory range. On most 32-bit platforms, this is -0xe0000000 and above. This variable is set per platform, and can be found by finding the `kernelBase` variable -in the seL4 source. - -### Paging structures - -As part of the boot process, seL4 initialises the root task with a top-level hardware virtual -memory object, which is referred to as a *VSpace*. A capability to this structure is made available in the -`seL4_CapInitThreadVSpace` slot in the root tasks CSpace. For each architecture, this capability is -to a different object type corresponding to the hardware, top-level paging structure. The table below - lists the VSpace object type for each supported architecture. - -Architecture | VSpace Object --------------|-------------- -aarch32 | `seL4_PageDirectory` | -aarch64 | `seL4_PageGlobalDirectory` | -ia32 | `seL4_PageDirectory` | -x86_64 | `seL4_PML4 ` | -RISC-V | `seL4_PageTable` | - -In addition to the top-level paging structure, intermediate hardware virtual memory objects are required to -map pages. The table below lists those objects, in order, for each architecture. - -Architecture | Objects --------------|-------- -aarch32 | `seL4_PageTable` -aarch64 | `seL4_PageUpperDirectory`, `seL4_PageDirectory`, `seL4_PageTable` -ia32 | `seL4_PageTable` -x86_64 | `seL4_PDPT`, `seL4_PageDirectory`, `seL4_PageTable` -RISC-V | `seL4_PageTable` - -This tutorial covers the x86_64 architecture, but should contain sufficient information on the virtual -memory API provided by seL4 to generalise to other architectures. - -Each paging structure can be invoked in order to map or unmap it. Below is an example of mapping -an x86_64 `seL4_PDPT` object: - -```c - /* map a PDPT at TEST_VADDR */ - error = seL4_X86_PDPT_Map(pdpt, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_X86_Default_VMAttributes); -``` - -All mapping functions take three arguments: -* the VSpace to map the object into, -* the virtual address to map the object at, -* and virtual memory attributes. - -If the virtual memory address provided is not aligned to the size of the paging object, seL4 will mask out any -unused bits e.g a 4KiB page mapped at 0xDEADBEEF will end up mapped at 0xDEADB000. - -Virtual memory attributes determine the caching attributes of the mapping, which is architecture dependent. -Alongside the attributes used in this tutorial (`seL4_X86_Default_VMAttributes`) you can find alternative values, in -`libsel4`. - -### Pages - -Once all of the intermediate paging structures have been mapped for a specific virtual address range, -physical frames can be mapped into that range by invoking the frame capability. The code snippet below -shows an example of mapping a frame at address `TEST_VADDR`. - -```c - /* map a read-only page at TEST_VADDR */ - error = seL4_X86_Page_Map(frame, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_CanRead, seL4_X86_Default_VMAttributes); -``` - -For a page mapping to succeed, all mid-level paging structures must be mapped. The `libsel4` function -`seL4_MappingFailedLookupLevel()` can be used to determine at which level paging structures are missing. -Note that to map a frame multiple times, one must make copies of the frame capability: each frame capability -can only track one mapping. - -In addition to the arguments taken by the map methods for intermediate paging structures, page mapping takes a -`rights` argument which determines the mapping type. In the example above, we map the page read only. - -#### Types and sizes - -Page types and sizes are architecture dependent. For both x86 and ARM architectures, -each size of page is a different object type with a specific size. -On RISC-V, pages are the same object type and variably sized. -Configuration and hardware settings alter the available page sizes. - -## Exercises - -This tutorial uses several helper functions to allocate objects and capabilities. All object and -CSlot allocations have already been done for you using these functions. For more information see the -on these mechanisms, see the capabilities and untyped tutorials. - -### Map a page directory - -On starting the tutorial, you will see the following output: -``` -Missing intermediate paging structure at level 30 -main@main.c:34 [Cond failed: error != seL4_NoError] - Failed to map page -``` -This is because while the provided code maps in a `seL4_PDPT` object, there are two missing levels of -paging structures. The value corresponds to the `libsel4` constant `SEL4_MAPPING_LOOKUP_NO_PD` which is -the number of bits in the virtual address that could not be resolved due to missing paging structures. - -**Exercise** Map in the `pd` structure using (`seL4_PageDirectory_Map`)[https://docs.sel4.systems/ApiDoc.html#map-5]. - -```c - // TODO map a page directory object -``` -
    -Quick solution -```c - // TODO map a page directory object - error = seL4_X86_PageDirectory_Map(pd,seL4_CapInitThreadVSpace, TEST_VADDR, seL4_X86_Default_VMAttributes); - assert(error == seL4_NoError); -``` -
    - - -On success, you should see the following: -``` -Missing intermediate paging structure at level 21 -main@main.c:34 [Cond failed: error != seL4_NoError] - Failed to map page -``` - -### Map a page table - -Note that in the above output, the number of failed bits has changed from `30` to `21`: this is because another -9 bits could be resolved from the newly mapped page directory. - -**Exercise** Map in the `pt` structure using [`seL4_PageTable_Map`](https://docs.sel4.systems/ApiDoc.html#map-6). - -```c - // TODO map a page table object -``` -
    -Quick solution -```c - // map a page table object - error = seL4_X86_PageTable_Map(pt, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_X86_Default_VMAttributes); - assert(error == seL4_NoError); -``` -
    - -On success, you should see the following: -``` -Read x: 0 -Set x to 5 -Caught cap fault in send phase at address (nil) -while trying to handle: -vm fault on data at address 0xa000000000 with status 0x7 -in thread 0xffffff801ffb5400 "rootserver" at address 0x401afe -With stack: -0x41c920: 0x41c9d0 -... -``` - -The page is successfully mapped and we read a value of 0: as seL4 zeros all non-device pages when they are retyped from -untyped memory. However, then the code attempts to write to the page. Since you mapped the page as read-only, this fails -and the kernel raises a VM fault. - -Since the initial task does not have a fault handler (more details in the upcoming -threads tutorial), this triggers a subsequent capability fault (cap fault) on slot 0 (nil). Because you are running a -debug kernel for the tutorial, the kernel outputs the details of both faults. - -The vm fault is the most interesting: it shows the fault address, fault status register, and the instruction pointer -that the fault occured on (address). - -### Remap a page - -**Exercise** Fix the fault by remapping the page with `seL4_ReadWrite` permissions, using the -[seL4_X86_Page_Map](https://docs.sel4.systems/ApiDoc.html#map-4) invocation. -```c - // TODO remap the page -``` -
    -Quick solution -```c - // remap the page - error = seL4_X86_Page_Map(frame, seL4_CapInitThreadVSpace, TEST_VADDR, seL4_ReadWrite, seL4_X86_Default_VMAttributes); - assert(error == seL4_NoError); -``` -
    - - -### Unmapping pages - -Pages can be unmapped by either using `Unmap` invocations on the page or any intermediate paging structure, or deleting -the final capability to any of the paging structure. - -### Further exercises - -That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, -to become more familiar with virtual memory management on seL4. - -* Try unmapping the structures you just mapped in. -* Port this tutorial to another architecture (ARM, RISCV). -* Create a generic function for converting from `seL4_MappingFailedLookupLevel` to the required seL4 object. +{% include tutorial.md %} Next tutorial: Threads diff --git a/Tutorials/seL4Kernel/notifications.md b/Tutorials/seL4Kernel/notifications.md index b8baa5177b..928ffb76ff 100644 --- a/Tutorials/seL4Kernel/notifications.md +++ b/Tutorials/seL4Kernel/notifications.md @@ -1,224 +1,13 @@ --- toc: true +title: Notifications +tutorial: notifications +tutorial-order: mechanisms-6 layout: tutorial +description: using notification objects and signals. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- - -# Notifications and shared memory -This tuotorial covers notification objects. - -You will learn how to: -1. Set up shared memory between tasks. -2. Use notification objects for synchronisation between tasks. -3. Use badges to differentiate notifications. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut notifications -# building the tutorial exercise -cd notifications_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut notifications -``` -Answers are also available in drop down menus under each section. -
    - -## CapDL Loader - -This tutorial uses a the *capDL loader*, a root task which allocates statically - configured objects and capabilities. - -
    -Get CapDL -The capDL loader parses -a static description of the system and the relevant ELF binaries. -It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects -but we also use it in the tutorials to reduce redundant code. -The program that you construct will end up with its own CSpace and VSpace, which are separate -from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning -in applications loaded by the capDL loader. - -More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). - -For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. -
    - -## Background - -Notifications allow processes to send asynchronous signals to each other, and are primarily used for interrupt handling -and to synchronise access to shared data buffers. - -### Notification objects - -Signals are sent and received with invocations on capabilities to notification objects. -A notification object consists of a data word, which acts as an array of binary semaphores, and a queue of -TCBs waiting for notifications. - -Notification objects can be in three states: -* Waiting - there are TCBs queued on this notification waiting for it to be signalled. -* Active - TCBs have signalled data on this notification, -* Idle - no TCBs are queued and no TCBs have signalled this object since it was last set to idle. - -#### Signalling - -When a task signals a notification object (using `seL4_Signal`), what occurs depends on the state of the object: -* Idle - the data word is set to the badge of the capability used to send the signal, and the object is converted - to active. -* Active - the badge of the capability used to signal the notification object is bitwise-orred with the notifications data word. -* Waiting - the head of the queue of TCBs is woken and the badge sent to that TCB. If the queue is empty, the notification -object is transitioned to idle. - -In this way notification objects can be seen as a binary array of semaphores - if the signallers all use a -different bit in the badge, they can set different badge bits and waiters can observe which bits have been set. - -#### Waiting - -Tasks can wait on a notification object using `seL4_Wait`, which does the following: - -* Idle - the TCB is queued, and the notification transitioned to waiting. -* Active - the TCB receives the data word, the data word is reset to 0 and the notification transitioned to idle, -* Waiting - the TCB is appended to the queue. - -#### Polling - -Notification objects can also be polled with `seL4_Poll`, which is a non-blocking version of `seL4_Wait` that returns -immediately regardless of the state. - -## Interrupts and IPC - -Notification objects can be used to receive signals of interrupt delivery, and can also be bound to TCBs -such that signals and IPC can be received by the same thread. This is explained in more detail in the -timer tutorial. - -## Exercises - -These exercises guide you through a basic producer consumer set up using notifications and shared memory. The -tutorial uses the capDL loader, and already has 2 producer processes (`producer_1.c` and `producer_2`) and 1 consumer - process running (`consumer.c`). Each has access to a number of capabilities. - -Each producer shares a buffer with the consumer, and the consumer processes data from both producers when it is -available. - -When you start the tutorial, the output will look something like this: -``` -Booting all finished, dropped to user space -Waiting for producer -``` -### Set up shared memory - -Both producers start and block immediately, waiting for the consumer to send an IPC with the address of the shared -mapping. We provide code below that sets up the shared page between producer 1 and the consumer: - -```c - /* set up shared memory for consumer 1 */ - /* first duplicate the cap */ - error = seL4_CNode_Copy(cnode, mapping_1, seL4_WordBits, - cnode, buf1_frame_cap, seL4_WordBits, seL4_AllRights); - ZF_LOGF_IFERR(error, "Failed to copy cap"); - /* now do the mapping */ - error = seL4_ARCH_Page_Map(mapping_1, producer_1_vspace, BUF_VADDR, - seL4_AllRights, seL4_ARCH_Default_VMAttributes); - ZF_LOGF_IFERR(error, "Failed to map frame"); -``` - -However, we do not map the second buffer in, so producer 2 crashes immediately. - -**Exercise** Understand the above code, and create a second shared page between `producer_2` and `consumer`. - -```c - // TODO share buf2_frame_cap with producer_2 -``` -
    -Quick solution -```c - error = seL4_CNode_Copy(cnode, mapping_2, seL4_WordBits, - cnode, buf2_frame_cap, seL4_WordBits, seL4_AllRights); - ZF_LOGF_IFERR(error, "Failed to copy cap"); -``` -
    - -Whether this is successful will be visible after the next exercise when the consumers access their buffers. If the shared page setup for producer 2 is not correct, it will fail with a vm fault. - -### Signal the producers to go - -At this point, both producers are waiting on the `empty` notification for a signal that the buffer is ready -to be written to. - -**Exercise** signal both producers via the `buf1_empty` and `buf2_empty` notification objects. - -```c - // TODO signal both producers -``` -
    -Quick solution -```c - seL4_Signal(buf1_empty); - seL4_Signal(buf2_empty); -``` -
    - -### Differentiate signals - -Now you should see something like the following: - -``` -Booting all finished, dropped to user space -Waiting for producer -2: produce -1: produce -Got badge: 2 -Got badge: 1 -``` - -At this point, the consumer should consume data from the appropriate buffer(s) and signal to the appropriate consumer(s) -that the buffer is empty again. The capability to the `full` notification object has already been badged: `producer_1`s -copy has a badge of `0b1` and `producer_2` a badge of `0b10`. By checking the bits in the badge, you can see -which of the producers (it may be both) has produced data. - -**Exercise** Check the badge and signal the empty notification for the producers according to the bits set in the badge - value. - -```c - // TODO, use the badge to check which producer has signalled you, and signal it back. Note that you - // may recieve more than 1 signal at a time. -``` -
    -Quick solution -```c - if (badge & 0b01) { - assert(*buf1 == 1); - *buf1 = 0; - seL4_Signal(buf1_empty); - } - if (badge & 0b10) { - assert(*buf2 == 2); - *buf2 = 0; - seL4_Signal(buf2_empty); - } -``` -
    - -At this point, you should see signals from both producers being processed, and the final `Success!` message printed. - -### Further exercises - -That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, -to become more familiar with IPC. - -* Create a counting semaphore implementation using notification objects. -* Create a bounded-buffer producer consumer with a buffer size greater than 1. +{% include tutorial.md %} Next tutorial: Interrupts diff --git a/Tutorials/seL4Kernel/threads.md b/Tutorials/seL4Kernel/threads.md index 7692f9e615..5b480cdde9 100644 --- a/Tutorials/seL4Kernel/threads.md +++ b/Tutorials/seL4Kernel/threads.md @@ -1,493 +1,13 @@ --- toc: true +title: Threads +tutorial: threads +tutorial-order: mechanisms-4 layout: tutorial +description: how to start a thread using the seL4 API. SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -# Threads - -This is a tutorial for using threads on seL4. - -In this tutorial, you will -1. Learn the jargon TCB. -2. Learn how to start a thread in the same address space. -3. Understand how to read and update TCB register state. -4. Learn how to suspend and resume a thread. -5. Understand thread priorities and their interaction with the seL4 scheduler. -6. Gain a basic understanding of exceptions and debug fault handlers. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/seL4Kernel/setting-ip#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut threads -# building the tutorial exercise -cd untyped_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut threads -``` -Answers are also available in drop down menus under each section. -
    - -## CapDL Loader - -Previous tutorials have taken place in the root task where the starting CSpace layout is set by the -seL4 boot protocol. This tutorial uses a the *capDL loader*, a root task which allocates statically - configured objects and capabilities. - -The capDL loader parses -a static description of the system and the relevant ELF binaries. -It is primarily used in [Camkes](https://docs.sel4.systems/CAmkES/) projects -but we also use it in the tutorials to reduce redundant code. -The program that you construct will end up with its own CSpace and VSpace, which are separate -from the root task, meaning CSlots like `seL4_CapInitThreadVSpace` have no meaning -in applications loaded by the capDL loader. - -More information about CapDL projects can be found [here](https://docs.sel4.systems/CapDL.html). - -For this tutorial clone the [CapDL repo](https://github.com/sel4/capdl). This can be added in a directory that is adjacent to the tutorials-manifest directory. - - -## Background - -### Thread Control Blocks - -seL4 provides threads to represent an execution context and manage processor time. Threads in -seL4 are realised by *thread control block* objects (TCBs), one for each kernel thread. - -TCBs contain the following information: -* a priority and maximum control priority, -* register state and floating-point context, -* CSpace capability, -* VSpace capability, -* endpoint capability to send fault messages to, -* and the reply capability slot. - -### Scheduling model - -The seL4 scheduler chooses the next thread to run on a specific -processing core, and is a priority-based round-robin scheduler. The scheduler picks -threads that are runnable: that is, resumed, and not blocked on any IPC operation. - -#### Priorities - -The scheduler picks the highest-priority, runnable thread. seL4 provides a priority range of 0-255, where -255 is the maximum priority (encoded in `libsel4` as `seL4_MinPrio` and `seL4_MaxPrio`). - -TCBs also have a *maximum control priority* (MCP), which acts as an informal capability over priorities. -When setting the priority of a TCB, an explicit TCB capability must be provided to derive the -authority from to set the priority. The priority being set is checked against the authority TCB's -MCP and the target priority is greater, the operation fails. The root task starts with both priority and -MCP set to `seL4_MaxPrio`. - -#### Round robin - -When multiple TCBs are runnable and have the same priority, they are scheduled in a -first-in, first-out round-robin fashion. In more detail, kernel time -is accounted for in fixed-time quanta referred to as ticks, and each TCB has -a timeslice field which represents the number of ticks that TCB is eligible to execute -until preempted. The kernel timer driver is configured to fire a periodic interrupt which -marks each tick, and when the timeslice is exhausted round robin scheduling is applied. -Threads can surrender their current timeslice using the `seL4_Yield` system call. - -#### Domain scheduling - -In order to provide confidentiality seL4 provides a top-level hierarchical scheduler which -provides static, cyclical scheduling of scheduling partitions known as domains. Domains are -statically configured at compile time with a cyclic schedule, and are non-preemptible resulting in -completely deterministic scheduling of domains. - -Threads can be assigned to domains, and threads are only scheduled -when their domain is active. Cross-domain IPC is delayed until a domain switch, and -seL4_Yield between domains is not possible. When there are no threads to run while a -domain is scheduled, a domain-specific idle thread will run until a switch occurs. - -Assigning a thread to a domain requires access to the `seL4_DomainSet` capability. This allows a -thread to be added to any domain. - -```c -/* Set thread's domain */ -seL4_Error seL4_DomainSet_Set(seL4_DomainSet _service, seL4_Uint8 domain, seL4_TCB thread); - -``` - -### Thread Attributes - -seL4 threads are configured by [invocations on the TCB object](https://docs.sel4.systems/ApiDoc.html#sel4_tcb). - -## Exercises - -This tutorial will guide you through using TCB invocations to create a new thread in the same -address space and pass arguments to the new thread. -Additionally, you will learn about how to debug a virtual memory -fault. - -By the end of this tutorial you want to spawn a new thread to call the function in the code example - below. - -```c - -int new_thread(void *arg1, void *arg2, void *arg3) { - printf("Hello2: arg1 %p, arg2 %p, arg3 %p\n", arg1, arg2, arg3); - void (*func)(int) = arg1; - func(*(int *)arg2); - while(1); -} - -``` - - -### Configure a TCB - -When you first build and run the tutorial, you should see something like the following: -``` -Hello, World! -Dumping all tcbs! -Name State IP Prio Core --------------------------------------------------------------------------------------- -tcb_threads running 0x4012ef 254 0 -idle_thread idle (nil) 0 0 -rootserver inactive 0x4024c2 255 0 -< -main@threads.c:42 [Cond failed: result] -Failed to retype thread: 2 -``` - -`Dumping all tcbs!` and the following table is generated by a debug syscall called `seL4_DebugDumpScheduler()`. -seL4 has a series of debug syscalls that are available in debug kernel builds. The available debug syscalls -can be found in [libsel4](https://docs.sel4.systems/ApiDoc.html#debugging-system-calls). `seL4_DebugDumpScheduler()` -is used to dump the current state of the scheduler and can be useful to debug situations where a -system seems to have hung. - -After the TCB table, you can see the `seL4_Untyped_Retype` invocation is failing due to invalid arguments. -The loader has been configured to set up the following capabilities and symbols: - -```c - -// the root CNode of the current thread -extern seL4_CPtr root_cnode; -// VSpace of the current thread -extern seL4_CPtr root_vspace; -// TCB of the current thread -extern seL4_CPtr root_tcb; -// Untyped object large enough to create a new TCB object - -extern seL4_CPtr tcb_untyped; -extern seL4_CPtr buf2_frame_cap; -extern const char buf2_frame[4096]; - -// Empty slot for the new TCB object -extern seL4_CPtr tcb_cap_slot; -// Symbol for the IPC buffer mapping in the VSpace, and capability to the mapping -extern seL4_CPtr tcb_ipc_frame; -extern const char thread_ipc_buff_sym[4096]; -// Symbol for the top of a 16 * 4KiB stack mapping, and capability to the mapping -extern const char tcb_stack_base[65536]; -static const uintptr_t tcb_stack_top = (const uintptr_t)&tcb_stack_base + sizeof(tcb_stack_base); -``` - -**Exercise** Fix the `seL4_Untyped_Retype` call (shown below) using the capabilities provided above, such -that a new TCB object is created in `tcb_cap_slot`. - -```c -int main(int c, char* arbv[]) { - - printf("Hello, World!\n"); - - seL4_DebugDumpScheduler(); - // TODO fix the parameters in this invocation - seL4_Error result = seL4_Untyped_Retype(seL4_CapNull, seL4_TCBObject, seL4_TCBBits, seL4_CapNull, 0, 0, seL4_CapNull, 1); - ZF_LOGF_IF(result, "Failed to retype thread: %d", result); - seL4_DebugDumpScheduler(); -``` - -
    -Quick solution -```c - seL4_Error result = seL4_Untyped_Retype(tcb_untyped, seL4_TCBObject, seL4_TCBBits, root_cnode, 0, 0, tcb_cap_slot, 1); -``` -
    - -Once the TCB has been created it will show up in the `seL4_DebugDumpScheduler()` output as -`child of: 'tcb_threads'`. Throughout the tutorial you can use this syscall to debug some of the TCB attributes -that you set. - -After the scheduler table, you should see a another error: - -``` - <> -main@threads.c:46 [Cond failed: result] - Failed to configure thread: 2 -``` - -**Exercise** Now that you have a TCB object, configure it to have the same CSpace and VSpace -as the current thread. Use the IPC buffer we have provided, but don't set a fault handler, - as the kernel will print any fault we receive with a debug build. - -```c - //TODO fix the parameters in this invocation - result = seL4_TCB_Configure(seL4_CapNull, seL4_CapNull, 0, seL4_CapNull, 0, 0, (seL4_Word) NULL, seL4_CapNull); - ZF_LOGF_IF(result, "Failed to configure thread: %d", result); -``` -
    -Quick solution -```c - result = seL4_TCB_Configure(tcb_cap_slot, seL4_CapNull, root_cnode, 0, root_vspace, 0, (seL4_Word) thread_ipc_buff_sym, tcb_ipc_frame); -``` -
    - - - -You should now be getting the following error: -``` -< -main@threads.c:51 [Cond failed: result] -Failed to set the priority for the new TCB object. -``` - -### Change priority via `seL4_TCB_SetPriority` - -A newly created thread will have a priority of 0, while the thread created by the loader is at -a priority of 254. You need to change the priority of your new thread such that it will be - scheduled round-robin with the current thread. - -**Exercise** use `seL4_TCB_SetPriority` to set the priority. Remember that to set a thread's priority, -the calling thread must have the authority to do so. In this case, the main thread can use its own -TCB capability, which has an MCP of 254. - -```c - // TODO fix the call to set priority using the authority of the current thread - // and change the priority to 254 - result = seL4_TCB_SetPriority(tcb_cap_slot, seL4_CapNull, 0); - ZF_LOGF_IF(result, "Failed to set the priority for the new TCB object.\n"); - seL4_DebugDumpScheduler(); -``` -
    -Quick solution -```c - result = seL4_TCB_SetPriority(tcb_cap_slot, root_tcb, 254); -``` -
    - - -Fixing up the `seL4_TCB_SetPriority` call should allow you to see that the thread's priority is now -set to the same as the main thread in the next `seL4_DebugDumpScheduler()` call. - -``` -Name State IP Prio Core --------------------------------------------------------------------------------------- -child of: 'tcb_threads' inactive (nil) 254 0 -tcb_threads running 0x4012ef 254 0 -idle_thread idle (nil) 0 0 -rootserver inactive 0x4024c2 255 0 -< -main@threads.c:57 [Err seL4_InvalidCapability]: -Failed to write the new thread's register set. -``` - -### Set initial register state - -The TCB is nearly ready to run, except for its initial registers. You need to set the -program counter and stack pointer to valid values, otherwise your thread will crash immediately. - -`libsel4utils` contains some functions for setting register contents in a platform agnostic manner. -You can use these methods to set the program counter (instruction pointer) and stack pointer in -this way. _Note: It is assumed that the stack grows downwards on all platforms._ - -**Exercise** Set up the new thread to call the function `new_thread`. You can use the debug syscall to verify that -you have at least set the instruction pointer (IP) correctly. - -```c - seL4_UserContext regs = {0}; - int error = seL4_TCB_ReadRegisters(tcb_cap_slot, 0, 0, sizeof(regs)/sizeof(seL4_Word), ®s); - ZF_LOGF_IFERR(error, "Failed to read the new thread's register set.\n"); - - // TODO use valid instruction pointer - sel4utils_set_instruction_pointer(®s, (seL4_Word)NULL); - // TODO use valid stack pointer - sel4utils_set_stack_pointer(®s, NULL); - // TODO fix parameters to this invocation - error = seL4_TCB_WriteRegisters(seL4_CapNull, 0, 0, 0, ®s); - ZF_LOGF_IFERR(error, "Failed to write the new thread's register set.\n" - "\tDid you write the correct number of registers? See arg4.\n"); - seL4_DebugDumpScheduler(); -``` -
    -Quick solution -```c - // use valid instruction pointer - sel4utils_set_instruction_pointer(®s, (seL4_Word) new_thread); - // use valid stack pointer - sel4utils_set_stack_pointer(®s, tcb_stack_top); - // fix parameters to this invocation - error = seL4_TCB_WriteRegisters(tcb_cap_slot, 0, 0, sizeof(regs)/sizeof(seL4_Word), ®s); -``` -
    - - -On success, you will see the following output: -``` -<> -main@threads.c:63 [Err seL4_InvalidCapability]: - Failed to start new thread. -``` - -### Start the thread - -Finally you are ready to start the thread, which makes the TCB runnable and eligible to be picked by - the seL4 scheduler. This can be done by changing the second argument of -`seL4_TCB_WriteRegisters` to 1 and removing the `seL4_TCB_Resume` call, or by fixing the resume call below. - -**Exercise** resume the new thread. - -```c - // TODO resume the new thread - error = seL4_TCB_Resume(seL4_CapNull); - ZF_LOGF_IFERR(error, "Failed to start new thread.\n"); -``` -
    -Quick solution -```c - error = seL4_TCB_Resume(tcb_cap_slot); -``` -
    - - -If everything has been configured correctly, resuming the thread should result in the string -`Hello2: arg1 0, arg2 0, arg3 0` followed by a fault. - -### Passing arguments - -You will notice that all of the arguments to the new thread are 0. You can set the arguments by -using the helper function `sel4utils_arch_init_local_context` or by directly manipulating the registers -for your target architecture. - -**Exercise** update the values written with `seL4_TCB_WriteRegisters` to pass the values 1, 2, 3 as arg1, -arg2, and arg3 respectively. - -```c - UNUSED seL4_UserContext regs = {0}; - int error = seL4_TCB_ReadRegisters(tcb_cap_slot, 0, 0, sizeof(regs)/sizeof(seL4_Word), ®s); - ZF_LOGF_IFERR(error, "Failed to write the new thread's register set.\n" - "\tDid you write the correct number of registers? See arg4.\n"); - - error = seL4_TCB_WriteRegisters(0, 0, 0, 0, ®s); - ZF_LOGF_IFERR(error, "Failed to write the new thread's register set.\n" - "\tDid you write the correct number of registers? See arg4.\n"); -``` -
    -Quick solution -```c - sel4utils_arch_init_local_context((void*)new_thread, - (void *)1, (void *)2, (void *)3, - (void *)tcb_stack_top, ®s); - error = seL4_TCB_WriteRegisters(tcb_cap_slot, 0, 0, sizeof(regs)/sizeof(seL4_Word), ®s); - -``` -
    - -### Resolving a fault - -At this point, you have created and configured a new thread, and given it initial arguments. -The last part of this tutorial is what to do when your thread faults. We provide further detail - on fault handling in a future tutorial, but for now you can rely on the -kernel printing a fault message, as the thread you have created does not have a fault handler. - -In the output below you can see a cap fault has occurred. The first part of the error is that -the kernel was unable to send a fault to a fault handler as it is set to `(nil)`. The kernel -then prints out the fault it was trying to send. In this case, the fault is a virtual memory fault. -The new thread has tried to access data at address `0x2` which is an invalid and unmapped address. -The output shows that the program counter of the thread when it faulted was `0x401e66`. - -The fault status register is also output, which can be decoded by -using the relevant architecture manual. -Additionally, the kernel prints a raw stack dump from the current stack pointer. -The size of the stack dump is configurable, using the - `KernelUserStackTraceLength` cmake variable. - -``` -Caught cap fault in send phase at address (nil) -while trying to handle: -vm fault on data at address 0x2 with status 0x4 -in thread 0xffffff8008140400 "child of: 'tcb_threads'" at address 0x401e66 -With stack: -0x439fc0: 0x0 -0x439fc8: 0x3 -0x439fd0: 0x2 -0x439fd8: 0x1 -0x439fe0: 0x0 -0x439fe8: 0x1 -0x439ff0: 0x0 -0x439ff8: 0x0 -0x43a000: 0x404fb3 -0x43a008: 0x0 -0x43a010: 0x0 -0x43a018: 0x0 -0x43a020: 0x0 -0x43a028: 0x0 -0x43a030: 0x0 -0x43a038: 0x0 -``` - -To investigate the fault, you can use a tool such as `objdump` on the ELF file that was loaded to -inspect the instruction that caused the fault. - In this case, the ELF file is located at `.///threads`. - -You should be able to see that `arg2` is being dereferenced, but does not point to valid memory. - -**Exercise** pass a valid arg2, by passing the address of a global variable. -
    -Quick solution -Fix `sel4utils_arch_init_local_context` -```c - sel4utils_arch_init_local_context((void*)new_thread, - (void *)1, (void *)&data, (void *)3, - (void *)tcb_stack_top, ®s); -``` -
    - -Next, another fault will occur as the new thread expects `arg1` to be a pointer to a function. - -**Exercise** Pass the address of a function which outputs the argument which is passed to it, as `arg2`. -
    -Quick solution -Create a new function -```c - int call_once(int arg) { - printf("Hello 3 %d\n", arg); - } - -``` -and fix `sel4utils_arch_init_local_context` -```c - sel4utils_arch_init_local_context((void*)new_thread, - (void *)call_once, (void *)&data, (void *)3, - (void *)tcb_stack_top, ®s); -``` -
    - -Now you should have a new thread, which immediately calls the function passed in `arg2`. - -### Further exercises - -That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try, -to become more familiar with TCBs and threading in seL4. - -- Using different TCB invocations to change the new thread's attributes or objects -- Investigate how setting different priorities affects when the threads are scheduled to run -- Implementing synchronisation primitives using global memory. -- Trying to repeat this tutorial in the root task where there are more resources available to - create more thread objects. -- Another tutorial... +{% include tutorial.md %} Next tutorial: IPC \ No newline at end of file diff --git a/Tutorials/seL4Kernel/untyped.md b/Tutorials/seL4Kernel/untyped.md index 94ca65687f..4ea4aa181b 100644 --- a/Tutorials/seL4Kernel/untyped.md +++ b/Tutorials/seL4Kernel/untyped.md @@ -1,358 +1,13 @@ --- toc: true +title: Untyped +tutorial: untyped +tutorial-order: mechanisms-2 +description: user-level memory management. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -# Untyped -This tutorial provides an introduction to physical memory management on seL4. - -By the end of this tutorial, you should be familiar with: - -1. The jargon *untyped*, *device untyped*, and *bit size*. -2. Know how to create objects from untyped memory in seL4. -3. Know how to reclaim objects. - -## Initialising - -```sh -# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/seL4Kernel/setting-ip#get-the-code -# -# Follow these instructions to initialise the tutorial -# initialising the build directory with a tutorial exercise -./init --tut untyped -# building the tutorial exercise -cd untyped_build -ninja -``` - -
    -Hint: tutorial solutions -
    -All tutorials come with complete solutions. To get solutions run: -``` -./init --solution --tut untyped -``` -Answers are also available in drop down menus under each section. -
    - - -## Background - -### Physical memory - -Apart from a small, static amount of kernel memory, all physical memory is managed by user level in an seL4 -system. Capabilities to objects created by seL4 at boot, as well as the rest of the physical resources managed by seL4, -are passed to the root task on start up. - -### Untyped memory and capabilities - -Excluding the objects used to create the root task, capabilities to all -available physical memory are passed to the root task as capabilities to -*untyped* memory. Untyped memory is a block of contiguous physical memory with a -specific size. Untyped capabilities are capabilities to untyped memory. Untyped -capabilities can be *retyped* into kernel objects together with capabilities to -them, or into further, usually smaller, untyped capabilities. - -Untyped capabilities have a boolean property *device* which indicates whether -the memory is writable by the kernel or not: it may not be backed by RAM but -some other device, or it may be in an area of RAM not addressable by the kernel. -Device untyped capabilities can only be retyped intro frame objects (physical -memory frames, which can be mapped into virtual memory), and cannot be written -to by the kernel. - - - -### Initial state - -The `seL4_BootInfo` structure provided to the root task describes all of the untyped capabilities, including their size, -if they are a device untyped, and the physical address of the untyped. The code example below -shows how to print out the initial untyped capabilities provided from `seL4_BootInfo`. - -```c - printf(" CSlot \tPaddr \tSize\tType\n"); - for (seL4_CPtr slot = info->untyped.start; slot != info->untyped.end; slot++) { - seL4_UntypedDesc *desc = &info->untypedList[slot - info->untyped.start]; - printf("%8p\t%16p\t2^%d\t%s\n", (void *) slot, (void *) desc->paddr, desc->sizeBits, desc->isDevice ? "device untyped" : "untyped"); - } -``` - -### Retyping - -Untyped capabilities have a single invocation: -[seL4_Untyped_Retype](https://docs.sel4.systems/ApiDoc.html#retype) which is -used to create a new capability (and potentially object) from an untyped -capability. Specifically, the new capability created by a retype invocation -provides access to a subset of the memory range of the original capability, -either as a smaller untyped capability, or pointing to a new object with a -specific type. New capabilities created by retyping an untyped capability are -referred to as *children* of that untyped capability. - -Untyped capabilities are retyped incrementally in a greedy fashion from the -invoked untyped, which is important to understand in order to gain efficient -memory utilisation in seL4 systems. Each untyped capability maintains a single -watermark, with addresses before the watermark being unavailable (already -retyped) and after the watermark being free (not retyped yet). On a retype -operation, the watermark is moved first to the alignment of the object being -created, and then to the end of the size of the object. For example, if we -create first a 4KiB object and then a 16KiB object, the 12KiB between the end of -the 4KiB object and the start of the 16KiB object are wasted due to alignment. -The memory cannot be reclaimed until both children are revoked. - -TL;DR: objects should be allocated in order of size, largest first, to avoid wasting memory. - -```c - error = seL4_Untyped_Retype(parent_untyped, // the untyped capability to retype - seL4_UntypedObject, // type - untyped_size_bits, //size - seL4_CapInitThreadCNode, // root - 0, // node_index - 0, // node_depth - child_untyped, // node_offset - 1 // num_caps - ); -``` - -The above code snippet shows an example of retyping an untyped into a smaller, -4KiB untyped capability (despite the name `seL4_UntypedObject` no object is -created, the new untyped capability simply points to a subset of the untyped -memory of `parent_untyped`. However, it is convenient to treat this memory like -an object for the purposes of this operation). We will refer to this snippet as -we discuss each parameter in the retype invocation. Recall that the first -parameter is the untyped capability being invoked to do the retype. - -#### Types - -Each object in seL4 has a specific type, and all of the type constants can be found in `libsel4`. Some types -are architecture specific, while others are general across architectures. In the example above, we create a -new untyped capability, which can be further retyped. All other object type parameters create kernel objects *and* -capabilities to them, and the type of the created object (and capability) determines the invocations -that can be made on that capability. For example, were we to retype into a thread control block -(TCB -- `seL4_TCBObject`), we could then perform TCB invocations on the capability to the new TCB object, including `seL4_TCB_SetPriority`. - -#### Size - -The size argument determines the size of the new object. The meaning of the argument -depends on the object type that is being requested: - -- most objects in seL4 are fixed size, and for these, the kernel will *ignore* - the size argument; -- the types `seL4_UntypedObject` and `seL4_SchedContextObject` allow a - variable size, which is specified in `size_bits` (more below); -- the type `seL4_CapTableObject` is also of variable size, and the argument specifies - the *number of capability slots*. The same mechanism as for `size_bits` is used, - but for the number of slots, not the size in bytes. - -In general in seL4, if sizes are measured in bits, they are powers -of two. "Bits" does not refer to the number of bits the object takes up, but -the bit-width that is needed to describe its contents. An object of bit size `n` -measures 2`n` bytes. Also, generally in seL4, objects and memory -regions are aligned to their size, i.e. an `n`-bit object is aligned to -2`n` bytes, or, equivalently, the address of the object has 0 as its -`n` bottom bits. - -For `retype`, it is enough to remember that the parameter `size_bits` means the -object will measure 2`size_bits` bytes, and for `seL4_CapTableObject` -that you are requesting 2`size_bits` slots (you can compute the size -in bytes by taking 2`size_bits + seL4_SlotBits`). - -#### Root, node_index & node_depth - -The `root`, `node_index` and `node_depth` parameters are used to specify the CNode in which to place the new capabilities. -Depending on the `depth` parameter, the CSlot to use is addressed by invocation or by direct addressing (see the [capabilities tutorial](https://docs.sel4.systems/Tutorials/capabilities.html) for an explanation of those terms). - -In the example above, `node_depth` is set to 0, which means invocation addressing is used: the `root` parameter is -looked up implicitly using the CSpace root of the current thread at a depth of `seL4_WordBits`. So the example code -specifies the root task's CNode (`seL4_CapInitThreadCNode`). The `node_index` parameter in this case is ignored. - -If the `node_depth` value is not set to 0, then direct addressing is used with the current thread's CSpace root -as the root. Then the `node_index` parameter is used to locate the CNode capability to place new capabilities in, -at the specified `node_depth`. This is designed for managing multi-level CSpaces, and is not covered in this tutorial. - -#### Node_offset - -The node_offset is the CSlot to start creating new capabilities at, in the CNode selected by the previous parameters. - In this case, the first empty CSlot in the initial CNode is selected. - -#### Num_caps - -The retype invocation can be used to create more than 1 capability and object at a time -- the number of capabilities is -specified using this argument. Note that there are two constraints on this value: - -1. The untyped must be big enough to fit all of the memory being retyped (`num_caps * (1u << size_bits)`). -2. The CNode must have enough consecutive free CSlots to fit all of the new capabilities. - -## Exercises - -### Create an untyped capability - -When you first run this tutorial, you will see something like the following output, which lists all of the -untyped capabilities provided to the root task on boot: - -``` -Booting all finished, dropped to user space - CSlot Paddr Size Type - 0x12d 0x100000 2^20 device untyped - 0x12e 0x200000 2^21 device untyped - 0x12f 0x400000 2^22 device untyped - 0x130 0xb2e000 2^13 device untyped -``` - -At the end of the output, there is an error: - -``` -<> -main@main.c:49 [Cond failed: error != seL4_NoError] - Failed to retype -``` - -This error happens because we are trying to create an untyped of size 0. - -**Exercise** Calculate the size of the child untyped required, such that the child untyped can be used - to create all of the objects listed in the `objects` array. Remember that object sizes are measured in - bits, that is, in powers of two. - -```c - // list of general seL4 objects - seL4_Word objects[] = {seL4_TCBObject, seL4_EndpointObject, seL4_NotificationObject}; - // list of general seL4 object size_bits - seL4_Word sizes[] = {seL4_TCBBits, seL4_EndpointBits, seL4_NotificationBits}; - - // TODO work out what size object we need to create to be able to create all of the objects - // listed above. Remember that sizes are in bits, that is, the exponents of powers of two. - seL4_Word untyped_size_bits = 0; - seL4_CPtr parent_untyped = 0; - seL4_CPtr child_untyped = info->empty.start; - - // First, find an untyped big enough to fit all of our objects - for (int i = 0; i < (info->untyped.end - info->untyped.start); i++) { - if (info->untypedList[i].sizeBits >= untyped_size_bits && !info->untypedList[i].isDevice) { - parent_untyped = info->untyped.start + i; - break; - } - } -``` -
    -Quick solution -```c - // seL4_EndpointBits and seL4_NotificationBits are both less than seL4_TCBBits, which - // means that all objects together fit into the size of two TCBs, or 2^(seL4_TCBBits + 1): - seL4_Word untyped_size_bits = seL4_TCBBits + 1; -``` -
    - -On success, the tutorial will progress further, printing "Failed to set priority" - -### Create a TCB object - -The priority check is failing as `child_tcb` is an empty CSlot. - -**Exercise** fix this by creating a TCB object from `child_untyped` and place its cap into the `child_tcb` CSlot. - -```c - // use the slot after child_untyped for the new TCB cap: - seL4_CPtr child_tcb = child_untyped + 1; - /* TODO create a TCB in CSlot child_tcb */ - - // try to set the TCB priority - error = seL4_TCB_SetPriority(child_tcb, seL4_CapInitThreadTCB, 10); - ZF_LOGF_IF(error != seL4_NoError, "Failed to set priority"); -``` -
    -Quick solution -```c - /* create a TCB in CSlot child_tcb */ - seL4_Untyped_Retype(child_untyped, seL4_TCBObject, 0, seL4_CapInitThreadCNode, 0, 0, child_tcb, 1); -``` -
    - -On success, the tutorial will progress further, printing "Endpoint cap is null cap". - -### Create an endpoint object - -The error you see now is caused be an invalid endpoint capability. - -**Exercise** Create an endpoint object from `child_untyped` and place its cap into the `child_ep` CSlot. - -```c - // use the slot after child_tcb for the new endpoint cap: - seL4_CPtr child_ep = child_tcb + 1; - /* TODO create an endpoint in CSlot child_ep */ - - // identify the type of child_ep - uint32_t cap_id = seL4_DebugCapIdentify(child_ep); - ZF_LOGF_IF(cap_id == 0, "Endpoint cap is null cap"); -``` -
    -Quick solution -```c - /* create an endpoint in CSlot child_ep */ - seL4_Untyped_Retype(child_untyped, seL4_EndpointObject, 0, seL4_CapInitThreadCNode, 0, 0, child_ep, 1); -``` -
    - - -On success, 'Failed to bind notification' should be output. - -### Create a notification object - -The next part of the tutorial attempts to use a notification object that does not yet exist. - -**Exercise** create a notification object from `child_untyped` and place its cap into the `child_ntfn` CSlot. - -```c - // use the slot after child_ep for the new notification cap: - seL4_CPtr child_ntfn = child_ep + 1; - // TODO create a notification object in CSlot child_ntfn - - // try to use child_ntfn - error = seL4_TCB_BindNotification(child_tcb, child_ntfn); - ZF_LOGF_IF(error != seL4_NoError, "Failed to bind notification."); -``` -
    -Quick solution -```c - // create a notification object in CSlot child_ntfn - seL4_Untyped_Retype(child_untyped, seL4_NotificationObject, 0, seL4_CapInitThreadCNode, 0, 0, child_ntfn, 1); -``` -
    - - -### Delete the objects - -The final part of the tutorial attempts to create enough endpoint objects from `child_untyped` to consume the -entire untyped object. However, this fails, because the untyped is already completely consumed by the previous allocations. - -**Exercise** revoke the child untyped, so we can create new objects from it that use up the whole thing. - -```c - // TODO revoke the child untyped - - // allocate the whole child_untyped as endpoints - // Remember the sizes are exponents, so this computes 2^untyped_size_bits / 2^seL4_EndpointBits: - seL4_Word num_eps = BIT(untyped_size_bits - seL4_EndpointBits); - error = seL4_Untyped_Retype(child_untyped, seL4_EndpointObject, 0, seL4_CapInitThreadCNode, 0, 0, child_tcb, num_eps); - ZF_LOGF_IF(error != seL4_NoError, "Failed to create endpoints."); - - printf("Success\n"); -``` -
    -Quick solution -```c - // revoke the child untyped - error = seL4_CNode_Revoke(seL4_CapInitThreadCNode, child_untyped, seL4_WordBits); - assert(error == seL4_NoError); -``` -
    - -Once the tutorial is completed successfully, you should see the message "Success". - -### Further exercises - -That's all for the detailed content of this tutorial. Below we list other ideas for exercises you can try -to become more familiar with untyped objects and memory allocation in seL4. - -* Allocate objects at specific physical addresses. -* Create a simple object allocator for allocating seL4 objects. +{% include tutorial.md %} Next tutorial: Mapping From 94045ffcaf17ef060236e36975d217a503d4a176 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 13 May 2024 10:16:55 +1000 Subject: [PATCH 029/103] fix links in nav sidebar Signed-off-by: Birgit Brecknell --- _includes/nav-sidebar.html | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index f3942a2f87..44841591c6 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -76,27 +76,27 @@
  • IPC
  • Notifications
  • Interrupts
  • -
  • Fault Handling
  • +
  • Fault Handling
  • MCS
  • Dynamic libraries
  • CAmkES
  • Microkit
    • From 5e86114069aca2cc91db92573bc1e8cfffee4361 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 27 May 2024 13:27:53 +1000 Subject: [PATCH 030/103] Makefile testing code Signed-off-by: Birgit Brecknell --- Makefile | 111 +++++++++++++++++++++++++++++++++- Tutorials/Resources/how-to.md | 19 +++--- 2 files changed, 119 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index e2a1118a47..c95cc130c0 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Copyright 2020 seL4 Project a Series of LF Projects, LLC. # SPDX-License-Identifier: BSD-2-Clause -default: serve +default: serve --trace .PHONY: ruby_deps ruby_deps: Gemfile Gemfile.lock @@ -48,10 +48,117 @@ $(REPOSITORIES): _repos/tutes: mkdir -p $@ + + + + + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-world/hello-world.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-world/hello-world.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-world/hello-world.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-world/hello-world.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/capabilities/capabilities.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/capabilities/capabilities.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/capabilities/capabilities.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/capabilities/capabilities.md + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/untyped/untyped.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/untyped/untyped.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/untyped/untyped.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/untyped/untyped.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/mapping/mapping.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/mapping/mapping.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/threads/threads.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/threads/threads.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/threads/threads.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/threads/threads.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/ipc/ipc.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/ipc/ipc.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/ipc/ipc.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/ipc/ipc.md + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/notifications/notifications.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/notifications/notifications.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/notifications/notifications.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/notifications/notifications.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/interrupts/interrupts.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/interrupts/interrupts.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/interrupts/interrupts.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/interrupts/interrupts.md + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/fault-handlers/fault-handlers.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/fault-handlers/fault-handlers.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/fault-handlers/fault-handlers.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/fault-handlers/fault-handlers.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mcs/mcs.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/mcs/mcs.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/mcs/mcs.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mcs/mcs.md + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-1/dynamic-1.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-1/dynamic-1.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-1/dynamic-1.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-1/dynamic-1.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-2/dynamic-2.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-2/dynamic-2.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-2/dynamic-2.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-2/dynamic-2.md + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-3/dynamic-3.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-3/dynamic-3.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-3/dynamic-3.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-3/dynamic-3.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-4/dynamic-4.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-4/dynamic-4.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-4/dynamic-4.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-4/dynamic-4.md + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-0/hello-camkes-0.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-0/hello-camkes-0.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-0/hello-camkes-0.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-0/hello-camkes-0.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-1/hello-camkes-1.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-1/hello-camkes-1.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-1/hello-camkes-1.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-1/hello-camkes-1.md + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-2/hello-camkes-2.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-2/hello-camkes-2.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-2/hello-camkes-2.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-2/hello-camkes-2.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md + + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-vm-crossvm/hello-camkes-vm-crossvm.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-vm-crossvm/hello-camkes-vm-crossvm.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-vm-crossvm/hello-camkes-vm-crossvm.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-vm-crossvm/hello-camkes-vm-crossvm.md + +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-vm-linux/hello-camkes-vm-linux.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-vm-linux/hello-camkes-vm-linux.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-vm-linux/hello-camkes-vm-linux.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-vm-linux/hello-camkes-vm-linux.md + + +all: /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-world/hello-world.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/capabilities/capabilities.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/threads/threads.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/ipc/ipc.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/notifications/notifications.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/interrupts/interrupts.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/fault-handlers/fault-handlers.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mcs/mcs.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-1/dynamic-1.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-2/dynamic-2.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-3/dynamic-3.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-4/dynamic-4.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-0/hello-camkes-0.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-1/hello-camkes-1.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-2/hello-camkes-2.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md + + + + + + + + + + + _repos/tutes/%.md: _repos/sel4proj/sel4-tutorials/tutorials/% _repos/tutes PYTHONPATH=_repos/sel4/capdl/python-capdl-tool _repos/sel4proj/sel4-tutorials/template.py --docsite --out-dir _repos/tutes --tut-file $ Date: Fri, 17 May 2024 10:00:35 +1000 Subject: [PATCH 031/103] add refs and headers to how-to page Signed-off-by: Birgit Brecknell --- Makefile | 8 +++--- Tutorials/Resources/how-to.md | 48 +++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index c95cc130c0..54866cef76 100644 --- a/Makefile +++ b/Makefile @@ -117,11 +117,11 @@ _repos/tutes: cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-vm-crossvm/hello-camkes-vm-crossvm.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-vm-crossvm/hello-camkes-vm-crossvm.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-vm-crossvm/hello-camkes-vm-crossvm.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-vm-crossvm/hello-camkes-vm-crossvm.md +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-vm-linux/hello-camkes-vm-linux.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-vm-linux/hello-camkes-vm-linux.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-vm-linux/hello-camkes-vm-linux.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-vm-linux/hello-camkes-vm-linux.md +/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md + cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md all: /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-world/hello-world.md \ diff --git a/Tutorials/Resources/how-to.md b/Tutorials/Resources/how-to.md index db89900a49..39e3458421 100644 --- a/Tutorials/Resources/how-to.md +++ b/Tutorials/Resources/how-to.md @@ -122,7 +122,7 @@ This guide provides links to tutorial solutions as quick references for seL4 cal ## [CAmkES](../CAmkES/hello-camkes-0) ### [A basic CAmkES application](../CAmkES/hello-camkes-1) - - [Define instance in the composition section of the ADL](../CAmkES/hello-camkes-1#define-instance-in-the-composition-section-of-the-adl) + - [Define an instance in the composition section of the ADL](../CAmkES/hello-camkes-1#define-an-instance-in-the-composition-section-of-the-adl) - [Add a connection](../CAmkES/hello-camkes-1#add-a-connection) - [Define an interface](../CAmkES/hello-camkes-1#define-an-interface) - [Implement a RPC function](../CAmkES/hello-camkes-1#implement-a-rpc-function) @@ -133,7 +133,7 @@ This guide provides links to tutorial solutions as quick references for seL4 cal - [Wait for data to become available](../CAmkES/hello-camkes-2#wait-for-data-to-become-available) - [Signal that data is available](../CAmkES/hello-camkes-2#signal-that-data-is-available) - [Register a callback handler](../CAmkES/hello-camkes-2#register-a-callback-handler) - - [Specify dataport interfaces](../CAmkES/hello-camkes-2#specify-an-events-interface) + - [Specify dataport interfaces](../CAmkES/hello-camkes-2#specify-dataport-interfaces) - [Specify dataport connections](../CAmkES/hello-camkes-2#specify-dataport-connections) - [Copy strings to an untyped dataport](../CAmkES/hello-camkes-2#copy-strings-to-an-untyped-dataport) - [Read the reply data from a typed dataport](../CAmkES/hello-camkes-2#read-the-reply-data-from-a-typed-dataport) @@ -145,17 +145,33 @@ This guide provides links to tutorial solutions as quick references for seL4 cal - [Restrict access to dataports](../CAmkES/hello-camkes-2#restrict-access-to-dataports) - [Test the read and write permissions on the dataport](../CAmkES/hello-camkes-2#test-the-read-and-write-permissions-on-the-dataport) -### [CAmkES Timer](../CAmkES/camkes) - - [Instantiate a Timer and Timerbase](../CAmkES/hello-camkes-timer#task-1) - - [Connect a timer driver component](../CAmkES/hello-camkes-timer#task-2) - - [Configure a timer hardware component instance](../CAmkES/hello-camkes-timer#task-3) - - [Call into a supplied driver to handle the interrupt](../CAmkES/hello-camkes-timer#task-4) - - [Stop a timer](../CAmkES/hello-camkes-timer#task-5) - - [Acknowledge an interrupt](../CAmkES/hello-camkes-timer#task-6) - - [Get a timer handler](../CAmkES/hello-camkes-timer#task-7) - - [Start a timer](../CAmkES/hello-camkes-timer#task-8) - - [Implement a RPC interface](../CAmkES/hello-camkes-timer#task-9) - - [Set a timer interrupt](../CAmkES/hello-camkes-timer#task-10) - - [Instantiate a TimerDTB component](../CAmkES/hello-camkes-timer#task-1-1) - - [Connect interfaces using the seL4DTBHardware connector](../CAmkES/hello-camkes-timer#task-2-1) - - [Configure the TimerDTB component](../CAmkES/hello-camkes-timer#task-3-1) +### [CAmkES Timer](../CAmkES/hello-camkes-timer) + - [Instantiate a Timer and Timerbase](../CAmkES/hello-camkes-timer#instantiate-a-timer-and-timerbase) + - [Connect a timer driver component](../CAmkES/hello-camkes-timer#connect-a-timer-driver-component) + - [Configure a timer hardware component instance](../CAmkES/hello-camkes-timer#configure-a-timer-hardware-component-instance) + - [Call into a supplied driver to handle the interrupt](../CAmkES/hello-camkes-timer#call-into-a-supplied-driver-to-handle-the-interrupt) + - [Stop a timer](../CAmkES/hello-camkes-timer#stop-a-timer) + - [Acknowledge an interrupt](../CAmkES/hello-camkes-timer#acknowledge-an-interrupt) + - [Get a timer handler](../CAmkES/hello-camkes-timer#get-a-timer-handler) + - [Start a timer](../CAmkES/hello-camkes-timer#start-a-timer) + - [Implement a RPC interface](../CAmkES/hello-camkes-timer#implement-a-rpc-interface) + - [Set a timer interrupt](../CAmkES/hello-camkes-timer#set-a-timer-interrupt) + - [Instantiate a TimerDTB component](../CAmkES/hello-camkes-timer#instantiate-a-timerdtb-component) + - [Connect interfaces using the seL4DTBHardware connector](../CAmkES/hello-camkes-timer#connect-interfaces-using-the-sel4dtbhardware-connector) + - [Configure the TimerDTB component](../CAmkES/hello-camkes-timer#configure-the-timerdtb-component) + +### [CAmkES VM Linux](../CAmkES/camkes-vm-linux) + - [Add a program](../CAmkES/camkes-vm-linux#adding-a-program) + - [Add a kernel module](../CAmkES/camkes-vm-linux#adding-a-kernel-module) + - [Create a hypercall](../CAmkES/camkes-vm-linux#creating-a-hypercall) + +### [CAmkeES Cross VM Connectors](../CAmkES/camkes-vm-crossvm) + - [Add modules to the guest](../CAmkES/camkes-vm-crossvm#add-modules-to-the-guest) + - [Define interfaces in the VMM](../CAmkES/camkes-vm-crossvm#define-interfaces-in-the-vmm) + - [Define the component interface](../CAmkES/camkes-vm-crossvm#define-the-component-interface) + - [Instantiate the print server](../CAmkES/camkes-vm-crossvm#instantiate-the-print-server) + - [Implement the print server](../CAmkES/camkes-vm-crossvm#implement-the-print-server) + - [Implement the VMM side of the connection](../CAmkES/camkes-vm-crossvm#implement-the-vmm-side-of-the-connection) + - [Update the build system](../CAmkES/camkes-vm-crossvm#update-the-build-system) + - [Add interfaces to the Guest](../CAmkES/camkes-vm-crossvm#add-interfaces-to-the-guest) + - [Create a process](../CAmkES/camkes-vm-crossvm#create-a-process) \ No newline at end of file From 4758f09d4cdc62f14405baa1abeaf129e5803bcf Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 17 May 2024 10:07:38 +1000 Subject: [PATCH 032/103] fix typo Signed-off-by: Birgit Brecknell --- Tutorials/GettingStarted/about-seL4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tutorials/GettingStarted/about-seL4.md b/Tutorials/GettingStarted/about-seL4.md index f9727896de..fbf9cebe65 100644 --- a/Tutorials/GettingStarted/about-seL4.md +++ b/Tutorials/GettingStarted/about-seL4.md @@ -20,7 +20,7 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. memory object, which allocates the memory for the object, initialises it, and returns a capability to the new object.

      - Virtual address spaces are formed by explicit manipulation of virtual-memoryrelated kernel objects: PageDirectories, PageTables, ASIDPools and Frames (mappable physical memory). As such, address spaces have no kernel-defined structure (except for a protected region reserved for the seL4 kernel itself). Whether the userlevel system is Exokernel like, a multi-server, or a para-virtualised monolithic OS is determined by user-level via a map and unmap interface to Frames and PageTables. The distribution of authority to the kernel virtual memory (VM) objects ultimately determines the scope of influence over virtual and physical memory. + Virtual address spaces are formed by explicit manipulation of virtual-memory related kernel objects: PageDirectories, PageTables, ASIDPools and Frames (mappable physical memory). As such, address spaces have no kernel-defined structure (except for a protected region reserved for the seL4 kernel itself). Whether the userlevel system is Exokernel like, a multi-server, or a para-virtualised monolithic OS is determined by user-level via a map and unmap interface to Frames and PageTables. The distribution of authority to the kernel virtual memory (VM) objects ultimately determines the scope of influence over virtual and physical memory.

      Threads are the active entity in seL4. By associating a CNode and a virtual address space with a thread, user-level policies create high-level abstractions, such as processes or virtual machines. From c22a3e6628c0edb2f0cf2678beb76263c9be9a37 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 17 May 2024 10:09:03 +1000 Subject: [PATCH 033/103] fix href target blank Signed-off-by: Birgit Brecknell --- Tutorials/GettingStarted/microkit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tutorials/GettingStarted/microkit.md b/Tutorials/GettingStarted/microkit.md index 0003ac8a30..1bf5969301 100644 --- a/Tutorials/GettingStarted/microkit.md +++ b/Tutorials/GettingStarted/microkit.md @@ -15,7 +15,7 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. After completing the Microkit tutorial, go to seL4 kernel tutorials for a deep dive into seL4 concepts.

      - Go to the Microkit tutorial + Go to the Microkit tutorial

      Next tutorial: seL4 kernel tutorials From 61f321cf8f3fc6d95f51e71504d2febcf21baa63 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 17 May 2024 10:10:39 +1000 Subject: [PATCH 034/103] fix link Signed-off-by: Birgit Brecknell --- Tutorials/seL4Kernel/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tutorials/seL4Kernel/overview.md b/Tutorials/seL4Kernel/overview.md index dfaa2fe556..e1c9794ed0 100644 --- a/Tutorials/seL4Kernel/overview.md +++ b/Tutorials/seL4Kernel/overview.md @@ -23,7 +23,7 @@ architecture. Suggested resources for these include: - [Instruction Set Architecture (wikipedia)](https://en.wikipedia.org/wiki/Instruction_set_architecture)

      Resources

      -We recommend having access to the seL4 manual and the API references. +We recommend having access to the seL4 manual and the API references. The How to page provides links to tutorial solutions as quick references for seL4 calls and methods. From cd34825994578147571d2a958f6ef8f52dcfa098 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 20 May 2024 12:06:20 +1000 Subject: [PATCH 035/103] expand solutions if using how-to page Signed-off-by: Birgit Brecknell --- Tutorials/CAmkES/camkes-vm-crossvm.md | 1 + Tutorials/CAmkES/camkes-vm-linux.md | 1 + Tutorials/CAmkES/hello-camkes-0.md | 1 + Tutorials/CAmkES/hello-camkes-1.md | 1 + Tutorials/CAmkES/hello-camkes-2.md | 1 + Tutorials/CAmkES/hello-camkes-timer.md | 1 + Tutorials/DynamicLibraries/dynamic-1.md | 1 + Tutorials/DynamicLibraries/dynamic-2.md | 1 + Tutorials/DynamicLibraries/dynamic-3.md | 1 + Tutorials/DynamicLibraries/dynamic-4.md | 1 + Tutorials/MCS/mcs.md | 1 + Tutorials/Resources/how-to.md | 3 +++ Tutorials/seL4Kernel/capabilities.md | 1 + Tutorials/seL4Kernel/fault-handlers.md | 1 + Tutorials/seL4Kernel/hello-world.md | 1 + Tutorials/seL4Kernel/interrupts.md | 1 + Tutorials/seL4Kernel/ipc.md | 1 + Tutorials/seL4Kernel/mapping.md | 1 + Tutorials/seL4Kernel/notifications.md | 1 + Tutorials/seL4Kernel/threads.md | 1 + Tutorials/seL4Kernel/untyped.md | 1 + assets/js/toggle-markdown.js | 16 ++++++++++++++++ 22 files changed, 39 insertions(+) create mode 100644 assets/js/toggle-markdown.js diff --git a/Tutorials/CAmkES/camkes-vm-crossvm.md b/Tutorials/CAmkES/camkes-vm-crossvm.md index 3fc835fb72..1138a4b58d 100644 --- a/Tutorials/CAmkES/camkes-vm-crossvm.md +++ b/Tutorials/CAmkES/camkes-vm-crossvm.md @@ -9,3 +9,4 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + diff --git a/Tutorials/CAmkES/camkes-vm-linux.md b/Tutorials/CAmkES/camkes-vm-linux.md index 9c8a032c8a..00641bda65 100644 --- a/Tutorials/CAmkES/camkes-vm-linux.md +++ b/Tutorials/CAmkES/camkes-vm-linux.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: CAmkES Cross VM diff --git a/Tutorials/CAmkES/hello-camkes-0.md b/Tutorials/CAmkES/hello-camkes-0.md index 1ed57a311e..eed9ce1d72 100644 --- a/Tutorials/CAmkES/hello-camkes-0.md +++ b/Tutorials/CAmkES/hello-camkes-0.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: CAmkES 1: Introduction to CAmkES diff --git a/Tutorials/CAmkES/hello-camkes-1.md b/Tutorials/CAmkES/hello-camkes-1.md index f981d02ef9..608b55d2f8 100644 --- a/Tutorials/CAmkES/hello-camkes-1.md +++ b/Tutorials/CAmkES/hello-camkes-1.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: CAmkES 2: Events \ No newline at end of file diff --git a/Tutorials/CAmkES/hello-camkes-2.md b/Tutorials/CAmkES/hello-camkes-2.md index 935e1896f6..964054e427 100644 --- a/Tutorials/CAmkES/hello-camkes-2.md +++ b/Tutorials/CAmkES/hello-camkes-2.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: CAmkES 3: Timer diff --git a/Tutorials/CAmkES/hello-camkes-timer.md b/Tutorials/CAmkES/hello-camkes-timer.md index 021b449d5f..9da8e28c2f 100644 --- a/Tutorials/CAmkES/hello-camkes-timer.md +++ b/Tutorials/CAmkES/hello-camkes-timer.md @@ -9,6 +9,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: CAmkES VM diff --git a/Tutorials/DynamicLibraries/dynamic-1.md b/Tutorials/DynamicLibraries/dynamic-1.md index ce60d43856..e80493f5cc 100644 --- a/Tutorials/DynamicLibraries/dynamic-1.md +++ b/Tutorials/DynamicLibraries/dynamic-1.md @@ -9,6 +9,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: IPC diff --git a/Tutorials/DynamicLibraries/dynamic-2.md b/Tutorials/DynamicLibraries/dynamic-2.md index ce1486f7fe..21dad15c03 100644 --- a/Tutorials/DynamicLibraries/dynamic-2.md +++ b/Tutorials/DynamicLibraries/dynamic-2.md @@ -9,6 +9,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Processes & Elf loading diff --git a/Tutorials/DynamicLibraries/dynamic-3.md b/Tutorials/DynamicLibraries/dynamic-3.md index 0e90c0733a..814d1b2ac2 100644 --- a/Tutorials/DynamicLibraries/dynamic-3.md +++ b/Tutorials/DynamicLibraries/dynamic-3.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Timer diff --git a/Tutorials/DynamicLibraries/dynamic-4.md b/Tutorials/DynamicLibraries/dynamic-4.md index f3984c190e..a3e2acdf91 100644 --- a/Tutorials/DynamicLibraries/dynamic-4.md +++ b/Tutorials/DynamicLibraries/dynamic-4.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Hello CAmkES diff --git a/Tutorials/MCS/mcs.md b/Tutorials/MCS/mcs.md index d7c5d29197..972ff6b45b 100644 --- a/Tutorials/MCS/mcs.md +++ b/Tutorials/MCS/mcs.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Dynamic libraries diff --git a/Tutorials/Resources/how-to.md b/Tutorials/Resources/how-to.md index 39e3458421..d70584a15c 100644 --- a/Tutorials/Resources/how-to.md +++ b/Tutorials/Resources/how-to.md @@ -7,6 +7,9 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. # How to: A quick solutions guide This guide provides links to tutorial solutions as quick references for seL4 calls and methods. +[//]: # (Show me some foo) + + ## The seL4 kernel ### [Capabilities](../seL4Kernel/capabilities) diff --git a/Tutorials/seL4Kernel/capabilities.md b/Tutorials/seL4Kernel/capabilities.md index c7ca44aa25..df7f392372 100644 --- a/Tutorials/seL4Kernel/capabilities.md +++ b/Tutorials/seL4Kernel/capabilities.md @@ -10,5 +10,6 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Untyped diff --git a/Tutorials/seL4Kernel/fault-handlers.md b/Tutorials/seL4Kernel/fault-handlers.md index a5321f4752..b41cf80df9 100644 --- a/Tutorials/seL4Kernel/fault-handlers.md +++ b/Tutorials/seL4Kernel/fault-handlers.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: MCS diff --git a/Tutorials/seL4Kernel/hello-world.md b/Tutorials/seL4Kernel/hello-world.md index df1711d74c..0b16f833a1 100644 --- a/Tutorials/seL4Kernel/hello-world.md +++ b/Tutorials/seL4Kernel/hello-world.md @@ -10,5 +10,6 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Capabilities \ No newline at end of file diff --git a/Tutorials/seL4Kernel/interrupts.md b/Tutorials/seL4Kernel/interrupts.md index 8b04dc03a3..a200651425 100644 --- a/Tutorials/seL4Kernel/interrupts.md +++ b/Tutorials/seL4Kernel/interrupts.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Fault handling diff --git a/Tutorials/seL4Kernel/ipc.md b/Tutorials/seL4Kernel/ipc.md index d7494b3f3c..026e22585c 100644 --- a/Tutorials/seL4Kernel/ipc.md +++ b/Tutorials/seL4Kernel/ipc.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Notifications diff --git a/Tutorials/seL4Kernel/mapping.md b/Tutorials/seL4Kernel/mapping.md index 9de492e6d7..ee63720c14 100644 --- a/Tutorials/seL4Kernel/mapping.md +++ b/Tutorials/seL4Kernel/mapping.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Threads diff --git a/Tutorials/seL4Kernel/notifications.md b/Tutorials/seL4Kernel/notifications.md index 928ffb76ff..ab2fd58b57 100644 --- a/Tutorials/seL4Kernel/notifications.md +++ b/Tutorials/seL4Kernel/notifications.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Interrupts diff --git a/Tutorials/seL4Kernel/threads.md b/Tutorials/seL4Kernel/threads.md index 5b480cdde9..6e715ef39a 100644 --- a/Tutorials/seL4Kernel/threads.md +++ b/Tutorials/seL4Kernel/threads.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: IPC \ No newline at end of file diff --git a/Tutorials/seL4Kernel/untyped.md b/Tutorials/seL4Kernel/untyped.md index 4ea4aa181b..6bcfc2f746 100644 --- a/Tutorials/seL4Kernel/untyped.md +++ b/Tutorials/seL4Kernel/untyped.md @@ -9,5 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} + Next tutorial: Mapping diff --git a/assets/js/toggle-markdown.js b/assets/js/toggle-markdown.js new file mode 100644 index 0000000000..5f8a867977 --- /dev/null +++ b/assets/js/toggle-markdown.js @@ -0,0 +1,16 @@ +// Open all solutions if previous link was how-to page + +let text = document.referrer; +let result = text.includes("Tutorials/Resources/how-to"); + +if (result==true){ + document.body.querySelectorAll('details') + .forEach((e) => {(e.hasAttribute('open')) ? + e.removeAttribute('open') : e.setAttribute('open',true); + console.log(e.hasAttribute('open')) + }) +} + + + + From 74e041337557a5fb99a37ebb78415d32458d3779 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 20 May 2024 13:21:27 +1000 Subject: [PATCH 036/103] add css space after solution boxes Signed-off-by: Birgit Brecknell --- assets/css/style.scss | 5 +++++ assets/js/toggle-markdown.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/assets/css/style.scss b/assets/css/style.scss index 7e224e395c..5abd29f1a8 100644 --- a/assets/css/style.scss +++ b/assets/css/style.scss @@ -291,3 +291,8 @@ a[href*="//"]:not([href*="{{site.url}}"],.skip-icon):after { .flex-grid-thirds .col { width: 32%; } + +/* add margin below tutorials solutions boxes */ +details { + padding-bottom: 20px; +} diff --git a/assets/js/toggle-markdown.js b/assets/js/toggle-markdown.js index 5f8a867977..d55457deca 100644 --- a/assets/js/toggle-markdown.js +++ b/assets/js/toggle-markdown.js @@ -1,4 +1,4 @@ -// Open all solutions if previous link was how-to page +// Expand all solutions if previous link was how-to page let text = document.referrer; let result = text.includes("Tutorials/Resources/how-to"); From f159026cb320c4acd0d7277531bbc65147a2176f Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 20 May 2024 13:29:27 +1000 Subject: [PATCH 037/103] separate instructions for getting tutes manifest Signed-off-by: Birgit Brecknell --- Tutorials/seL4Kernel/get-the-tutorials.md | 32 +++++++++++++++++++++++ Tutorials/seL4Kernel/setting-up.md | 24 +---------------- _includes/nav-sidebar.html | 1 + 3 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 Tutorials/seL4Kernel/get-the-tutorials.md diff --git a/Tutorials/seL4Kernel/get-the-tutorials.md b/Tutorials/seL4Kernel/get-the-tutorials.md new file mode 100644 index 0000000000..fe8c2e285c --- /dev/null +++ b/Tutorials/seL4Kernel/get-the-tutorials.md @@ -0,0 +1,32 @@ +--- +toc: true +layout: tutorial +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# Tutorials +## Python Dependencies +Additional python dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: +``` +pip install --user aenum +pip install --user pyelftools +``` +*Hint:* This step only needs to be done once, i.e. before doing your first tutorial + +## Get the code +All tutorials are in the sel4-tutorials-manifest. Get the code with: +``` +mkdir sel4-tutorials-manifest +cd sel4-tutorials-manifest +repo init -u https://github.com/seL4/sel4-tutorials-manifest +repo sync +``` + +`repo sync` may take a few moments to run + +*Hint:* The **Get the code** step only needs to be done once, i.e. before doing your first tutorial. + +

      + Next: Hello world +

      diff --git a/Tutorials/seL4Kernel/setting-up.md b/Tutorials/seL4Kernel/setting-up.md index b8a742c00e..bff2d66292 100644 --- a/Tutorials/seL4Kernel/setting-up.md +++ b/Tutorials/seL4Kernel/setting-up.md @@ -232,28 +232,6 @@ That's it! seL4 is running. To quit QEMU: `Ctrl+a, x` -# Tutorials -## Python Dependencies -Additional python dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: -``` -pip install --user aenum -pip install --user pyelftools -``` -*Hint:* This step only needs to be done once, i.e. before doing your first tutorial - -## Get the code -All tutorials are in the sel4-tutorials-manifest. Get the code with: -``` -mkdir sel4-tutorials-manifest -cd sel4-tutorials-manifest -repo init -u https://github.com/seL4/sel4-tutorials-manifest -repo sync -``` - -`repo sync` may take a few moments to run - -*Hint:* The **Get the code** step only needs to be done once, i.e. before doing your first tutorial. -

      - Next tutorial: Hello world + Next: Get the tutorials

      diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index 44841591c6..4f7eeae5cb 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -68,6 +68,7 @@
      • Overview
      • Setting up your machine
      • +
      • Getting the tutorials
      • Hello world
      • Capabilities
      • Untyped
      • From afc4010295ae1fb8758b83aff05e9e6d999e30fe Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 24 May 2024 11:11:55 +1000 Subject: [PATCH 038/103] fix fault handlers link Signed-off-by: Birgit Brecknell --- Tutorials/seL4Kernel/interrupts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tutorials/seL4Kernel/interrupts.md b/Tutorials/seL4Kernel/interrupts.md index a200651425..90412cab2c 100644 --- a/Tutorials/seL4Kernel/interrupts.md +++ b/Tutorials/seL4Kernel/interrupts.md @@ -11,4 +11,4 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. {% include tutorial.md %} -Next tutorial: Fault handling +Next tutorial: Fault handling From 8af55ad2b8a589e0e09e16ac4315db03661ebafb Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 24 May 2024 12:02:34 +1000 Subject: [PATCH 039/103] update mcs link in fault handlers tut Signed-off-by: Birgit Brecknell --- Tutorials/seL4Kernel/fault-handlers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tutorials/seL4Kernel/fault-handlers.md b/Tutorials/seL4Kernel/fault-handlers.md index b41cf80df9..2ac8f3a755 100644 --- a/Tutorials/seL4Kernel/fault-handlers.md +++ b/Tutorials/seL4Kernel/fault-handlers.md @@ -11,4 +11,4 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. {% include tutorial.md %} -Next tutorial: MCS +Next tutorial: MCS From 264bdc47fd833aee0a607f39034d0e0e31945f22 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 27 May 2024 13:23:25 +1000 Subject: [PATCH 040/103] add item to how-to page Signed-off-by: Birgit Brecknell --- Makefile | 3 ++- Tutorials/Resources/how-to.md | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 54866cef76..27d1d37fcb 100644 --- a/Makefile +++ b/Makefile @@ -127,6 +127,7 @@ _repos/tutes: all: /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-world/hello-world.md \ /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md \ /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/capabilities/capabilities.md \ + /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/untyped/untyped.md \ /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md \ /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/threads/threads.md \ /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/ipc/ipc.md \ @@ -158,7 +159,7 @@ all: /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/ _repos/tutes/%.md: _repos/sel4proj/sel4-tutorials/tutorials/% _repos/tutes PYTHONPATH=_repos/sel4/capdl/python-capdl-tool _repos/sel4proj/sel4-tutorials/template.py --docsite --out-dir _repos/tutes --tut-file $ Date: Mon, 27 May 2024 13:39:43 +1000 Subject: [PATCH 041/103] fix whitespace error Signed-off-by: Birgit Brecknell --- assets/js/toggle-markdown.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/assets/js/toggle-markdown.js b/assets/js/toggle-markdown.js index d55457deca..6aad9c11f5 100644 --- a/assets/js/toggle-markdown.js +++ b/assets/js/toggle-markdown.js @@ -9,8 +9,4 @@ if (result==true){ e.removeAttribute('open') : e.setAttribute('open',true); console.log(e.hasAttribute('open')) }) -} - - - - +} \ No newline at end of file From 43542f418593b78d4c8be0d26fe0fa7183656f56 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 27 May 2024 13:43:51 +1000 Subject: [PATCH 042/103] remove testing code from Makefile Signed-off-by: Birgit Brecknell --- Makefile | 108 ------------------------------------------------------- 1 file changed, 108 deletions(-) diff --git a/Makefile b/Makefile index 27d1d37fcb..b6451c2bd1 100644 --- a/Makefile +++ b/Makefile @@ -48,114 +48,6 @@ $(REPOSITORIES): _repos/tutes: mkdir -p $@ - - - - - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-world/hello-world.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-world/hello-world.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-world/hello-world.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-world/hello-world.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/capabilities/capabilities.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/capabilities/capabilities.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/capabilities/capabilities.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/capabilities/capabilities.md - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/untyped/untyped.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/untyped/untyped.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/untyped/untyped.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/untyped/untyped.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/mapping/mapping.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/mapping/mapping.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/threads/threads.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/threads/threads.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/threads/threads.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/threads/threads.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/ipc/ipc.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/ipc/ipc.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/ipc/ipc.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/ipc/ipc.md - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/notifications/notifications.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/notifications/notifications.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/notifications/notifications.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/notifications/notifications.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/interrupts/interrupts.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/interrupts/interrupts.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/interrupts/interrupts.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/interrupts/interrupts.md - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/fault-handlers/fault-handlers.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/fault-handlers/fault-handlers.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/fault-handlers/fault-handlers.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/fault-handlers/fault-handlers.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mcs/mcs.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/mcs/mcs.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/mcs/mcs.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mcs/mcs.md - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-1/dynamic-1.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-1/dynamic-1.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-1/dynamic-1.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-1/dynamic-1.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-2/dynamic-2.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-2/dynamic-2.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-2/dynamic-2.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-2/dynamic-2.md - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-3/dynamic-3.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-3/dynamic-3.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-3/dynamic-3.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-3/dynamic-3.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-4/dynamic-4.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-4/dynamic-4.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/dynamic-4/dynamic-4.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-4/dynamic-4.md - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-0/hello-camkes-0.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-0/hello-camkes-0.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-0/hello-camkes-0.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-0/hello-camkes-0.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-1/hello-camkes-1.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-1/hello-camkes-1.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-1/hello-camkes-1.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-1/hello-camkes-1.md - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-2/hello-camkes-2.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-2/hello-camkes-2.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-2/hello-camkes-2.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-2/hello-camkes-2.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md - - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md - -/Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md: /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md - cp /Users/birgitbrecknell/seL4-Foundation/tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md - - -all: /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-world/hello-world.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/capabilities/capabilities.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/untyped/untyped.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mapping/mapping.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/threads/threads.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/ipc/ipc.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/notifications/notifications.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/interrupts/interrupts.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/fault-handlers/fault-handlers.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/mcs/mcs.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-1/dynamic-1.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-2/dynamic-2.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-3/dynamic-3.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/dynamic-4/dynamic-4.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-0/hello-camkes-0.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-1/hello-camkes-1.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-2/hello-camkes-2.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/hello-camkes-timer/hello-camkes-timer.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-crossvm/camkes-vm-crossvm.md \ - /Users/birgitbrecknell/seL4-Foundation/docs/_repos/sel4proj/sel4-tutorials/tutorials/camkes-vm-linux/camkes-vm-linux.md - - - - - - - - - - - _repos/tutes/%.md: _repos/sel4proj/sel4-tutorials/tutorials/% _repos/tutes PYTHONPATH=_repos/sel4/capdl/python-capdl-tool _repos/sel4proj/sel4-tutorials/template.py --docsite --out-dir _repos/tutes --tut-file $ Date: Mon, 27 May 2024 13:50:14 +1000 Subject: [PATCH 043/103] add licence to toggle-markdown.js Signed-off-by: Birgit Brecknell --- assets/js/toggle-markdown.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/js/toggle-markdown.js b/assets/js/toggle-markdown.js index 6aad9c11f5..7e90f032d1 100644 --- a/assets/js/toggle-markdown.js +++ b/assets/js/toggle-markdown.js @@ -1,3 +1,6 @@ +// SPDX-License-Identifier: CC-BY-SA-4.0 +// Copyright 2024 seL4 Project a Series of LF Projects, LLC. + // Expand all solutions if previous link was how-to page let text = document.referrer; From ba70bbeb08f1393d338ab9ca6fc40a8a3b8a6e18 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 27 May 2024 14:03:32 +1000 Subject: [PATCH 044/103] remove old tutorial files Signed-off-by: Birgit Brecknell --- Tutorials-old/camkes-vm-crossvm.md | 11 -- Tutorials-old/camkes-vm-linux.md | 11 -- Tutorials-old/capabilities.md | 10 -- Tutorials-old/dynamic-1.md | 11 -- Tutorials-old/dynamic-2.md | 11 -- Tutorials-old/dynamic-3.md | 11 -- Tutorials-old/dynamic-4.md | 11 -- Tutorials-old/fault-handlers.md | 10 -- Tutorials-old/hello-camkes-0.md | 11 -- Tutorials-old/hello-camkes-1.md | 11 -- Tutorials-old/hello-camkes-2.md | 11 -- Tutorials-old/hello-camkes-timer.md | 11 -- Tutorials-old/hello-world.md | 10 -- Tutorials-old/index.md | 253 ---------------------------- Tutorials-old/interrupts.md | 11 -- Tutorials-old/ipc.md | 10 -- Tutorials-old/mapping.md | 10 -- Tutorials-old/mcs.md | 11 -- Tutorials-old/notifications.md | 11 -- Tutorials-old/threads.md | 10 -- Tutorials-old/untyped.md | 10 -- 21 files changed, 466 deletions(-) delete mode 100644 Tutorials-old/camkes-vm-crossvm.md delete mode 100644 Tutorials-old/camkes-vm-linux.md delete mode 100644 Tutorials-old/capabilities.md delete mode 100644 Tutorials-old/dynamic-1.md delete mode 100644 Tutorials-old/dynamic-2.md delete mode 100644 Tutorials-old/dynamic-3.md delete mode 100644 Tutorials-old/dynamic-4.md delete mode 100644 Tutorials-old/fault-handlers.md delete mode 100644 Tutorials-old/hello-camkes-0.md delete mode 100644 Tutorials-old/hello-camkes-1.md delete mode 100644 Tutorials-old/hello-camkes-2.md delete mode 100644 Tutorials-old/hello-camkes-timer.md delete mode 100644 Tutorials-old/hello-world.md delete mode 100644 Tutorials-old/index.md delete mode 100644 Tutorials-old/interrupts.md delete mode 100644 Tutorials-old/ipc.md delete mode 100644 Tutorials-old/mapping.md delete mode 100644 Tutorials-old/mcs.md delete mode 100644 Tutorials-old/notifications.md delete mode 100644 Tutorials-old/threads.md delete mode 100644 Tutorials-old/untyped.md diff --git a/Tutorials-old/camkes-vm-crossvm.md b/Tutorials-old/camkes-vm-crossvm.md deleted file mode 100644 index e6a5d8baf0..0000000000 --- a/Tutorials-old/camkes-vm-crossvm.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Camkes Cross-VM communication -tutorial: camkes-vm-crossvm -tutorial-order: vm-2 -description: walkthrough of adding communication between Linux guests in separate VMs. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/camkes-vm-linux.md b/Tutorials-old/camkes-vm-linux.md deleted file mode 100644 index 38225b7050..0000000000 --- a/Tutorials-old/camkes-vm-linux.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Camkes VM Linux -tutorial: camkes-vm-linux -tutorial-order: vm-1 -description: using Linux as a guest in the Camkes VM. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/capabilities.md b/Tutorials-old/capabilities.md deleted file mode 100644 index 657b851250..0000000000 --- a/Tutorials-old/capabilities.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -toc: true -title: Capabilities -tutorial: capabilities -tutorial-order: mechanisms-1 -description: an introduction to capabilities in the seL4 kernel API. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} diff --git a/Tutorials-old/dynamic-1.md b/Tutorials-old/dynamic-1.md deleted file mode 100644 index 091b71918f..0000000000 --- a/Tutorials-old/dynamic-1.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Dynamic Libraries 1 -tutorial: dynamic-1 -tutorial-order: dynamic-1 -description: system initialisation & threading with seL4_libs. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/dynamic-2.md b/Tutorials-old/dynamic-2.md deleted file mode 100644 index 0795b76fa9..0000000000 --- a/Tutorials-old/dynamic-2.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Dynamic Libraries 2 -tutorial: dynamic-2 -tutorial-order: dynamic-2 -description: IPC with seL4_libs. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/dynamic-3.md b/Tutorials-old/dynamic-3.md deleted file mode 100644 index 2c38d921a1..0000000000 --- a/Tutorials-old/dynamic-3.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Dynamic Libraries 3 -tutorial: dynamic-3 -tutorial-order: dynamic-3 -description: process management with seL4_libs. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/dynamic-4.md b/Tutorials-old/dynamic-4.md deleted file mode 100644 index e66a050f9f..0000000000 --- a/Tutorials-old/dynamic-4.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Dynamic Libraries 4 -tutorial: dynamic-4 -tutorial-order: dynamic-4 -description: timers and timeouts with seL4_libs. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/fault-handlers.md b/Tutorials-old/fault-handlers.md deleted file mode 100644 index 6ad6f1ad46..0000000000 --- a/Tutorials-old/fault-handlers.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -toc: true -title: Faults -tutorial: fault-handlers -tutorial-order: mechanisms-8 -description: fault (e.g virtual memory fault) handling and fault endpoints. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} diff --git a/Tutorials-old/hello-camkes-0.md b/Tutorials-old/hello-camkes-0.md deleted file mode 100644 index e2d52f9d88..0000000000 --- a/Tutorials-old/hello-camkes-0.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Camkes -tutorial: hello-camkes-0 -tutorial-order: camkes-0 -description: an introduction to Camkes concepts. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/hello-camkes-1.md b/Tutorials-old/hello-camkes-1.md deleted file mode 100644 index 2fbbf4786c..0000000000 --- a/Tutorials-old/hello-camkes-1.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Camkes 1 -tutorial: hello-camkes-1 -tutorial-order: camkes-1 -description: an introduction to Camkes concepts. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/hello-camkes-2.md b/Tutorials-old/hello-camkes-2.md deleted file mode 100644 index 4cf55e8411..0000000000 --- a/Tutorials-old/hello-camkes-2.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Camkes 2 -tutorial: hello-camkes-2 -tutorial-order: camkes-2 -description: an introduction to Camkes concepts. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/hello-camkes-timer.md b/Tutorials-old/hello-camkes-timer.md deleted file mode 100644 index bfd34499fc..0000000000 --- a/Tutorials-old/hello-camkes-timer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Camkes 3 -tutorial: hello-camkes-timer -tutorial-order: camkes-3 -description: introduce Camkes hardware components. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/hello-world.md b/Tutorials-old/hello-world.md deleted file mode 100644 index 1a8adf4dbc..0000000000 --- a/Tutorials-old/hello-world.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -toc: true -title: Hello, World! -tutorial: hello-world -tutorial-order: 0-hello -description: an introduction to seL4 projects and tutorials. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} diff --git a/Tutorials-old/index.md b/Tutorials-old/index.md deleted file mode 100644 index d8c2c60cf6..0000000000 --- a/Tutorials-old/index.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -toc: true -redirect_from: - - /projects/sel4-tutorials.html - - /projects/sel4-tutorials/ -layout: project -project: sel4-tutorials -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- - -# Tutorials - -{% assign tutorials = site.pages | where_exp: 'page', 'page.tutorial' | sort: 'tutorial-order' %} - -We have developed a series of tutorials to introduce seL4 and -developing systems on seL4. - -## How to use the tutorials - -Depending on your goals and what you want to do with seL4, we suggest -different paths to follow through the tutorial material. Choose the -most relevant category below and follow the tutorials in the suggested -order. - -Note that all of these tutorials require C programming -experience and some understanding of operating systems and computer -architecture. Suggested resources for these include: - -- C programming language - - [C tutorial](https://www.cprogramming.com/tutorial/c-tutorial.html) -- Operating Systems: - - [Modern Operating Systems (book)](https://www.amazon.com/Modern-Operating-Systems-Andrew-Tanenbaum/dp/013359162X) - - [COMP3231 at UNSW](http://www.cse.unsw.edu.au/~cs3231) -- Computer Architecture - - [Computer Architecture (wikipedia)](https://en.wikipedia.org/wiki/Computer_architecture) - - [Instruction Set Architecture (wikipedia)](https://en.wikipedia.org/wiki/Instruction_set_architecture) - -### Evaluation - -Goal: - -- You want to understand what seL4 is and what benefits it gives. -- You want to understand how seL4 can be used to develop trustworthy systems. -- You want to get your hands a little dirty and see, compile, and run some code. - -Follow these tutorials: - -1. [seL4 overview](https://sel4.systems/About/seL4-whitepaper.pdf) -2. [Introduction tutorial](#introduction-tutorial) - -### System Building - -Goal: - -- You want to build systems based on seL4. -- You want to know what tools are available to do so and how to use those tools. -- You want experience with how to use seL4 and the tools to build trustworthy systems. - -Follow these tutorials: - -1. [seL4 overview](https://sel4.systems/About/seL4-whitepaper.pdf) -2. [Introduction tutorial](#introduction-tutorial) -3. [CAmkES tutorials](#camkes-tutorials) -4. [Virtualisation tutorials](#virtual-machines) -5. [MCS tutorial](#mcs-extensions) - -### Platform Development - -Goal: - -- You want to contribute to development of the seL4 (user-level) platform. -- You want to develop operating system services and device drivers. -- You want to develop seL4-based frameworks and operating systems. - -Follow these tutorials: - -1. [seL4 overview](https://sel4.systems/About/seL4-whitepaper.pdf) -2. [Introduction tutorial](#introduction-tutorial) -3. [seL4 mechanisms tutorial](#seL4-mechanisms-tutorials) -4. [Rapid prototyping tutorials](#rapid-prototyping-tutorials) -5. [CAmkES tutorials](#camkes-tutorials) -6. [Virtualisation tutorial](#virtual-machines) -7. [MCS tutorial](#mcs-extensions) - - -### Kernel Development - -Goal: - -- You want to contribute to the seL4 kernel itself. -- You want to port seL4 to a new platform. -- You want to add new features to the kernel. - -Read this first: - -- [Contributing to kernel code](/projects/sel4/kernel-contribution.html) - -Then follow these tutorials: - -1. [seL4 overview](https://sel4.systems/About/seL4-whitepaper.pdf) -2. [Introduction tutorial](#introduction-tutorial) -3. [seL4 mechanisms tutorial](#seL4-mechanisms-tutorials) -4. [MCS tutorial](#mcs-extensions) - -# The Tutorials - -## Prerequisites - -* [set up your machine](/GettingStarted#setting-up-your-machine). - -### Python Dependencies -Additional python dependencies are required to build tutorials. To install you can run: -``` -pip install --user aenum -pip install --user pyelftools -``` - -### Get the code -``` -mkdir sel4-tutorials-manifest -cd sel4-tutorials-manifest -repo init -u https://github.com/seL4/sel4-tutorials-manifest -repo sync -``` - -### Doing the tutorials - -The top of the source tree contains the kernel itself, and the tutorials are found in the subfolder: "`projects/sel4-tutorials`". The tutorial consists of some pre-written sample applications which have been deliberately half-written. You will be guided through filling in the missing portions, and thereby become acquainted with seL4. For each of the sample applications however, there is a completed solution that shows all the correct answers, as a reference. -When completing the tutorials you will be initialising and building your solutions with CMake. The general flow of completing a tutorial exercise involves: -``` -# creating a Tutorial directory -mkdir tutorial -cd tutorial -# initialising the build directory with a tutorial exercise -../init --plat --tut -# building the tutorial exercise -ninja -``` - -After initialising your directory you will be setup with half-written source for you to complete. Additinally, a build -directory will be created based on your directory name eg `tutorial_build`. - -Your job is to follow the tutorial instructions to complete the application in the tutorial folder. - -- The completed sample applications showing the solutions to the - tutorial challenges can be retrieved by initialsing a directory with the `--solution` argument - e.g. `../init --plat --tut --solution` - -## List of tutorials - -### Introduction tutorial - -Before starting tutorials, make sure that you have read through the -[Prerequisites](#prerequisites) and in particular [Doing the -tutorials](#doing-the-tutorials). - -Then, before any other tutorial, do the hello-world tutorial: - -{%- for t in tutorials %} -{%- if t.tutorial-order contains '0-hello' %} -1. [{{t.title}}]({{t.url}}) {{t.description}} -{%- endif %} -{%- endfor %} - -which will ensure your setup is working correctly. - -### seL4 mechanisms tutorials - -This set of tutorials are for people keen to learn about the base mechanisms provided -by the seL4 kernel. You will learn about the kernel API through small exercises -that show basic examples. - -{% assign tutorials = site.pages | where_exp: 'page', 'page.tutorial' | sort: 'tutorial-order' %} -{%- for t in tutorials %} -{%- if t.tutorial-order contains 'mechanisms' %} -1. [{{t.title}}]({{t.url}}) {{t.description}} -{%- endif %} -{%- endfor %} - -### Rapid prototyping tutorials - -This set of tutorials provides walkthroughs and exercises for using the dynamic -libraries provided in [seL4_libs](TODO LINK). These libraries are provided as is, -and have been developed for rapidly prototyping systems on seL4. They have not been -through intensive quality assurance and do have bugs. Contributions are welcome. - -{%- for t in tutorials %} -{%- if t.tutorial-order contains 'dynamic' %} -1. [{{t.title}}]({{t.url}}) {{t.description}} -{%- endif %} -{%- endfor %} - -* The slide presentations to guide you through the tutorials are in the following files: - - - `projects/sel4-tutorials/docs/seL4-Overview.pdf`: This - is an overview of the design and thoughts behind seL4, and - we strongly recommend you read it before starting - the tutorials. - - `projects/sel4-tutorials/docs/seL4-APILib-details.pdf`: This is the actual tutorial. - -### CAmkES tutorials - -These tutorials get you started with our component system CAmkES, which -allows you to configure static systems through components. CAmkES -generates the glue code for interacting with seL4 and is designed for building -high-assurance, static systems. - -These tutorials work similarly to the SEL4 tutorials in that they are -guided by a slide presentation. There are half-completed sample -applications, with a set of slides giving instructions, with TASK -challenges once again. There are also completed sample solutions. - -{%- for t in tutorials %} -{%- if t.tutorial-order contains 'camkes' %} -1. [{{t.title}}]({{t.url}}) {{t.description}} -{%- endif %} -{%- endfor %} - -- The slide presentations to guide you through the tutorials are - in this - file: `projects/sel4-tutorials/docs/CAmkESTutorial.pdf`. - -### Virtual machines - -These tutorials show how to run Linux guests on Camkes and how to communicate between them. -Currently these tutorials are for x86 only. - -{%- for t in tutorials %} -{%- if t.tutorial-order contains 'vm' %} -1. [{{t.title}}]({{t.url}}) {{t.description}} -{%- endif %} -{%- endfor %} - -### MCS extensions - -The MCS extensions are upcoming API changes to seL4. - -{%- for t in tutorials %} -{%- if t.tutorial-order contains 'mcs' %} -1. [{{t.title}}]({{t.url}}) {{t.description}} -{%- endif %} -{%- endfor %} - -## What next? - -You can try building and running [seL4test](../seL4Test). - -Next steps include working on one of our [suggested -projects](/SuggestedProjects.html) or helping to expand the collection -of [libraries and -components](/projects/available-user-components.html) available to -build seL4-based systems. diff --git a/Tutorials-old/interrupts.md b/Tutorials-old/interrupts.md deleted file mode 100644 index ffeb05c281..0000000000 --- a/Tutorials-old/interrupts.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Interrupts -tutorial: interrupts -tutorial-order: mechanisms-7 -description: receiving and handling interrupts. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/ipc.md b/Tutorials-old/ipc.md deleted file mode 100644 index a7e313dc2c..0000000000 --- a/Tutorials-old/ipc.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -toc: true -title: IPC -tutorial: ipc -tutorial-order: mechanisms-5 -description: overview of interprocess communication (IPC). -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} diff --git a/Tutorials-old/mapping.md b/Tutorials-old/mapping.md deleted file mode 100644 index b3c5136bc7..0000000000 --- a/Tutorials-old/mapping.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -toc: true -title: Mapping -tutorial: mapping -tutorial-order: mechanisms-3 -description: virtual memory in seL4. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} diff --git a/Tutorials-old/mcs.md b/Tutorials-old/mcs.md deleted file mode 100644 index 64ba2f8382..0000000000 --- a/Tutorials-old/mcs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: MCS -tutorial: mcs -tutorial-order: mcs-1 -description: an introduction to the seL4 MCS extensions. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/notifications.md b/Tutorials-old/notifications.md deleted file mode 100644 index f4227272cd..0000000000 --- a/Tutorials-old/notifications.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -toc: true -title: Notifications -tutorial: notifications -tutorial-order: mechanisms-6 -description: using notification objects and signals. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - diff --git a/Tutorials-old/threads.md b/Tutorials-old/threads.md deleted file mode 100644 index 99cadd657c..0000000000 --- a/Tutorials-old/threads.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -toc: true -title: Threads -tutorial: threads -tutorial-order: mechanisms-4 -description: how to start a thread using the seL4 API. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} diff --git a/Tutorials-old/untyped.md b/Tutorials-old/untyped.md deleted file mode 100644 index 17c1ab3b48..0000000000 --- a/Tutorials-old/untyped.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -toc: true -title: Untyped -tutorial: untyped -tutorial-order: mechanisms-2 -description: user-level memory management. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} From d3ba4f855a498cce54c0ab2d1f28b44e10d9146a Mon Sep 17 00:00:00 2001 From: bbrcknl <32238793+bbrcknl@users.noreply.github.com> Date: Wed, 10 Jul 2024 12:46:04 +1000 Subject: [PATCH 045/103] Update Tutorials/seL4Kernel/setting-up.md Co-authored-by: Gerwin Klein Signed-off-by: bbrcknl <32238793+bbrcknl@users.noreply.github.com> --- Tutorials/seL4Kernel/setting-up.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tutorials/seL4Kernel/setting-up.md b/Tutorials/seL4Kernel/setting-up.md index bff2d66292..0cdbfca76a 100644 --- a/Tutorials/seL4Kernel/setting-up.md +++ b/Tutorials/seL4Kernel/setting-up.md @@ -187,7 +187,7 @@ This then allows you to run `container` from any directory. A good workflow is to run two terminals: - - Terminal A is just a normal terminal, and is used for git operations, editing (e.g., vim, emacs), and other normal operations. + - Terminal A is just a normal terminal, and is used for git operations, editing (e.g., vim, emacs, vscode), and other non-build operations. - Terminal B is running in a container, and is only used for compilation. This gives you the flexibility to use all the normal tools you are used to, while having the seL4 dependencies separated from your machine. From 0556ae4bf2f88473856a998f0706b88d90a3df4e Mon Sep 17 00:00:00 2001 From: bbrcknl <32238793+bbrcknl@users.noreply.github.com> Date: Wed, 10 Jul 2024 12:46:28 +1000 Subject: [PATCH 046/103] Update Tutorials/seL4Kernel/setting-up.md Co-authored-by: Gerwin Klein Signed-off-by: bbrcknl <32238793+bbrcknl@users.noreply.github.com> --- Tutorials/seL4Kernel/setting-up.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tutorials/seL4Kernel/setting-up.md b/Tutorials/seL4Kernel/setting-up.md index 0cdbfca76a..7c8b5a3a6c 100644 --- a/Tutorials/seL4Kernel/setting-up.md +++ b/Tutorials/seL4Kernel/setting-up.md @@ -180,7 +180,7 @@ echo $'alias container=\'make -C //home/jblogs/seL4-CAmkES-L4v-dockerfiles user This then allows you to run `container` from any directory. -*Reminder:* Restart Ubuntu or run a new terminal for the changes in `.bashrc` to take effect. +*Reminder:* start a new terminal for the changes in `.bashrc` to take effect or run `source ~/.bashrc`. ## An example workflow From d28d363f19b3b53b31f12770754fdea1c7a0c778 Mon Sep 17 00:00:00 2001 From: bbrcknl <32238793+bbrcknl@users.noreply.github.com> Date: Wed, 10 Jul 2024 12:46:56 +1000 Subject: [PATCH 047/103] Update Tutorials/seL4Kernel/setting-up.md Co-authored-by: Gerwin Klein Signed-off-by: bbrcknl <32238793+bbrcknl@users.noreply.github.com> --- Tutorials/seL4Kernel/setting-up.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tutorials/seL4Kernel/setting-up.md b/Tutorials/seL4Kernel/setting-up.md index 7c8b5a3a6c..4a281b7556 100644 --- a/Tutorials/seL4Kernel/setting-up.md +++ b/Tutorials/seL4Kernel/setting-up.md @@ -51,7 +51,7 @@ sudo usermod -aG docker $(whoami) ## Google's Repo tool -The primary way of obtaining and managing seL4 project source is through the use of Google's Repo tool. +The primary way of obtaining and managing seL4 project sources is through the use of Google's Repo tool. To install run: ```sh From 68c00ea5893404402807c44fe599f4e2d5334aae Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 12 Jul 2024 18:09:10 +1000 Subject: [PATCH 048/103] address Gerwin's high level comments (incomplete) Signed-off-by: Birgit Brecknell --- Tutorials/GettingStarted/about-seL4.md | 45 ----------- Tutorials/GettingStarted/microkit.md | 22 ----- Tutorials/GettingStarted/overview.md | 44 ++++++++++ Tutorials/GettingStarted/pathways.md | 80 +++++++++++++++++++ Tutorials/index.md | 28 +------ Tutorials/seL4Kernel/get-the-tutorials.md | 3 +- Tutorials/seL4Kernel/overview.md | 4 + _includes/custom-navbar.html | 7 +- _includes/header.html | 2 +- _includes/nav-sidebar.html | 6 +- .../_releases/sel4/10.1.1-mcs.md | 2 +- .../_releases/sel4/5.2.0-mcs.md | 6 +- .../_releases/sel4/9.0.0-mcs.md | 6 +- index.md | 2 +- projects/camkes/index.md | 2 +- 15 files changed, 150 insertions(+), 109 deletions(-) delete mode 100644 Tutorials/GettingStarted/about-seL4.md delete mode 100644 Tutorials/GettingStarted/microkit.md create mode 100644 Tutorials/GettingStarted/overview.md create mode 100644 Tutorials/GettingStarted/pathways.md diff --git a/Tutorials/GettingStarted/about-seL4.md b/Tutorials/GettingStarted/about-seL4.md deleted file mode 100644 index fbf9cebe65..0000000000 --- a/Tutorials/GettingStarted/about-seL4.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -toc: true -layout: overview -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. ---- -

        About seL4

        - -

        - seL4 is a third-generation microkernel. It is broadly based on L4 and influenced by EROS. Like L4 it features abstractions for virtual address spaces, threads, IPC, and, unlike most earlier L4 kernels, an explicit in-kernel memory management model and capabilities for authorisation. -

        -

        - Authority in seL4 is conferred by possession of a capability. Capabilities are segregated and stored in capability address spaces composed of capability container objects called CNodes. seL4 has six system calls, of which five require possession of a capability (the sixth is a yield to the scheduler). The five system calls are IPC primitives that are used either to invoke services implemented by other processes (using capabilities to port-like endpoints that facilitate message passing), or invoke kernel services (using capabilities to kernel objects, such as a thread control block (TCB)). While the number of system calls is small, the kernel’s effective API is the sum of all the interfaces presented by all kernel object types. -

        -

        - Kernel memory management in seL4 is explicit. All kernel data structures are either statically allocated at boot time, or are dynamically-allocated first-class objects in the API. Kernel objects thus act as both inkernel data structures, and user-invoked fine-grained kernel services. Kernel objects include TCBs, CNodes, and level-1 and level-2 page tables (termed PageDirectories and PageTables). -

        -

        - Authority over free memory is encapsulated in an untyped memory object. Creating new kernel objects explicitly involves invoking the retype method of an untyped -memory object, which allocates the memory for the object, initialises it, and returns a capability to the new object. -

        -

        - Virtual address spaces are formed by explicit manipulation of virtual-memory related kernel objects: PageDirectories, PageTables, ASIDPools and Frames (mappable physical memory). As such, address spaces have no kernel-defined structure (except for a protected region reserved for the seL4 kernel itself). Whether the userlevel system is Exokernel like, a multi-server, or a para-virtualised monolithic OS is determined by user-level via a map and unmap interface to Frames and PageTables. The distribution of authority to the kernel virtual memory (VM) objects ultimately determines the scope of influence over virtual and physical memory. -

        -

        - Threads are the active entity in seL4. By associating a CNode and a virtual address space with a thread, user-level policies create high-level abstractions, such as processes or virtual machines. -

        -

        - IPC is supported in two forms: synchronous message passing via endpoints (portlike destinations without in-kernel buffering), and asynchronous notification via asynchronous endpoints (rendezvous objects consisting of a single in-kernel word that is used to combine IPC sends using a logical or). Remote procedure call semantics are facilitated over synchronous IPC via reply capabilities. Send capabilities are minted from an initial endpoint capability. Send capabilities feature an immutable badge which is used by the specific endpoint’s IPC recipients to distinguish which send capability (and thus which authority) was used to send a message. The unforgeable badge, represented by an integer value, is delivered with the message. -

        -

        - Exceptions are propagated via synchronous IPC to each thread’s exception handler (registered in the TCB via a capability to an endpoint). Similarly, page faults are also propagated using synchronous IPC to a thread’s page fault handler. Non-native system calls are treated as exceptions to support virtualisation. -

        -

        - Device Drivers run as user-mode applications that have access to device registers and memory, either by mapping the device into the virtual address space, or by controlled access to device ports on x86 hardware. seL4 provides a mechanism to receive notification of interrupts (via asynchronous IPC) and acknowledge their receipt. -

        -

        - The seL4 kernel runs on multiple platforms, and runs on common architectures like ARM and RiscV. -

        -

        - Because sel4 is small, a lot more needs to be done in user space and there are a lot more choices about how to do that. We'll start by building a simple system using the seL4 Microkit, which is a software development kit for building static systems on seL4. -

        -

        - Next: Get started with the seL4 microkit tutorial -

        \ No newline at end of file diff --git a/Tutorials/GettingStarted/microkit.md b/Tutorials/GettingStarted/microkit.md deleted file mode 100644 index 1bf5969301..0000000000 --- a/Tutorials/GettingStarted/microkit.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -toc: true -layout: overview -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. ---- -

        Using the seL4 Microkit tutorial to get started with seL4

        -

        - The seL4 Microkit is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4, while still leveraging the kernel’s benefits of security and performance. -

        -

        - The Microkit is distributed as an SDK that integrates with the build system of your choice, significantly reducing the barrier to entry for new users of seL4. We recommend it as the first tutorial, to familiarise new users with seL4 concepts. -

        -

        - After completing the Microkit tutorial, go to seL4 kernel tutorials for a deep dive into seL4 concepts. -

        -

        - Go to the Microkit tutorial -

        -

        - Next tutorial: seL4 kernel tutorials -

        \ No newline at end of file diff --git a/Tutorials/GettingStarted/overview.md b/Tutorials/GettingStarted/overview.md new file mode 100644 index 0000000000..5e13aee069 --- /dev/null +++ b/Tutorials/GettingStarted/overview.md @@ -0,0 +1,44 @@ +--- +toc: true +title: Overview +layout: tutorial +redirect_from: + - /tutorials/ +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- +# Overview + +We have developed a series of tutorials to introduce seL4 and developing systems on seL4. + +## List of tutorials +The tutorials are split into a number of broad categories, and have been designed around developer needs. + +- The [seL4 tutorials](seL4/overview.md) are for people keen to learn about the base mechanisms provided by the seL4 kernel. The kernel API is explained with short exercises that show basic examples. + +- [MCS](MCS/mcs) introduces seL4 MCS extensions, which are detailed in this [paper](https://trustworthy.systems/publications/full_text/Lyons_MAH_18.pdf) and [PhD](https://github.com/pingerino/phd/blob/master/phd.pdf). + +- [Dynamic Libraries](DynamicLibraries/dynamic-1) provides walkthroughs and exercises for using the dynamic libraries provided in `seL4_libs`, which were developed for rapidly prototyping systems on seL4. + +- [CAmkES](CAmkES/hello-camkes-0) generates the glue code for interacting with seL4 and is designed for building high-assurance, static systems. These tutorials demonstrate how to configure static systems through components. + +- [Microkit](https://trustworthy.systems/projects/microkit/tutorial/) enables system designers to create static software systems based on the seL4 microkernel. We recommend this as a potential introduction to seL4, bearing in mind that the Microkit hides many of the seL4 mechanisms - it is designed that way, to make building on top of seL4 easier. + +- [Rust](https://github.com/seL4/rust-sel4) allows people to write safer user-level code on top of seL4 without needing full formal verification, with a language that is receiving increasing interest and that aligns extremely well with security and safety critical embedded systems programming. + +## Resources +Additional resources to assist with learning: +- The [seL4 manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf) +- [API references](projects/sel4/api-doc) +- The [How to](Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. +- The [seL4 white paper](https://sel4.systems/About/seL4-whitepaper.pdf) +- [FAQs](projects/sel4/frequently-asked-questions) +- [Debugging guide](projects/sel4-tutorials/debugging-guide) +- [Discourse forum](https://sel4.discourse.group/) +- [Developer mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) +- [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/channels/web-doc-revamp) + + +

        + Next: Pathways through the tutorials +

        \ No newline at end of file diff --git a/Tutorials/GettingStarted/pathways.md b/Tutorials/GettingStarted/pathways.md new file mode 100644 index 0000000000..6c7a55665d --- /dev/null +++ b/Tutorials/GettingStarted/pathways.md @@ -0,0 +1,80 @@ +--- +toc: true +title: Tutorial pathways +layout: tutorial +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# Pathways through tutorials +The tutorials can be approached in a number of different ways. Our recommended approach for newcomers is to begin the [Microkit](https://trustworthy.systems/projects/microkit/tutorial/), bearing in mind that the Microkit hides many of the seL4 mechanisms - it is designed that way, to make building on top of seL4 easier. Having built a small system on top of seL4, the developer can delve into the concepts in the order list in the navigation bar to the left. + +## Alternate pathways +Alternate pathways through the tutorials depend on development goals. + +### Evaluation +Goals: +- to understand seL4 and its benefits +- to learn how to use seL4 to develop trustworthy systems +- to see, compile, and run some code + +Recommended tutorials +- [Setting up your machine](../seL4Kernel/setting-up) +- [Getting the tutorials](../seL4Kernel/get-the-tutorials.md) +- [Hello world](../seL4Kernel/hello-world.md) + +### System Building +Goals: +- to build systems based on seL4 +- to know which tools are available to build systems, and how to use those tools +- to build trustworthy systems +- +Follow these tutorials: +Recommended tutorials +- [Setting up your machine](../seL4Kernel/setting-up) +- [Getting the tutorials](../seL4Kernel/get-the-tutorials.md) +- [Hello world](../seL4Kernel/hello-world.md) + +**up to here** + +seL4 overview +Introduction tutorial +CAmkES tutorials +Virtualisation tutorials +MCS tutorial + +Platform Development +Goal: + +You want to contribute to development of the seL4 (user-level) platform. +You want to develop operating system services and device drivers. +You want to develop seL4-based frameworks and operating systems. +Follow these tutorials: + +seL4 overview +Introduction tutorial +seL4 mechanisms tutorial +Rapid prototyping tutorials +CAmkES tutorials +Virtualisation tutorial +MCS tutorial +Kernel Development +Goal: + +You want to contribute to the seL4 kernel itself. +You want to port seL4 to a new platform. +You want to add new features to the kernel. +Read this first: + +Contributing to kernel code +Then follow these tutorials: + +seL4 overview +Introduction tutorial +seL4 mechanisms tutorial +MCS tutorial + + +

        + Next tutorial: seL4 kernel tutorials +

        \ No newline at end of file diff --git a/Tutorials/index.md b/Tutorials/index.md index 15fb25580f..def57a79e0 100644 --- a/Tutorials/index.md +++ b/Tutorials/index.md @@ -1,32 +1,6 @@ --- toc: true -layout: overview +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- -# Tutorials about seL4 - -We have developed a series of tutorials to introduce seL4 and -developing systems on seL4. - -

        Categories

        -The tutorials are split into a number of broad categories: - -- [About seL4](GettingStarted/about-seL4) and [Getting started with the Microkit tutorial](GettingStarted/microkit) introduce seL4 concepts. -- The [seL4 Kernel tutorials](seL4Kernel/overview.md) are a deep dive into seL4 concepts. -- [MCS](MCS/mcs) introduces seL4 MCS extensions. -- [Dynamic Libraries](DynamicLibraries/dynamic-1) covers the libraries that have been developed for rapidly prototyping systems on seL4. -- [CAmkES](CAmkES/hello-camkes-0) is a platform for building componentised systems for embedded platforms. -- [Microkit](https://trustworthy.systems/projects/microkit/tutorial/)is an operating system framework on top of seL4 provides a small set of simple abstractions that ease the design and implementation of statically structured systems on seL4. (Links to the same tutorial as in the [Getting Started](GettingStarted/microkit) section.) -- [Rust](https://github.com/seL4/rust-sel4) provide crates for supporting the use of Rust in seL4 userspace. - -

        Resources

        -Additional resources to assist with learning: -- The [seL4 manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf) -- [API references](projects/sel4/api-doc) -- The [How to](Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. -- [FAQs](projects/sel4/frequently-asked-questions) -- [Debugging guide](projects/sel4-tutorials/debugging-guide) -- [Discourse forum](https://sel4.discourse.group/) -- [Developer mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) -- [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/channels/web-doc-revamp) diff --git a/Tutorials/seL4Kernel/get-the-tutorials.md b/Tutorials/seL4Kernel/get-the-tutorials.md index fe8c2e285c..ea9d6a079d 100644 --- a/Tutorials/seL4Kernel/get-the-tutorials.md +++ b/Tutorials/seL4Kernel/get-the-tutorials.md @@ -1,11 +1,12 @@ --- toc: true +title: Getting the tutorials layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- -# Tutorials +# Getting the tutorials ## Python Dependencies Additional python dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: ``` diff --git a/Tutorials/seL4Kernel/overview.md b/Tutorials/seL4Kernel/overview.md index e1c9794ed0..b6167a9044 100644 --- a/Tutorials/seL4Kernel/overview.md +++ b/Tutorials/seL4Kernel/overview.md @@ -8,6 +8,10 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC.

        Overview

        We have developed a series of tutorials to on seL4 concepts. These assume a basic understanding of seL4, e.g. by having done the Microkit tutorial. +Recommended reading: +- the [seL4 white paper](https://sel4.systems/About/seL4-whitepaper.pdf) + +

        Prerequisites

        Note that all of these tutorials require C programming experience and some understanding of operating systems and computer diff --git a/_includes/custom-navbar.html b/_includes/custom-navbar.html index d5966f0441..d18399d89f 100644 --- a/_includes/custom-navbar.html +++ b/_includes/custom-navbar.html @@ -18,7 +18,12 @@ diff --git a/_includes/header.html b/_includes/header.html index be14b39a87..277700d72d 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -19,7 +19,7 @@

        Working with seL4

        Contributing

        Projects

        -

        Tutorials

        +

        Tutorials

        diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index 4f7eeae5cb..07fc6ebc0e 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -54,15 +54,15 @@
      {% endif %} -{% if page_url[1] == "Tutorials" %} +{% if page_url[1] == "tutorials" %} {% if page_url[2] contains "" %} {% assign url = "../" %} {% endif %}
    -

    Tutorials

    +

    Tutorials

    Tutorials and other material to learn about seL4.

    diff --git a/projects/camkes/index.md b/projects/camkes/index.md index fafa35d7eb..bca6f3e158 100644 --- a/projects/camkes/index.md +++ b/projects/camkes/index.md @@ -58,7 +58,7 @@ ninja To learn about developing your own CAmkES application, read the -[Tutorials#CAmkES_tutorials](/Tutorials#camkes-tutorials). +[Tutorials#CAmkES_tutorials](/tutorials#camkes-tutorials). ## Camkes Terminology/Glossary From 28d8d6dcad73ab718042b535bc75586bfa5389a5 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 12 Jul 2024 18:29:17 +1000 Subject: [PATCH 049/103] work (incomplete) on tutorial pathways Signed-off-by: Birgit Brecknell --- Tutorials/GettingStarted/pathways.md | 36 +++++++++++++++------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/Tutorials/GettingStarted/pathways.md b/Tutorials/GettingStarted/pathways.md index 6c7a55665d..9fd8ae416a 100644 --- a/Tutorials/GettingStarted/pathways.md +++ b/Tutorials/GettingStarted/pathways.md @@ -28,36 +28,38 @@ Goals: - to build systems based on seL4 - to know which tools are available to build systems, and how to use those tools - to build trustworthy systems -- -Follow these tutorials: -Recommended tutorials + +Recommended tutorials: - [Setting up your machine](../seL4Kernel/setting-up) - [Getting the tutorials](../seL4Kernel/get-the-tutorials.md) - [Hello world](../seL4Kernel/hello-world.md) +- [MCS](../MCS/mcs.md) +- The CAmkES tutorials beginning with [Hello CAmkES](../CAmkES/hello-camkes-0.md) +- Virtualisation tutorials + - [CAmkES VM](../CAmkES/camkes-vm-linux) using Linux as a guest in the CAmkES VM; and + - [CAmkES Cross-VM communication](../CAmkES/camkes-vm-crossvm.md) walkthrough of adding communication between Linux guests in separate VMs -**up to here** -seL4 overview -Introduction tutorial -CAmkES tutorials -Virtualisation tutorials -MCS tutorial +### Platform Development +Goals: +- to contribute to development of the seL4 (user-level) platform +- to develop operating system services and device drivers +- to develop seL4-based frameworks and operating systems -Platform Development -Goal: +Recommended tutorials: +- [Setting up your machine](../seL4Kernel/setting-up) +- [Getting the tutorials](../seL4Kernel/get-the-tutorials.md) +- [Hello world](../seL4Kernel/hello-world.md) +- [M] +**up to here** -You want to contribute to development of the seL4 (user-level) platform. -You want to develop operating system services and device drivers. -You want to develop seL4-based frameworks and operating systems. -Follow these tutorials: -seL4 overview -Introduction tutorial seL4 mechanisms tutorial Rapid prototyping tutorials CAmkES tutorials Virtualisation tutorial MCS tutorial + Kernel Development Goal: From 51ad64164456158809bd646f5a564b05ffa1689b Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 15 Jul 2024 08:27:58 +1000 Subject: [PATCH 050/103] finish adding tutorial pathways Signed-off-by: Birgit Brecknell --- Working-with-seL4.md => Resources.md | 2 +- Tutorials/GettingStarted/pathways.md | 59 +++---- Tutorials/seL4/capabilities.md | 15 ++ Tutorials/seL4/fault-handlers.md | 14 ++ Tutorials/seL4/get-the-tutorials.md | 33 ++++ Tutorials/seL4/hello-world.md | 15 ++ Tutorials/seL4/interrupts.md | 14 ++ Tutorials/seL4/ipc.md | 14 ++ Tutorials/seL4/mapping.md | 14 ++ Tutorials/seL4/notifications.md | 14 ++ Tutorials/seL4/overview.md | 38 +++++ Tutorials/seL4/setting-up.md | 237 +++++++++++++++++++++++++++ Tutorials/seL4/threads.md | 14 ++ Tutorials/seL4/untyped.md | 14 ++ 14 files changed, 459 insertions(+), 38 deletions(-) rename Working-with-seL4.md => Resources.md (99%) create mode 100644 Tutorials/seL4/capabilities.md create mode 100644 Tutorials/seL4/fault-handlers.md create mode 100644 Tutorials/seL4/get-the-tutorials.md create mode 100644 Tutorials/seL4/hello-world.md create mode 100644 Tutorials/seL4/interrupts.md create mode 100644 Tutorials/seL4/ipc.md create mode 100644 Tutorials/seL4/mapping.md create mode 100644 Tutorials/seL4/notifications.md create mode 100644 Tutorials/seL4/overview.md create mode 100644 Tutorials/seL4/setting-up.md create mode 100644 Tutorials/seL4/threads.md create mode 100644 Tutorials/seL4/untyped.md diff --git a/Working-with-seL4.md b/Resources.md similarity index 99% rename from Working-with-seL4.md rename to Resources.md index e1ba843ba2..41ad57df01 100644 --- a/Working-with-seL4.md +++ b/Resources.md @@ -5,7 +5,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -# Working with seL4 +# Resources This page provides an overview on working with seL4 and its ecosystem. diff --git a/Tutorials/GettingStarted/pathways.md b/Tutorials/GettingStarted/pathways.md index 9fd8ae416a..6f6eabd5cf 100644 --- a/Tutorials/GettingStarted/pathways.md +++ b/Tutorials/GettingStarted/pathways.md @@ -13,26 +13,26 @@ The tutorials can be approached in a number of different ways. Our recommended a Alternate pathways through the tutorials depend on development goals. ### Evaluation -Goals: +Goals - to understand seL4 and its benefits - to learn how to use seL4 to develop trustworthy systems - to see, compile, and run some code Recommended tutorials -- [Setting up your machine](../seL4Kernel/setting-up) -- [Getting the tutorials](../seL4Kernel/get-the-tutorials.md) -- [Hello world](../seL4Kernel/hello-world.md) +- [Setting up your machine](../seL4/setting-up) +- [Getting the tutorials](../seL4/get-the-tutorials.md) +- [Hello world](../seL4/hello-world.md) ### System Building -Goals: +Goals - to build systems based on seL4 - to know which tools are available to build systems, and how to use those tools - to build trustworthy systems -Recommended tutorials: -- [Setting up your machine](../seL4Kernel/setting-up) -- [Getting the tutorials](../seL4Kernel/get-the-tutorials.md) -- [Hello world](../seL4Kernel/hello-world.md) +Recommended tutorials +- [Setting up your machine](../seL4/setting-up) +- [Getting the tutorials](../seL4/get-the-tutorials.md) +- [Hello world](../seL4/hello-world.md) - [MCS](../MCS/mcs.md) - The CAmkES tutorials beginning with [Hello CAmkES](../CAmkES/hello-camkes-0.md) - Virtualisation tutorials @@ -41,42 +41,27 @@ Recommended tutorials: ### Platform Development -Goals: +Goals - to contribute to development of the seL4 (user-level) platform - to develop operating system services and device drivers - to develop seL4-based frameworks and operating systems -Recommended tutorials: -- [Setting up your machine](../seL4Kernel/setting-up) -- [Getting the tutorials](../seL4Kernel/get-the-tutorials.md) -- [Hello world](../seL4Kernel/hello-world.md) -- [M] -**up to here** - - -seL4 mechanisms tutorial -Rapid prototyping tutorials -CAmkES tutorials -Virtualisation tutorial -MCS tutorial - -Kernel Development -Goal: +Recommended tutorials +To gain a comprehensive understanding of seL4, we recommend that you go through all the tutorials in the order listed in the default pathway. -You want to contribute to the seL4 kernel itself. -You want to port seL4 to a new platform. -You want to add new features to the kernel. -Read this first: -Contributing to kernel code -Then follow these tutorials: +### Kernel Development +Goals +- to contribute to the seL4 kernel itself +- to port seL4 to a new platform +- to add new features to the kernel -seL4 overview -Introduction tutorial -seL4 mechanisms tutorial -MCS tutorial +Recommended reading +- [Contributing to kernel code](../../projects/sel4/kernel-contribution) +Recommended tutorials +- Follow the tutorial in the default pathway up to and including MCS.

    - Next tutorial: seL4 kernel tutorials + Next tutorial: seL4 tutorials

    \ No newline at end of file diff --git a/Tutorials/seL4/capabilities.md b/Tutorials/seL4/capabilities.md new file mode 100644 index 0000000000..df7f392372 --- /dev/null +++ b/Tutorials/seL4/capabilities.md @@ -0,0 +1,15 @@ +--- +toc: true +title: Capabilities +tutorial: capabilities +tutorial-order: mechanisms-1 +description: an introduction to capabilities in the seL4 kernel API. +layout: tutorial +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +{% include tutorial.md %} + + +Next tutorial: Untyped diff --git a/Tutorials/seL4/fault-handlers.md b/Tutorials/seL4/fault-handlers.md new file mode 100644 index 0000000000..2ac8f3a755 --- /dev/null +++ b/Tutorials/seL4/fault-handlers.md @@ -0,0 +1,14 @@ +--- +toc: true +title: Faults +tutorial: fault-handlers +tutorial-order: mechanisms-8 +layout: tutorial +description: fault (e.g virtual memory fault) handling and fault endpoints. +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. +--- +{% include tutorial.md %} + + +Next tutorial: MCS diff --git a/Tutorials/seL4/get-the-tutorials.md b/Tutorials/seL4/get-the-tutorials.md new file mode 100644 index 0000000000..ea9d6a079d --- /dev/null +++ b/Tutorials/seL4/get-the-tutorials.md @@ -0,0 +1,33 @@ +--- +toc: true +title: Getting the tutorials +layout: tutorial +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# Getting the tutorials +## Python Dependencies +Additional python dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: +``` +pip install --user aenum +pip install --user pyelftools +``` +*Hint:* This step only needs to be done once, i.e. before doing your first tutorial + +## Get the code +All tutorials are in the sel4-tutorials-manifest. Get the code with: +``` +mkdir sel4-tutorials-manifest +cd sel4-tutorials-manifest +repo init -u https://github.com/seL4/sel4-tutorials-manifest +repo sync +``` + +`repo sync` may take a few moments to run + +*Hint:* The **Get the code** step only needs to be done once, i.e. before doing your first tutorial. + +

    + Next: Hello world +

    diff --git a/Tutorials/seL4/hello-world.md b/Tutorials/seL4/hello-world.md new file mode 100644 index 0000000000..0b16f833a1 --- /dev/null +++ b/Tutorials/seL4/hello-world.md @@ -0,0 +1,15 @@ +--- +toc: true +title: Hello, World! +tutorial: hello-world +tutorial-order: 0-hello +description: an introduction to seL4 projects and tutorials. +layout: tutorial +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +{% include tutorial.md %} + + +Next tutorial: Capabilities \ No newline at end of file diff --git a/Tutorials/seL4/interrupts.md b/Tutorials/seL4/interrupts.md new file mode 100644 index 0000000000..90412cab2c --- /dev/null +++ b/Tutorials/seL4/interrupts.md @@ -0,0 +1,14 @@ +--- +toc: true +title: Interrupts +tutorial: interrupts +tutorial-order: mechanisms-7 +layout: tutorial +description: receiving and handling interrupts. +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. +--- +{% include tutorial.md %} + + +Next tutorial: Fault handling diff --git a/Tutorials/seL4/ipc.md b/Tutorials/seL4/ipc.md new file mode 100644 index 0000000000..026e22585c --- /dev/null +++ b/Tutorials/seL4/ipc.md @@ -0,0 +1,14 @@ +--- +toc: true +title: IPC +tutorial: ipc +tutorial-order: mechanisms-5 +layout: tutorial +description: overview of interprocess communication (IPC). +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. +--- +{% include tutorial.md %} + + +Next tutorial: Notifications diff --git a/Tutorials/seL4/mapping.md b/Tutorials/seL4/mapping.md new file mode 100644 index 0000000000..ee63720c14 --- /dev/null +++ b/Tutorials/seL4/mapping.md @@ -0,0 +1,14 @@ +--- +toc: true +title: Mapping +tutorial: mapping +tutorial-order: mechanisms-3 +description: virtual memory in seL4. +layout: tutorial +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. +--- +{% include tutorial.md %} + + +Next tutorial: Threads diff --git a/Tutorials/seL4/notifications.md b/Tutorials/seL4/notifications.md new file mode 100644 index 0000000000..ab2fd58b57 --- /dev/null +++ b/Tutorials/seL4/notifications.md @@ -0,0 +1,14 @@ +--- +toc: true +title: Notifications +tutorial: notifications +tutorial-order: mechanisms-6 +layout: tutorial +description: using notification objects and signals. +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. +--- +{% include tutorial.md %} + + +Next tutorial: Interrupts diff --git a/Tutorials/seL4/overview.md b/Tutorials/seL4/overview.md new file mode 100644 index 0000000000..a732f87862 --- /dev/null +++ b/Tutorials/seL4/overview.md @@ -0,0 +1,38 @@ +--- +toc: true +layout: tutorial +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# Overview +The [seL4 tutorials](seL4/overview.md) are for people keen to learn about the base mechanisms provided by the seL4 kernel. The kernel API is explained with short exercises that show basic examples. +We have developed a series of tutorials to on seL4 concepts. + +Recommended reading: +- the [seL4 white paper](https://sel4.systems/About/seL4-whitepaper.pdf) + + +

    Recommended reading

    +Note that all of these tutorials require C programming +experience and some understanding of operating systems and computer +architecture. Suggested resources for these include: + +- C programming language + - [C tutorial](https://www.cprogramming.com/tutorial/c-tutorial.html) +- Operating Systems: + - [Modern Operating Systems (book)](https://www.amazon.com/Modern-Operating-Systems-Andrew-Tanenbaum/dp/013359162X) + - [COMP3231 at UNSW](http://www.cse.unsw.edu.au/~cs3231) +- Computer Architecture + - [Computer Architecture (wikipedia)](https://en.wikipedia.org/wiki/Computer_architecture) + - [Instruction Set Architecture (wikipedia)](https://en.wikipedia.org/wiki/Instruction_set_architecture) + +

    Resources

    +We recommend having access to the seL4 manual and the API references. + +The How to page provides links to tutorial solutions as quick references for seL4 calls and methods. + + +

    + Next tutorial: Setting up your machine +

    \ No newline at end of file diff --git a/Tutorials/seL4/setting-up.md b/Tutorials/seL4/setting-up.md new file mode 100644 index 0000000000..4a281b7556 --- /dev/null +++ b/Tutorials/seL4/setting-up.md @@ -0,0 +1,237 @@ +--- +toc: true +layout: tutorial +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +--- + +# Setting up your machine +**Overview** +- Set up your machine - install dependencies required to run seL4`` +- Run seL4test on a simulator +- Gain awareness of terminology used for seL4 + + + +## Docker +To compile and use seL4, it is recommended that you use Docker to isolate the dependencies from your machine. + +These instructions assume you are using Debian (or a derivative, such as Ubuntu), and are using Bash for your shell. However, it should be informative enough for users of other distros/shells to adapt. + +These instructions are intended for Ubuntu LTS versions 20.04 and 22.04. + +To begin, you will need at least these two programs: + + * make (`sudo apt install make`) + * docker (See [here](https://get.docker.com) or [here](https://docs.docker.com/engine/installation) for installation instructions) + +For convenience, add your account to the docker group: + +```bash +sudo usermod -aG docker $(whoami) +``` + +
    + More on Docker +
    + + **Available images** + + All the prebuilt docker images are available on [DockerHub here](https://hub.docker.com/u/trustworthysystems) + + These images are used by the Trustworthy Systems Continuous Integration (CI) software, and so represent a standard software setup we use. + The CI software always uses the `latest` docker image, but images are also tagged with the date they were built. + + **More information** + + You can find the dockerfiles and supporting Makefile [here](https://github.com/seL4/seL4-CAmkES-L4v-dockerfiles) + +
    + + +## Google's Repo tool + +The primary way of obtaining and managing seL4 project sources is through the use of Google's Repo tool. + +To install run: +```sh + sudo apt-get update + sudo apt-get install repo +``` + +
    +More on Repo +
    +[More details about on installing Repo](https://source.android.com/setup/develop#installing-repo). + +[seL4 Repo cheatsheet](../projects/buildsystem/repo-cheatsheet) +
    + + +## Base build dependencies +To establish a usable development environment it is important to install your distributions basic build packages. + +### Base dependencies + +The basic build package on Ubuntu is the `build-essential` package. To install run: + +```sh +sudo apt-get update +sudo apt-get install build-essential +``` + +Additional base dependencies for building seL4 projects on Ubuntu include installing: + +```sh +sudo apt-get install cmake ccache ninja-build cmake-curses-gui +sudo apt-get install libxml2-utils ncurses-dev +sudo apt-get install curl git doxygen device-tree-compiler +sudo apt-get install u-boot-tools +sudo apt-get install python3-dev python3-pip python-is-python3 +sudo apt-get install protobuf-compiler python3-protobuf +``` + +### Simulating with QEMU + +To run seL4 projects on a simulator you will need QEMU. QEMU is a generic and open source machine emulator and virtualizer, and can emulate different architectures on different systems. + + +```sh +sudo apt-get install qemu-system-arm qemu-system-x86 qemu-system-misc +``` + +### Cross-compiling for ARM targets + +To build for ARM targets you will need a cross compiler: + +```sh +sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi +sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu +``` + +(you can install the hardware floating point versions as well if you wish) + +```sh +sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf +``` + +### Cross-compiling for RISC-V targets + +To build for RISC-V targets you will need a cross compiler: + +{% include risc-v.md %} + + +
    +More on host dependencies +
    +[A detailed guide on host dependencies](../projects/buildsystem/host-dependencies) +
    + + +## Python Dependencies + +Regardless of your Linux distribution, python dependencies are required to build seL4, the manual and its proofs. To install you can run: + +```sh +pip3 install --user setuptools +pip3 install --user sel4-deps +``` + +(Some distributions use `pip` for python3, others use `pip3`. Use the Python 3 version for your distribution.) + + +## Getting a build environment +To get a running build environment for seL4 and Camkes, run: + +```bash +git clone https://github.com/seL4/seL4-CAmkES-L4v-dockerfiles.git +cd seL4-CAmkES-L4v-dockerfiles +make user +``` + +This will give you a terminal inside a container that has all the relevant tools to build, simulate, and test seL4 & Camkes programs. + +The first time you run this, docker will fetch the relevant images, which may take a while. + +The last line will say something like: + +``` +Hello, welcome to the seL4/CAmkES/L4v docker build environment +``` + +## Mapping a container +To run the container from other directories (e.g. starting a container for the [Hello World](hello-world) tutorial, which we'll do next), you can setup a bash alias such as this: + +```bash +echo $'alias container=\'make -C ///seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc +# now open a new terminal, or run `source ~/.bashrc` +``` + +Replace `///` to match where you cloned the git repo of the docker files. + +*Reminder:* Include the absolute path to your `seL4-CAmkES-L4v-dockerfiles` folder, e.g. + +```bash +echo $'alias container=\'make -C //home/jblogs/seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc +# now open a new terminal, or run `source ~/.bashrc` + +``` + +This then allows you to run `container` from any directory. + +*Reminder:* start a new terminal for the changes in `.bashrc` to take effect or run `source ~/.bashrc`. + + +## An example workflow + +A good workflow is to run two terminals: + + - Terminal A is just a normal terminal, and is used for git operations, editing (e.g., vim, emacs, vscode), and other non-build operations. + - Terminal B is running in a container, and is only used for compilation. + +This gives you the flexibility to use all the normal tools you are used to, while having the seL4 dependencies separated from your machine. + +### Compiling seL4 test + +Start two terminals (terminal A and terminal B). + +In terminal A, run these commands: + +```bash +jblogs@host:~$ mkdir ~/seL4test +jblogs@host:~$ cd ~/seL4test +jblogs@host:~/seL4test$ repo init -u https://github.com/seL4/seL4test-manifest.git +jblogs@host:~/seL4test$ repo sync +``` + +In terminal B, run these commands: + +```bash +jblogs@host:~$ cd ~/seL4test +jblogs@host:~/seL4test$ container # using the bash alias defined above +jblogs@in-container:/host$ mkdir build-x86 +jblogs@in-container:/host$ cd build-x86 +jblogs@in-container:/host/build-x86$ ../init-build.sh -DPLATFORM=x86_64 -DSIMULATION=TRUE +jblogs@in-container:/host/build-x86$ ninja +jblogs@in-container:/host/build-x86$ ./simulate +``` + +If you need to make any code modifications or commit things to git, use terminal A. If you need to recompile or simulate an image, use terminal B. + +`./simulate` will take a few minutes to run. If QEMU works, you'll see something like + +``` +Test suite passed. 121 tests passed. 57 tests disabled. +All is well in the universe +``` + +Note, if QEMU fails when trying to simulate the image, try configuring your Docker host to give the container more memory using [Docker Desktop](https://docs.docker.com/desktop/use-desktop/). + +That's it! seL4 is running. + +To quit QEMU: `Ctrl+a, x` + +

    + Next: Get the tutorials +

    diff --git a/Tutorials/seL4/threads.md b/Tutorials/seL4/threads.md new file mode 100644 index 0000000000..6e715ef39a --- /dev/null +++ b/Tutorials/seL4/threads.md @@ -0,0 +1,14 @@ +--- +toc: true +title: Threads +tutorial: threads +tutorial-order: mechanisms-4 +layout: tutorial +description: how to start a thread using the seL4 API. +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. +--- +{% include tutorial.md %} + + +Next tutorial: IPC \ No newline at end of file diff --git a/Tutorials/seL4/untyped.md b/Tutorials/seL4/untyped.md new file mode 100644 index 0000000000..6bcfc2f746 --- /dev/null +++ b/Tutorials/seL4/untyped.md @@ -0,0 +1,14 @@ +--- +toc: true +title: Untyped +tutorial: untyped +tutorial-order: mechanisms-2 +description: user-level memory management. +layout: tutorial +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. +--- +{% include tutorial.md %} + + +Next tutorial: Mapping From 9b3284ca196bace637efc0cb1f7ddd565b69aa27 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 15 Jul 2024 08:28:23 +1000 Subject: [PATCH 051/103] finish addressing Gerwin high-level issues Signed-off-by: Birgit Brecknell --- Hardware/HiKey/index.md | 2 +- Hardware/IA32.md | 6 +- Hardware/VMware/index.md | 2 +- Hardware/jetsontk1.md | 2 +- Makefile | 2 +- Resources.md | 7 +- Tutorials/GettingStarted/overview.md | 2 +- Tutorials/Resources/how-to.md | 102 ++++----- Tutorials/seL4/overview.md | 21 +- Tutorials/seL4Kernel/capabilities.md | 15 -- Tutorials/seL4Kernel/fault-handlers.md | 14 -- Tutorials/seL4Kernel/get-the-tutorials.md | 33 --- Tutorials/seL4Kernel/hello-world.md | 15 -- Tutorials/seL4Kernel/interrupts.md | 14 -- Tutorials/seL4Kernel/ipc.md | 14 -- Tutorials/seL4Kernel/mapping.md | 14 -- Tutorials/seL4Kernel/notifications.md | 14 -- Tutorials/seL4Kernel/overview.md | 37 --- Tutorials/seL4Kernel/setting-up.md | 237 -------------------- Tutorials/seL4Kernel/threads.md | 14 -- Tutorials/seL4Kernel/untyped.md | 14 -- _data/sidebar.yml | 8 +- _includes/header.html | 2 +- _includes/nav-sidebar.html | 30 ++- index.md | 31 +-- projects/buildsystem/index.md | 2 +- projects/sel4/documentation.md | 2 +- projects/sel4/frequently-asked-questions.md | 2 +- 28 files changed, 112 insertions(+), 546 deletions(-) delete mode 100644 Tutorials/seL4Kernel/capabilities.md delete mode 100644 Tutorials/seL4Kernel/fault-handlers.md delete mode 100644 Tutorials/seL4Kernel/get-the-tutorials.md delete mode 100644 Tutorials/seL4Kernel/hello-world.md delete mode 100644 Tutorials/seL4Kernel/interrupts.md delete mode 100644 Tutorials/seL4Kernel/ipc.md delete mode 100644 Tutorials/seL4Kernel/mapping.md delete mode 100644 Tutorials/seL4Kernel/notifications.md delete mode 100644 Tutorials/seL4Kernel/overview.md delete mode 100644 Tutorials/seL4Kernel/setting-up.md delete mode 100644 Tutorials/seL4Kernel/threads.md delete mode 100644 Tutorials/seL4Kernel/untyped.md diff --git a/Hardware/HiKey/index.md b/Hardware/HiKey/index.md index 1317f9cf2f..8e659cb92e 100644 --- a/Hardware/HiKey/index.md +++ b/Hardware/HiKey/index.md @@ -23,7 +23,7 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. - One HiKey Board. See [Hikey 96Board](http://www.96boards.org/products/ce/hikey/) - Fully working development environment. See - [Working with seL4](/Working-with-seL4) + [Resources](/Resources) ### Getting Started The Hikey board is based around the diff --git a/Hardware/IA32.md b/Hardware/IA32.md index 21e0056b7c..071715628a 100644 --- a/Hardware/IA32.md +++ b/Hardware/IA32.md @@ -29,7 +29,7 @@ menuentry "Load seL4 VM" --class os { insmod part_msdos insmod ext2 set root='(hd0,msdos2)' - multiboot /boot/sel4kernel + multiboot /boot/seL4 module /boot/sel4rootserver } ``` @@ -59,13 +59,13 @@ install-mbr /dev/sdb syslinux --install /dev/sdb1 mount /dev/sdb1 /mnt cp images/sel4test-driver-image-ia32-pc99 /mnt/rootserver -cp images/kernel-ia32-pc99 /mnt/sel4kernel +cp images/kernel-ia32-pc99 /mnt/seL4 cat > /mnt/syslinux.cfg <seL4 manual +- the API references +- the [How to page](../Resources/how-to), which provides links to tutorial solutions as quick references for seL4 calls and methods +**Recommended reading** -

    Recommended reading

    Note that all of these tutorials require C programming experience and some understanding of operating systems and computer architecture. Suggested resources for these include: @@ -23,15 +25,6 @@ architecture. Suggested resources for these include: - Operating Systems: - [Modern Operating Systems (book)](https://www.amazon.com/Modern-Operating-Systems-Andrew-Tanenbaum/dp/013359162X) - [COMP3231 at UNSW](http://www.cse.unsw.edu.au/~cs3231) -- Computer Architecture - - [Computer Architecture (wikipedia)](https://en.wikipedia.org/wiki/Computer_architecture) - - [Instruction Set Architecture (wikipedia)](https://en.wikipedia.org/wiki/Instruction_set_architecture) - -

    Resources

    -We recommend having access to the seL4 manual and the API references. - -The How to page provides links to tutorial solutions as quick references for seL4 calls and methods. -

    Next tutorial: Setting up your machine diff --git a/Tutorials/seL4Kernel/capabilities.md b/Tutorials/seL4Kernel/capabilities.md deleted file mode 100644 index df7f392372..0000000000 --- a/Tutorials/seL4Kernel/capabilities.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -toc: true -title: Capabilities -tutorial: capabilities -tutorial-order: mechanisms-1 -description: an introduction to capabilities in the seL4 kernel API. -layout: tutorial -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. ---- - -{% include tutorial.md %} - - -Next tutorial: Untyped diff --git a/Tutorials/seL4Kernel/fault-handlers.md b/Tutorials/seL4Kernel/fault-handlers.md deleted file mode 100644 index 2ac8f3a755..0000000000 --- a/Tutorials/seL4Kernel/fault-handlers.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -toc: true -title: Faults -tutorial: fault-handlers -tutorial-order: mechanisms-8 -layout: tutorial -description: fault (e.g virtual memory fault) handling and fault endpoints. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - - -Next tutorial: MCS diff --git a/Tutorials/seL4Kernel/get-the-tutorials.md b/Tutorials/seL4Kernel/get-the-tutorials.md deleted file mode 100644 index ea9d6a079d..0000000000 --- a/Tutorials/seL4Kernel/get-the-tutorials.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -toc: true -title: Getting the tutorials -layout: tutorial -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. ---- - -# Getting the tutorials -## Python Dependencies -Additional python dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: -``` -pip install --user aenum -pip install --user pyelftools -``` -*Hint:* This step only needs to be done once, i.e. before doing your first tutorial - -## Get the code -All tutorials are in the sel4-tutorials-manifest. Get the code with: -``` -mkdir sel4-tutorials-manifest -cd sel4-tutorials-manifest -repo init -u https://github.com/seL4/sel4-tutorials-manifest -repo sync -``` - -`repo sync` may take a few moments to run - -*Hint:* The **Get the code** step only needs to be done once, i.e. before doing your first tutorial. - -

    - Next: Hello world -

    diff --git a/Tutorials/seL4Kernel/hello-world.md b/Tutorials/seL4Kernel/hello-world.md deleted file mode 100644 index 0b16f833a1..0000000000 --- a/Tutorials/seL4Kernel/hello-world.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -toc: true -title: Hello, World! -tutorial: hello-world -tutorial-order: 0-hello -description: an introduction to seL4 projects and tutorials. -layout: tutorial -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. ---- - -{% include tutorial.md %} - - -Next tutorial: Capabilities \ No newline at end of file diff --git a/Tutorials/seL4Kernel/interrupts.md b/Tutorials/seL4Kernel/interrupts.md deleted file mode 100644 index 90412cab2c..0000000000 --- a/Tutorials/seL4Kernel/interrupts.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -toc: true -title: Interrupts -tutorial: interrupts -tutorial-order: mechanisms-7 -layout: tutorial -description: receiving and handling interrupts. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - - -Next tutorial: Fault handling diff --git a/Tutorials/seL4Kernel/ipc.md b/Tutorials/seL4Kernel/ipc.md deleted file mode 100644 index 026e22585c..0000000000 --- a/Tutorials/seL4Kernel/ipc.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -toc: true -title: IPC -tutorial: ipc -tutorial-order: mechanisms-5 -layout: tutorial -description: overview of interprocess communication (IPC). -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - - -Next tutorial: Notifications diff --git a/Tutorials/seL4Kernel/mapping.md b/Tutorials/seL4Kernel/mapping.md deleted file mode 100644 index ee63720c14..0000000000 --- a/Tutorials/seL4Kernel/mapping.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -toc: true -title: Mapping -tutorial: mapping -tutorial-order: mechanisms-3 -description: virtual memory in seL4. -layout: tutorial -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - - -Next tutorial: Threads diff --git a/Tutorials/seL4Kernel/notifications.md b/Tutorials/seL4Kernel/notifications.md deleted file mode 100644 index ab2fd58b57..0000000000 --- a/Tutorials/seL4Kernel/notifications.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -toc: true -title: Notifications -tutorial: notifications -tutorial-order: mechanisms-6 -layout: tutorial -description: using notification objects and signals. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - - -Next tutorial: Interrupts diff --git a/Tutorials/seL4Kernel/overview.md b/Tutorials/seL4Kernel/overview.md deleted file mode 100644 index b6167a9044..0000000000 --- a/Tutorials/seL4Kernel/overview.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -toc: true -layout: tutorial -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. ---- - -

    Overview

    -We have developed a series of tutorials to on seL4 concepts. These assume a basic understanding of seL4, e.g. by having done the Microkit tutorial. - -Recommended reading: -- the [seL4 white paper](https://sel4.systems/About/seL4-whitepaper.pdf) - - -

    Prerequisites

    -Note that all of these tutorials require C programming -experience and some understanding of operating systems and computer -architecture. Suggested resources for these include: - -- C programming language - - [C tutorial](https://www.cprogramming.com/tutorial/c-tutorial.html) -- Operating Systems: - - [Modern Operating Systems (book)](https://www.amazon.com/Modern-Operating-Systems-Andrew-Tanenbaum/dp/013359162X) - - [COMP3231 at UNSW](http://www.cse.unsw.edu.au/~cs3231) -- Computer Architecture - - [Computer Architecture (wikipedia)](https://en.wikipedia.org/wiki/Computer_architecture) - - [Instruction Set Architecture (wikipedia)](https://en.wikipedia.org/wiki/Instruction_set_architecture) - -

    Resources

    -We recommend having access to the seL4 manual and the API references. - -The How to page provides links to tutorial solutions as quick references for seL4 calls and methods. - - -

    - Next tutorial: Setting up your machine -

    \ No newline at end of file diff --git a/Tutorials/seL4Kernel/setting-up.md b/Tutorials/seL4Kernel/setting-up.md deleted file mode 100644 index 4a281b7556..0000000000 --- a/Tutorials/seL4Kernel/setting-up.md +++ /dev/null @@ -1,237 +0,0 @@ ---- -toc: true -layout: tutorial -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. ---- - -# Setting up your machine -**Overview** -- Set up your machine - install dependencies required to run seL4`` -- Run seL4test on a simulator -- Gain awareness of terminology used for seL4 - - - -## Docker -To compile and use seL4, it is recommended that you use Docker to isolate the dependencies from your machine. - -These instructions assume you are using Debian (or a derivative, such as Ubuntu), and are using Bash for your shell. However, it should be informative enough for users of other distros/shells to adapt. - -These instructions are intended for Ubuntu LTS versions 20.04 and 22.04. - -To begin, you will need at least these two programs: - - * make (`sudo apt install make`) - * docker (See [here](https://get.docker.com) or [here](https://docs.docker.com/engine/installation) for installation instructions) - -For convenience, add your account to the docker group: - -```bash -sudo usermod -aG docker $(whoami) -``` - -
    - More on Docker -
    - - **Available images** - - All the prebuilt docker images are available on [DockerHub here](https://hub.docker.com/u/trustworthysystems) - - These images are used by the Trustworthy Systems Continuous Integration (CI) software, and so represent a standard software setup we use. - The CI software always uses the `latest` docker image, but images are also tagged with the date they were built. - - **More information** - - You can find the dockerfiles and supporting Makefile [here](https://github.com/seL4/seL4-CAmkES-L4v-dockerfiles) - -
    - - -## Google's Repo tool - -The primary way of obtaining and managing seL4 project sources is through the use of Google's Repo tool. - -To install run: -```sh - sudo apt-get update - sudo apt-get install repo -``` - -
    -More on Repo -
    -[More details about on installing Repo](https://source.android.com/setup/develop#installing-repo). - -[seL4 Repo cheatsheet](../projects/buildsystem/repo-cheatsheet) -
    - - -## Base build dependencies -To establish a usable development environment it is important to install your distributions basic build packages. - -### Base dependencies - -The basic build package on Ubuntu is the `build-essential` package. To install run: - -```sh -sudo apt-get update -sudo apt-get install build-essential -``` - -Additional base dependencies for building seL4 projects on Ubuntu include installing: - -```sh -sudo apt-get install cmake ccache ninja-build cmake-curses-gui -sudo apt-get install libxml2-utils ncurses-dev -sudo apt-get install curl git doxygen device-tree-compiler -sudo apt-get install u-boot-tools -sudo apt-get install python3-dev python3-pip python-is-python3 -sudo apt-get install protobuf-compiler python3-protobuf -``` - -### Simulating with QEMU - -To run seL4 projects on a simulator you will need QEMU. QEMU is a generic and open source machine emulator and virtualizer, and can emulate different architectures on different systems. - - -```sh -sudo apt-get install qemu-system-arm qemu-system-x86 qemu-system-misc -``` - -### Cross-compiling for ARM targets - -To build for ARM targets you will need a cross compiler: - -```sh -sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi -sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu -``` - -(you can install the hardware floating point versions as well if you wish) - -```sh -sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -``` - -### Cross-compiling for RISC-V targets - -To build for RISC-V targets you will need a cross compiler: - -{% include risc-v.md %} - - -
    -More on host dependencies -
    -[A detailed guide on host dependencies](../projects/buildsystem/host-dependencies) -
    - - -## Python Dependencies - -Regardless of your Linux distribution, python dependencies are required to build seL4, the manual and its proofs. To install you can run: - -```sh -pip3 install --user setuptools -pip3 install --user sel4-deps -``` - -(Some distributions use `pip` for python3, others use `pip3`. Use the Python 3 version for your distribution.) - - -## Getting a build environment -To get a running build environment for seL4 and Camkes, run: - -```bash -git clone https://github.com/seL4/seL4-CAmkES-L4v-dockerfiles.git -cd seL4-CAmkES-L4v-dockerfiles -make user -``` - -This will give you a terminal inside a container that has all the relevant tools to build, simulate, and test seL4 & Camkes programs. - -The first time you run this, docker will fetch the relevant images, which may take a while. - -The last line will say something like: - -``` -Hello, welcome to the seL4/CAmkES/L4v docker build environment -``` - -## Mapping a container -To run the container from other directories (e.g. starting a container for the [Hello World](hello-world) tutorial, which we'll do next), you can setup a bash alias such as this: - -```bash -echo $'alias container=\'make -C ///seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc -# now open a new terminal, or run `source ~/.bashrc` -``` - -Replace `///` to match where you cloned the git repo of the docker files. - -*Reminder:* Include the absolute path to your `seL4-CAmkES-L4v-dockerfiles` folder, e.g. - -```bash -echo $'alias container=\'make -C //home/jblogs/seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc -# now open a new terminal, or run `source ~/.bashrc` - -``` - -This then allows you to run `container` from any directory. - -*Reminder:* start a new terminal for the changes in `.bashrc` to take effect or run `source ~/.bashrc`. - - -## An example workflow - -A good workflow is to run two terminals: - - - Terminal A is just a normal terminal, and is used for git operations, editing (e.g., vim, emacs, vscode), and other non-build operations. - - Terminal B is running in a container, and is only used for compilation. - -This gives you the flexibility to use all the normal tools you are used to, while having the seL4 dependencies separated from your machine. - -### Compiling seL4 test - -Start two terminals (terminal A and terminal B). - -In terminal A, run these commands: - -```bash -jblogs@host:~$ mkdir ~/seL4test -jblogs@host:~$ cd ~/seL4test -jblogs@host:~/seL4test$ repo init -u https://github.com/seL4/seL4test-manifest.git -jblogs@host:~/seL4test$ repo sync -``` - -In terminal B, run these commands: - -```bash -jblogs@host:~$ cd ~/seL4test -jblogs@host:~/seL4test$ container # using the bash alias defined above -jblogs@in-container:/host$ mkdir build-x86 -jblogs@in-container:/host$ cd build-x86 -jblogs@in-container:/host/build-x86$ ../init-build.sh -DPLATFORM=x86_64 -DSIMULATION=TRUE -jblogs@in-container:/host/build-x86$ ninja -jblogs@in-container:/host/build-x86$ ./simulate -``` - -If you need to make any code modifications or commit things to git, use terminal A. If you need to recompile or simulate an image, use terminal B. - -`./simulate` will take a few minutes to run. If QEMU works, you'll see something like - -``` -Test suite passed. 121 tests passed. 57 tests disabled. -All is well in the universe -``` - -Note, if QEMU fails when trying to simulate the image, try configuring your Docker host to give the container more memory using [Docker Desktop](https://docs.docker.com/desktop/use-desktop/). - -That's it! seL4 is running. - -To quit QEMU: `Ctrl+a, x` - -

    - Next: Get the tutorials -

    diff --git a/Tutorials/seL4Kernel/threads.md b/Tutorials/seL4Kernel/threads.md deleted file mode 100644 index 6e715ef39a..0000000000 --- a/Tutorials/seL4Kernel/threads.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -toc: true -title: Threads -tutorial: threads -tutorial-order: mechanisms-4 -layout: tutorial -description: how to start a thread using the seL4 API. -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - - -Next tutorial: IPC \ No newline at end of file diff --git a/Tutorials/seL4Kernel/untyped.md b/Tutorials/seL4Kernel/untyped.md deleted file mode 100644 index 6bcfc2f746..0000000000 --- a/Tutorials/seL4Kernel/untyped.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -toc: true -title: Untyped -tutorial: untyped -tutorial-order: mechanisms-2 -description: user-level memory management. -layout: tutorial -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- -{% include tutorial.md %} - - -Next tutorial: Mapping diff --git a/_data/sidebar.yml b/_data/sidebar.yml index d7c287b8a9..716b413a53 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -2,11 +2,11 @@ # Copyright 2020 seL4 Project a Series of LF Projects, LLC. toc: - - title: Working with seL4 - url: /Working-with-seL4.html + - title: Resources + url: /Resources.html subfolderitems: - - page: Working with seL4 - url: /Working-with-seL4.html + - page: Resources + url: /Resources.html - page: seL4 Documentation url: /projects/sel4/documentation.html - page: seL4 FAQ diff --git a/_includes/header.html b/_includes/header.html index 277700d72d..fe57493654 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -16,7 +16,7 @@
    -
    +
    -

    Working with seL4

    +

    Resources

    Information about working with seL4 and its ecosystem

    @@ -41,6 +41,8 @@ This documentation site is for cooperatively developing and sharing documentatio
  • Style Guide
  • +
    +

    Projects

    List and details of all the projects that make up the seL4 platform.

    @@ -56,17 +58,20 @@ This documentation site is for cooperatively developing and sharing documentatio
  • Example system: seL4webserver
  • -
    -

    Tutorials

    Tutorials and other material to learn about seL4.

    -
    -
    -

    How to: A quick solutions guide

    -

    Links to tutorial solutions as quick references for seL4 calls and methods.

    -
    -
    \ No newline at end of file diff --git a/projects/buildsystem/index.md b/projects/buildsystem/index.md index 5d669d2bc7..9a1c411bec 100644 --- a/projects/buildsystem/index.md +++ b/projects/buildsystem/index.md @@ -37,7 +37,7 @@ It is assumed that * CMake of an appropriate version is installed * You are using the Ninja CMake generator * You understand how to checkout projects using the repo tool as described on the - [Working with seL4](/Working-with-seL4) page + [Resources](/Resources) page * You have the [required dependencies](/HostDependencies) installed to build your project. diff --git a/projects/sel4/documentation.md b/projects/sel4/documentation.md index f01ee8227d..f1c36bd32f 100644 --- a/projects/sel4/documentation.md +++ b/projects/sel4/documentation.md @@ -11,7 +11,7 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. - [Technical overview paper](https://trustworthy.systems/publications/nictaabstracts/Klein_AEMSKH_14.abstract) - [L4 Microkernels: The Lessons from 20 Years of Research and Deployment](https://trustworthy.systems/publications/nictaabstracts/Heiser_Elphinstone_16.abstract), a retrospective explaining how we got to where we are; -- [Working with seL4](/Working-with-seL4) +- [Resources](/Resources) - [Trustworthy Systems seL4 research project pages](https://trustworthy.systems/projects/seL4/) - [UNSW Advanced OS lecture slides](https://www.cse.unsw.edu.au/~cs9242/14/lectures/), especialy the Introduction and diff --git a/projects/sel4/frequently-asked-questions.md b/projects/sel4/frequently-asked-questions.md index 24956a7c42..49cabe853a 100644 --- a/projects/sel4/frequently-asked-questions.md +++ b/projects/sel4/frequently-asked-questions.md @@ -627,7 +627,7 @@ There are two recommended ways to do this. processes, but is generally more low-level. For build instructions, and how to get started, see the -[Working with seL4](/Working-with-seL4) page. +[Resources](/Resources) page. Also, UNSW's [Advanced Operating Systems course](https://www.cse.unsw.edu.au/~cs9242) has an extensive project component that builds an OS on top of seL4. If you have access to an [Odroid-C2](https://www.hardkernel.com/shop/odroid-c2/), you should be able to do the project work yourself as a way of From 5e641fb824a35cb5ed0881b2bc1e42ea90aa2cb8 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 15 Jul 2024 08:38:26 +1000 Subject: [PATCH 052/103] move toggle markdown to tutorial layout Signed-off-by: Birgit Brecknell --- Tutorials/CAmkES/camkes-vm-crossvm.md | 3 +-- Tutorials/CAmkES/camkes-vm-linux.md | 2 +- Tutorials/CAmkES/hello-camkes-0.md | 2 +- Tutorials/CAmkES/hello-camkes-1.md | 2 +- Tutorials/CAmkES/hello-camkes-2.md | 2 +- Tutorials/CAmkES/hello-camkes-timer.md | 2 +- Tutorials/DynamicLibraries/dynamic-1.md | 2 +- Tutorials/DynamicLibraries/dynamic-2.md | 2 +- Tutorials/DynamicLibraries/dynamic-3.md | 2 +- Tutorials/DynamicLibraries/dynamic-4.md | 2 +- Tutorials/MCS/mcs.md | 2 +- Tutorials/seL4/capabilities.md | 2 +- Tutorials/seL4/fault-handlers.md | 2 +- Tutorials/seL4/hello-world.md | 2 +- Tutorials/seL4/interrupts.md | 2 +- Tutorials/seL4/ipc.md | 2 +- Tutorials/seL4/mapping.md | 2 +- Tutorials/seL4/notifications.md | 2 +- Tutorials/seL4/threads.md | 2 +- Tutorials/seL4/untyped.md | 2 +- _layouts/tutorial.html | 2 +- assets/js/toggle-markdown.js | 2 +- 22 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Tutorials/CAmkES/camkes-vm-crossvm.md b/Tutorials/CAmkES/camkes-vm-crossvm.md index 1138a4b58d..6dc1a6ed7b 100644 --- a/Tutorials/CAmkES/camkes-vm-crossvm.md +++ b/Tutorials/CAmkES/camkes-vm-crossvm.md @@ -8,5 +8,4 @@ description: walkthrough of adding communication between Linux guests in separat SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- -{% include tutorial.md %} - +{% include tutorial.md %} \ No newline at end of file diff --git a/Tutorials/CAmkES/camkes-vm-linux.md b/Tutorials/CAmkES/camkes-vm-linux.md index 00641bda65..163881bede 100644 --- a/Tutorials/CAmkES/camkes-vm-linux.md +++ b/Tutorials/CAmkES/camkes-vm-linux.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: CAmkES Cross VM diff --git a/Tutorials/CAmkES/hello-camkes-0.md b/Tutorials/CAmkES/hello-camkes-0.md index eed9ce1d72..b31008d5bc 100644 --- a/Tutorials/CAmkES/hello-camkes-0.md +++ b/Tutorials/CAmkES/hello-camkes-0.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: CAmkES 1: Introduction to CAmkES diff --git a/Tutorials/CAmkES/hello-camkes-1.md b/Tutorials/CAmkES/hello-camkes-1.md index 608b55d2f8..3d9a314605 100644 --- a/Tutorials/CAmkES/hello-camkes-1.md +++ b/Tutorials/CAmkES/hello-camkes-1.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: CAmkES 2: Events \ No newline at end of file diff --git a/Tutorials/CAmkES/hello-camkes-2.md b/Tutorials/CAmkES/hello-camkes-2.md index 964054e427..a78f3d8f02 100644 --- a/Tutorials/CAmkES/hello-camkes-2.md +++ b/Tutorials/CAmkES/hello-camkes-2.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: CAmkES 3: Timer diff --git a/Tutorials/CAmkES/hello-camkes-timer.md b/Tutorials/CAmkES/hello-camkes-timer.md index 9da8e28c2f..b2672ff815 100644 --- a/Tutorials/CAmkES/hello-camkes-timer.md +++ b/Tutorials/CAmkES/hello-camkes-timer.md @@ -9,7 +9,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: CAmkES VM diff --git a/Tutorials/DynamicLibraries/dynamic-1.md b/Tutorials/DynamicLibraries/dynamic-1.md index e80493f5cc..67ad9714c1 100644 --- a/Tutorials/DynamicLibraries/dynamic-1.md +++ b/Tutorials/DynamicLibraries/dynamic-1.md @@ -9,7 +9,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: IPC diff --git a/Tutorials/DynamicLibraries/dynamic-2.md b/Tutorials/DynamicLibraries/dynamic-2.md index 21dad15c03..f7124892cd 100644 --- a/Tutorials/DynamicLibraries/dynamic-2.md +++ b/Tutorials/DynamicLibraries/dynamic-2.md @@ -9,7 +9,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Processes & Elf loading diff --git a/Tutorials/DynamicLibraries/dynamic-3.md b/Tutorials/DynamicLibraries/dynamic-3.md index 814d1b2ac2..9ee7be9503 100644 --- a/Tutorials/DynamicLibraries/dynamic-3.md +++ b/Tutorials/DynamicLibraries/dynamic-3.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Timer diff --git a/Tutorials/DynamicLibraries/dynamic-4.md b/Tutorials/DynamicLibraries/dynamic-4.md index a3e2acdf91..75e3a9b9b0 100644 --- a/Tutorials/DynamicLibraries/dynamic-4.md +++ b/Tutorials/DynamicLibraries/dynamic-4.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Hello CAmkES diff --git a/Tutorials/MCS/mcs.md b/Tutorials/MCS/mcs.md index 972ff6b45b..d6fb87e678 100644 --- a/Tutorials/MCS/mcs.md +++ b/Tutorials/MCS/mcs.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Dynamic libraries diff --git a/Tutorials/seL4/capabilities.md b/Tutorials/seL4/capabilities.md index df7f392372..2ed17384cc 100644 --- a/Tutorials/seL4/capabilities.md +++ b/Tutorials/seL4/capabilities.md @@ -10,6 +10,6 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Untyped diff --git a/Tutorials/seL4/fault-handlers.md b/Tutorials/seL4/fault-handlers.md index 2ac8f3a755..cd508d663c 100644 --- a/Tutorials/seL4/fault-handlers.md +++ b/Tutorials/seL4/fault-handlers.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: MCS diff --git a/Tutorials/seL4/hello-world.md b/Tutorials/seL4/hello-world.md index 0b16f833a1..66ca2f78e9 100644 --- a/Tutorials/seL4/hello-world.md +++ b/Tutorials/seL4/hello-world.md @@ -10,6 +10,6 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Capabilities \ No newline at end of file diff --git a/Tutorials/seL4/interrupts.md b/Tutorials/seL4/interrupts.md index 90412cab2c..eaf16db098 100644 --- a/Tutorials/seL4/interrupts.md +++ b/Tutorials/seL4/interrupts.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Fault handling diff --git a/Tutorials/seL4/ipc.md b/Tutorials/seL4/ipc.md index 026e22585c..9c380727b5 100644 --- a/Tutorials/seL4/ipc.md +++ b/Tutorials/seL4/ipc.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Notifications diff --git a/Tutorials/seL4/mapping.md b/Tutorials/seL4/mapping.md index ee63720c14..41aacd3622 100644 --- a/Tutorials/seL4/mapping.md +++ b/Tutorials/seL4/mapping.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Threads diff --git a/Tutorials/seL4/notifications.md b/Tutorials/seL4/notifications.md index ab2fd58b57..963969008d 100644 --- a/Tutorials/seL4/notifications.md +++ b/Tutorials/seL4/notifications.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Interrupts diff --git a/Tutorials/seL4/threads.md b/Tutorials/seL4/threads.md index 6e715ef39a..deadd63e6a 100644 --- a/Tutorials/seL4/threads.md +++ b/Tutorials/seL4/threads.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: IPC \ No newline at end of file diff --git a/Tutorials/seL4/untyped.md b/Tutorials/seL4/untyped.md index 6bcfc2f746..a7a04677f0 100644 --- a/Tutorials/seL4/untyped.md +++ b/Tutorials/seL4/untyped.md @@ -9,6 +9,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - + Next tutorial: Mapping diff --git a/_layouts/tutorial.html b/_layouts/tutorial.html index 80f4ce0310..c8b42a6aa1 100644 --- a/_layouts/tutorial.html +++ b/_layouts/tutorial.html @@ -28,5 +28,5 @@ {% if page.toc %} {% include toc-sidebar.html %} {% endif %} -
    + diff --git a/assets/js/toggle-markdown.js b/assets/js/toggle-markdown.js index 7e90f032d1..42badccf0a 100644 --- a/assets/js/toggle-markdown.js +++ b/assets/js/toggle-markdown.js @@ -4,7 +4,7 @@ // Expand all solutions if previous link was how-to page let text = document.referrer; -let result = text.includes("Tutorials/Resources/how-to"); +let result = text.includes("tutorials/Resources/how-to"); if (result==true){ document.body.querySelectorAll('details') From cd0344e26badceb91fa9ba2f9e6ec04b8e20810c Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 15 Jul 2024 08:41:47 +1000 Subject: [PATCH 053/103] fix trailing whitespace Signed-off-by: Birgit Brecknell --- Tutorials/GettingStarted/overview.md | 4 ++-- Tutorials/GettingStarted/pathways.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Tutorials/GettingStarted/overview.md b/Tutorials/GettingStarted/overview.md index 91ab078739..01e08cc3dd 100644 --- a/Tutorials/GettingStarted/overview.md +++ b/Tutorials/GettingStarted/overview.md @@ -15,7 +15,7 @@ We have developed a series of tutorials to introduce seL4 and developing systems The tutorials are split into a number of broad categories, and have been designed around developer needs. - The [seL4 tutorials](seL4/overview.md) are for people keen to learn about the base mechanisms provided by the seL4 kernel. The kernel API is explained with short exercises that show basic examples. - + - [MCS](MCS/mcs) introduces seL4 MCS extensions, which are detailed in this [paper](https://trustworthy.systems/publications/full_text/Lyons_MAH_18.pdf) and [PhD](https://github.com/pingerino/phd/blob/master/phd.pdf). - [Dynamic Libraries](DynamicLibraries/dynamic-1) provides walkthroughs and exercises for using the dynamic libraries provided in `seL4_libs`, which were developed for rapidly prototyping systems on seL4. @@ -23,7 +23,7 @@ The tutorials are split into a number of broad categories, and have been designe - [CAmkES](CAmkES/hello-camkes-0) generates the glue code for interacting with seL4 and is designed for building high-assurance, static systems. These tutorials demonstrate how to configure static systems through components. - [Microkit](https://trustworthy.systems/projects/microkit/tutorial/) enables system designers to create static software systems based on the seL4 microkernel. We recommend this as a potential introduction to seL4, bearing in mind that the Microkit hides many of the seL4 mechanisms - it is designed that way, to make building on top of seL4 easier. - + - [Rust](https://github.com/seL4/rust-sel4) allows people to write safer user-level code on top of seL4 without needing full formal verification, with a language that is receiving increasing interest and that aligns extremely well with security and safety critical embedded systems programming. ## Resources diff --git a/Tutorials/GettingStarted/pathways.md b/Tutorials/GettingStarted/pathways.md index 6f6eabd5cf..37cffbf2d4 100644 --- a/Tutorials/GettingStarted/pathways.md +++ b/Tutorials/GettingStarted/pathways.md @@ -35,7 +35,7 @@ Recommended tutorials - [Hello world](../seL4/hello-world.md) - [MCS](../MCS/mcs.md) - The CAmkES tutorials beginning with [Hello CAmkES](../CAmkES/hello-camkes-0.md) -- Virtualisation tutorials +- Virtualisation tutorials - [CAmkES VM](../CAmkES/camkes-vm-linux) using Linux as a guest in the CAmkES VM; and - [CAmkES Cross-VM communication](../CAmkES/camkes-vm-crossvm.md) walkthrough of adding communication between Linux guests in separate VMs From e8ff93d86456b2f69ae2c43ccafcf0f8eadc9390 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 15 Jul 2024 09:04:50 +1000 Subject: [PATCH 054/103] fix mattermost link Signed-off-by: Birgit Brecknell --- Resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources.md b/Resources.md index 0ec9dccc9f..bf7c7f1a47 100644 --- a/Resources.md +++ b/Resources.md @@ -173,7 +173,7 @@ You can find a long list of seL4 publications here: ### Forums - [Discourse forum](https://sel4.discourse.group/) -- [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/channels/web-doc-revamp) +- [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/) ### Mailing lists From 42b9c6cb0e4ab764afd08ce3a363835b3e09ae01 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 15 Jul 2024 10:49:30 +1000 Subject: [PATCH 055/103] address Gerwin's comments on setting-up page Signed-off-by: Birgit Brecknell --- Tutorials/seL4/setting-up.md | 122 ++++++----------------------------- 1 file changed, 21 insertions(+), 101 deletions(-) diff --git a/Tutorials/seL4/setting-up.md b/Tutorials/seL4/setting-up.md index 4a281b7556..41f981f125 100644 --- a/Tutorials/seL4/setting-up.md +++ b/Tutorials/seL4/setting-up.md @@ -6,12 +6,24 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- # Setting up your machine -**Overview** -- Set up your machine - install dependencies required to run seL4`` -- Run seL4test on a simulator -- Gain awareness of terminology used for seL4 +## Google's Repo tool + +The primary way of obtaining and managing seL4 project sources is through the use of Google's Repo tool. +To install run: +```sh + sudo apt-get update + sudo apt-get install repo +``` + +
    +More on Repo +
    +[More details about on installing Repo](https://source.android.com/setup/develop#installing-repo). + +[seL4 Repo cheatsheet](../projects/buildsystem/repo-cheatsheet) +
    ## Docker To compile and use seL4, it is recommended that you use Docker to isolate the dependencies from your machine. @@ -49,100 +61,8 @@ sudo usermod -aG docker $(whoami) -## Google's Repo tool - -The primary way of obtaining and managing seL4 project sources is through the use of Google's Repo tool. - -To install run: -```sh - sudo apt-get update - sudo apt-get install repo -``` - -
    -More on Repo -
    -[More details about on installing Repo](https://source.android.com/setup/develop#installing-repo). - -[seL4 Repo cheatsheet](../projects/buildsystem/repo-cheatsheet) -
    - - -## Base build dependencies -To establish a usable development environment it is important to install your distributions basic build packages. - -### Base dependencies - -The basic build package on Ubuntu is the `build-essential` package. To install run: - -```sh -sudo apt-get update -sudo apt-get install build-essential -``` - -Additional base dependencies for building seL4 projects on Ubuntu include installing: - -```sh -sudo apt-get install cmake ccache ninja-build cmake-curses-gui -sudo apt-get install libxml2-utils ncurses-dev -sudo apt-get install curl git doxygen device-tree-compiler -sudo apt-get install u-boot-tools -sudo apt-get install python3-dev python3-pip python-is-python3 -sudo apt-get install protobuf-compiler python3-protobuf -``` - -### Simulating with QEMU - -To run seL4 projects on a simulator you will need QEMU. QEMU is a generic and open source machine emulator and virtualizer, and can emulate different architectures on different systems. - - -```sh -sudo apt-get install qemu-system-arm qemu-system-x86 qemu-system-misc -``` - -### Cross-compiling for ARM targets - -To build for ARM targets you will need a cross compiler: - -```sh -sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi -sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu -``` - -(you can install the hardware floating point versions as well if you wish) - -```sh -sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -``` - -### Cross-compiling for RISC-V targets - -To build for RISC-V targets you will need a cross compiler: - -{% include risc-v.md %} - - -
    -More on host dependencies -
    -[A detailed guide on host dependencies](../projects/buildsystem/host-dependencies) -
    - - -## Python Dependencies - -Regardless of your Linux distribution, python dependencies are required to build seL4, the manual and its proofs. To install you can run: - -```sh -pip3 install --user setuptools -pip3 install --user sel4-deps -``` - -(Some distributions use `pip` for python3, others use `pip3`. Use the Python 3 version for your distribution.) - - -## Getting a build environment -To get a running build environment for seL4 and Camkes, run: +### Getting a build environment +To get a running build environment for seL4 and CAmkES, run: ```bash git clone https://github.com/seL4/seL4-CAmkES-L4v-dockerfiles.git @@ -160,7 +80,7 @@ The last line will say something like: Hello, welcome to the seL4/CAmkES/L4v docker build environment ``` -## Mapping a container +### Mapping a container To run the container from other directories (e.g. starting a container for the [Hello World](hello-world) tutorial, which we'll do next), you can setup a bash alias such as this: ```bash @@ -173,7 +93,7 @@ Replace `///` to match where you cloned the git repo of the docker fil *Reminder:* Include the absolute path to your `seL4-CAmkES-L4v-dockerfiles` folder, e.g. ```bash -echo $'alias container=\'make -C //home/jblogs/seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc +echo $'alias container=\'make -C /~/seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc # now open a new terminal, or run `source ~/.bashrc` ``` @@ -219,7 +139,7 @@ jblogs@in-container:/host/build-x86$ ./simulate If you need to make any code modifications or commit things to git, use terminal A. If you need to recompile or simulate an image, use terminal B. -`./simulate` will take a few minutes to run. If QEMU works, you'll see something like +`./simulate` is run using [QEMU](https://www.qemu.org/), and will take a few minutes to run. If QEMU works, you'll see something like ``` Test suite passed. 121 tests passed. 57 tests disabled. From 6502de90898177ab34784d4061c42c662c9a6a09 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 15 Jul 2024 11:12:53 +1000 Subject: [PATCH 056/103] put dependencies in one line of code Signed-off-by: Birgit Brecknell --- Tutorials/seL4/get-the-tutorials.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Tutorials/seL4/get-the-tutorials.md b/Tutorials/seL4/get-the-tutorials.md index ea9d6a079d..e19ae11693 100644 --- a/Tutorials/seL4/get-the-tutorials.md +++ b/Tutorials/seL4/get-the-tutorials.md @@ -8,10 +8,9 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. # Getting the tutorials ## Python Dependencies -Additional python dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: +Additional python and CAmkES dependencies are required to build [tutorials](ReworkedTutorials). To install you can run: ``` -pip install --user aenum -pip install --user pyelftools +pip3 install --user aenum pyelftools camkes-deps ``` *Hint:* This step only needs to be done once, i.e. before doing your first tutorial From c6d7a3a88701cc8490dfed71e3438f131c8a468e Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 15 Jul 2024 16:55:58 +1000 Subject: [PATCH 057/103] fix links Signed-off-by: Birgit Brecknell --- Tutorials/GettingStarted/overview.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Tutorials/GettingStarted/overview.md b/Tutorials/GettingStarted/overview.md index 01e08cc3dd..c313a2c84d 100644 --- a/Tutorials/GettingStarted/overview.md +++ b/Tutorials/GettingStarted/overview.md @@ -14,13 +14,13 @@ We have developed a series of tutorials to introduce seL4 and developing systems ## List of tutorials The tutorials are split into a number of broad categories, and have been designed around developer needs. -- The [seL4 tutorials](seL4/overview.md) are for people keen to learn about the base mechanisms provided by the seL4 kernel. The kernel API is explained with short exercises that show basic examples. +- The [seL4 tutorials](../seL4/overview.md) are for people keen to learn about the base mechanisms provided by the seL4 kernel. The kernel API is explained with short exercises that show basic examples. -- [MCS](MCS/mcs) introduces seL4 MCS extensions, which are detailed in this [paper](https://trustworthy.systems/publications/full_text/Lyons_MAH_18.pdf) and [PhD](https://github.com/pingerino/phd/blob/master/phd.pdf). +- [MCS](../MCS/mcs) introduces seL4 MCS extensions, which are detailed in this [paper](https://trustworthy.systems/publications/full_text/Lyons_MAH_18.pdf) and [PhD](https://github.com/pingerino/phd/blob/master/phd.pdf). -- [Dynamic Libraries](DynamicLibraries/dynamic-1) provides walkthroughs and exercises for using the dynamic libraries provided in `seL4_libs`, which were developed for rapidly prototyping systems on seL4. +- [Dynamic Libraries](../DynamicLibraries/dynamic-1) provides walkthroughs and exercises for using the dynamic libraries provided in `seL4_libs`, which were developed for rapidly prototyping systems on seL4. -- [CAmkES](CAmkES/hello-camkes-0) generates the glue code for interacting with seL4 and is designed for building high-assurance, static systems. These tutorials demonstrate how to configure static systems through components. +- [CAmkES](../CAmkES/hello-camkes-0) generates the glue code for interacting with seL4 and is designed for building high-assurance, static systems. These tutorials demonstrate how to configure static systems through components. - [Microkit](https://trustworthy.systems/projects/microkit/tutorial/) enables system designers to create static software systems based on the seL4 microkernel. We recommend this as a potential introduction to seL4, bearing in mind that the Microkit hides many of the seL4 mechanisms - it is designed that way, to make building on top of seL4 easier. @@ -29,15 +29,12 @@ The tutorials are split into a number of broad categories, and have been designe ## Resources Additional resources to assist with learning: - The [seL4 manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf) -- [API references](projects/sel4/api-doc) -- The [How to](Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. +- [API references](../../projects/sel4/api-doc) +- The [How to](../Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. - The [seL4 white paper](https://sel4.systems/About/seL4-whitepaper.pdf) -- [FAQs](projects/sel4/frequently-asked-questions) -- [Debugging guide](projects/sel4-tutorials/debugging-guide) -- [Discourse forum](https://sel4.discourse.group/) -- [Developer mailing list](https://lists.sel4.systems/postorius/lists/devel.sel4.systems/) -- [Mattermost channel](https://mattermost.trustworthy.systems/sel4-external/channels/web-doc-revamp) - +- [FAQs](../../projects/sel4/frequently-asked-questions) +- [Debugging guide](../../projects/sel4-tutorials/debugging-guide) +- [Contact](../../Resources#contact)

    Next: Pathways through the tutorials From 3e2f994957baa0d078039a8f4e600e21350bbcda Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Wed, 17 Jul 2024 16:42:26 +1000 Subject: [PATCH 058/103] revert to old tutorials structure Signed-off-by: Birgit Brecknell --- Makefile | 2 +- Tutorials/GettingStarted/overview.md | 41 --- Tutorials/Resources/how-to.md | 338 +++++++++--------- Tutorials/{CAmkES => }/camkes-vm-crossvm.md | 0 Tutorials/{CAmkES => }/camkes-vm-linux.md | 0 Tutorials/{seL4 => }/capabilities.md | 0 Tutorials/{DynamicLibraries => }/dynamic-1.md | 0 Tutorials/{DynamicLibraries => }/dynamic-2.md | 0 Tutorials/{DynamicLibraries => }/dynamic-3.md | 0 Tutorials/{DynamicLibraries => }/dynamic-4.md | 2 +- Tutorials/{seL4 => }/fault-handlers.md | 2 +- Tutorials/{seL4 => }/get-the-tutorials.md | 0 Tutorials/{CAmkES => }/hello-camkes-0.md | 0 Tutorials/{CAmkES => }/hello-camkes-1.md | 0 Tutorials/{CAmkES => }/hello-camkes-2.md | 0 Tutorials/{CAmkES => }/hello-camkes-timer.md | 0 Tutorials/{seL4 => }/hello-world.md | 0 Tutorials/index.md | 32 ++ Tutorials/{seL4 => }/interrupts.md | 0 Tutorials/{seL4 => }/ipc.md | 0 Tutorials/{seL4 => }/mapping.md | 0 Tutorials/{MCS => }/mcs.md | 2 +- Tutorials/{seL4 => }/notifications.md | 0 Tutorials/{GettingStarted => }/pathways.md | 20 +- .../{seL4/overview.md => sel4-overview.md} | 2 +- Tutorials/{seL4 => }/setting-up.md | 2 +- Tutorials/{seL4 => }/threads.md | 0 Tutorials/{seL4 => }/untyped.md | 0 _includes/nav-sidebar.html | 62 ++-- index.md | 8 +- 30 files changed, 251 insertions(+), 262 deletions(-) delete mode 100644 Tutorials/GettingStarted/overview.md rename Tutorials/{CAmkES => }/camkes-vm-crossvm.md (100%) rename Tutorials/{CAmkES => }/camkes-vm-linux.md (100%) rename Tutorials/{seL4 => }/capabilities.md (100%) rename Tutorials/{DynamicLibraries => }/dynamic-1.md (100%) rename Tutorials/{DynamicLibraries => }/dynamic-2.md (100%) rename Tutorials/{DynamicLibraries => }/dynamic-3.md (100%) rename Tutorials/{DynamicLibraries => }/dynamic-4.md (80%) rename Tutorials/{seL4 => }/fault-handlers.md (87%) rename Tutorials/{seL4 => }/get-the-tutorials.md (100%) rename Tutorials/{CAmkES => }/hello-camkes-0.md (100%) rename Tutorials/{CAmkES => }/hello-camkes-1.md (100%) rename Tutorials/{CAmkES => }/hello-camkes-2.md (100%) rename Tutorials/{CAmkES => }/hello-camkes-timer.md (100%) rename Tutorials/{seL4 => }/hello-world.md (100%) rename Tutorials/{seL4 => }/interrupts.md (100%) rename Tutorials/{seL4 => }/ipc.md (100%) rename Tutorials/{seL4 => }/mapping.md (100%) rename Tutorials/{MCS => }/mcs.md (78%) rename Tutorials/{seL4 => }/notifications.md (100%) rename Tutorials/{GettingStarted => }/pathways.md (76%) rename Tutorials/{seL4/overview.md => sel4-overview.md} (94%) rename Tutorials/{seL4 => }/setting-up.md (97%) rename Tutorials/{seL4 => }/threads.md (100%) rename Tutorials/{seL4 => }/untyped.md (100%) diff --git a/Makefile b/Makefile index 074e4253cd..ee65a3a866 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ _repos/tutes: _repos/tutes/%.md: _repos/sel4proj/sel4-tutorials/tutorials/% _repos/tutes PYTHONPATH=_repos/sel4/capdl/python-capdl-tool _repos/sel4proj/sel4-tutorials/template.py --docsite --out-dir _repos/tutes --tut-file $ - Next: Pathways through the tutorials -

    \ No newline at end of file diff --git a/Tutorials/Resources/how-to.md b/Tutorials/Resources/how-to.md index 01fdd64ae9..b7a9d29054 100644 --- a/Tutorials/Resources/how-to.md +++ b/Tutorials/Resources/how-to.md @@ -12,172 +12,172 @@ This guide provides links to tutorial solutions as quick references for seL4 cal ## The seL4 kernel -### [Capabilities](../seL4/capabilities) - - - [Calculate the size of a CSpace](../seL4/capabilities#how-big-is-your-cspace) - - [Copy a capability between CSlots](../seL4/capabilities#copy-a-capability-between-cslots) - - [Delete a capability](../seL4/capabilities#how-do-you-delete-capabilities) - - [Suspend a thread](../seL4/capabilities#suspend-a-thread) - -### [Untyped](../seL4/untyped) - - - [Create an untyped capability](../seL4/untyped#create-an-untyped-capability) - - [Create a TCB object](../seL4/untyped#create-a-tcb-object) - - [Create an endpoint object](../seL4/untyped#create-an-endpoint-object) - - [Create a notification object](../seL4/untyped#create-a-notification-object) - - [Delete an object](../seL4/untyped#delete-the-objects) - -### [Mapping](../seL4/mapping) -- [Map a page directory](../seL4/mapping#map-a-page-directory) -- [Map a page table](../seL4/mapping#map-a-page-table) -- [Remap a page](../seL4/mapping#remap-a-page) -- [Unmap a page](../seL4/mapping#unmapping-pages) - -### [Threads](../seL4/threads) -- [Configure a TCB](../seL4/threads#configure-a-tcb) -- [Change the priority of a thread](../seL4/threads#change-priority-via-sel4_tcb_setpriority) -- [Set initial register state](../seL4/threads#set-initial-register-state) -- [Start the thread](../seL4/threads#start-the-thread) -- [Set the arguments of a thread](../seL4/threads#passing-arguments) -- [Resolve a fault](../seL4/threads#resolving-a-fault) - -### [IPC](../seL4/ipc) - - [Use capability transfer to send the badged capability](../seL4/ipc#use-capability-transfer-to-send-the-badged-capability) - - [Get a message](../seL4/ipc#get-a-message) - - [Reply and wait](../seL4/ipc#reply-and-wait) - - [Save a reply and store reply capabilities](../seL4/ipc#save-a-reply-and-store-reply-capabilities) - -### [Notifications](../seL4/notifications) - - [Set up shared memory](../seL4/notifications#set-up-shared-memory) - - [Signalling](../seL4/notifications#signal-the-producers-to-go) - - [Differentiate signals](../seL4/notifications#differentiate-signals) - -### [Interrupts](../seL4/interrupts) - - [Invoke IRQ control](../seL4/interrupts#invoke-irq-control) - - [Set NTFN](../seL4/interrupts#set-ntfn) - - [Acknowledge an interrupt](../seL4/interrupts#acknowledge-an-interrupt) - -### [Fault handling](../seL4/fault-handlers) - - [Set up an endpoint for thread fault IPC messages](../seL4/fault-handlers#setting-up-the-endpoint-to-be-used-for-thread-fault-ipc-messages) - - [Receive an IPC message from the kernel](../seL4/fault-handlers#receiving-the-ipc-message-from-the-kernel) - - [Get information about a thread fault](../seL4/fault-handlers#finding-out-information-about-the-generated-thread-fault) - - [Handle a thread fault](../seL4/fault-handlers#handling-a-thread-fault) - - [Resume a faulting thread](../seL4/fault-handlers#resuming-a-faulting-thread) - -## [MCS Extensions](../MCS/mcs) - - [Set up a periodic thread](../MCS/mcs#periodic-threads) - - [Unbind a scheduling context](../MCS/mcs#unbinding-scheduling-contexts) - - [Experiment with sporadic tasks](../MCS/mcs#sporadic-threads) - - [Use passive servers](../MCS/mcs#passive-servers) - - [Configure fault endpoints](../MCS/mcs#configuring-a-fault-endpoint-on-the-mcs-kernel) - -## [Dynamic libraries](../DynamicLibraries/dynamic-1) - -### [Initiliasation & threading](../DynamicLibraries/dynamic-1) - - [Obtain BootInfo](../DynamicLibraries/dynamic-1#obtain-bootinfo) - - [Initialise simple](../DynamicLibraries/dynamic-1#initialise-simple) - - [Use simple to print BootInfo](../DynamicLibraries/dynamic-1#use-simple-to-print-bootinfo) - - [Initialise an allocator](../DynamicLibraries/dynamic-1#initialise-an-allocator) - - [Obtain a generic allocation interface (vka)](../DynamicLibraries/dynamic-1#obtain-a-generic-allocation-interface-vka) - - [Find the CSpace root cap](../DynamicLibraries/dynamic-1#find-the-cspace-root-cap) - - [Find the VSpace root cap](../DynamicLibraries/dynamic-1#find-the-vspace-root-cap) - - [Allocate a TCB Object](../DynamicLibraries/dynamic-1#allocate-a-tcb-object) - - [Configure the new TCB](../DynamicLibraries/dynamic-1#configure-the-new-tcb) - - [Name the new TCB](../DynamicLibraries/dynamic-1#name-the-new-tcb) - - [Set the instruction pointer](../DynamicLibraries/dynamic-1#set-the-instruction-pointer) - - [Set the stack pointer](../DynamicLibraries/dynamic-1#set-the-stack-pointer) - - [Write the registers](../DynamicLibraries/dynamic-1#write-the-registers) - - [Start the new thread](../DynamicLibraries/dynamic-1#start-the-new-thread) - - [Print](../DynamicLibraries/dynamic-1#print-something) - -### [IPC](../DynamicLibraries/dynamic-2) - - [Allocate an IPC buffer](../DynamicLibraries/dynamic-2#allocate-an-ipc-buffer) - - [Allocate a page table](../DynamicLibraries/dynamic-2#allocate-a-page-table) - - [Map a page table](../DynamicLibraries/dynamic-2#map-a-page-table) - - [Map a page](../DynamicLibraries/dynamic-2#map-a-page) - - [Allocate an endpoint](../DynamicLibraries/dynamic-2#allocate-an-endpoint) - - [Badge an endpoint](../DynamicLibraries/dynamic-2#badge-an-endpoint) - - [Set a message register](../DynamicLibraries/dynamic-2#message-registers) - - [Send and wait for a reply](../DynamicLibraries/dynamic-2#ipc) - - [Receive a reply](../DynamicLibraries/dynamic-2#receive-a-reply) - - [Receive an IPC](../DynamicLibraries/dynamic-2#receive-an-ipc) - - [Validate a message](../DynamicLibraries/dynamic-2#validate-the-message) - - [Write the message registers](../DynamicLibraries/dynamic-2#write-the-message-registers) - - [Reply to a message](../DynamicLibraries/dynamic-2#reply-to-a-message) - -### [Processes & Elf loading](../DynamicLibraries/dynamic-3) - - [Create a VSpace object](../DynamicLibraries/dynamic-3#virtual-memory-management) - - [Configure a process](../DynamicLibraries/dynamic-3#configure-a-process) - - [Get a cspacepath](../DynamicLibraries/dynamic-3#get-a-cspacepath) - - [Badge a capability](../DynamicLibraries/dynamic-3#badge-a-capability) - - [Spawn a process](../DynamicLibraries/dynamic-3#spawn-a-process) - - [Receive a message](../DynamicLibraries/dynamic-3#receive-a-message) - - [Send a reply](../DynamicLibraries/dynamic-3#send-a-reply) - - [Initiate communications by using seL4_Call](../DynamicLibraries/dynamic-3#client-call) - -### [Timer](../DynamicLibraries/dynamic-4) - - [Allocate a notification object](../DynamicLibraries/dynamic-4#allocate-a-notification-object) - - [Initialise a timer](../DynamicLibraries/dynamic-4#initialise-the-timer) - - [Use a timer](../DynamicLibraries/dynamic-4#use-the-timer) - - [Handle an interrupt](../DynamicLibraries/dynamic-4#handle-the-interrupt) - - [Destroy a timer](../DynamicLibraries/dynamic-4#destroy-the-timer) - -## [CAmkES](../CAmkES/hello-camkes-0) - -### [A basic CAmkES application](../CAmkES/hello-camkes-1) - - [Define an instance in the composition section of the ADL](../CAmkES/hello-camkes-1#define-an-instance-in-the-composition-section-of-the-adl) - - [Add a connection](../CAmkES/hello-camkes-1#add-a-connection) - - [Define an interface](../CAmkES/hello-camkes-1#define-an-interface) - - [Implement a RPC function](../CAmkES/hello-camkes-1#implement-a-rpc-function) - - [Invoke a RPC function](../CAmkES/hello-camkes-1#invoke-a-rpc-function) - -### [Events in CAmkES](../CAmkES/hello-camkes-2) - - [Specify an events interface](../CAmkES/hello-camkes-2#specify-an-events-interface) - - [Add connections](../CAmkES/hello-camkes-2#add-connections) - - [Wait for data to become available](../CAmkES/hello-camkes-2#wait-for-data-to-become-available) - - [Signal that data is available](../CAmkES/hello-camkes-2#signal-that-data-is-available) - - [Register a callback handler](../CAmkES/hello-camkes-2#register-a-callback-handler) - - [Specify dataport interfaces](../CAmkES/hello-camkes-2#specify-dataport-interfaces) - - [Specify dataport connections](../CAmkES/hello-camkes-2#specify-dataport-connections) - - [Copy strings to an untyped dataport](../CAmkES/hello-camkes-2#copy-strings-to-an-untyped-dataport) - - [Read the reply data from a typed dataport](../CAmkES/hello-camkes-2#read-the-reply-data-from-a-typed-dataport) - - [Send data using dataports](../CAmkES/hello-camkes-2#send-data-using-dataports) - - [Read data from an untyped dataport](../CAmkES/hello-camkes-2#read-data-from-an-untyped-dataport) - - [Put data into a typed dataport](../CAmkES/hello-camkes-2#put-data-into-a-typed-dataport) - - [Read data from a typed dataport](../CAmkES/hello-camkes-2#read-data-from-a-typed-dataport) - - [Set component priorities](../CAmkES/hello-camkes-2#set-component-priorities) - - [Restrict access to dataports](../CAmkES/hello-camkes-2#restrict-access-to-dataports) - - [Test the read and write permissions on the dataport](../CAmkES/hello-camkes-2#test-the-read-and-write-permissions-on-the-dataport) - -### [CAmkES Timer](../CAmkES/hello-camkes-timer) - - [Instantiate a Timer and Timerbase](../CAmkES/hello-camkes-timer#instantiate-a-timer-and-timerbase) - - [Connect a timer driver component](../CAmkES/hello-camkes-timer#connect-a-timer-driver-component) - - [Configure a timer hardware component instance](../CAmkES/hello-camkes-timer#configure-a-timer-hardware-component-instance) - - [Call into a supplied driver to handle the interrupt](../CAmkES/hello-camkes-timer#call-into-a-supplied-driver-to-handle-the-interrupt) - - [Stop a timer](../CAmkES/hello-camkes-timer#stop-a-timer) - - [Acknowledge an interrupt](../CAmkES/hello-camkes-timer#acknowledge-an-interrupt) - - [Get a timer handler](../CAmkES/hello-camkes-timer#get-a-timer-handler) - - [Start a timer](../CAmkES/hello-camkes-timer#start-a-timer) - - [Implement a RPC interface](../CAmkES/hello-camkes-timer#implement-a-rpc-interface) - - [Set a timer interrupt](../CAmkES/hello-camkes-timer#set-a-timer-interrupt) - - [Instantiate a TimerDTB component](../CAmkES/hello-camkes-timer#instantiate-a-timerdtb-component) - - [Connect interfaces using the seL4DTBHardware connector](../CAmkES/hello-camkes-timer#connect-interfaces-using-the-sel4dtbhardware-connector) - - [Configure the TimerDTB component](../CAmkES/hello-camkes-timer#configure-the-timerdtb-component) - - [Handle the interrupt](../CAmkES/hello-camkes-timer#handle-the-interrupt) - - [Stop the timer](../CAmkES/hello-camkes-timer#stop-the-timer) - -### [CAmkES VM Linux](../CAmkES/camkes-vm-linux) - - [Add a program](../CAmkES/camkes-vm-linux#adding-a-program) - - [Add a kernel module](../CAmkES/camkes-vm-linux#adding-a-kernel-module) - - [Create a hypercall](../CAmkES/camkes-vm-linux#creating-a-hypercall) - -### [CAmkeES Cross VM Connectors](../CAmkES/camkes-vm-crossvm) - - [Add modules to the guest](../CAmkES/camkes-vm-crossvm#add-modules-to-the-guest) - - [Define interfaces in the VMM](../CAmkES/camkes-vm-crossvm#define-interfaces-in-the-vmm) - - [Define the component interface](../CAmkES/camkes-vm-crossvm#define-the-component-interface) - - [Instantiate the print server](../CAmkES/camkes-vm-crossvm#instantiate-the-print-server) - - [Implement the print server](../CAmkES/camkes-vm-crossvm#implement-the-print-server) - - [Implement the VMM side of the connection](../CAmkES/camkes-vm-crossvm#implement-the-vmm-side-of-the-connection) - - [Update the build system](../CAmkES/camkes-vm-crossvm#update-the-build-system) - - [Add interfaces to the Guest](../CAmkES/camkes-vm-crossvm#add-interfaces-to-the-guest) - - [Create a process](../CAmkES/camkes-vm-crossvm#create-a-process) \ No newline at end of file +### [Capabilities](../capabilities.md) + + - [Calculate the size of a CSpace](../capabilities.md#how-big-is-your-cspace) + - [Copy a capability between CSlots](../capabilities.md#copy-a-capability-between-cslots) + - [Delete a capability](../capabilities.md#how-do-you-delete-capabilities) + - [Suspend a thread](../capabilities.md#suspend-a-thread) + +### [Untyped](../untyped.md) + + - [Create an untyped capability](../untyped.md#create-an-untyped-capability) + - [Create a TCB object](../untyped.md#create-a-tcb-object) + - [Create an endpoint object](../untyped.md#create-an-endpoint-object) + - [Create a notification object](../untyped.md#create-a-notification-object) + - [Delete an object](../untyped.md#delete-the-objects) + +### [Mapping](../mapping.md) +- [Map a page directory](../mapping.md#map-a-page-directory) +- [Map a page table](../mapping.md#map-a-page-table) +- [Remap a page](../mapping.md#remap-a-page) +- [Unmap a page](../mapping.md#unmapping-pages) + +### [Threads](../threads.md) +- [Configure a TCB](../threads.md#configure-a-tcb) +- [Change the priority of a thread](../threads.md#change-priority-via-sel4_tcb_setpriority) +- [Set initial register state](../threads.md#set-initial-register-state) +- [Start the thread](../threads.md#start-the-thread) +- [Set the arguments of a thread](../threads.md#passing-arguments) +- [Resolve a fault](../threads.md#resolving-a-fault) + +### [IPC](../ipc.md) + - [Use capability transfer to send the badged capability](../ipc.md#use-capability-transfer-to-send-the-badged-capability) + - [Get a message](../ipc.md#get-a-message) + - [Reply and wait](../ipc.md#reply-and-wait) + - [Save a reply and store reply capabilities](../ipc.md#save-a-reply-and-store-reply-capabilities) + +### [Notifications](../notifications.md) + - [Set up shared memory](../notifications.md#set-up-shared-memory) + - [Signalling](../notifications.md#signal-the-producers-to-go) + - [Differentiate signals](../notifications.md#differentiate-signals) + +### [Interrupts](../interrupts.md) + - [Invoke IRQ control](../interrupts.md#invoke-irq-control) + - [Set NTFN](../interrupts.md#set-ntfn) + - [Acknowledge an interrupt](../interrupts.md#acknowledge-an-interrupt) + +### [Fault handling](../fault-handlers.md) + - [Set up an endpoint for thread fault IPC messages](../fault-handlers.md#setting-up-the-endpoint-to-be-used-for-thread-fault-ipc-messages) + - [Receive an IPC message from the kernel](../fault-handlers.md#receiving-the-ipc-message-from-the-kernel) + - [Get information about a thread fault](../fault-handlers.md#finding-out-information-about-the-generated-thread-fault) + - [Handle a thread fault](../fault-handlers.md#handling-a-thread-fault) + - [Resume a faulting thread](../fault-handlers.md#resuming-a-faulting-thread) + +## [MCS Extensions](../mcs.md) + - [Set up a periodic thread](../mcs.md#periodic-threads) + - [Unbind a scheduling context](../mcs.md#unbinding-scheduling-contexts) + - [Experiment with sporadic tasks](../mcs.md#sporadic-threads) + - [Use passive servers](../mcs.md#passive-servers) + - [Configure fault endpoints](../mcs.md#configuring-a-fault-endpoint-on-the-mcs-kernel) + +## [Dynamic libraries](../dynamic-1.md) + +### [Initiliasation & threading](../dynamic-1.md) + - [Obtain BootInfo](../dynamic-1.md#obtain-bootinfo) + - [Initialise simple](../dynamic-1.md#initialise-simple) + - [Use simple to print BootInfo](../dynamic-1.md#use-simple-to-print-bootinfo) + - [Initialise an allocator](../dynamic-1.md#initialise-an-allocator) + - [Obtain a generic allocation interface (vka)](../dynamic-1.md#obtain-a-generic-allocation-interface-vka) + - [Find the CSpace root cap](../dynamic-1.md#find-the-cspace-root-cap) + - [Find the VSpace root cap](../dynamic-1.md#find-the-vspace-root-cap) + - [Allocate a TCB Object](../dynamic-1.md#allocate-a-tcb-object) + - [Configure the new TCB](../dynamic-1.md#configure-the-new-tcb) + - [Name the new TCB](../dynamic-1.md#name-the-new-tcb) + - [Set the instruction pointer](../dynamic-1.md#set-the-instruction-pointer) + - [Set the stack pointer](../dynamic-1.md#set-the-stack-pointer) + - [Write the registers](../dynamic-1.md#write-the-registers) + - [Start the new thread](../dynamic-1.md#start-the-new-thread) + - [Print](../dynamic-1.md#print-something) + +### [IPC](../dynamic-2.md) + - [Allocate an IPC buffer](../dynamic-2.md#allocate-an-ipc-buffer) + - [Allocate a page table](../dynamic-2.md#allocate-a-page-table) + - [Map a page table](../dynamic-2.md#map-a-page-table) + - [Map a page](../dynamic-2.md#map-a-page) + - [Allocate an endpoint](../dynamic-2.md#allocate-an-endpoint) + - [Badge an endpoint](../dynamic-2.md#badge-an-endpoint) + - [Set a message register](../dynamic-2.md#message-registers) + - [Send and wait for a reply](../dynamic-2.md#ipc) + - [Receive a reply](../dynamic-2.md#receive-a-reply) + - [Receive an IPC](../dynamic-2.md#receive-an-ipc) + - [Validate a message](../dynamic-2.md#validate-the-message) + - [Write the message registers](../dynamic-2.md#write-the-message-registers) + - [Reply to a message](../dynamic-2.md#reply-to-a-message) + +### [Processes & Elf loading](../dynamic-3.md) + - [Create a VSpace object](../dynamic-3.md#virtual-memory-management) + - [Configure a process](../dynamic-3.md#configure-a-process) + - [Get a cspacepath](../dynamic-3.md#get-a-cspacepath) + - [Badge a capability](../dynamic-3.md#badge-a-capability) + - [Spawn a process](../dynamic-3.md#spawn-a-process) + - [Receive a message](../dynamic-3.md#receive-a-message) + - [Send a reply](../dynamic-3.md#send-a-reply) + - [Initiate communications by using seL4_Call](../dynamic-3.md#client-call) + +### [Timer](../dynamic-4.md) + - [Allocate a notification object](../dynamic-4.md#allocate-a-notification-object) + - [Initialise a timer](../dynamic-4.md#initialise-the-timer) + - [Use a timer](../dynamic-4.md#use-the-timer) + - [Handle an interrupt](../dynamic-4.md#handle-the-interrupt) + - [Destroy a timer](../dynamic-4.md#destroy-the-timer) + +## [CAmkES](../hello-camkes-0.md) + +### [A basic CAmkES application](../hello-camkes-1.md) + - [Define an instance in the composition section of the ADL](../hello-camkes-1.md#define-an-instance-in-the-composition-section-of-the-adl) + - [Add a connection](../hello-camkes-1.md#add-a-connection) + - [Define an interface](../hello-camkes-1.md#define-an-interface) + - [Implement a RPC function](../hello-camkes-1.md#implement-a-rpc-function) + - [Invoke a RPC function](../hello-camkes-1.md#invoke-a-rpc-function) + +### [Events in CAmkES](../hello-camkes-2.md) + - [Specify an events interface](../hello-camkes-2.md#specify-an-events-interface) + - [Add connections](../hello-camkes-2.md#add-connections) + - [Wait for data to become available](../hello-camkes-2.md#wait-for-data-to-become-available) + - [Signal that data is available](../hello-camkes-2.md#signal-that-data-is-available) + - [Register a callback handler](../hello-camkes-2.md#register-a-callback-handler) + - [Specify dataport interfaces](../hello-camkes-2.md#specify-dataport-interfaces) + - [Specify dataport connections](../hello-camkes-2.md#specify-dataport-connections) + - [Copy strings to an untyped dataport](../hello-camkes-2.md#copy-strings-to-an-untyped-dataport) + - [Read the reply data from a typed dataport](../hello-camkes-2.md#read-the-reply-data-from-a-typed-dataport) + - [Send data using dataports](../hello-camkes-2.md#send-data-using-dataports) + - [Read data from an untyped dataport](../hello-camkes-2.md#read-data-from-an-untyped-dataport) + - [Put data into a typed dataport](../hello-camkes-2.md#put-data-into-a-typed-dataport) + - [Read data from a typed dataport](../hello-camkes-2.md#read-data-from-a-typed-dataport) + - [Set component priorities](../hello-camkes-2.md#set-component-priorities) + - [Restrict access to dataports](../hello-camkes-2.md#restrict-access-to-dataports) + - [Test the read and write permissions on the dataport](../hello-camkes-2.md#test-the-read-and-write-permissions-on-the-dataport) + +### [CAmkES Timer](../hello-camkes-timer.md) + - [Instantiate a Timer and Timerbase](../hello-camkes-timer.md#instantiate-a-timer-and-timerbase) + - [Connect a timer driver component](../hello-camkes-timer.md#connect-a-timer-driver-component) + - [Configure a timer hardware component instance](../hello-camkes-timer.md#configure-a-timer-hardware-component-instance) + - [Call into a supplied driver to handle the interrupt](../hello-camkes-timer.md#call-into-a-supplied-driver-to-handle-the-interrupt) + - [Stop a timer](../hello-camkes-timer.md#stop-a-timer) + - [Acknowledge an interrupt](../hello-camkes-timer.md#acknowledge-an-interrupt) + - [Get a timer handler](../hello-camkes-timer.md#get-a-timer-handler) + - [Start a timer](../hello-camkes-timer.md#start-a-timer) + - [Implement a RPC interface](../hello-camkes-timer.md#implement-a-rpc-interface) + - [Set a timer interrupt](../hello-camkes-timer.md#set-a-timer-interrupt) + - [Instantiate a TimerDTB component](../hello-camkes-timer.md#instantiate-a-timerdtb-component) + - [Connect interfaces using the seL4DTBHardware connector](../hello-camkes-timer.md#connect-interfaces-using-the-sel4dtbhardware-connector) + - [Configure the TimerDTB component](../hello-camkes-timer.md#configure-the-timerdtb-component) + - [Handle the interrupt](../hello-camkes-timer.md#handle-the-interrupt) + - [Stop the timer](../hello-camkes-timer.md#stop-the-timer) + +### [CAmkES VM Linux](../camkes-vm-linux.md) + - [Add a program](../camkes-vm-linux.md#adding-a-program) + - [Add a kernel module](../camkes-vm-linux.md#adding-a-kernel-module) + - [Create a hypercall](../camkes-vm-linux.md#creating-a-hypercall) + +### [CAmkeES Cross VM Connectors](../camkes-vm-crossvm.md) + - [Add modules to the guest](../camkes-vm-crossvm.md#add-modules-to-the-guest) + - [Define interfaces in the VMM](../camkes-vm-crossvm.md#define-interfaces-in-the-vmm) + - [Define the component interface](../camkes-vm-crossvm.md#define-the-component-interface) + - [Instantiate the print server](../camkes-vm-crossvm.md#instantiate-the-print-server) + - [Implement the print server](../camkes-vm-crossvm.md#implement-the-print-server) + - [Implement the VMM side of the connection](../camkes-vm-crossvm.md#implement-the-vmm-side-of-the-connection) + - [Update the build system](../camkes-vm-crossvm.md#update-the-build-system) + - [Add interfaces to the Guest](../camkes-vm-crossvm.md#add-interfaces-to-the-guest) + - [Create a process](../camkes-vm-crossvm.md#create-a-process) \ No newline at end of file diff --git a/Tutorials/CAmkES/camkes-vm-crossvm.md b/Tutorials/camkes-vm-crossvm.md similarity index 100% rename from Tutorials/CAmkES/camkes-vm-crossvm.md rename to Tutorials/camkes-vm-crossvm.md diff --git a/Tutorials/CAmkES/camkes-vm-linux.md b/Tutorials/camkes-vm-linux.md similarity index 100% rename from Tutorials/CAmkES/camkes-vm-linux.md rename to Tutorials/camkes-vm-linux.md diff --git a/Tutorials/seL4/capabilities.md b/Tutorials/capabilities.md similarity index 100% rename from Tutorials/seL4/capabilities.md rename to Tutorials/capabilities.md diff --git a/Tutorials/DynamicLibraries/dynamic-1.md b/Tutorials/dynamic-1.md similarity index 100% rename from Tutorials/DynamicLibraries/dynamic-1.md rename to Tutorials/dynamic-1.md diff --git a/Tutorials/DynamicLibraries/dynamic-2.md b/Tutorials/dynamic-2.md similarity index 100% rename from Tutorials/DynamicLibraries/dynamic-2.md rename to Tutorials/dynamic-2.md diff --git a/Tutorials/DynamicLibraries/dynamic-3.md b/Tutorials/dynamic-3.md similarity index 100% rename from Tutorials/DynamicLibraries/dynamic-3.md rename to Tutorials/dynamic-3.md diff --git a/Tutorials/DynamicLibraries/dynamic-4.md b/Tutorials/dynamic-4.md similarity index 80% rename from Tutorials/DynamicLibraries/dynamic-4.md rename to Tutorials/dynamic-4.md index 75e3a9b9b0..7dac922784 100644 --- a/Tutorials/DynamicLibraries/dynamic-4.md +++ b/Tutorials/dynamic-4.md @@ -11,4 +11,4 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. {% include tutorial.md %} -Next tutorial: Hello CAmkES +Next tutorial: Hello CAmkES diff --git a/Tutorials/seL4/fault-handlers.md b/Tutorials/fault-handlers.md similarity index 87% rename from Tutorials/seL4/fault-handlers.md rename to Tutorials/fault-handlers.md index cd508d663c..50f844a4f0 100644 --- a/Tutorials/seL4/fault-handlers.md +++ b/Tutorials/fault-handlers.md @@ -11,4 +11,4 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. {% include tutorial.md %} -Next tutorial: MCS +Next tutorial: MCS diff --git a/Tutorials/seL4/get-the-tutorials.md b/Tutorials/get-the-tutorials.md similarity index 100% rename from Tutorials/seL4/get-the-tutorials.md rename to Tutorials/get-the-tutorials.md diff --git a/Tutorials/CAmkES/hello-camkes-0.md b/Tutorials/hello-camkes-0.md similarity index 100% rename from Tutorials/CAmkES/hello-camkes-0.md rename to Tutorials/hello-camkes-0.md diff --git a/Tutorials/CAmkES/hello-camkes-1.md b/Tutorials/hello-camkes-1.md similarity index 100% rename from Tutorials/CAmkES/hello-camkes-1.md rename to Tutorials/hello-camkes-1.md diff --git a/Tutorials/CAmkES/hello-camkes-2.md b/Tutorials/hello-camkes-2.md similarity index 100% rename from Tutorials/CAmkES/hello-camkes-2.md rename to Tutorials/hello-camkes-2.md diff --git a/Tutorials/CAmkES/hello-camkes-timer.md b/Tutorials/hello-camkes-timer.md similarity index 100% rename from Tutorials/CAmkES/hello-camkes-timer.md rename to Tutorials/hello-camkes-timer.md diff --git a/Tutorials/seL4/hello-world.md b/Tutorials/hello-world.md similarity index 100% rename from Tutorials/seL4/hello-world.md rename to Tutorials/hello-world.md diff --git a/Tutorials/index.md b/Tutorials/index.md index def57a79e0..2e05d14237 100644 --- a/Tutorials/index.md +++ b/Tutorials/index.md @@ -4,3 +4,35 @@ layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- +# Overview + +We have developed a series of tutorials to introduce seL4 and developing systems on seL4. + +## List of tutorials +The tutorials are split into a number of broad categories, and have been designed around developer needs. + +- The [seL4 tutorials](../sel4-overview) are for people keen to learn about the base mechanisms provided by the seL4 kernel. The kernel API is explained with short exercises that show basic examples. + +- [MCS](../MCS/mcs) introduces seL4 MCS extensions, which are detailed in this [paper](https://trustworthy.systems/publications/full_text/Lyons_MAH_18.pdf) and [PhD](https://github.com/pingerino/phd/blob/master/phd.pdf). + +- [Dynamic Libraries](../DynamicLibraries/dynamic-1) provides walkthroughs and exercises for using the dynamic libraries provided in `seL4_libs`, which were developed for rapidly prototyping systems on seL4. + +- [CAmkES](../CAmkES/hello-camkes-0) generates the glue code for interacting with seL4 and is designed for building high-assurance, static systems. These tutorials demonstrate how to configure static systems through components. + +- [Microkit](https://trustworthy.systems/projects/microkit/tutorial/) enables system designers to create static software systems based on the seL4 microkernel. We recommend this as a potential introduction to seL4, bearing in mind that the Microkit hides many of the seL4 mechanisms - it is designed that way, to make building on top of seL4 easier. + +- [Rust](https://github.com/seL4/rust-sel4) allows people to write safer user-level code on top of seL4 without needing full formal verification, with a language that is receiving increasing interest and that aligns extremely well with security and safety critical embedded systems programming. + +## Resources +Additional resources to assist with learning: +- The [seL4 manual](https://sel4.systems/Info/Docs/seL4-manual-latest.pdf) +- [API references](../../projects/sel4/api-doc) +- The [How to](../Resources/how-to) page provides links to tutorial solutions as quick references for seL4 calls and methods. +- The [seL4 white paper](https://sel4.systems/About/seL4-whitepaper.pdf) +- [FAQs](../../projects/sel4/frequently-asked-questions) +- [Debugging guide](../../projects/sel4-tutorials/debugging-guide) +- [Contact](../../Resources#contact) + +

    + Next: Pathways through the tutorials +

    \ No newline at end of file diff --git a/Tutorials/seL4/interrupts.md b/Tutorials/interrupts.md similarity index 100% rename from Tutorials/seL4/interrupts.md rename to Tutorials/interrupts.md diff --git a/Tutorials/seL4/ipc.md b/Tutorials/ipc.md similarity index 100% rename from Tutorials/seL4/ipc.md rename to Tutorials/ipc.md diff --git a/Tutorials/seL4/mapping.md b/Tutorials/mapping.md similarity index 100% rename from Tutorials/seL4/mapping.md rename to Tutorials/mapping.md diff --git a/Tutorials/MCS/mcs.md b/Tutorials/mcs.md similarity index 78% rename from Tutorials/MCS/mcs.md rename to Tutorials/mcs.md index d6fb87e678..b4ab1a24fb 100644 --- a/Tutorials/MCS/mcs.md +++ b/Tutorials/mcs.md @@ -11,4 +11,4 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. {% include tutorial.md %} -Next tutorial: Dynamic libraries +Next tutorial: Dynamic libraries diff --git a/Tutorials/seL4/notifications.md b/Tutorials/notifications.md similarity index 100% rename from Tutorials/seL4/notifications.md rename to Tutorials/notifications.md diff --git a/Tutorials/GettingStarted/pathways.md b/Tutorials/pathways.md similarity index 76% rename from Tutorials/GettingStarted/pathways.md rename to Tutorials/pathways.md index 37cffbf2d4..7ff2c72c33 100644 --- a/Tutorials/GettingStarted/pathways.md +++ b/Tutorials/pathways.md @@ -19,9 +19,9 @@ Goals - to see, compile, and run some code Recommended tutorials -- [Setting up your machine](../seL4/setting-up) -- [Getting the tutorials](../seL4/get-the-tutorials.md) -- [Hello world](../seL4/hello-world.md) +- [Setting up your machine](setting-up.md) +- [Getting the tutorials](get-the-tutorials.md) +- [Hello world](hello-world.md) ### System Building Goals @@ -30,14 +30,14 @@ Goals - to build trustworthy systems Recommended tutorials -- [Setting up your machine](../seL4/setting-up) -- [Getting the tutorials](../seL4/get-the-tutorials.md) -- [Hello world](../seL4/hello-world.md) -- [MCS](../MCS/mcs.md) -- The CAmkES tutorials beginning with [Hello CAmkES](../CAmkES/hello-camkes-0.md) +- [Setting up your machine](setting-up.md) +- [Getting the tutorials](get-the-tutorials.md) +- [Hello world](hello-world.md) +- [MCS](mcs.md) +- The CAmkES tutorials beginning with [Hello CAmkES](hello-camkes-0.md) - Virtualisation tutorials - [CAmkES VM](../CAmkES/camkes-vm-linux) using Linux as a guest in the CAmkES VM; and - - [CAmkES Cross-VM communication](../CAmkES/camkes-vm-crossvm.md) walkthrough of adding communication between Linux guests in separate VMs + - [CAmkES Cross-VM communication](camkes-vm-crossvm.md) walkthrough of adding communication between Linux guests in separate VMs ### Platform Development @@ -63,5 +63,5 @@ Recommended tutorials - Follow the tutorial in the default pathway up to and including MCS.

    - Next tutorial: seL4 tutorials + Next tutorial: seL4 tutorials

    \ No newline at end of file diff --git a/Tutorials/seL4/overview.md b/Tutorials/sel4-overview.md similarity index 94% rename from Tutorials/seL4/overview.md rename to Tutorials/sel4-overview.md index ca19081899..ae94d873a4 100644 --- a/Tutorials/seL4/overview.md +++ b/Tutorials/sel4-overview.md @@ -27,5 +27,5 @@ architecture. Suggested resources for these include: - [COMP3231 at UNSW](http://www.cse.unsw.edu.au/~cs3231)

    - Next tutorial: Setting up your machine + Next tutorial: Setting up your machine

    \ No newline at end of file diff --git a/Tutorials/seL4/setting-up.md b/Tutorials/setting-up.md similarity index 97% rename from Tutorials/seL4/setting-up.md rename to Tutorials/setting-up.md index 41f981f125..dd6639698e 100644 --- a/Tutorials/seL4/setting-up.md +++ b/Tutorials/setting-up.md @@ -81,7 +81,7 @@ Hello, welcome to the seL4/CAmkES/L4v docker build environment ``` ### Mapping a container -To run the container from other directories (e.g. starting a container for the [Hello World](hello-world) tutorial, which we'll do next), you can setup a bash alias such as this: +To run the container from other directories (e.g. starting a container for the [Hello World](hello-world.md) tutorial, which we'll do next), you can setup a bash alias such as this: ```bash echo $'alias container=\'make -C ///seL4-CAmkES-L4v-dockerfiles user HOST_DIR=$(pwd)\'' >> ~/.bashrc diff --git a/Tutorials/seL4/threads.md b/Tutorials/threads.md similarity index 100% rename from Tutorials/seL4/threads.md rename to Tutorials/threads.md diff --git a/Tutorials/seL4/untyped.md b/Tutorials/untyped.md similarity index 100% rename from Tutorials/seL4/untyped.md rename to Tutorials/untyped.md diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index a1b1b8f38d..3b534039ec 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -48,56 +48,54 @@ {% assign url = "/projects/" | append: new_project[0].name | append: '/' %}
  • - {{new_project[0].display_name}} + {{new_project[0].display_name}}
  • {% endfor %} {% endif %} {% if page_url[1] == "tutorials" %} - {% if page_url[2] contains "" %} - {% assign url = "../" %} - {% endif %} + {% assign url = "/tutorials" %}
  • \ No newline at end of file diff --git a/assets/css/style.scss b/assets/css/style.scss index 5abd29f1a8..e4bc2eeea5 100644 --- a/assets/css/style.scss +++ b/assets/css/style.scss @@ -252,6 +252,20 @@ h2 a, background-color: #428bca; } +.tutorial-sidebar li { + padding-bottom: 0; + padding-top: 0; +} +.tutorial-sidebar li > a { + padding-bottom: 0.5ex; + padding-top: 0.5ex; +} + +li.nav-section { + padding-top: 1ex; + font-weight: bold; +} + /* This adds a unicode character corresponding to .fa-external-link-alt from fontawesome to every external link */ a[href*="//"]:not([href*="{{site.url}}"],.skip-icon):after { From 7a0599dff5fe993438f73d5b633afc047b752d57 Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Thu, 1 Aug 2024 15:20:00 +1000 Subject: [PATCH 077/103] [drop] temporarily revert library rename Signed-off-by: Gerwin Klein --- Tutorials/dynamic-1.md | 2 +- Tutorials/dynamic-2.md | 2 +- Tutorials/dynamic-3.md | 2 +- Tutorials/dynamic-4.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tutorials/dynamic-1.md b/Tutorials/dynamic-1.md index 38c4bdc2b8..6f80be2c47 100644 --- a/Tutorials/dynamic-1.md +++ b/Tutorials/dynamic-1.md @@ -1,7 +1,7 @@ --- toc: true title: Libraries 1 -tutorial: libraries-1 +tutorial: dynamic-1 tutorial-order: libraries-1 layout: tutorial description: system initialisation & threading with seL4_libs. diff --git a/Tutorials/dynamic-2.md b/Tutorials/dynamic-2.md index 7ffd3ad8d9..48cd05aff6 100644 --- a/Tutorials/dynamic-2.md +++ b/Tutorials/dynamic-2.md @@ -1,7 +1,7 @@ --- toc: true title: Libraries 2 -tutorial: libraries-2 +tutorial: dynamic-2 tutorial-order: libraries-2 layout: tutorial description: IPC with seL4_libs. diff --git a/Tutorials/dynamic-3.md b/Tutorials/dynamic-3.md index d5a602cc52..5e73893b6d 100644 --- a/Tutorials/dynamic-3.md +++ b/Tutorials/dynamic-3.md @@ -1,7 +1,7 @@ --- toc: true title: Libraries 3 -tutorial: libraries-3 +tutorial: dynamic-3 tutorial-order: libraries-3 layout: tutorial description: IPC with seL4_libs. diff --git a/Tutorials/dynamic-4.md b/Tutorials/dynamic-4.md index 8794f303d2..5eeb7d5ca4 100644 --- a/Tutorials/dynamic-4.md +++ b/Tutorials/dynamic-4.md @@ -1,7 +1,7 @@ --- toc: true title: Libraries 4 -tutorial: libraries-4 +tutorial: dynamic-4 tutorial-order: libraries-4 layout: tutorial description: IPC with seL4_libs. From f635bf13ad89e4db5eb3dd5469efe10a938a9f73 Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Thu, 1 Aug 2024 15:28:58 +1000 Subject: [PATCH 078/103] tutorials: remove unused front matter description The "description" item in the tutorials front matter is unused. Remove to avoid confusion with the description item in _data/projects/sel4-tutorials.yml. Signed-off-by: Gerwin Klein --- Tutorials/camkes-vm-crossvm.md | 1 - Tutorials/camkes-vm-linux.md | 1 - Tutorials/capabilities.md | 1 - Tutorials/dynamic-1.md | 1 - Tutorials/dynamic-2.md | 1 - Tutorials/dynamic-3.md | 1 - Tutorials/dynamic-4.md | 1 - Tutorials/fault-handlers.md | 1 - Tutorials/hello-camkes-0.md | 1 - Tutorials/hello-camkes-1.md | 1 - Tutorials/hello-camkes-2.md | 1 - Tutorials/hello-camkes-timer.md | 1 - Tutorials/hello-world.md | 1 - Tutorials/interrupts.md | 1 - Tutorials/ipc.md | 1 - Tutorials/mapping.md | 1 - Tutorials/mcs.md | 1 - Tutorials/notifications.md | 1 - Tutorials/threads.md | 1 - Tutorials/untyped.md | 1 - 20 files changed, 20 deletions(-) diff --git a/Tutorials/camkes-vm-crossvm.md b/Tutorials/camkes-vm-crossvm.md index 6dc1a6ed7b..2b03b8962c 100644 --- a/Tutorials/camkes-vm-crossvm.md +++ b/Tutorials/camkes-vm-crossvm.md @@ -4,7 +4,6 @@ title: Camkes Cross-VM communication tutorial: camkes-vm-crossvm tutorial-order: vm-2 layout: tutorial -description: walkthrough of adding communication between Linux guests in separate VMs. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/camkes-vm-linux.md b/Tutorials/camkes-vm-linux.md index 163881bede..dd61695139 100644 --- a/Tutorials/camkes-vm-linux.md +++ b/Tutorials/camkes-vm-linux.md @@ -4,7 +4,6 @@ title: Camkes VM Linux tutorial: camkes-vm-linux tutorial-order: vm-1 layout: tutorial -description: using Linux as a guest in the Camkes VM. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/capabilities.md b/Tutorials/capabilities.md index 03071afde5..727fa01c35 100644 --- a/Tutorials/capabilities.md +++ b/Tutorials/capabilities.md @@ -3,7 +3,6 @@ toc: true title: Capabilities tutorial: capabilities tutorial-order: mechanisms-1 -description: an introduction to capabilities in the seL4 kernel API. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/dynamic-1.md b/Tutorials/dynamic-1.md index 6f80be2c47..d8a65c526c 100644 --- a/Tutorials/dynamic-1.md +++ b/Tutorials/dynamic-1.md @@ -4,7 +4,6 @@ title: Libraries 1 tutorial: dynamic-1 tutorial-order: libraries-1 layout: tutorial -description: system initialisation & threading with seL4_libs. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/dynamic-2.md b/Tutorials/dynamic-2.md index 48cd05aff6..22593be411 100644 --- a/Tutorials/dynamic-2.md +++ b/Tutorials/dynamic-2.md @@ -4,7 +4,6 @@ title: Libraries 2 tutorial: dynamic-2 tutorial-order: libraries-2 layout: tutorial -description: IPC with seL4_libs. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/dynamic-3.md b/Tutorials/dynamic-3.md index 5e73893b6d..c0a65d389a 100644 --- a/Tutorials/dynamic-3.md +++ b/Tutorials/dynamic-3.md @@ -4,7 +4,6 @@ title: Libraries 3 tutorial: dynamic-3 tutorial-order: libraries-3 layout: tutorial -description: IPC with seL4_libs. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/dynamic-4.md b/Tutorials/dynamic-4.md index 5eeb7d5ca4..8d7a4cfe44 100644 --- a/Tutorials/dynamic-4.md +++ b/Tutorials/dynamic-4.md @@ -4,7 +4,6 @@ title: Libraries 4 tutorial: dynamic-4 tutorial-order: libraries-4 layout: tutorial -description: IPC with seL4_libs. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/fault-handlers.md b/Tutorials/fault-handlers.md index 50f844a4f0..235981aaf3 100644 --- a/Tutorials/fault-handlers.md +++ b/Tutorials/fault-handlers.md @@ -4,7 +4,6 @@ title: Faults tutorial: fault-handlers tutorial-order: mechanisms-8 layout: tutorial -description: fault (e.g virtual memory fault) handling and fault endpoints. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/hello-camkes-0.md b/Tutorials/hello-camkes-0.md index b31008d5bc..e2e9f225d7 100644 --- a/Tutorials/hello-camkes-0.md +++ b/Tutorials/hello-camkes-0.md @@ -4,7 +4,6 @@ title: Camkes tutorial: hello-camkes-0 tutorial-order: camkes-0 layout: tutorial -description: an introduction to Camkes concepts. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/hello-camkes-1.md b/Tutorials/hello-camkes-1.md index 3d9a314605..38313a0134 100644 --- a/Tutorials/hello-camkes-1.md +++ b/Tutorials/hello-camkes-1.md @@ -4,7 +4,6 @@ title: Camkes 1 tutorial: hello-camkes-1 tutorial-order: camkes-1 layout: tutorial -description: an introduction to Camkes concepts. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/hello-camkes-2.md b/Tutorials/hello-camkes-2.md index a78f3d8f02..9d5e5b1e09 100644 --- a/Tutorials/hello-camkes-2.md +++ b/Tutorials/hello-camkes-2.md @@ -4,7 +4,6 @@ title: Camkes 2 tutorial: hello-camkes-2 tutorial-order: camkes-2 layout: tutorial -description: an introduction to Camkes concepts. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/hello-camkes-timer.md b/Tutorials/hello-camkes-timer.md index b2672ff815..90031bdef8 100644 --- a/Tutorials/hello-camkes-timer.md +++ b/Tutorials/hello-camkes-timer.md @@ -4,7 +4,6 @@ title: Camkes 3 tutorial: hello-camkes-timer tutorial-order: camkes-3 layout: tutorial -description: introduce Camkes hardware components. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/hello-world.md b/Tutorials/hello-world.md index 66ca2f78e9..c91d7faa32 100644 --- a/Tutorials/hello-world.md +++ b/Tutorials/hello-world.md @@ -3,7 +3,6 @@ toc: true title: Hello, World! tutorial: hello-world tutorial-order: 0-hello -description: an introduction to seL4 projects and tutorials. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/interrupts.md b/Tutorials/interrupts.md index eaf16db098..b7432eb8d7 100644 --- a/Tutorials/interrupts.md +++ b/Tutorials/interrupts.md @@ -4,7 +4,6 @@ title: Interrupts tutorial: interrupts tutorial-order: mechanisms-7 layout: tutorial -description: receiving and handling interrupts. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/ipc.md b/Tutorials/ipc.md index 9c380727b5..bcb4fb11c9 100644 --- a/Tutorials/ipc.md +++ b/Tutorials/ipc.md @@ -4,7 +4,6 @@ title: IPC tutorial: ipc tutorial-order: mechanisms-5 layout: tutorial -description: overview of interprocess communication (IPC). SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/mapping.md b/Tutorials/mapping.md index 41aacd3622..f007c276d1 100644 --- a/Tutorials/mapping.md +++ b/Tutorials/mapping.md @@ -3,7 +3,6 @@ toc: true title: Mapping tutorial: mapping tutorial-order: mechanisms-3 -description: virtual memory in seL4. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/mcs.md b/Tutorials/mcs.md index 54d11830dc..ce3f8e6696 100644 --- a/Tutorials/mcs.md +++ b/Tutorials/mcs.md @@ -3,7 +3,6 @@ toc: true title: MCS tutorial: mcs tutorial-order: mcs-1 -description: an introduction to the seL4 MCS extensions. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/notifications.md b/Tutorials/notifications.md index 963969008d..0aa1aeed14 100644 --- a/Tutorials/notifications.md +++ b/Tutorials/notifications.md @@ -4,7 +4,6 @@ title: Notifications tutorial: notifications tutorial-order: mechanisms-6 layout: tutorial -description: using notification objects and signals. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/threads.md b/Tutorials/threads.md index deadd63e6a..7d61fba411 100644 --- a/Tutorials/threads.md +++ b/Tutorials/threads.md @@ -4,7 +4,6 @@ title: Threads tutorial: threads tutorial-order: mechanisms-4 layout: tutorial -description: how to start a thread using the seL4 API. SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- diff --git a/Tutorials/untyped.md b/Tutorials/untyped.md index a7a04677f0..5b1475958b 100644 --- a/Tutorials/untyped.md +++ b/Tutorials/untyped.md @@ -3,7 +3,6 @@ toc: true title: Untyped tutorial: untyped tutorial-order: mechanisms-2 -description: user-level memory management. layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. From b787447aa0e0263649ec97eb7e67a7b3e86f5b17 Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Thu, 1 Aug 2024 17:13:18 +1000 Subject: [PATCH 079/103] tutorial nav: factor out tutorial navigation - put tutorial nav bar into own include file to remove complexity from nav-sidebar.html - add tutorials-sidebar.yml for nav content, with references to sel4-tutorials.yml for actual tutorial files. - arrange order, display names, and section categories in sel4-tutorials.yml for nav bar. Signed-off-by: Gerwin Klein --- _data/projects/sel4-tutorials.yml | 148 +++++++++++++++++++----------- _data/tutorials-sidebar.yml | 70 ++++++++++++++ _includes/nav-sidebar.html | 44 --------- _includes/tutorials-sidebar.html | 28 ++++++ _layouts/tutorial.html | 3 +- 5 files changed, 195 insertions(+), 98 deletions(-) create mode 100644 _data/tutorials-sidebar.yml create mode 100644 _includes/tutorials-sidebar.html diff --git a/_data/projects/sel4-tutorials.yml b/_data/projects/sel4-tutorials.yml index efb7bc47fb..61ea5492dd 100644 --- a/_data/projects/sel4-tutorials.yml +++ b/_data/projects/sel4-tutorials.yml @@ -12,6 +12,10 @@ repositories: - org: sel4proj repo: sel4-tutorials-manifest +# The order of the components list determines the order of the tutorials in the +# tutorial nav side bar. The field section is used there to include groups of +# tutorials. + components: - name: hello-world display_name: "Hello world" @@ -19,120 +23,160 @@ components: maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: hello-camkes-0 - display_name: "CAmkES" - description: "The first CAmkES application to run" + section: sel4 + + - name: capabilities + display_name: "Capabilities" + description: "seL4 capabilities tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: hello-camkes-1 - display_name: "CAmkES 1" - description: "CAmkES ADL and RPC interface tutorial" + section: sel4 + + - name: untyped + display_name: "Untyped" + description: "Physical memory management tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: hello-camkes-2 - display_name: "CAmkES 2" - description: "CAmkES event and dataport tutorial" + section: sel4 + + - name: mapping + display_name: "Mapping" + description: "Virtual memory management tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: hello-camkes-timer - display_name: "CAmkES timer" - description: "CAmkES tutorial for accessing hardware" + section: sel4 + + - name: threads + display_name: "Threads" + description: "Threads on seL4 tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: libraries-1 - display_name: "Dynamic Libraries 1" - description: "Initialisation and threading tutorial" + section: sel4 + + - name: ipc + display_name: "IPC" + description: "seL4 IPC tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: libraries-2 - display_name: "Dynamic Libraries 2" - description: "seL4 IPC and userspace paging management tutorial" + section: sel4 + + - name: notifications + display_name: "Notification" + description: "seL4 notification tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: libraries-3 - display_name: "Dynamic Libraries 3" - description: "Processes and ELF loading tutorial" + section: sel4 + + - name: interrupts + display_name: "Interrupts" + description: "Tutorial for accessing interrupts on seL4" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: libraries-4 - display_name: "Dynamic Libraries 4" - description: "Tutorial for using device drivers" + section: sel4 + + - name: fault-handlers + display_name: "Fault handling" + description: "Fault handling tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application + section: sel4 + - name: mcs - display_name: "MCS" + display_name: "MCS Extensions" description: "MCS extension tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: capabilities - display_name: "Capabilities" - description: "seL4 capabilities tutorial" + section: sel4 + + - name: dynamic-1 + display_name: "Initialisation & threading" + description: "Initialisation and threading tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: untyped - display_name: "Untyped" - description: "Physical memory management tutorial" + section: libraries + + - name: dynamic-2 + display_name: "IPC" + description: "seL4 IPC and userspace paging management tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: mapping - display_name: "Mapping" - description: "Virtual memory management tutorial" + section: libraries + + - name: dynamic-3 + display_name: "Processes & Elf loading" + description: "Processes and ELF loading tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: threads - display_name: "Threads" - description: "Threads on seL4 tutorial" + section: libraries + + - name: dynamic-4 + display_name: "Timer" + description: "Tutorial for using device drivers" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: ipc - display_name: "IPC" - description: "seL4 IPC tutorial" + section: libraries + + - name: hello-camkes-0 + display_name: "Hello CAmkES" + description: "The first CAmkES application to run" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: notifications - display_name: "Notification" - description: "seL4 notification tutorial" + section: camkes + + - name: hello-camkes-1 + display_name: "CAmkES 1: Introduction to CAmkES" + description: "CAmkES ADL and RPC interface tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: interrupts - display_name: "Interrupts" - description: "Tutorial for accessing interrupts on seL4" + section: camkes + + - name: hello-camkes-2 + display_name: "CAmkES 2: Events" + description: "CAmkES event and dataport tutorial" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application - - name: fault-handlers - display_name: "Fault handling" - description: "Fault handling tutorial" + section: camkes + + - name: hello-camkes-timer + display_name: "CAmkES 3: Timer" + description: "CAmkES tutorial for accessing hardware" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application + section: camkes + - name: camkes-vm-linux - display_name: "CAmkES VM Linux" + display_name: "CAmkES VM" description: "Tutorial for creating VM guests and applications on seL4 using CAmkES" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application + section: camkes + - name: camkes-vm-crossvm - display_name: "CAmkES cross-VM communication" - description: "Tutorial for using cross virtual machine connector" + display_name: "CAmkES Cross-VM Connectors" + description: "Tutorial for using cross virtual machine connectors" maintainer: "seL4 Foundation" status: "active" component_type: sel4-tutorials-application + section: camkes + - name: libsel4tutorials display_name: "libsel4tutorials" description: "Utility Library for doing seL4 tutorials" diff --git a/_data/tutorials-sidebar.yml b/_data/tutorials-sidebar.yml new file mode 100644 index 0000000000..8c45afeff0 --- /dev/null +++ b/_data/tutorials-sidebar.yml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: CC-BY-SA-4.0 +# Copyright 2024 seL4 Project a Series of LF Projects, LLC. + +# nav side bar for tutorials +# +# refers to sections from projects/sel4-tutorials.yml via the "section" field +# there, and "include" field here. + +- name: Getting started + type: header +- name: Overview of tutorials + file: "" + type: file +- name: Tutorial pathways + file: pathways + type: file + +- name: seL4 + type: header +- name: Overview + file: sel4-overview + type: file +- name: Setting up your machine + file: setting-up + type: file +- name: Getting the tutorials + file: get-the-tutorials + type: file +- name: sel4 + type: include + +- name: C Libraries + type: header +- name: libraries + type: include + +- name: Microkit + type: header +- name: Tutorial + url: https://trustworthy.systems/projects/microkit/tutorial/ + type: url + +- name: CAmkES + type: header +- name: camkes + type: include + +- name: Rust + type: header +- name: GitHub + url: https://github.com/seL4/rust-sel4 + type: url + +- name: Resources + type: header +- name: seL4 Manual + url: https://sel4.systems/Info/Docs/seL4-manual-latest.pdf + type: url +- name: seL4 API reference + url: /projects/sel4/api-doc.html + type: url +- name: "How to: a quick solutions guide" + file: how-to + type: file +- name: Debugging guide + url: /projects/sel4-tutorials/debugging-guide + type: url +- name: Help contacts + url: "/Resources#contact" + type: url diff --git a/_includes/nav-sidebar.html b/_includes/nav-sidebar.html index 092fb29896..5de88be0e4 100644 --- a/_includes/nav-sidebar.html +++ b/_includes/nav-sidebar.html @@ -54,48 +54,4 @@ {% endif %} -{% if page_url[1] == "Tutorials" %} - {% assign url = "" %} - -{% endif %}
    \ No newline at end of file diff --git a/_includes/tutorials-sidebar.html b/_includes/tutorials-sidebar.html new file mode 100644 index 0000000000..f4a7b8f6cf --- /dev/null +++ b/_includes/tutorials-sidebar.html @@ -0,0 +1,28 @@ +{% comment %} +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +{% endcomment %} + + diff --git a/_layouts/tutorial.html b/_layouts/tutorial.html index c8b42a6aa1..87dae841d0 100644 --- a/_layouts/tutorial.html +++ b/_layouts/tutorial.html @@ -6,8 +6,7 @@
    {{ content }} From 35dd7375cfcccc2fd3b213b6f24b45a1d926b843 Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Thu, 1 Aug 2024 17:18:17 +1000 Subject: [PATCH 080/103] layouts/tutorial: remove unused code Tutorials don't use the "project" settings. Signed-off-by: Gerwin Klein --- _layouts/tutorial.html | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/_layouts/tutorial.html b/_layouts/tutorial.html index 87dae841d0..ce0e74c055 100644 --- a/_layouts/tutorial.html +++ b/_layouts/tutorial.html @@ -12,18 +12,6 @@ {{ content }}
    -{% assign url = page.url | split: "/" %} -{% capture project_name %} -{% if page.project %} -{{page.project}} -{% elsif url[1] == "projects" %} -{{url[2]}} -{% endif %} -{% endcapture %} - -{% assign project_name = project_name | strip %} -{% assign project = site.data.projects[project_name] %} - {% if page.toc %} {% include toc-sidebar.html %} {% endif %} From 9aa42071c18416b16679e62a9bc63dc836fc722e Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Thu, 1 Aug 2024 17:19:04 +1000 Subject: [PATCH 081/103] layout/tutorials: tweak js link Use link relative to site root. Signed-off-by: Gerwin Klein --- _layouts/tutorial.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_layouts/tutorial.html b/_layouts/tutorial.html index ce0e74c055..00508c587a 100644 --- a/_layouts/tutorial.html +++ b/_layouts/tutorial.html @@ -16,4 +16,4 @@ {% include toc-sidebar.html %} {% endif %}
    - + From a50cf29cf0c4612e5bb0279bfcc409cc2fb035be Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Thu, 1 Aug 2024 17:20:09 +1000 Subject: [PATCH 082/103] debugging-guide: use tutorial layout We are most likely to get here via the tutorial navigation, and don't want that to switch when we navigate to this page. Signed-off-by: Gerwin Klein --- projects/sel4-tutorials/debugging-guide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/sel4-tutorials/debugging-guide.md b/projects/sel4-tutorials/debugging-guide.md index 423aca56cc..4c94cc259f 100644 --- a/projects/sel4-tutorials/debugging-guide.md +++ b/projects/sel4-tutorials/debugging-guide.md @@ -2,6 +2,7 @@ toc: true redirect_from: - /DebuggingGuide +layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- From 1e2e4b193af66afa1c782d16a47196193d6b8c07 Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Thu, 1 Aug 2024 17:25:43 +1000 Subject: [PATCH 083/103] tutorials: remove unused tutorial-order field The only two tutorials where this field is currently still used (and not removed) are the CAmkES VM tutorials. Signed-off-by: Gerwin Klein --- Tutorials/capabilities.md | 1 - Tutorials/dynamic-1.md | 1 - Tutorials/dynamic-2.md | 1 - Tutorials/dynamic-3.md | 1 - Tutorials/dynamic-4.md | 1 - Tutorials/fault-handlers.md | 1 - Tutorials/hello-camkes-0.md | 1 - Tutorials/hello-camkes-1.md | 1 - Tutorials/hello-camkes-2.md | 1 - Tutorials/hello-camkes-timer.md | 1 - Tutorials/hello-world.md | 1 - Tutorials/interrupts.md | 1 - Tutorials/ipc.md | 1 - Tutorials/mapping.md | 1 - Tutorials/mcs.md | 1 - Tutorials/notifications.md | 1 - Tutorials/threads.md | 1 - Tutorials/untyped.md | 1 - 18 files changed, 18 deletions(-) diff --git a/Tutorials/capabilities.md b/Tutorials/capabilities.md index 727fa01c35..fa452297fd 100644 --- a/Tutorials/capabilities.md +++ b/Tutorials/capabilities.md @@ -2,7 +2,6 @@ toc: true title: Capabilities tutorial: capabilities -tutorial-order: mechanisms-1 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/dynamic-1.md b/Tutorials/dynamic-1.md index d8a65c526c..771ade5dea 100644 --- a/Tutorials/dynamic-1.md +++ b/Tutorials/dynamic-1.md @@ -2,7 +2,6 @@ toc: true title: Libraries 1 tutorial: dynamic-1 -tutorial-order: libraries-1 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/dynamic-2.md b/Tutorials/dynamic-2.md index 22593be411..a892a91de6 100644 --- a/Tutorials/dynamic-2.md +++ b/Tutorials/dynamic-2.md @@ -2,7 +2,6 @@ toc: true title: Libraries 2 tutorial: dynamic-2 -tutorial-order: libraries-2 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/dynamic-3.md b/Tutorials/dynamic-3.md index c0a65d389a..af9a32fbc8 100644 --- a/Tutorials/dynamic-3.md +++ b/Tutorials/dynamic-3.md @@ -2,7 +2,6 @@ toc: true title: Libraries 3 tutorial: dynamic-3 -tutorial-order: libraries-3 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/dynamic-4.md b/Tutorials/dynamic-4.md index 8d7a4cfe44..9855076c85 100644 --- a/Tutorials/dynamic-4.md +++ b/Tutorials/dynamic-4.md @@ -2,7 +2,6 @@ toc: true title: Libraries 4 tutorial: dynamic-4 -tutorial-order: libraries-4 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/fault-handlers.md b/Tutorials/fault-handlers.md index 235981aaf3..91d8d85f51 100644 --- a/Tutorials/fault-handlers.md +++ b/Tutorials/fault-handlers.md @@ -2,7 +2,6 @@ toc: true title: Faults tutorial: fault-handlers -tutorial-order: mechanisms-8 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/hello-camkes-0.md b/Tutorials/hello-camkes-0.md index e2e9f225d7..965bb2a30e 100644 --- a/Tutorials/hello-camkes-0.md +++ b/Tutorials/hello-camkes-0.md @@ -2,7 +2,6 @@ toc: true title: Camkes tutorial: hello-camkes-0 -tutorial-order: camkes-0 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/hello-camkes-1.md b/Tutorials/hello-camkes-1.md index 38313a0134..39bd76ebe1 100644 --- a/Tutorials/hello-camkes-1.md +++ b/Tutorials/hello-camkes-1.md @@ -2,7 +2,6 @@ toc: true title: Camkes 1 tutorial: hello-camkes-1 -tutorial-order: camkes-1 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/hello-camkes-2.md b/Tutorials/hello-camkes-2.md index 9d5e5b1e09..76ab54e90b 100644 --- a/Tutorials/hello-camkes-2.md +++ b/Tutorials/hello-camkes-2.md @@ -2,7 +2,6 @@ toc: true title: Camkes 2 tutorial: hello-camkes-2 -tutorial-order: camkes-2 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/hello-camkes-timer.md b/Tutorials/hello-camkes-timer.md index 90031bdef8..ae141a9a35 100644 --- a/Tutorials/hello-camkes-timer.md +++ b/Tutorials/hello-camkes-timer.md @@ -2,7 +2,6 @@ toc: true title: Camkes 3 tutorial: hello-camkes-timer -tutorial-order: camkes-3 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/hello-world.md b/Tutorials/hello-world.md index c91d7faa32..0426b4c0af 100644 --- a/Tutorials/hello-world.md +++ b/Tutorials/hello-world.md @@ -2,7 +2,6 @@ toc: true title: Hello, World! tutorial: hello-world -tutorial-order: 0-hello layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/interrupts.md b/Tutorials/interrupts.md index b7432eb8d7..761dc686ff 100644 --- a/Tutorials/interrupts.md +++ b/Tutorials/interrupts.md @@ -2,7 +2,6 @@ toc: true title: Interrupts tutorial: interrupts -tutorial-order: mechanisms-7 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/ipc.md b/Tutorials/ipc.md index bcb4fb11c9..e7820b6e04 100644 --- a/Tutorials/ipc.md +++ b/Tutorials/ipc.md @@ -2,7 +2,6 @@ toc: true title: IPC tutorial: ipc -tutorial-order: mechanisms-5 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/mapping.md b/Tutorials/mapping.md index f007c276d1..d3171409eb 100644 --- a/Tutorials/mapping.md +++ b/Tutorials/mapping.md @@ -2,7 +2,6 @@ toc: true title: Mapping tutorial: mapping -tutorial-order: mechanisms-3 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/mcs.md b/Tutorials/mcs.md index ce3f8e6696..6ed1e3533f 100644 --- a/Tutorials/mcs.md +++ b/Tutorials/mcs.md @@ -2,7 +2,6 @@ toc: true title: MCS tutorial: mcs -tutorial-order: mcs-1 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/notifications.md b/Tutorials/notifications.md index 0aa1aeed14..8ab6c187fb 100644 --- a/Tutorials/notifications.md +++ b/Tutorials/notifications.md @@ -2,7 +2,6 @@ toc: true title: Notifications tutorial: notifications -tutorial-order: mechanisms-6 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/threads.md b/Tutorials/threads.md index 7d61fba411..38aaadc5d4 100644 --- a/Tutorials/threads.md +++ b/Tutorials/threads.md @@ -2,7 +2,6 @@ toc: true title: Threads tutorial: threads -tutorial-order: mechanisms-4 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/Tutorials/untyped.md b/Tutorials/untyped.md index 5b1475958b..26c74348f9 100644 --- a/Tutorials/untyped.md +++ b/Tutorials/untyped.md @@ -2,7 +2,6 @@ toc: true title: Untyped tutorial: untyped -tutorial-order: mechanisms-2 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. From 09108e135a0ca55ec5056133d1589e704610ee26 Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Thu, 1 Aug 2024 17:32:09 +1000 Subject: [PATCH 084/103] tutorials: redirect /projects/sel4-tutorials/ Set up redirect from /projects/sel4-tutorials/ to overview page, so that the link in the "projects" nav bar goes somewhere useful. Signed-off-by: Gerwin Klein --- Tutorials/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tutorials/index.md b/Tutorials/index.md index c242c721b4..bc71c9ca6b 100644 --- a/Tutorials/index.md +++ b/Tutorials/index.md @@ -3,8 +3,9 @@ toc: true layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. +redirect_from: /projects/sel4-tutorials/ --- -# Overview +# Tutorials Overview We have developed a series of tutorials to introduce seL4 and developing systems on seL4. From 34f5313abe0105790a5776a77a276cc28b3c27fe Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Thu, 1 Aug 2024 19:22:21 +1000 Subject: [PATCH 085/103] tutorial nav: automate "next" link Compute the next page in the tutorial nav side bar, and link to that on the bottom of the current page. If the link goes off site, include the name of the preceding header (e.g. Microkit and Rust). This does not yet remove the manual "next" links in the .md documents. Signed-off-by: Gerwin Klein --- _includes/tutorials-sidebar.html | 13 +++----- _layouts/tutorial.html | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/_includes/tutorials-sidebar.html b/_includes/tutorials-sidebar.html index f4a7b8f6cf..73604debdc 100644 --- a/_includes/tutorials-sidebar.html +++ b/_includes/tutorials-sidebar.html @@ -5,7 +5,7 @@
    -

    Tutorials

    +

    Tutorials

    Tutorials and other material to learn about seL4.

      -
    • Overview
    • -
    • seL4
    • -
    • MCS
    • -
    • Libraries
    • -
    • CAmkES
    • -
    • How to: A quick solutions guide to the tutorials
    • +
    • Overview
    • +
    • seL4
    • +
    • MCS
    • +
    • Libraries
    • +
    • CAmkES
    • +
    • How to: A quick solutions guide to the tutorials
    • seL4 Manual
    • API reference
    • Microkit
    • From 5336a786defc3ee0f98f9675d8f376ee4ab2591e Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 12 Aug 2024 09:39:13 +1000 Subject: [PATCH 095/103] change libraries->dynamic in old release notes Signed-off-by: Birgit Brecknell --- content_collections/_updates/sel4-tutorials/camkes-3.8.x.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content_collections/_updates/sel4-tutorials/camkes-3.8.x.md b/content_collections/_updates/sel4-tutorials/camkes-3.8.x.md index 835c427c9d..719f5e25cf 100644 --- a/content_collections/_updates/sel4-tutorials/camkes-3.8.x.md +++ b/content_collections/_updates/sel4-tutorials/camkes-3.8.x.md @@ -20,7 +20,7 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. - `hello-camkes-timer`: Use device tree for binding timer component to device and update tutorial. - `hello-camkes-timer`: Add part-2 to tutorial for describing how to use new seL4DTBHardware camkes connector. - `camkes-vm-crossvm`: Add error message if build configuration is incorrect. -- `libraries-4`: Remove duplicate vspace init function. +- `dynamic-4`: Remove duplicate vspace init function. - `hello-camkes-2`: Fix error in hint in task 8. - Refactor tutorial build system to better match typical usage in other project. Previously the tutorials indicated that their build scripts shouldn't be used outside of the tutorial project, but this is no longer the case. From 06e6c24b4591c14d725f963a69232c2f47d94443 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 12 Aug 2024 10:20:20 +1000 Subject: [PATCH 096/103] consolidate two tutorials overview pages Signed-off-by: Birgit Brecknell --- Makefile | 2 +- Tutorials/index.md | 16 ++++++++++++++-- Tutorials/pathways.md | 2 +- Tutorials/sel4-overview.md | 31 ------------------------------- _data/tutorials-sidebar.yml | 5 +---- index.md | 1 - 6 files changed, 17 insertions(+), 40 deletions(-) delete mode 100644 Tutorials/sel4-overview.md diff --git a/Makefile b/Makefile index 2ba012343d..167ed6b3ba 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ _repos/tutes: _repos/tutes/%.md: _repos/sel4proj/sel4-tutorials/tutorials/% _repos/tutes PYTHONPATH=_repos/sel4/capdl/python-capdl-tool _repos/sel4proj/sel4-tutorials/template.py --docsite --out-dir _repos/tutes --tut-file $ - Next tutorial: seL4 tutorials + Next tutorial: Setting up your machine

      \ No newline at end of file diff --git a/Tutorials/sel4-overview.md b/Tutorials/sel4-overview.md deleted file mode 100644 index cd3c49af22..0000000000 --- a/Tutorials/sel4-overview.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -toc: true -layout: tutorial -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. ---- - -# Overview -The seL4 tutorials are for people keen to learn about the base mechanisms provided by the seL4 kernel. The kernel API is explained with short exercises that show basic examples. - -While doing these tutorials, we recommend having access to the -- [seL4 white paper](https://sel4.systems/About/seL4-whitepaper.pdf) -- the seL4 manual -- the API references -- the [How to page](how-to), which provides links to tutorial solutions as quick references for seL4 calls and methods - -**Recommended reading** - -Note that all of these tutorials require C programming -experience and some understanding of operating systems and computer -architecture. Suggested resources for these include: - -- C programming language - - [C tutorial](https://www.cprogramming.com/tutorial/c-tutorial.html) -- Operating Systems: - - [Modern Operating Systems (book)](https://www.amazon.com/Modern-Operating-Systems-Andrew-Tanenbaum/dp/013359162X) - - [COMP3231 at UNSW](http://www.cse.unsw.edu.au/~cs3231) - -

      - Next tutorial: Setting up your machine -

      \ No newline at end of file diff --git a/_data/tutorials-sidebar.yml b/_data/tutorials-sidebar.yml index 8c45afeff0..50918a4050 100644 --- a/_data/tutorials-sidebar.yml +++ b/_data/tutorials-sidebar.yml @@ -8,7 +8,7 @@ - name: Getting started type: header -- name: Overview of tutorials +- name: Overview file: "" type: file - name: Tutorial pathways @@ -17,9 +17,6 @@ - name: seL4 type: header -- name: Overview - file: sel4-overview - type: file - name: Setting up your machine file: setting-up type: file diff --git a/index.md b/index.md index 564c57ee72..c205f58261 100644 --- a/index.md +++ b/index.md @@ -63,7 +63,6 @@ This documentation site is for cooperatively developing and sharing documentatio

      Tutorials and other material to learn about seL4.

      • Overview
      • -
      • seL4
      • MCS
      • Libraries
      • CAmkES
      • From 07952f12c7c3a4a4396363103134069f9c277d7a Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 23 Aug 2024 11:41:22 +1000 Subject: [PATCH 097/103] remove next link for external tutes Signed-off-by: Birgit Brecknell --- _layouts/tutorial.html | 1 - 1 file changed, 1 deletion(-) diff --git a/_layouts/tutorial.html b/_layouts/tutorial.html index a83bad0d3d..10fec7164e 100644 --- a/_layouts/tutorial.html +++ b/_layouts/tutorial.html @@ -43,7 +43,6 @@ {%- assign url = "/Tutorials/" | append: item.file | relative_url %} Next: {{ item.name }} {%- when "url" -%} - Next: {{ header_name }} {{ item.name }} {%- else -%} {%- assign url = "/Tutorials/" | append: item.name | relative_url %} Next: {{ item.display_name }} From ad85e98f42664499048ba1a187cc4b082bbcae44 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 23 Aug 2024 11:41:42 +1000 Subject: [PATCH 098/103] remove duplicate next links Signed-off-by: Birgit Brecknell --- Tutorials/camkes-vm-linux.md | 3 - Tutorials/capabilities.md | 2 - Tutorials/fault-handlers.md | 3 - Tutorials/hello-camkes-0.md | 3 - Tutorials/hello-camkes-1.md | 3 - Tutorials/hello-camkes-2.md | 3 - Tutorials/hello-camkes-timer.md | 4 - Tutorials/hello-world.md | 3 - Tutorials/interrupts.md | 3 - Tutorials/ipc.md | 3 - Tutorials/libraries-1.md | 2 - Tutorials/libraries-2.md | 4 - Tutorials/libraries-3.md | 3 - Tutorials/libraries-4.md | 3 - Tutorials/mapping.md | 3 - Tutorials/mcs.md | 3 - Tutorials/notifications.md | 3 - Tutorials/pathways.md | 4 - Tutorials/threads.md | 3 - Tutorials/untyped.md | 3 - camkes-vm-crossvm/camkes-vm-crossvm.md | 650 +++++++++++++++++++++++++ 21 files changed, 650 insertions(+), 61 deletions(-) create mode 100644 camkes-vm-crossvm/camkes-vm-crossvm.md diff --git a/Tutorials/camkes-vm-linux.md b/Tutorials/camkes-vm-linux.md index dd61695139..00348f0e7c 100644 --- a/Tutorials/camkes-vm-linux.md +++ b/Tutorials/camkes-vm-linux.md @@ -8,6 +8,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: CAmkES Cross VM diff --git a/Tutorials/capabilities.md b/Tutorials/capabilities.md index fa452297fd..0ae7d2f158 100644 --- a/Tutorials/capabilities.md +++ b/Tutorials/capabilities.md @@ -8,5 +8,3 @@ SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - -Next tutorial: Untyped \ No newline at end of file diff --git a/Tutorials/fault-handlers.md b/Tutorials/fault-handlers.md index 91d8d85f51..0a7c8e81f5 100644 --- a/Tutorials/fault-handlers.md +++ b/Tutorials/fault-handlers.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: MCS diff --git a/Tutorials/hello-camkes-0.md b/Tutorials/hello-camkes-0.md index 965bb2a30e..35b8f5abf3 100644 --- a/Tutorials/hello-camkes-0.md +++ b/Tutorials/hello-camkes-0.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: CAmkES 1: Introduction to CAmkES diff --git a/Tutorials/hello-camkes-1.md b/Tutorials/hello-camkes-1.md index 39bd76ebe1..6eee75c2fa 100644 --- a/Tutorials/hello-camkes-1.md +++ b/Tutorials/hello-camkes-1.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: CAmkES 2: Events \ No newline at end of file diff --git a/Tutorials/hello-camkes-2.md b/Tutorials/hello-camkes-2.md index 76ab54e90b..43380fd551 100644 --- a/Tutorials/hello-camkes-2.md +++ b/Tutorials/hello-camkes-2.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: CAmkES 3: Timer diff --git a/Tutorials/hello-camkes-timer.md b/Tutorials/hello-camkes-timer.md index ae141a9a35..2c65983dc2 100644 --- a/Tutorials/hello-camkes-timer.md +++ b/Tutorials/hello-camkes-timer.md @@ -7,7 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - - -Next tutorial: CAmkES VM diff --git a/Tutorials/hello-world.md b/Tutorials/hello-world.md index 0426b4c0af..cb029650f6 100644 --- a/Tutorials/hello-world.md +++ b/Tutorials/hello-world.md @@ -8,6 +8,3 @@ SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: Capabilities \ No newline at end of file diff --git a/Tutorials/interrupts.md b/Tutorials/interrupts.md index 761dc686ff..e97240d93e 100644 --- a/Tutorials/interrupts.md +++ b/Tutorials/interrupts.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: Fault handling diff --git a/Tutorials/ipc.md b/Tutorials/ipc.md index e7820b6e04..77e6742240 100644 --- a/Tutorials/ipc.md +++ b/Tutorials/ipc.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: Notifications diff --git a/Tutorials/libraries-1.md b/Tutorials/libraries-1.md index f6ad813dcc..40ff94e043 100644 --- a/Tutorials/libraries-1.md +++ b/Tutorials/libraries-1.md @@ -7,5 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - -Next tutorial: IPC diff --git a/Tutorials/libraries-2.md b/Tutorials/libraries-2.md index 2e3658bd44..12be983091 100644 --- a/Tutorials/libraries-2.md +++ b/Tutorials/libraries-2.md @@ -7,7 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - - -Next tutorial: Processes & Elf loading diff --git a/Tutorials/libraries-3.md b/Tutorials/libraries-3.md index 9c43b6a43b..858212203b 100644 --- a/Tutorials/libraries-3.md +++ b/Tutorials/libraries-3.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: Timer diff --git a/Tutorials/libraries-4.md b/Tutorials/libraries-4.md index 86399a5621..fcc5f21289 100644 --- a/Tutorials/libraries-4.md +++ b/Tutorials/libraries-4.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: Hello CAmkES diff --git a/Tutorials/mapping.md b/Tutorials/mapping.md index d3171409eb..b931d9732c 100644 --- a/Tutorials/mapping.md +++ b/Tutorials/mapping.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: Threads diff --git a/Tutorials/mcs.md b/Tutorials/mcs.md index 6ed1e3533f..fac1ee019d 100644 --- a/Tutorials/mcs.md +++ b/Tutorials/mcs.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: Dynamic libraries diff --git a/Tutorials/notifications.md b/Tutorials/notifications.md index 8ab6c187fb..f92ec784b3 100644 --- a/Tutorials/notifications.md +++ b/Tutorials/notifications.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: Interrupts diff --git a/Tutorials/pathways.md b/Tutorials/pathways.md index 26ecbf49c6..207629e1cc 100644 --- a/Tutorials/pathways.md +++ b/Tutorials/pathways.md @@ -61,7 +61,3 @@ Recommended reading Recommended tutorials - Follow the tutorial in the default pathway up to and including MCS. - -

        - Next tutorial: Setting up your machine -

        \ No newline at end of file diff --git a/Tutorials/threads.md b/Tutorials/threads.md index 38aaadc5d4..7a1d2f1d8d 100644 --- a/Tutorials/threads.md +++ b/Tutorials/threads.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: IPC \ No newline at end of file diff --git a/Tutorials/untyped.md b/Tutorials/untyped.md index 26c74348f9..5948a7a492 100644 --- a/Tutorials/untyped.md +++ b/Tutorials/untyped.md @@ -7,6 +7,3 @@ SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. --- {% include tutorial.md %} - - -Next tutorial: Mapping diff --git a/camkes-vm-crossvm/camkes-vm-crossvm.md b/camkes-vm-crossvm/camkes-vm-crossvm.md new file mode 100644 index 0000000000..72b0e2162c --- /dev/null +++ b/camkes-vm-crossvm/camkes-vm-crossvm.md @@ -0,0 +1,650 @@ + + +/*? declare_task_ordering([ + 'crossvm' +]) ?*/ + +# CAmkES VM: Cross VM Connectors + +This tutorial provides an introduction to using the cross virtual machine (VM) connector mechanisms +provided by seL4 and Camkes in order to connect processes in a guest Linux instance to Camkes components. + +In this tutorial you will learn how to: + +* Configure processes in a Linux guest VM to communicate with CAmkES components + +## Prerequisites +1. [Set up your machine](https://docs.sel4.systems/tutorials/setting-up) +2. [CAmkES VM Linux tutorial](https://docs.sel4.systems/tutorials/camkes-vm-linux) + +*Note that the instructions for this tutorial are for Linux only.* + +## Initialising + +/*? macros.tutorial_init("camkes-vm-crossvm") ?*/ + +
        +Hint: tutorial solutions +
        +All tutorials come with complete solutions. To get solutions run: + +/*? macros.tutorial_init_with_solution("camkes-vm-crossvm") ?*/ +
        + +## Background + +In order to connect guest Linux instances to CAmkES components, +three additional kernel modules must be installed in the guest. +These modules are included in the root filesystem by default: + +- `dataport`: facilitates setting up shared memory between the guest +and CAmkES components. +- `consumes_event`: allows a process in the guest to wait or poll +for an event sent by a CAmkES component. +- `emits_event`: allows a process to emit an event to a CAmkES component. + +Each type of module can be statically assigned to one or more file descriptors to associate that +file descriptor with a specific instance of an interface. `ioctl` can then be used to +manipulate that file descriptor and use the module. + +### Dataports + +Dataports are the mechanism which allows guests and components to share memory. +The dataport initialisation process is as follows: + +- The guest process uses `ioctl` on on the file associated with the dataport and specify a + page-aligned size for the shared memory. +- The dataport kernel module in the guest then allocates a page-aligned buffer of the requested size, + and makes a hypercall to the VMM, with the guest physical address and id of the data port. + The ID is derived from the file on which `ioctl` was called. +- The virtual machine manager (VMM) then modifies the guest's address space, creating the shared memory region. + between a camkes component and the guest. +- Linux processes can then map this memory into their own address space by calling `mmap` on the file + associated with the dataport. + +### Emitting Events + +Guest processes can emit events by using `ioctl` on files associated with the event interface. +This results in the `emits_event` kernel module in the guest making a +making a hypercall to the VMM, which triggers the event and resumes the guest. + +### Consuming Events + +Linux process can wait or poll for an event by calling `poll` +on the file associated with that event, using the timeout argument to +specify whether or not it should block. The event it polls for is +`POLLIN`. When the VMM receives an event destined for the guest, it places +the event id in some memory shared between the VMM and the +`consumes_event` kernel module, and then injects an interrupt into the +guest. The `consumes_event` kernel module is registered to handle this +interrupt, which reads the event ID from shared memory, and wakes a +thread blocked on the corresponding event file. If no threads are +blocked on the file, some state is set in the module such that the next +time a process waits on that file, it returns immediately and clears the +state, mimicking the behaviour of notifications. + +## Exercises + +In this tutorial you will +create a program that runs in the guest, and sends a string +to a CAmkES component to output. To achieve this, the guest program will write a string +to a shared buffer between itself and a CAmkES component. When its ready +for the string to be printed, it will emit an event, received by the +CAmkES component. The CAmkES component will print the string, then send +an event to the guest process so the guest knows it's safe to send a new +string. + +### Add modules to the guest + +There is a library in `projects/camkes/vm-linux/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/libs` +containing Linux system call wrappers, and some utility programs in +`projects/camkes/vm-linux/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/pkgs/{dataport,consumes_event,emits_event}` +which initialize and interact with cross VM connections. To build and use these modules in your rootfs the vm-linux +project provides an overlay target you can use. + +**Exercise** First add the `dataport`, `consumes_event` and `emits_event` kernel modules to the rootfs in the guest. + +Start by replacing the line: + +```cmake +/*-- filter TaskContent("crossvm", TaskContentType.BEFORE, subtask="vm-cmake-start", completion='buildroot login') -*/ +AddToFileServer("rootfs.cpio" ${default_rootfs_file}) +/*-- endfilter -*/ +``` + +in the target applications `CMakeLists.txt` file with the following: + +```cmake +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-start", completion='buildroot login') -*/ +set(CAmkESVMDefaultBuildrootOverlay ON CACHE BOOL "" FORCE) +AddOverlayDirToRootfs(default_buildroot_overlay ${default_rootfs_file} "buildroot" "rootfs_install" + rootfs_file rootfs_target) +AddToFileServer("rootfs.cpio" ${rootfs_file}) +/*-- endfilter -*/ +``` + +### Define interfaces in the VMM + +**Exercise** Update the CAmkES file, `crossvm_tutorial.camkes` by replacing the Init0 component definition: + +```c +/*-- filter TaskContent("crossvm", TaskContentType.BEFORE, subtask="vm-camkes-init0") -*/ +component Init0 { + VM_INIT_DEF() +} +/*-- endfilter -*/ +``` + +with the following definition: + +```c +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-camkes-init0", completion='buildroot login') -*/ +component Init0 { + VM_INIT_DEF() + + // this is the data port for shared memory between the component and guest process + dataport Buf(4096) data; + // this event tells the component that there is data ready to print + emits DoPrint do_print; + // this event tells the guest process that priting is complete + consumes DonePrinting done_printing; + // this mutex protects access to shared state between the VMM and the guest Linux + has mutex cross_vm_event_mutex; +} +/*-- endfilter -*/ +``` + +These interfaces will eventually be made visible to processes running in +the guest linux. The mutex is used to protect access to shared state +between the VMM and guest. + +### Define the component interface + +**Exercise** Define the print server component by adding the following to +the `crossvm_tutorial.camkes` file, after the `Init0` definition: +```c +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-camkes-printserver", completion='buildroot login') -*/ +component PrintServer { + control; + dataport Buf(4096) data; + consumes DoPrint do_print; + emits DonePrinting done_printing; +} +/*-- endfilter -*/ +``` + +### Instantiate the print server + +**Exercise** Replace the `composition` definition: + +```c +/*-- filter TaskContent("crossvm", TaskContentType.BEFORE, subtask="vm-camkes-composition", completion='buildroot login') -*/ + composition { + VM_COMPOSITION_DEF() + VM_PER_VM_COMP_DEF(0) + } +/*-- endfilter -*/ +``` + +with the following: + +```c +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-camkes-composition", completion='buildroot login') -*/ + composition { + VM_COMPOSITION_DEF() + VM_PER_VM_COMP_DEF(0) + + component PrintServer print_server; + connection seL4Notification conn_do_print(from vm0.do_print, + to print_server.do_print); + connection seL4Notification conn_done_printing(from print_server.done_printing, + to vm0.done_printing); + + connection seL4SharedDataWithCaps conn_data(from print_server.data, + to vm0.data); + } +/*-- endfilter -*/ +``` + +The [seL4SharedDataWithCaps][] +connector is a dataport connector much like `seL4SharedData`. +However, the `to` side of the connection also receives access to +the capabilities to the frames backing the dataport, which is required +for cross VM dataports, as the VMM must be able to establish shared memory +at runtime by inserting new mappings into the guest's address space. + +[seL4SharedDataWithCaps]: https://docs.sel4.systems/projects/camkes/seL4SharedDataWithCaps.html + +**Exercise** Interfaces connected with [seL4SharedDataWithCaps][] must be +configured with an integer specifying the ID and size of the dataport. + Do this now by modifying `crossvm_tutorial.camkes` with the following +two lines in the configuration section: + +```c + configuration { + ... +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-camkes-configuration", completion='buildroot login') -*/ + // Add the following 2 lines: + vm0.data_id = 1; // ids must be contiguous, starting from 1 + vm0.data_size = 4096; +/*-- endfilter -*/ + } +``` + +### Implement the print server + +**Exercise** Add the file `components/print_server.c` with the following contents: +```c +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-printserver", completion='buildroot login') -*/ +#include +#include + +int run(void) { + + while (1) { + // wait for the next event + do_print_wait(); + + printf("%s\n", (char*)data); + + // signal that we are done printing + done_printing_emit(); + } + + return 0; +} +/*-- endfilter -*/ +``` + +This provides a very simple component definition that loops forever, printing a string from +shared memory whenever an event is received then emitting an event. +The example code assumes that the shared buffer will contain a valid, null-terminated c string, which is not + something you should do in practice. + +### Implement the VMM side of the connection +Create another c file that tells the VMM about the cross VM connections. + This file must define 3 functions which initialize each type of cross vm interface: + +- `cross_vm_dataports_init` +- `cross_vm_emits_events_init` +- `cross_vm_consumes_events_init` + +**Exercise** Add a file `src/cross_vm.c` with the following contents: + +```c +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-crossvm-src", completion='buildroot login') -*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this is defined in the dataport's glue code +extern dataport_caps_handle_t data_handle; + +// Array of dataport handles at positions corresponding to handle ids from spec +static dataport_caps_handle_t *dataports[] = { + NULL, // entry 0 is NULL so ids correspond with indices + &data_handle, +}; + +// Array of consumed event callbacks and ids +static camkes_consumes_event_t consumed_events[] = { + { .id = 1, .reg_callback = done_printing_reg_callback }, +}; + +// Array of emitted event emit functions +static camkes_emit_fn emitted_events[] = { + NULL, // entry 0 is NULL so ids correspond with indices + do_print_emit, +}; + +// mutex to protect shared event context +static camkes_mutex_t cross_vm_event_mutex = (camkes_mutex_t) { + .lock = cross_vm_event_mutex_lock, + .unlock = cross_vm_event_mutex_unlock, +}; + +int cross_vm_dataports_init(vmm_t *vmm) { + return cross_vm_dataports_init_common(vmm, dataports, sizeof(dataports)/sizeof(dataports[0])); +} + +int cross_vm_emits_events_init(vmm_t *vmm) { + return cross_vm_emits_events_init_common(vmm, emitted_events, + sizeof(emitted_events)/sizeof(emitted_events[0])); +} + +int cross_vm_consumes_events_init(vmm_t *vmm, vspace_t *vspace, seL4_Word irq_badge) { + return cross_vm_consumes_events_init_common(vmm, vspace, &cross_vm_event_mutex, + consumed_events, sizeof(consumed_events)/sizeof(consumed_events[0]), irq_badge); +} +/*-- endfilter -*/ +``` + +### Update the build system + +**Exercise** Make the following changes in `CMakeLists.txt` by firstly replacing the declaration of Init0: + +```cmake +/*-- filter TaskContent("crossvm", TaskContentType.BEFORE, subtask="vm-cmake-init0", completion='buildroot login') -*/ +DeclareCAmkESVM(Init0) +/*-- endfilter -*/ +``` + +with the following declaration: + +```cmake +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-init0", completion='buildroot login') -*/ +# Retrieve Init0 cross vm src files +file(GLOB init0_extra src/*.c) +# Declare VM component: Init0 +DeclareCAmkESVM(Init0 + EXTRA_SOURCES ${init0_extra} + EXTRA_LIBS crossvm +) +/*-- endfilter -*/ +``` + +Also add a declaration for a PrintServer component: + +```cmake +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-printserver", completion='buildroot login') -*/ +# Declare the CAmkES PrintServer component +DeclareCAmkESComponent(PrintServer SOURCES components/print_server.c) +/*-- endfilter -*/ +``` + +This extends the definition of the Init component with the `cross_vm connector` source and the crossvm +library, and defines the new CAmkES component `PrintServer`. + +### Add interfaces to the Guest + +**Exercise** Create the following `camkes_init` shell script that is executed as Linux is initialized: + +```bash +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-init-crossvm", completion='buildroot login') -*/ +#!/bin/sh +# Initialises linux-side of cross vm connections. + +# Dataport sizes must match those in the camkes spec. +# For each argument to dataport_init, the nth pair +# corresponds to the dataport with id n. +dataport_init /dev/camkes_data 4096 + +# The nth argument to event_init corresponds to the +# event with id n according to the camkes vmm. +consumes_event_init /dev/camkes_done_printing +emits_event_init /dev/camkes_do_print +/*-- endfilter -*/ +``` + +Each of these commands creates device nodes associated with a particular +Linux kernel module supporting cross VM communication. Each command +takes a list of device nodes to create, which must correspond to the IDs +assigned to interfaces in `crossvm_tutorial.camkes` and `cross_vm.c`. The +`dataport_init` command must also be passed the size of each dataport. + +These changes will cause device nodes to be created which correspond to +the interfaces you added to the VMM component. + +### Create a process + +Now make a process that uses the device nodes to communicate with the +print server. + +**Exercise** First create a new directory: +``` +mkdir -p pkgs/print_client +``` + +with the following file `pkgs/print_client/print_client.c`: + +```c +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-pkg-print_client-src", completion='buildroot login') -*/ +#include +#include + +#include +#include +#include +#include + +#include "dataport.h" +#include "consumes_event.h" +#include "emits_event.h" + +int main(int argc, char *argv[]) { + + int data_fd = open("/dev/camkes_data", O_RDWR); + assert(data_fd >= 0); + + int do_print_fd = open("/dev/camkes_do_print", O_RDWR); + assert(do_print_fd >= 0); + + int done_printing_fd = open("/dev/camkes_done_printing", O_RDWR); + assert(done_printing_fd >= 0); + + char *data = (char*)dataport_mmap(data_fd); + assert(data != MAP_FAILED); + + ssize_t dataport_size = dataport_get_size(data_fd); + assert(dataport_size > 0); + + for (int i = 1; i < argc; i++) { + strncpy(data, argv[i], dataport_size); + emits_event_emit(do_print_fd); + consumes_event_wait(done_printing_fd); + } + + close(data_fd); + close(do_print_fd); + close(done_printing_fd); + + return 0; +} +/*-- endfilter -*/ +``` + +This program prints each of its arguments on a separate line, by sending +each argument to the print server one at a time. + +**Exercise** Create `pkgs/print_client/CMakeLists.txt` for our client program: + +```cmake +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-pkg-print_client-cmake", completion='buildroot login') -*/ +cmake_minimum_required(VERSION 3.8.2) + +project(print_client C) + +file(READ ${CMAKE_MODULE_PATH_FILE} module_path) +list(APPEND CMAKE_MODULE_PATH ${module_path}) +find_package(camkes-vm-linux REQUIRED) +add_subdirectory(${CAMKES_VM_LINUX_DIR}/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/libs/camkes camkes) + +add_executable(print_client print_client.c) +target_link_libraries(print_client camkeslinux) +/*-- endfilter -*/ +``` + +**Exercise** Update our the VM apps `CMakeLists.txt`. Below the line: + +```cmake +AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel) +``` + +add the `ExternalProject` declaration to include the print application: + +```cmake +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-printclient-proj", completion='buildroot login') -*/ +# Get Custom toolchain for 32 bit Linux +include(cross_compiling) +FindCustomPollyToolchain(LINUX_32BIT_TOOLCHAIN "linux-gcc-32bit-pic") +# Declare our print server app external project +include(ExternalProject) +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/module_path "${CMAKE_MODULE_PATH}") +ExternalProject_Add(print_client-app + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/pkgs/print_client + BINARY_DIR ${CMAKE_BINARY_DIR}/print_client-app + BUILD_ALWAYS ON + STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/print_client-app-stamp + EXCLUDE_FROM_ALL + INSTALL_COMMAND "" + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_TOOLCHAIN_FILE=${LINUX_32BIT_TOOLCHAIN} + -DCMAKE_MODULE_PATH_FILE=${CMAKE_CURRENT_BINARY_DIR}/module_path +) +# Add the print client app to our overlay ('default_buildroot_overlay') +AddExternalProjFilesToOverlay(print_client-app ${CMAKE_BINARY_DIR}/print_client-app default_buildroot_overlay "usr/sbin" + FILES print_client) +/*-- endfilter -*/ +``` + +Directly below this we also want to add our `camkes_init` script into the overlay. We place this into the VMs `init.d` directory so +the script is run on start up: + +```cmake +/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-camkes_init", completion='buildroot login') -*/ +AddFileToOverlayDir("S90camkes_init" ${CMAKE_CURRENT_LIST_DIR}/camkes_init "etc/init.d" default_buildroot_overlay) +/*-- endfilter -*/ +``` + +That's it. Build and run the system, and you should see the following output: + +``` +... +Creating dataport node /dev/camkes_data +Allocating 4096 bytes for /dev/camkes_data +Creating consuming event node /dev/camkes_done_printing +Creating emitting event node /dev/camkes_do_print + +Welcome to Buildroot +buildroot login: root +Password: +# print_client hello world +[ 12.730073] dataport received mmap for minor 1 +hello +world +``` + +/*- filter ExcludeDocs() -*/ + +```cmake +/*- filter File("CMakeLists.txt") -*/ +include(${SEL4_TUTORIALS_DIR}/settings.cmake) +sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR}) + +cmake_minimum_required(VERSION 3.8.2) + +project(vm-app C ASM) +find_package(camkes-vm REQUIRED) +include(${CAMKES_VM_SETTINGS_PATH}) +camkes_x86_vm_setup_x86_vm_environment() +include(${CAMKES_VM_HELPERS_PATH}) +find_package(camkes-vm-linux REQUIRED) +include(${CAMKES_VM_LINUX_HELPERS_PATH}) + +include(simulation) +GenerateSimulateScript() + +# Check kernel config options +if(NOT "${KernelX86Sel4Arch}" STREQUAL "x86_64") + message(FATAL_ERROR "This application is only supported on x86_64") +endif() +if(NOT "${KernelMaxNumNodes}" STREQUAL 1) + message(FATAL_ERROR "KernelMaxNumNodes must be set to 1 but are set to:${KernelMaxNumNodes}") +endif() + +/*? include_task_type_append([("crossvm", "vm-cmake-init0")]) ?*/ +/*? include_task_type_append([("crossvm", "vm-cmake-printserver")]) ?*/ +# Get Default Linux VM files +GetArchDefaultLinuxKernelFile("32" default_kernel_file) +GetArchDefaultLinuxRootfsFile("32" default_rootfs_file) + +# Decompress Linux Kernel image and add to file server +DecompressLinuxKernel(extract_linux_kernel decompressed_kernel ${default_kernel_file}) + +AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel) + +/*? include_task_type_append([("crossvm", "vm-cmake-printclient-proj")]) ?*/ +/*? include_task_type_append([("crossvm", "vm-cmake-camkes_init")]) ?*/ +/*? include_task_type_append([("crossvm", "vm-cmake-start")]) ?*/ +# Initialise CAmkES Root Server with addition CPP includes +DeclareCAmkESVMRootServer(crossvm_tutorial.camkes) +GenerateCAmkESRootserver() +/*- endfilter -*/ +``` + +```c +/*- filter File("crossvm_tutorial.camkes") --*/ +import ; + +#include + +#define VM_GUEST_CMDLINE "earlyprintk=ttyS0,115200 console=ttyS0,115200 i8042.nokbd=y i8042.nomux=y \ +i8042.noaux=y io_delay=udelay noisapnp pci=nomsi debug root=/dev/mem" + +/*? include_task_type_append([("crossvm", "vm-camkes-init0")]) ?*/ +/*? include_task_type_append([("crossvm", "vm-camkes-printserver")]) ?*/ +assembly { + + /*? include_task_type_append([("crossvm", "vm-camkes-composition")]) ?*/ + configuration { + VM_CONFIGURATION_DEF() + VM_PER_VM_CONFIG_DEF(0) + + vm0.simple_untyped23_pool = 20; + vm0.heap_size = 0x2000000; + vm0.guest_ram_mb = 128; + vm0.kernel_cmdline = VM_GUEST_CMDLINE; + vm0.kernel_image = "bzimage"; + vm0.kernel_relocs = "bzimage"; + vm0.initrd_image = "rootfs.cpio"; + vm0.iospace_domain = 0x0f; + /*? include_task_type_append([("crossvm", "vm-camkes-configuration")]) ?*/ + } +} +/*- endfilter -*/ +``` + +```c +/*- filter File("components/print_server.c") --*/ +/*? include_task_type_append([("crossvm", "vm-printserver")]) ?*/ +/*- endfilter -*/ +``` + +```c +/*- filter File("src/cross_vm.c") --*/ +/*? include_task_type_append([("crossvm", "vm-crossvm-src")]) ?*/ +/*- endfilter -*/ +``` + +```bash +/*- filter File("camkes_init", mode="executable") --*/ +/*? include_task_type_append([("crossvm", "vm-init-crossvm")]) ?*/ +/*- endfilter -*/ +``` + +```c +/*- filter File("pkgs/print_client/print_client.c") --*/ +/*? include_task_type_append([("crossvm", "vm-pkg-print_client-src")]) ?*/ +/*- endfilter -*/ +``` + +```cmake +/*- filter File("pkgs/print_client/CMakeLists.txt") --*/ +/*? include_task_type_append([("crossvm", "vm-pkg-print_client-cmake")]) ?*/ +/*- endfilter -*/ +``` + +/*- endfilter -*/ From 6505987e309c0a5d4e4a45186e672e87039a21e2 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 23 Aug 2024 12:02:50 +1000 Subject: [PATCH 099/103] fix solutions css styling and pointer Signed-off-by: Birgit Brecknell --- Tutorials/setting-up.md | 4 ++-- assets/css/style.scss | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Tutorials/setting-up.md b/Tutorials/setting-up.md index dd6639698e..ae34b36a38 100644 --- a/Tutorials/setting-up.md +++ b/Tutorials/setting-up.md @@ -18,7 +18,7 @@ To install run: ```
        -More on Repo +More on Repo
        [More details about on installing Repo](https://source.android.com/setup/develop#installing-repo). @@ -44,7 +44,7 @@ sudo usermod -aG docker $(whoami) ```
        - More on Docker + More on Docker
        **Available images** diff --git a/assets/css/style.scss b/assets/css/style.scss index e4bc2eeea5..b4f50107da 100644 --- a/assets/css/style.scss +++ b/assets/css/style.scss @@ -308,5 +308,10 @@ a[href*="//"]:not([href*="{{site.url}}"],.skip-icon):after { /* add margin below tutorials solutions boxes */ details { + cursor: pointer; padding-bottom: 20px; } + +summary { + display:list-item; +} From fd00916b90e1d31f1b7091da3630a971b244fcee Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 23 Aug 2024 12:57:27 +1000 Subject: [PATCH 100/103] fix pointer for expanded solutions box Signed-off-by: Birgit Brecknell --- assets/css/style.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/assets/css/style.scss b/assets/css/style.scss index b4f50107da..85a44ffb94 100644 --- a/assets/css/style.scss +++ b/assets/css/style.scss @@ -306,12 +306,13 @@ a[href*="//"]:not([href*="{{site.url}}"],.skip-icon):after { width: 32%; } -/* add margin below tutorials solutions boxes */ +/* tutorials solutions boxes */ details { - cursor: pointer; padding-bottom: 20px; } - summary { display:list-item; } +details > summary { + cursor: pointer; +} From 6e5059fa2bfcc4fe47059f79963147a8fdfe8faa Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Fri, 23 Aug 2024 13:19:07 +1000 Subject: [PATCH 101/103] remove accidental commit of camkes-vm Signed-off-by: Birgit Brecknell --- camkes-vm-crossvm/camkes-vm-crossvm.md | 650 ------------------------- 1 file changed, 650 deletions(-) delete mode 100644 camkes-vm-crossvm/camkes-vm-crossvm.md diff --git a/camkes-vm-crossvm/camkes-vm-crossvm.md b/camkes-vm-crossvm/camkes-vm-crossvm.md deleted file mode 100644 index 72b0e2162c..0000000000 --- a/camkes-vm-crossvm/camkes-vm-crossvm.md +++ /dev/null @@ -1,650 +0,0 @@ - - -/*? declare_task_ordering([ - 'crossvm' -]) ?*/ - -# CAmkES VM: Cross VM Connectors - -This tutorial provides an introduction to using the cross virtual machine (VM) connector mechanisms -provided by seL4 and Camkes in order to connect processes in a guest Linux instance to Camkes components. - -In this tutorial you will learn how to: - -* Configure processes in a Linux guest VM to communicate with CAmkES components - -## Prerequisites -1. [Set up your machine](https://docs.sel4.systems/tutorials/setting-up) -2. [CAmkES VM Linux tutorial](https://docs.sel4.systems/tutorials/camkes-vm-linux) - -*Note that the instructions for this tutorial are for Linux only.* - -## Initialising - -/*? macros.tutorial_init("camkes-vm-crossvm") ?*/ - -
        -Hint: tutorial solutions -
        -All tutorials come with complete solutions. To get solutions run: - -/*? macros.tutorial_init_with_solution("camkes-vm-crossvm") ?*/ -
        - -## Background - -In order to connect guest Linux instances to CAmkES components, -three additional kernel modules must be installed in the guest. -These modules are included in the root filesystem by default: - -- `dataport`: facilitates setting up shared memory between the guest -and CAmkES components. -- `consumes_event`: allows a process in the guest to wait or poll -for an event sent by a CAmkES component. -- `emits_event`: allows a process to emit an event to a CAmkES component. - -Each type of module can be statically assigned to one or more file descriptors to associate that -file descriptor with a specific instance of an interface. `ioctl` can then be used to -manipulate that file descriptor and use the module. - -### Dataports - -Dataports are the mechanism which allows guests and components to share memory. -The dataport initialisation process is as follows: - -- The guest process uses `ioctl` on on the file associated with the dataport and specify a - page-aligned size for the shared memory. -- The dataport kernel module in the guest then allocates a page-aligned buffer of the requested size, - and makes a hypercall to the VMM, with the guest physical address and id of the data port. - The ID is derived from the file on which `ioctl` was called. -- The virtual machine manager (VMM) then modifies the guest's address space, creating the shared memory region. - between a camkes component and the guest. -- Linux processes can then map this memory into their own address space by calling `mmap` on the file - associated with the dataport. - -### Emitting Events - -Guest processes can emit events by using `ioctl` on files associated with the event interface. -This results in the `emits_event` kernel module in the guest making a -making a hypercall to the VMM, which triggers the event and resumes the guest. - -### Consuming Events - -Linux process can wait or poll for an event by calling `poll` -on the file associated with that event, using the timeout argument to -specify whether or not it should block. The event it polls for is -`POLLIN`. When the VMM receives an event destined for the guest, it places -the event id in some memory shared between the VMM and the -`consumes_event` kernel module, and then injects an interrupt into the -guest. The `consumes_event` kernel module is registered to handle this -interrupt, which reads the event ID from shared memory, and wakes a -thread blocked on the corresponding event file. If no threads are -blocked on the file, some state is set in the module such that the next -time a process waits on that file, it returns immediately and clears the -state, mimicking the behaviour of notifications. - -## Exercises - -In this tutorial you will -create a program that runs in the guest, and sends a string -to a CAmkES component to output. To achieve this, the guest program will write a string -to a shared buffer between itself and a CAmkES component. When its ready -for the string to be printed, it will emit an event, received by the -CAmkES component. The CAmkES component will print the string, then send -an event to the guest process so the guest knows it's safe to send a new -string. - -### Add modules to the guest - -There is a library in `projects/camkes/vm-linux/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/libs` -containing Linux system call wrappers, and some utility programs in -`projects/camkes/vm-linux/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/pkgs/{dataport,consumes_event,emits_event}` -which initialize and interact with cross VM connections. To build and use these modules in your rootfs the vm-linux -project provides an overlay target you can use. - -**Exercise** First add the `dataport`, `consumes_event` and `emits_event` kernel modules to the rootfs in the guest. - -Start by replacing the line: - -```cmake -/*-- filter TaskContent("crossvm", TaskContentType.BEFORE, subtask="vm-cmake-start", completion='buildroot login') -*/ -AddToFileServer("rootfs.cpio" ${default_rootfs_file}) -/*-- endfilter -*/ -``` - -in the target applications `CMakeLists.txt` file with the following: - -```cmake -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-start", completion='buildroot login') -*/ -set(CAmkESVMDefaultBuildrootOverlay ON CACHE BOOL "" FORCE) -AddOverlayDirToRootfs(default_buildroot_overlay ${default_rootfs_file} "buildroot" "rootfs_install" - rootfs_file rootfs_target) -AddToFileServer("rootfs.cpio" ${rootfs_file}) -/*-- endfilter -*/ -``` - -### Define interfaces in the VMM - -**Exercise** Update the CAmkES file, `crossvm_tutorial.camkes` by replacing the Init0 component definition: - -```c -/*-- filter TaskContent("crossvm", TaskContentType.BEFORE, subtask="vm-camkes-init0") -*/ -component Init0 { - VM_INIT_DEF() -} -/*-- endfilter -*/ -``` - -with the following definition: - -```c -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-camkes-init0", completion='buildroot login') -*/ -component Init0 { - VM_INIT_DEF() - - // this is the data port for shared memory between the component and guest process - dataport Buf(4096) data; - // this event tells the component that there is data ready to print - emits DoPrint do_print; - // this event tells the guest process that priting is complete - consumes DonePrinting done_printing; - // this mutex protects access to shared state between the VMM and the guest Linux - has mutex cross_vm_event_mutex; -} -/*-- endfilter -*/ -``` - -These interfaces will eventually be made visible to processes running in -the guest linux. The mutex is used to protect access to shared state -between the VMM and guest. - -### Define the component interface - -**Exercise** Define the print server component by adding the following to -the `crossvm_tutorial.camkes` file, after the `Init0` definition: -```c -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-camkes-printserver", completion='buildroot login') -*/ -component PrintServer { - control; - dataport Buf(4096) data; - consumes DoPrint do_print; - emits DonePrinting done_printing; -} -/*-- endfilter -*/ -``` - -### Instantiate the print server - -**Exercise** Replace the `composition` definition: - -```c -/*-- filter TaskContent("crossvm", TaskContentType.BEFORE, subtask="vm-camkes-composition", completion='buildroot login') -*/ - composition { - VM_COMPOSITION_DEF() - VM_PER_VM_COMP_DEF(0) - } -/*-- endfilter -*/ -``` - -with the following: - -```c -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-camkes-composition", completion='buildroot login') -*/ - composition { - VM_COMPOSITION_DEF() - VM_PER_VM_COMP_DEF(0) - - component PrintServer print_server; - connection seL4Notification conn_do_print(from vm0.do_print, - to print_server.do_print); - connection seL4Notification conn_done_printing(from print_server.done_printing, - to vm0.done_printing); - - connection seL4SharedDataWithCaps conn_data(from print_server.data, - to vm0.data); - } -/*-- endfilter -*/ -``` - -The [seL4SharedDataWithCaps][] -connector is a dataport connector much like `seL4SharedData`. -However, the `to` side of the connection also receives access to -the capabilities to the frames backing the dataport, which is required -for cross VM dataports, as the VMM must be able to establish shared memory -at runtime by inserting new mappings into the guest's address space. - -[seL4SharedDataWithCaps]: https://docs.sel4.systems/projects/camkes/seL4SharedDataWithCaps.html - -**Exercise** Interfaces connected with [seL4SharedDataWithCaps][] must be -configured with an integer specifying the ID and size of the dataport. - Do this now by modifying `crossvm_tutorial.camkes` with the following -two lines in the configuration section: - -```c - configuration { - ... -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-camkes-configuration", completion='buildroot login') -*/ - // Add the following 2 lines: - vm0.data_id = 1; // ids must be contiguous, starting from 1 - vm0.data_size = 4096; -/*-- endfilter -*/ - } -``` - -### Implement the print server - -**Exercise** Add the file `components/print_server.c` with the following contents: -```c -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-printserver", completion='buildroot login') -*/ -#include -#include - -int run(void) { - - while (1) { - // wait for the next event - do_print_wait(); - - printf("%s\n", (char*)data); - - // signal that we are done printing - done_printing_emit(); - } - - return 0; -} -/*-- endfilter -*/ -``` - -This provides a very simple component definition that loops forever, printing a string from -shared memory whenever an event is received then emitting an event. -The example code assumes that the shared buffer will contain a valid, null-terminated c string, which is not - something you should do in practice. - -### Implement the VMM side of the connection -Create another c file that tells the VMM about the cross VM connections. - This file must define 3 functions which initialize each type of cross vm interface: - -- `cross_vm_dataports_init` -- `cross_vm_emits_events_init` -- `cross_vm_consumes_events_init` - -**Exercise** Add a file `src/cross_vm.c` with the following contents: - -```c -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-crossvm-src", completion='buildroot login') -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// this is defined in the dataport's glue code -extern dataport_caps_handle_t data_handle; - -// Array of dataport handles at positions corresponding to handle ids from spec -static dataport_caps_handle_t *dataports[] = { - NULL, // entry 0 is NULL so ids correspond with indices - &data_handle, -}; - -// Array of consumed event callbacks and ids -static camkes_consumes_event_t consumed_events[] = { - { .id = 1, .reg_callback = done_printing_reg_callback }, -}; - -// Array of emitted event emit functions -static camkes_emit_fn emitted_events[] = { - NULL, // entry 0 is NULL so ids correspond with indices - do_print_emit, -}; - -// mutex to protect shared event context -static camkes_mutex_t cross_vm_event_mutex = (camkes_mutex_t) { - .lock = cross_vm_event_mutex_lock, - .unlock = cross_vm_event_mutex_unlock, -}; - -int cross_vm_dataports_init(vmm_t *vmm) { - return cross_vm_dataports_init_common(vmm, dataports, sizeof(dataports)/sizeof(dataports[0])); -} - -int cross_vm_emits_events_init(vmm_t *vmm) { - return cross_vm_emits_events_init_common(vmm, emitted_events, - sizeof(emitted_events)/sizeof(emitted_events[0])); -} - -int cross_vm_consumes_events_init(vmm_t *vmm, vspace_t *vspace, seL4_Word irq_badge) { - return cross_vm_consumes_events_init_common(vmm, vspace, &cross_vm_event_mutex, - consumed_events, sizeof(consumed_events)/sizeof(consumed_events[0]), irq_badge); -} -/*-- endfilter -*/ -``` - -### Update the build system - -**Exercise** Make the following changes in `CMakeLists.txt` by firstly replacing the declaration of Init0: - -```cmake -/*-- filter TaskContent("crossvm", TaskContentType.BEFORE, subtask="vm-cmake-init0", completion='buildroot login') -*/ -DeclareCAmkESVM(Init0) -/*-- endfilter -*/ -``` - -with the following declaration: - -```cmake -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-init0", completion='buildroot login') -*/ -# Retrieve Init0 cross vm src files -file(GLOB init0_extra src/*.c) -# Declare VM component: Init0 -DeclareCAmkESVM(Init0 - EXTRA_SOURCES ${init0_extra} - EXTRA_LIBS crossvm -) -/*-- endfilter -*/ -``` - -Also add a declaration for a PrintServer component: - -```cmake -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-printserver", completion='buildroot login') -*/ -# Declare the CAmkES PrintServer component -DeclareCAmkESComponent(PrintServer SOURCES components/print_server.c) -/*-- endfilter -*/ -``` - -This extends the definition of the Init component with the `cross_vm connector` source and the crossvm -library, and defines the new CAmkES component `PrintServer`. - -### Add interfaces to the Guest - -**Exercise** Create the following `camkes_init` shell script that is executed as Linux is initialized: - -```bash -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-init-crossvm", completion='buildroot login') -*/ -#!/bin/sh -# Initialises linux-side of cross vm connections. - -# Dataport sizes must match those in the camkes spec. -# For each argument to dataport_init, the nth pair -# corresponds to the dataport with id n. -dataport_init /dev/camkes_data 4096 - -# The nth argument to event_init corresponds to the -# event with id n according to the camkes vmm. -consumes_event_init /dev/camkes_done_printing -emits_event_init /dev/camkes_do_print -/*-- endfilter -*/ -``` - -Each of these commands creates device nodes associated with a particular -Linux kernel module supporting cross VM communication. Each command -takes a list of device nodes to create, which must correspond to the IDs -assigned to interfaces in `crossvm_tutorial.camkes` and `cross_vm.c`. The -`dataport_init` command must also be passed the size of each dataport. - -These changes will cause device nodes to be created which correspond to -the interfaces you added to the VMM component. - -### Create a process - -Now make a process that uses the device nodes to communicate with the -print server. - -**Exercise** First create a new directory: -``` -mkdir -p pkgs/print_client -``` - -with the following file `pkgs/print_client/print_client.c`: - -```c -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-pkg-print_client-src", completion='buildroot login') -*/ -#include -#include - -#include -#include -#include -#include - -#include "dataport.h" -#include "consumes_event.h" -#include "emits_event.h" - -int main(int argc, char *argv[]) { - - int data_fd = open("/dev/camkes_data", O_RDWR); - assert(data_fd >= 0); - - int do_print_fd = open("/dev/camkes_do_print", O_RDWR); - assert(do_print_fd >= 0); - - int done_printing_fd = open("/dev/camkes_done_printing", O_RDWR); - assert(done_printing_fd >= 0); - - char *data = (char*)dataport_mmap(data_fd); - assert(data != MAP_FAILED); - - ssize_t dataport_size = dataport_get_size(data_fd); - assert(dataport_size > 0); - - for (int i = 1; i < argc; i++) { - strncpy(data, argv[i], dataport_size); - emits_event_emit(do_print_fd); - consumes_event_wait(done_printing_fd); - } - - close(data_fd); - close(do_print_fd); - close(done_printing_fd); - - return 0; -} -/*-- endfilter -*/ -``` - -This program prints each of its arguments on a separate line, by sending -each argument to the print server one at a time. - -**Exercise** Create `pkgs/print_client/CMakeLists.txt` for our client program: - -```cmake -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-pkg-print_client-cmake", completion='buildroot login') -*/ -cmake_minimum_required(VERSION 3.8.2) - -project(print_client C) - -file(READ ${CMAKE_MODULE_PATH_FILE} module_path) -list(APPEND CMAKE_MODULE_PATH ${module_path}) -find_package(camkes-vm-linux REQUIRED) -add_subdirectory(${CAMKES_VM_LINUX_DIR}/camkes-linux-artifacts/camkes-linux-apps/camkes-connector-apps/libs/camkes camkes) - -add_executable(print_client print_client.c) -target_link_libraries(print_client camkeslinux) -/*-- endfilter -*/ -``` - -**Exercise** Update our the VM apps `CMakeLists.txt`. Below the line: - -```cmake -AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel) -``` - -add the `ExternalProject` declaration to include the print application: - -```cmake -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-printclient-proj", completion='buildroot login') -*/ -# Get Custom toolchain for 32 bit Linux -include(cross_compiling) -FindCustomPollyToolchain(LINUX_32BIT_TOOLCHAIN "linux-gcc-32bit-pic") -# Declare our print server app external project -include(ExternalProject) -file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/module_path "${CMAKE_MODULE_PATH}") -ExternalProject_Add(print_client-app - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/pkgs/print_client - BINARY_DIR ${CMAKE_BINARY_DIR}/print_client-app - BUILD_ALWAYS ON - STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/print_client-app-stamp - EXCLUDE_FROM_ALL - INSTALL_COMMAND "" - CMAKE_ARGS - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_TOOLCHAIN_FILE=${LINUX_32BIT_TOOLCHAIN} - -DCMAKE_MODULE_PATH_FILE=${CMAKE_CURRENT_BINARY_DIR}/module_path -) -# Add the print client app to our overlay ('default_buildroot_overlay') -AddExternalProjFilesToOverlay(print_client-app ${CMAKE_BINARY_DIR}/print_client-app default_buildroot_overlay "usr/sbin" - FILES print_client) -/*-- endfilter -*/ -``` - -Directly below this we also want to add our `camkes_init` script into the overlay. We place this into the VMs `init.d` directory so -the script is run on start up: - -```cmake -/*-- filter TaskContent("crossvm", TaskContentType.COMPLETED, subtask="vm-cmake-camkes_init", completion='buildroot login') -*/ -AddFileToOverlayDir("S90camkes_init" ${CMAKE_CURRENT_LIST_DIR}/camkes_init "etc/init.d" default_buildroot_overlay) -/*-- endfilter -*/ -``` - -That's it. Build and run the system, and you should see the following output: - -``` -... -Creating dataport node /dev/camkes_data -Allocating 4096 bytes for /dev/camkes_data -Creating consuming event node /dev/camkes_done_printing -Creating emitting event node /dev/camkes_do_print - -Welcome to Buildroot -buildroot login: root -Password: -# print_client hello world -[ 12.730073] dataport received mmap for minor 1 -hello -world -``` - -/*- filter ExcludeDocs() -*/ - -```cmake -/*- filter File("CMakeLists.txt") -*/ -include(${SEL4_TUTORIALS_DIR}/settings.cmake) -sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR}) - -cmake_minimum_required(VERSION 3.8.2) - -project(vm-app C ASM) -find_package(camkes-vm REQUIRED) -include(${CAMKES_VM_SETTINGS_PATH}) -camkes_x86_vm_setup_x86_vm_environment() -include(${CAMKES_VM_HELPERS_PATH}) -find_package(camkes-vm-linux REQUIRED) -include(${CAMKES_VM_LINUX_HELPERS_PATH}) - -include(simulation) -GenerateSimulateScript() - -# Check kernel config options -if(NOT "${KernelX86Sel4Arch}" STREQUAL "x86_64") - message(FATAL_ERROR "This application is only supported on x86_64") -endif() -if(NOT "${KernelMaxNumNodes}" STREQUAL 1) - message(FATAL_ERROR "KernelMaxNumNodes must be set to 1 but are set to:${KernelMaxNumNodes}") -endif() - -/*? include_task_type_append([("crossvm", "vm-cmake-init0")]) ?*/ -/*? include_task_type_append([("crossvm", "vm-cmake-printserver")]) ?*/ -# Get Default Linux VM files -GetArchDefaultLinuxKernelFile("32" default_kernel_file) -GetArchDefaultLinuxRootfsFile("32" default_rootfs_file) - -# Decompress Linux Kernel image and add to file server -DecompressLinuxKernel(extract_linux_kernel decompressed_kernel ${default_kernel_file}) - -AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel) - -/*? include_task_type_append([("crossvm", "vm-cmake-printclient-proj")]) ?*/ -/*? include_task_type_append([("crossvm", "vm-cmake-camkes_init")]) ?*/ -/*? include_task_type_append([("crossvm", "vm-cmake-start")]) ?*/ -# Initialise CAmkES Root Server with addition CPP includes -DeclareCAmkESVMRootServer(crossvm_tutorial.camkes) -GenerateCAmkESRootserver() -/*- endfilter -*/ -``` - -```c -/*- filter File("crossvm_tutorial.camkes") --*/ -import ; - -#include - -#define VM_GUEST_CMDLINE "earlyprintk=ttyS0,115200 console=ttyS0,115200 i8042.nokbd=y i8042.nomux=y \ -i8042.noaux=y io_delay=udelay noisapnp pci=nomsi debug root=/dev/mem" - -/*? include_task_type_append([("crossvm", "vm-camkes-init0")]) ?*/ -/*? include_task_type_append([("crossvm", "vm-camkes-printserver")]) ?*/ -assembly { - - /*? include_task_type_append([("crossvm", "vm-camkes-composition")]) ?*/ - configuration { - VM_CONFIGURATION_DEF() - VM_PER_VM_CONFIG_DEF(0) - - vm0.simple_untyped23_pool = 20; - vm0.heap_size = 0x2000000; - vm0.guest_ram_mb = 128; - vm0.kernel_cmdline = VM_GUEST_CMDLINE; - vm0.kernel_image = "bzimage"; - vm0.kernel_relocs = "bzimage"; - vm0.initrd_image = "rootfs.cpio"; - vm0.iospace_domain = 0x0f; - /*? include_task_type_append([("crossvm", "vm-camkes-configuration")]) ?*/ - } -} -/*- endfilter -*/ -``` - -```c -/*- filter File("components/print_server.c") --*/ -/*? include_task_type_append([("crossvm", "vm-printserver")]) ?*/ -/*- endfilter -*/ -``` - -```c -/*- filter File("src/cross_vm.c") --*/ -/*? include_task_type_append([("crossvm", "vm-crossvm-src")]) ?*/ -/*- endfilter -*/ -``` - -```bash -/*- filter File("camkes_init", mode="executable") --*/ -/*? include_task_type_append([("crossvm", "vm-init-crossvm")]) ?*/ -/*- endfilter -*/ -``` - -```c -/*- filter File("pkgs/print_client/print_client.c") --*/ -/*? include_task_type_append([("crossvm", "vm-pkg-print_client-src")]) ?*/ -/*- endfilter -*/ -``` - -```cmake -/*- filter File("pkgs/print_client/CMakeLists.txt") --*/ -/*? include_task_type_append([("crossvm", "vm-pkg-print_client-cmake")]) ?*/ -/*- endfilter -*/ -``` - -/*- endfilter -*/ From 76200072dd3cbaa6e0b15312968591c2deb37dcc Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 26 Aug 2024 10:58:03 +1000 Subject: [PATCH 102/103] remove breadcrumb naming hack Signed-off-by: Birgit Brecknell --- Tutorials/index.md | 2 +- Tutorials/pathways.md | 2 +- _includes/custom-navbar.html | 7 +------ 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Tutorials/index.md b/Tutorials/index.md index 24b22940b9..3f9b635e76 100644 --- a/Tutorials/index.md +++ b/Tutorials/index.md @@ -1,9 +1,9 @@ --- toc: true +title: Tutorials layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2024 seL4 Project a Series of LF Projects, LLC. -redirect_from: /projects/sel4-tutorials/ --- # Overview diff --git a/Tutorials/pathways.md b/Tutorials/pathways.md index 207629e1cc..46bf7b9023 100644 --- a/Tutorials/pathways.md +++ b/Tutorials/pathways.md @@ -1,6 +1,6 @@ --- toc: true -title: Tutorial pathways +title: Pathways layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2020 seL4 Project a Series of LF Projects, LLC. diff --git a/_includes/custom-navbar.html b/_includes/custom-navbar.html index 0a8ad693d9..d5966f0441 100644 --- a/_includes/custom-navbar.html +++ b/_includes/custom-navbar.html @@ -18,12 +18,7 @@ From bcbc394a21e5626f75ff293eabb42fbac3908404 Mon Sep 17 00:00:00 2001 From: Birgit Brecknell Date: Mon, 26 Aug 2024 11:48:24 +1000 Subject: [PATCH 103/103] update camkes and library headers Signed-off-by: Birgit Brecknell --- Tutorials/camkes-vm-crossvm.md | 2 +- Tutorials/hello-camkes-0.md | 2 +- Tutorials/hello-camkes-1.md | 2 +- Tutorials/hello-camkes-2.md | 2 +- Tutorials/hello-camkes-timer.md | 2 +- Tutorials/libraries-1.md | 2 +- Tutorials/libraries-2.md | 2 +- Tutorials/libraries-3.md | 2 +- Tutorials/libraries-4.md | 2 +- _data/projects/sel4-tutorials.yml | 10 +++++----- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Tutorials/camkes-vm-crossvm.md b/Tutorials/camkes-vm-crossvm.md index 2b03b8962c..729f3579c4 100644 --- a/Tutorials/camkes-vm-crossvm.md +++ b/Tutorials/camkes-vm-crossvm.md @@ -1,6 +1,6 @@ --- toc: true -title: Camkes Cross-VM communication +title: Camkes cross-VM connectors tutorial: camkes-vm-crossvm tutorial-order: vm-2 layout: tutorial diff --git a/Tutorials/hello-camkes-0.md b/Tutorials/hello-camkes-0.md index 35b8f5abf3..692f565545 100644 --- a/Tutorials/hello-camkes-0.md +++ b/Tutorials/hello-camkes-0.md @@ -1,6 +1,6 @@ --- toc: true -title: Camkes +title: Hello CAmkES tutorial: hello-camkes-0 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/Tutorials/hello-camkes-1.md b/Tutorials/hello-camkes-1.md index 6eee75c2fa..37d2a54a92 100644 --- a/Tutorials/hello-camkes-1.md +++ b/Tutorials/hello-camkes-1.md @@ -1,6 +1,6 @@ --- toc: true -title: Camkes 1 +title: Introduction to CAmkES tutorial: hello-camkes-1 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/Tutorials/hello-camkes-2.md b/Tutorials/hello-camkes-2.md index 43380fd551..110cdf631f 100644 --- a/Tutorials/hello-camkes-2.md +++ b/Tutorials/hello-camkes-2.md @@ -1,6 +1,6 @@ --- toc: true -title: Camkes 2 +title: Events in CAmkES tutorial: hello-camkes-2 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/Tutorials/hello-camkes-timer.md b/Tutorials/hello-camkes-timer.md index 2c65983dc2..852127779f 100644 --- a/Tutorials/hello-camkes-timer.md +++ b/Tutorials/hello-camkes-timer.md @@ -1,6 +1,6 @@ --- toc: true -title: Camkes 3 +title: CAmkES timer tutorial tutorial: hello-camkes-timer layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/Tutorials/libraries-1.md b/Tutorials/libraries-1.md index 40ff94e043..f16348251b 100644 --- a/Tutorials/libraries-1.md +++ b/Tutorials/libraries-1.md @@ -1,6 +1,6 @@ --- toc: true -title: Libraries 1 +title: Libraries initialisation & threading tutorial: libraries-1 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/Tutorials/libraries-2.md b/Tutorials/libraries-2.md index 12be983091..21464a7344 100644 --- a/Tutorials/libraries-2.md +++ b/Tutorials/libraries-2.md @@ -1,6 +1,6 @@ --- toc: true -title: Libraries 2 +title: Libraries IPC tutorial: libraries-2 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/Tutorials/libraries-3.md b/Tutorials/libraries-3.md index 858212203b..0ca7e76a4d 100644 --- a/Tutorials/libraries-3.md +++ b/Tutorials/libraries-3.md @@ -1,6 +1,6 @@ --- toc: true -title: Libraries 3 +title: Libraries processes & ELF loading tutorial: libraries-3 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/Tutorials/libraries-4.md b/Tutorials/libraries-4.md index fcc5f21289..7fe099cb2e 100644 --- a/Tutorials/libraries-4.md +++ b/Tutorials/libraries-4.md @@ -1,6 +1,6 @@ --- toc: true -title: Libraries 4 +title: Libraries timer tutorial tutorial: libraries-4 layout: tutorial SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/_data/projects/sel4-tutorials.yml b/_data/projects/sel4-tutorials.yml index 2abd01f32f..ee35aa28c4 100644 --- a/_data/projects/sel4-tutorials.yml +++ b/_data/projects/sel4-tutorials.yml @@ -90,7 +90,7 @@ components: section: sel4 - name: mcs - display_name: "MCS Extensions" + display_name: "MCS extensions" description: "MCS extension tutorial" maintainer: "seL4 Foundation" status: "active" @@ -138,7 +138,7 @@ components: section: camkes - name: hello-camkes-1 - display_name: "CAmkES 1: Introduction to CAmkES" + display_name: "Introduction to CAmkES" description: "CAmkES ADL and RPC interface tutorial" maintainer: "seL4 Foundation" status: "active" @@ -146,7 +146,7 @@ components: section: camkes - name: hello-camkes-2 - display_name: "CAmkES 2: Events" + display_name: "Events in CAmkES" description: "CAmkES event and dataport tutorial" maintainer: "seL4 Foundation" status: "active" @@ -154,7 +154,7 @@ components: section: camkes - name: hello-camkes-timer - display_name: "CAmkES 3: Timer" + display_name: "CAmkES timer tutorial" description: "CAmkES tutorial for accessing hardware" maintainer: "seL4 Foundation" status: "active" @@ -170,7 +170,7 @@ components: section: camkes - name: camkes-vm-crossvm - display_name: "CAmkES Cross-VM Connectors" + display_name: "CAmkES cross-VM connectors" description: "Tutorial for using cross virtual machine connectors" maintainer: "seL4 Foundation" status: "active"