Launching executable programs

with fork/exec

fork() and exec() are provided by Genode's libc.

load_image() implementation

We also supply load_image() (as per Be-style API). The implementation within this directory in api-public_main.cpp is not self-contained, but instead interacts (depends on) the registrar (hai-src/server/registrar).

UPD: the implementation has been moved to sys-libroot/os/image.cpp (but that hierarchy should really be located here in system/ anyway)

Here's an outline of the call chain ; load_image() (or BRoster.Launch(), which amounts to the same) sends a BMessage to the registrar component, which then generate an XML report for the init/dyn component to make it launch the specified program:

App BRoster: Launch() _LaunchApp() load_image() rosterPrivate.RemoteLaunchInRegistrar() BRoster BMessage/RPC call registrar: _HandleLaunch DynRunRoster class Report to ROM init (dyn) App
arrow "App" ""
box  "BRoster:" "Launch()" "_LaunchApp()" fit
arrow down from last box.s

box "load_image()" "rosterPrivate.RemoteLaunchInRegistrar()" fit
arrow right from last box.e
box "BRoster" fit
arrow right 200% from last box.e "BMessage/RPC" "call"

oval "registrar:" "_HandleLaunch" "DynRunRoster class" fit

arrow right 200% "Report" "to ROM"
oval "init (dyn)"


move left from 2nd box.w
arrow right "App" ""

As to init/Dynit, it ultimately makes Genode's 'ldso' load the executable and its .so dependencies either from boot-module ROMs, or via fs_rom which creates virtual ROMs from a file system. Finally, ldso performs the loading in 'struct Linker::Elf_file' with a rom_connection.construct() call.

As far as Depot packages are concerned, the ROMs for the libraries (e.g. qt5.lib.so) are located deep within folder hierarchies. To avoid having to relocate or symlink them at the top of the volume, Genode changes the ROM label to the full path to the library (e.g. /depot/genodelabs/bin/x86_64/qt5/2023-04-25/qt5.lib.so) so that cached_fs_rom will find them -- this is done at the end of depot_deploy's gen_routes().

There are unresolved issues though, with an old Be-style API.

Issues with load_image()

The (historical Be API) load_image() is supposed to return a suspended (paused) thread, and indeed the Be applications that rely on it do call resume_thread() on the heels of load_image().

The issue with our implementation of load_image is

  1. the process we create is not suspended, and
  2. we do not return a valid thread_id

Since our current implementation does not provide 1) and 2), a subsequent resume_thread() call fails/errors out. It's easy to 'patch' the code to work around that (e.g. Roster::Launch()) but this should be looked into.