genode/repos/gems/run/sculpt.run
Norman Feske 9662d89cfb Replace input filter with event filter
This commit applies the transition from the "Input" session to the "Event"
session to the event-filtering mechansim. The functionality of the
input_filter is now provided by the event_filter. The event filter
requests only one "Event" session as destination for the filter result,
which is usually routed to the nitpicker GUI server. It provides an
"Event" service to which any number of event sources can connect.

The configuration of the filter chain remains almost the same. Only the
declaration of the <input> nodes is no longer needed. Instead, the
configuration must specify <policy> nodes, which define the mapping of
"Event" clients (event sources) to the inputs used in the filter chain.

The patch adjusts all uses of the nitpicker GUI server accordingly such
that the event filter reports events to nitpicker's event service
instead of having nitpicker request an "Input" session. This dissolves
the dependency of nitpicker from input drivers.

Issue #3827
2020-08-25 11:49:43 +02:00

680 lines
24 KiB
Plaintext

if {![have_spec x86] || [have_spec linux]} {
puts "Platform is unsupported."
exit 0
}
if {[have_spec nova]} {
proc kernel_output { } { return "novga serial logmem" }
}
create_boot_directory
import_from_depot [depot_user]/src/[base_src] \
[depot_user]/pkg/sculpt
proc config_system_content {} { return {\
<!-- supported states: "poweroff" or "reset" when acpica started -->
<!-- Note: power down your persistent Genode applications & VMs beforehand on your own ! -->
<system state=""/>} }
install_config {
<config prio_levels="4"> <!-- set prio_levels to 4 -->
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="TRACE"/>
<service name="VM"/>
</parent-provides>
<affinity-space width="2" height="1"/>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="100"/>
<resource name="RAM" preserve="2M"/>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>
<start name="report_rom">
<binary name="report_rom"/>
<resource name="RAM" quantum="2M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="no">
<policy label="leitzentrale_config -> leitzentrale"
report="global_keys_handler -> leitzentrale"/>
<policy label="leitzentrale -> manager -> nitpicker_hover"
report="nitpicker -> hover"/>
<policy label="pointer -> hover" report="nitpicker -> hover"/>
<policy label="pointer -> xray"
report="global_keys_handler -> leitzentrale"/>
<policy label="pointer -> shape" report="shape"/>
<policy label="clipboard -> focus" report="nitpicker -> focus"/>
<policy label="drivers -> capslock" report="global_keys_handler -> capslock"/>
<policy label="runtime -> capslock" report="global_keys_handler -> capslock"/>
<policy label="drivers -> numlock" report="global_keys_handler -> numlock"/>
<policy label="runtime -> clicked" report="nitpicker -> clicked"/>
<policy label="nit_focus -> leitzentrale"
report="global_keys_handler -> leitzentrale"/>
<policy label="nit_focus -> slides"
report="global_keys_handler -> slides"/>
<policy label="nit_focus -> hover" report="nitpicker -> hover"/>
<policy label="slides_gui_fb_config -> slides"
report="global_keys_handler -> slides"/>
<policy label="leitzentrale -> manager -> displays"
report="nitpicker -> displays"/>
</config>
</start>
<start name="report_logger" priority="-3">
<binary name="report_rom"/>
<resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="yes"/>
</start>
<start name="config_fs" caps="200">
<binary name="vfs"/>
<resource name="RAM" quantum="12M"/>
<provides> <service name="File_system"/> </provides>
<config>
<vfs>
<ram/>
<import>
<dir name="managed">
<rom name="fonts" label="fonts.config"/>
<rom name="fb_drv" label="fb_drv.config"/>
<rom name="wifi" label="wifi.config"/>
<rom name="installation"/>
<rom name="runtime" label="empty_runtime.config"/>
<rom name="event_filter" label="event_filter.config"/>
<inline name="depot_query"><query/></inline>
</dir>
<rom name="event_filter" label="event_filter.config"/>
<rom name="fb_drv" label="fb_drv.config"/>
<rom name="nitpicker" label="nitpicker.config"/>
<rom name="numlock_remap" label="numlock_remap.config"/>
<rom name="leitzentrale" label="leitzentrale.config"/>
<rom name="drivers" label="drivers.config"/>
<rom name="deploy" label="manual_deploy.config"/>
<rom name="usb" label="usb.config"/>
<rom name="clipboard" label="clipboard.config"/>
<rom name="en_us.chargen"/>
<rom name="de_ch.chargen"/>
<rom name="de_de.chargen"/>
<rom name="fr_ch.chargen"/>
<rom name="fr_fr.chargen"/>
<rom name="special.chargen"/>
<rom name="vimrc"/>
<tar name="launcher.tar"/>
<inline name="system">} [config_system_content] {
</inline>
</import>
</vfs>
<policy label="config_fs_rom -> " root="/" />
<policy label="rw" root="/" writeable="yes" />
</config>
</start>
<start name="config_fs_rom">
<binary name="fs_rom"/>
<resource name="RAM" quantum="10M"/>
<provides> <service name="ROM"/> </provides>
<route>
<service name="File_system"> <child name="config_fs"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="report_fs_rom">
<binary name="fs_rom"/>
<resource name="RAM" quantum="3M"/>
<provides> <service name="ROM"/> </provides>
<route>
<service name="File_system"> <child name="report_fs"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="report_fs">
<binary name="vfs"/>
<resource name="RAM" quantum="16M"/>
<provides> <service name="File_system"/> </provides>
<config>
<vfs>
<ram/>
<import>
<inline name="log">### start ###</inline>
<dir name="runtime">
<inline name="state"><empty/></inline>
<dir name="wifi_drv">
<inline name="accesspoints"><empty/></inline>
<inline name="state"> <empty/></inline>
</dir>
<dir name="nic_router"> <inline name="state"> <empty/></inline> </dir>
<dir name="update"> <inline name="state"> <empty/></inline> </dir>
<dir name="depot_query"><inline name="blueprint"><empty/></inline> </dir>
</dir>
</import>
</vfs>
<policy label="fs_report -> " root="/" writeable="yes"/>
<policy label="log_terminal -> " root="/" writeable="yes"/>
<policy label="report_fs_rom -> " root="/"/>
<policy label="ro" root="/"/>
</config>
</start>
<start name="log_terminal">
<binary name="file_terminal"/>
<resource name="RAM" quantum="2M"/>
<provides> <service name="Terminal"/> </provides>
<config>
<default-policy filename="log" />
<vfs> <dir name="dev"> <log/> </dir> <fs/> </vfs>
<libc stdout="/dev/log"/>
</config>
<route>
<service name="File_system"> <child name="report_fs"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="log">
<binary name="terminal_log"/>
<resource name="RAM" quantum="1M"/>
<provides> <service name="LOG"/> </provides>
<config/>
<route>
<service name="Terminal"> <child name="log_terminal"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="log_core">
<resource name="RAM" quantum="1M"/>
<config period_ms="2000"/>
<route>
<service name="ROM" label="log"> <parent label="core_log"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="LOG" label="log"> <child name="log" label="core"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="log_kernel">
<binary name="log_core"/>
<resource name="RAM" quantum="1M"/>
<config period_ms="2000"/>
<route>
<service name="ROM" label="log"> <parent label="kernel_log"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="LOG" label="log"> <child name="log" label="kernel"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="fs_report">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> </provides>
<config> <vfs> <fs/> </vfs> </config>
<route>
<service name="File_system"> <child name="report_fs"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="drivers" caps="3000" priority="-1">
<resource name="RAM" quantum="96M" constrain_phys="yes"/>
<binary name="init"/>
<route>
<service name="LOG"> <child name="log"/> </service>
<service name="ROM" label="config">
<child name="config_fs_rom" label="drivers"/> </service>
<service name="ROM" label_last="capslock"> <child name="report_rom"/> </service>
<service name="ROM" label_last="event_filter.config">
<child name="config_fs_rom" label="managed/event_filter"/> </service>
<service name="ROM" label_prefix="event_filter" label_suffix=".chargen">
<child name="config_fs_rom"/> </service>
<service name="ROM" label_last="fb_drv.config">
<child name="config_fs_rom" label="managed/fb_drv"/> </service>
<service name="ROM" label_last="numlock_remap.config">
<child name="config_fs_rom" label="numlock_remap"/> </service>
<service name="ROM" label_last="usb_policy">
<child name="config_fs_rom" label="usb"/> </service>
<service name="ROM" label_last="numlock"> <child name="report_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<service name="Report"> <child name="fs_report"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides>
<service name="Block"/>
<service name="Usb"/>
<service name="Platform"/>
</provides>
</start>
<start name="nitpicker" caps="1000">
<resource name="RAM" quantum="6M"/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<route>
<service name="ROM" label="config">
<child name="config_fs_rom" label="nitpicker"/> </service>
<service name="ROM" label="focus">
<child name="nit_focus"/> </service>
<service name="Report" label="keystate">
<child name="report_logger"/> </service>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<!-- override user focus when leitzentrale is active -->
<start name="nit_focus" priority="-1">
<binary name="rom_filter"/>
<resource name="RAM" quantum="1M"/>
<provides> <service name="ROM"/> </provides>
<config>
<input name="lockscreen_enabled" rom="hover" node="hover">
<attribute name="label" /> </input>
<input name="leitzentrale_enabled" rom="leitzentrale" node="leitzentrale">
<attribute name="enabled" /> </input>
<input name="slides_enabled" rom="slides" node="slides">
<attribute name="enabled" /> </input>
<output node="focus">
<if>
<has_value input="lockscreen_enabled" value="lock_screen" />
<then>
<attribute name="label" value="lock_screen"/>
</then>
<else>
<if>
<has_value input="leitzentrale_enabled" value="yes" />
<then>
<attribute name="label" value="leitzentrale -> manager -> fader -> "/>
</then>
<else>
<if>
<has_value input="slides_enabled" value="yes" />
<then>
<attribute name="label" value="slides"/>
</then>
<else>
<attribute name="label" value="runtime -> focus"/>
</else>
</if>
</else>
</if>
</else>
</if>
</output>
</config>
<route>
<service name="ROM" label="hover"> <child name="report_rom"/> </service>
<service name="ROM" label="leitzentrale"> <child name="report_rom"/> </service>
<service name="ROM" label="slides"> <child name="report_rom"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="pointer" priority="-1">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Report"/> </provides>
<config shapes="yes"/>
<route>
<service name="Gui"> <child name="nitpicker"/> </service>
<service name="ROM" label="hover"> <child name="report_rom"/> </service>
<service name="ROM" label="xray"> <child name="report_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="global_keys_handler" priority="-1">
<resource name="RAM" quantum="1M"/>
<config>
<bool name="leitzentrale" initial="yes"/>
<bool name="capslock" initial="no"/>
<bool name="numlock" initial="no"/>
<bool name="slides" initial="no"/>
<press name="KEY_PRESENTATION" bool="slides" change="toggle"/>
<press name="KEY_DASHBOARD" bool="leitzentrale" change="toggle"/>
<press name="KEY_CAPSLOCK" bool="capslock" change="toggle"/>
<press name="KEY_NUMLOCK" bool="numlock" change="toggle"/>
<report name="leitzentrale"> <bool name="leitzentrale"/> </report>
<report name="capslock"> <bool name="capslock"/> </report>
<report name="numlock"> <bool name="numlock"/> </report>
<report name="slides"> <bool name="slides"/> </report>
</config>
<route>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Gui"> <child name="nitpicker"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="leitzentrale_config" priority="-2">
<binary name="rom_filter"/>
<resource name="RAM" quantum="1M"/>
<provides><service name="ROM"/></provides>
<route>
<service name="ROM" label="leitzentrale"> <child name="report_rom"/> </service>
<service name="ROM" label="config">
<child name="config_fs_rom" label="leitzentrale"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="clipboard" priority="-2">
<resource name="RAM" quantum="2M"/>
<provides>
<service name="ROM"/> <service name="Report"/>
</provides>
<route>
<service name="ROM" label="config">
<child name="config_fs_rom" label="clipboard"/> </service>
<service name="ROM" label="focus"> <child name="report_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="leitzentrale" caps="2350" priority="-2">
<binary name="init"/>
<resource name="RAM" quantum="130M"/>
<affinity xpos="1" width="1"/> <!-- decouple leitzentrale from boot CPU -->
<provides>
<service name="Gui"/>
<service name="File_system"/> <!-- fonts -->
<service name="ROM"/> <!-- view dialog ROMs -->
<service name="Report"/> <!-- view hover reports -->
</provides>
<route>
<service name="LOG"> <child name="log"/> </service>
<service name="ROM" label="config">
<child name="leitzentrale_config"/> </service>
<service name="ROM" label_prefix="report -> ">
<child name="report_fs_rom"/> </service>
<service name="ROM" label_prefix="manager -> report -> ">
<child name="report_fs_rom"/> </service>
<service name="ROM" label_prefix="manager -> config -> ">
<child name="config_fs_rom"/> </service>
<service name="ROM" label_prefix="manager -> displays">
<child name="report_rom"/> </service>
<service name="ROM" label_prefix="config -> ">
<child name="config_fs_rom"/> </service>
<service name="ROM" label="manager -> nitpicker_hover">
<child name="report_rom"/> </service>
<service name="Report"> <child name="fs_report"/> </service>
<service name="Gui"> <child name="nitpicker"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="File_system" label="config">
<child name="config_fs" label="rw"/> </service>
<service name="File_system" label="report">
<child name="report_fs" label="ro"/> </service>
<service name="File_system" label="report">
<child name="report_fs" label="ro"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="rtc_drv" priority="-1">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Rtc"/> </provides>
</start>
<start name="runtime" caps="50000" priority="-3">
<binary name="init"/>
<resource name="RAM" quantum="32G"/>
<route>
<service name="ROM" label="config">
<child name="config_fs_rom" label="managed/runtime"/> </service>
<service name="ROM" label_prefix="config -> ">
<child name="config_fs_rom"/> </service>
<service name="ROM" label="capslock">
<child name="report_rom"/> </service>
<service name="ROM" label="clicked">
<child name="report_rom"/> </service>
<service name="File_system" label="config">
<child name="config_fs" label="rw"/> </service>
<service name="File_system" label="report">
<child name="report_fs" label="ro"/> </service>
<service name="Block"> <child name="drivers"/> </service>
<service name="Usb"> <child name="drivers"/> </service>
<service name="Platform" label_prefix="acpica">
<child name="drivers" label="acpica"/> </service>
<service name="Platform"> <child name="drivers"/> </service>
<service name="Gui" label_prefix="leitzentrale">
<child name="leitzentrale"/> </service>
<service name="Gui" label="backdrop">
<child name="nitpicker" label="backdrop"/> </service>
<service name="Gui" label="lock_screen">
<child name="nitpicker" label="lock_screen"/> </service>
<service name="Gui"> <child name="nitpicker"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Report" label_suffix="-> shape"> <child name="pointer"/> </service>
<service name="Report" label="inspect -> clipboard">
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
<service name="Report" label="editor -> clipboard">
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
<service name="ROM" label="inspect -> clipboard">
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
<service name="ROM" label="editor -> clipboard">
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
<service name="Report" label_suffix="-> clipboard"> <child name="clipboard"/> </service>
<service name="ROM" label_suffix="-> clipboard"> <child name="clipboard"/> </service>
<service name="Report" label_prefix="leitzentrale ->">
<child name="leitzentrale"/> </service>
<service name="ROM" label_prefix="leitzentrale ->">
<child name="leitzentrale"/> </service>
<service name="File_system" label="leitzentrale -> fonts">
<child name="leitzentrale" label="fonts"/> </service>
<service name="Report"> <child name="fs_report"/> </service>
<service name="LOG" label="unlogged"> <parent/> </service>
<service name="LOG"> <child name="log"/> </service>
<service name="Rtc"> <child name="rtc_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
</config>}
foreach file [glob "[genode_dir]/repos/gems/run/sculpt/*.config"] {
file copy -force $file [run_dir]/genode/ }
#
# Override files normally obtained from depot archive with the most current
# version found in the Genode source tree. This way, we don't need to
# rebuild the corresponding depot archives each time we tweak one of the
# files. This is just a hack to accelerate the work flow.
#
file copy -force [genode_dir]/repos/gems/recipes/pkg/sculpt/README [run_dir]/genode/
file copy -force [genode_dir]/repos/gems/run/sculpt/vimrc [run_dir]/genode/
file copy -force [genode_dir]/repos/gems/run/sculpt/machine.vbox [run_dir]/genode/
file copy -force [genode_dir]/repos/gems/recipes/raw/drivers_managed-pc/drivers.config \
[run_dir]/genode/drivers.config
foreach file { en_us.chargen de_ch.chargen de_de.chargen fr_ch.chargen fr_fr.chargen special.chargen } {
file copy -force [genode_dir]/repos/os/src/server/event_filter/$file \
[run_dir]/genode/$file }
file copy -force [genode_dir]/repos/gems/recipes/raw/drivers_managed-pc/event_filter.config \
[run_dir]/genode/event_filter.config
file copy -force [genode_dir]/repos/gems/recipes/raw/depot_download/depot_download.config \
[run_dir]/genode/depot_download.config
file copy -force [genode_dir]/VERSION [run_dir]/genode/
file copy -force [genode_dir]/repos/gems/src/app/backdrop/genode_logo.png [run_dir]/genode/
file copy -force [genode_dir]/repos/gems/run/sculpt/drop_shadow.png [run_dir]/genode/
exec gzip -dc [genode_dir]/repos/gems/run/sculpt/machine.vdi.gz > [run_dir]/genode/machine.vdi
#
# Define 'VERSION' ROM module
#
# Note: the string must be exactly 5 bytes long.
#
proc sculpt_version { } {
return "20.03" }
# write file with newline (for producing nice output when using 'cat /VERSION')
set fd [open [run_dir]/genode/VERSION w]
puts $fd "[sculpt_version]"
close $fd
#
# Depot packages to be included in the default installation
#
proc current_pkg { pkg } { return $pkg/[_current_depot_archive_version pkg $pkg] }
set pkgs_to_install { }
set fd [open [run_dir]/genode/installation w]
puts $fd "<installation arch=\"[depot_spec]\">"
foreach pkg $pkgs_to_install {
puts $fd " <archive path=\"[depot_user]/pkg/[current_pkg $pkg]\" source=\"false\"/>" }
puts $fd "</installation>"
close $fd
#
# Configuration of deploy runtime
#
# This configuration is not provided as a file at run/sculpt/ because some
# parts need to be filled in at run-script execution time, in particular the
# current versions of the packages to deploy.
#
append manual_deploy_config {
<config arch="} [depot_spec] {">
<common_routes>
<service name="ROM" label_last="ld.lib.so"> <parent/> </service>
<service name="ROM" label_last="vfs.lib.so"> <parent/> </service>
<service name="ROM" label_last="init"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service>
</common_routes>
</config>}
set fd [open [run_dir]/genode/manual_deploy.config w]
puts $fd $manual_deploy_config
close $fd
#
# Install launcher snippets
#
# The launcher snippets are wrapped into a tar archive to be loaded as boot
# module. This procedure involves the following steps:
#
# The launcher snippets are copied from run/sculpt/launcher/ to
# [run_dir]/genode/launcher. Each launcher is inspected regarding its 'pkg'
# attribute. If its 'pkg' attribute contains a single identifier (rather than
# a valid pkg path), the attribute value is replaced by a valid pkg path
# referring to the current version of the pkg and the [depot_user]. The
# filtered launchers are archived into 'launcher.tar' and removed from the
# [run_dir].
#
set launchers [glob -tails -directory [genode_dir]/repos/gems/run/sculpt/launcher/ *]
foreach file $launchers {
# skip backup files
if {[regexp {~$} $file dummy]} { continue }
set fd [open [genode_dir]/repos/gems/run/sculpt/launcher/$file r]
set content [read $fd]
close $fd
# filter 'pkg' attribute
set pattern {(\<launcher[^\>]+?pkg=")([^/]+)(")}
if {[regexp $pattern $content dummy head pkg tail]} {
set pkg_path [depot_user]/pkg/[current_pkg $pkg]
regsub $pattern $content "$head$pkg_path$tail" content
}
# write filtered launcher snippet
file mkdir [run_dir]/genode/launcher
set fd [open [run_dir]/genode/launcher/$file w]
puts $fd $content
close $fd
}
# wrap launcher snippets into tar archive and remove individual snippets
exec tar cf [run_dir]/genode/launcher.tar -C [run_dir]/genode launcher
exec rm -r [run_dir]/genode/launcher
#
# Generate depot index from gems/run/sculpt/index
#
set fd [open [genode_dir]/repos/gems/run/sculpt/index r]
set pkg_index [read $fd]
close $fd
# filter 'pkg' attribute
set pattern {(\<pkg[^\>]+?path=")([^/]+)(")}
while {[regexp $pattern $pkg_index dummy head pkg tail]} {
set pkg_path [depot_user]/pkg/[current_pkg $pkg]
regsub $pattern $pkg_index "$head$pkg_path$tail" pkg_index
}
# write filtered pkg index into the depot
file mkdir [depot_dir]/[depot_user]/index
set fd [open [depot_dir]/[depot_user]/index/[sculpt_version] w]
puts $fd $pkg_index
close $fd
#
# Assemble 'depot_users.tar' with the keys and download locations of the
# depot user found at genode/depot/.
#
# Add current depot index of [depot_user] as generated above.
#
set depot_users_files [exec sh -c "cd [genode_dir]; \
find depot -maxdepth 3 -name pubkey \
-or -name download"]
exec sh -c "tar cf [run_dir]/genode/depot_users.tar -C [genode_dir] \
[join $depot_users_files]"
#
# Create boot image
#
append boot_modules { }
build_boot_image $boot_modules