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
Prerequisites
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.
Revisiting containers
We will use two terminals, as described in Setting up your machine.
- 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
Initialising
Initialise the tutorial in Terminal B, which is running the container.
# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/get-the-tutorials
#
# Follow these instructions to initialise the tutorial
# initialising the build directory with a tutorial exercise
./init --tut hello-world
# building the tutorial exercise
cd hello-world_build
ninja
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:
# For instructions about obtaining the tutorial sources see https://docs.sel4.systems/Tutorials/get-the-tutorials
#
# Follow these instructions to initialise the tutorial
# initialising the build directory with a tutorial exercise
./init --solution --tut hello-world
# building the tutorial exercise
cd hello-world_build
ninja
This will generate another hello-world
directory and hello-world_build
directory, with unique names, e.g. hello-world44h1po5q
and hello-world44h1po5q_build
.
Build the program
cd sel4-tutorials-manifest/hello-world_build
Next, build the program in Terminal B using ninja
# In build directory
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 by:
./simulate
This will run the result on an instance of the QEMU 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.
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)
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.
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello, World!\n");
return 0;
}
Making a change
Test making a change to main.c
by adding a second printf to output "Second hello\n"
.
int main(int argc, char *argv[]) {
printf("Hello, World!\n");
printf("Second hello\n");
return 0;
}
Once you have made your change, use Terminal B to rebuild the project.
Hint: Remember to exit the QEMU simulator before rerunning the project with ctrl-A,x
# In build directory
ninja
Then run the simulator again:
# In build directory
./simulate
On success, you should see the following:
Second hello
Next: Capabilities
Tutorial included from github repo edit