Dear Genode Community ,
We are currently developing a network server application based on Genode OS, with the goal of running it on an i.MX8MP ARMSTONE development board. To test the network connectivity of the board, we wrote a simple program that connects to a website using a socket. Our objective is to retrieve the content of the website, and even a 404 error or a TLS handshake failure would be sufficient to confirm that the network communication is working. Unfortunately, we are unable to successfully run the program on the development board .
Here are the key points from our diagnostics:
-
The test program runs fine on both x86 and aarch64 platforms in QEMU, suggesting that the application layer implementation is most likely not the issue.
-
When the development board runs a standard Linux distribution, it can access the internet without any problems, indicating that the network environment is fine.
-
The networking issue only occurs when the board is running Genode OS.
Possible Causes and Observations
We suspect that Genode is logging a problem related to the loading of platform-specific device drivers. Specifically, we observed the following errors in the runtime log, which we believe could be the core issue:
[init -> drivers -> nic] --- i.MX FEC nic driver started ---
[init -> drivers -> platform] Error: ROM-session creation failed (label="system", ram_quota=6K, cap_quota=3, )
[init -> drivers -> platform] Error: could not open ROM session for "system"
[init -> drivers -> platform] Error: Uncaught exception of type 'Genode::Rom_connection::Rom_connection_failed'
Despite attempting to adjust the cap and RAM quotas in the run file, the core error message remains unchanged.
Version and Migration Attempts
-
We noticed that this error only occurs when the image is compiled with Genode 25.02. We tried migrating to Genode 25.05 to avoid this issue, but found that lwIP does not run properly in the QEMU-simulated aarch64 environment. Therefore, we reverted to Genode 25.02, where lwIP works correctly. We believe this is a bug in Genode 25.05, and we will describe this issue in more detail on GitHub and include a link to help improve the Genode project.
-
We are also unsure whether the issue with running Genode on the i.MX8MP development board is specific to this model, or if all boards in the i.MX8MP series require the loading of network drivers to function correctly. When compiling the i.MX8MP
uImage
image, we couldnât directly compile it using theBOARD ?= imx8mp_armstone
setting in thebuild.conf
file. By emulating thedrivers_nic-imx6q_sabrelite
approach, we addeddrivers_nic_imx8mp_armstone
to therecipe/pkg
folder in theimx
repository, and successfully compiled an image that could run on the board, but the network still does not behave correctly. We suspect this could be another root cause of the issue.
Further Information
If youâre interested in this issue and need more information, we have attached the simplified test program, corresponding run
script, the complete Genode output log from the i.MX8MP development board and our board picture for further analysis.
myapp.cc
#include <base/component.h>
#include <libc/component.h>
#include <base/heap.h>
#include <base/attached_rom_dataspace.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <fcntl.h>
struct AppMain {
Genode::Env& env;
Genode::Heap heap { env.ram(), env.rm() };
AppMain(Genode::Env&);
};
AppMain::AppMain(Genode::Env& env) : env {env} {
Genode::Attached_rom_dataspace configDs { env, "drivers.config" };
Genode::log("------ drivers.config ------");
Genode::log(configDs.xml());
Libc::with_libc([&] () {
auto fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1) {
perror("socket");
return;
}
{
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = adl::htons(443);
inet_pton(AF_INET, "202.120.189.175", &addr.sin_addr);
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("connect");
close(fd);
return;
}
}
char buf[1024] = "";
const char* http_get = "GET / HTTP/1.1\r\nHost: 202.120.189.175\r\nConnection: close\r\n\r\n";
send(fd, http_get, adl::strlen(http_get), 0);
int n = recv(fd, buf, sizeof(buf)-1, 0);
if (n > 0) {
buf[n] = 0;
printf("Received %d bytes:\n%s\n", n, buf);
} else {
if (n == 0) {
printf("Connection closed by peer\n");
} else {
perror("recv");
}
}
close(fd);
Genode::log((const char*)buf);
return ;
});
}
void Libc::Component::construct(Libc::Env& env) {
static AppMain main {env};
}
myapp.run
#
# Build
#
create_boot_directory
import_from_depot [depot_user]/src/[base_src] \
[depot_user]/pkg/[drivers_nic_pkg] \
[depot_user]/src/init \
[depot_user]/src/libc \
[depot_user]/src/nic_router \
[depot_user]/src/vfs \
[depot_user]/src/vfs_lwip \
[depot_user]/src/vfs_pipe \
[depot_user]/raw/[board]-devices
build {
core init timer app/myapp
driver/platform/imx8mq
}
#
# Generate config
#
install_config {
<config verbose="yes" prio_levels="4">
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<parent-provides>
<service name="LOG"/>
<service name="PD"/>
<service name="CPU"/>
<service name="ROM"/>
<service name="IRQ"/>
<service name="RM"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
</parent-provides>
<default caps="200"/>
<start name="timer" priority="0">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Timer"/> </provides>
</start>
<start name="drivers" caps="1200" managing_system="yes" priority="0">
<resource name="RAM" quantum="512M"/>
<binary name="init"/>
<route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Uplink"> <child name="nic_router"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="nic_router" caps="4000" priority="-1">
<resource name="RAM" quantum="128M"/>
<provides>
<service name="Nic"/>
<service name="Uplink"/>
</provides>
<config verbose_domain_state="yes" verbose_packet_drop="yes" trace_packets="yes" >
<policy label_prefix="myapp" domain="downlink"/>
<policy label_prefix="drivers" domain="uplink"/>
<!-- <domain name="uplink"> -->
<domain name="uplink" interface="192.168.1.101/24" gateway="192.168.1.1">
<!-- <domain name="uplink" interface="10.0.2.15/24" gateway="10.0.2.2"> -->
<nat domain="downlink"
tcp-ports="16384"
udp-ports="16384"
icmp-ids="16384"/>
<tcp-forward port="10000" domain="downlink" to="10.0.3.2"/>
</domain>
<domain name="downlink" interface="10.0.3.1/24">
<dhcp-server ip_first="10.0.3.2" ip_last="10.0.3.2">
<dns-server ip="8.8.8.8"/>
<dns-server ip="1.1.1.1"/>
</dhcp-server>
<tcp dst="0.0.0.0/0"><permit-any domain="uplink" /></tcp>
<udp dst="0.0.0.0/0"><permit-any domain="uplink" /></udp>
<icmp dst="0.0.0.0/0" domain="uplink"/>
</domain>
</config>
</start>
<start name="myapp" caps="2000" priority="-2">
<resource name="RAM" quantum="256M"/>
<config>
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="socket"> <lwip ip_addr="10.0.3.2" netmask="255.255.255.0" gateway="10.0.3.1"/> </dir>
<!-- <dir name="socket"> <lwip dhcp="yes"/> </dir> -->
<dir name="pipe"> <pipe/> </dir>
</vfs>
<libc stdout="/dev/log" socket="/socket" pipe="/pipe"/>
</config>
<route>
<service name="Nic"> <child name="nic_router"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
</config>
}
#
# Boot image
#
build_boot_image [build_artifacts]
append qemu_args " -nographic "
append_qemu_nic_args "hostfwd=tcp:127.0.0.1:5555-:10000"
run_genode_until forever
genode-output-from-imx_board.log
forlinx=> 0x40000000 OK8MP-C.<INTERRUPT>
forlinx=> <INTERRUPT>
forlinx=> fatload mmc 1 0x40000000 OK8MP-C.dtb && fatload mmc 1 0x40800000 con && bootm 0x40800000 - 0x40000000
67264 bytes read in 24 ms (2.7 MiB/s)
3135728 bytes read in 158 ms (18.9 MiB/s)
## Booting kernel from Legacy Image at 40800000 ...
Image Name:
Image Type: AArch64 Linux Kernel Image (gzip compressed)
Data Size: 3135664 Bytes = 3 MiB
Load Address: 40200000
Entry Point: 40200000
Verifying Checksum ... OK
## Flattened Device Tree blob at 40000000
Booting using the fdt blob at 0x40000000
Uncompressing Kernel Image
Using Device Tree in place at 0000000040000000, end 00000000400136bf
Starting kernel ...
kernel initialized
Genode 25.02-2-g6458c1bcf9 <local changes>
2037 MiB RAM and 64536 caps assigned to init
[init] parent provides
[init] service "LOG"
[init] service "PD"
[init] service "CPU"
[init] service "ROM"
[init] service "IRQ"
[init] service "RM"
[init] service "IO_MEM"
[init] service "IO_PORT"
[init] child "timer"
[init] RAM quota: 1800K
[init] cap quota: 166
[init] ELF binary: timer
[init] priority: 0
[init] provides service Timer
[init] child "drivers"
[init] RAM quota: 524040K
[init] cap quota: 1166
[init] ELF binary: init
[init] priority: 0
[init] child "nic_router"
[init] RAM quota: 130824K
[init] cap quota: 3966
[init] ELF binary: nic_router
[init] priority: 1
[init] provides service Nic
[init] provides service Uplink
[init] child "myapp"
[init] RAM quota: 261896K
[init] cap quota: 1966
[init] ELF binary: myapp
[init] priority: 2
[init -> drivers -> nic] --- i.MX FEC nic driver started ---
[init -> drivers -> platform] Error: ROM-session creation failed (label="system", ram_quota=6K, cap_quota=3, )
[init -> drivers -> platform] Error: could not open ROM session for "system"
[init -> drivers -> platform] Error: Uncaught exception of type 'Genode::Rom_connection::Rom_connection_failed'
[init -> drivers -> platform] Warning: abort called - thread: ep
[init] child "timer" announces service "Timer"
[init -> nic_router] [uplink] static IP config: interface 192.168.1.101/24, gateway 192.168.1.1, P2P 0
[init -> nic_router] [uplink] NIC sessions: 0
[init -> nic_router] [downlink] static IP config: interface 10.0.3.1/24, gateway 0.0.0.0, P2P 0
[init -> nic_router] [downlink] NIC sessions: 0
[init] child "nic_router" announces service "Nic"
[init] child "nic_router" announces service "Uplink"
[init -> nic_router] [downlink] NIC sessions: 1
[init -> myapp] lwIP Nic interface down
[init -> myapp] lwIP Nic interface up address=10.0.3.2 netmask=0.0.0.0 gateway=0.0.0.0
[init -> myapp] ------ drivers.config ------
[init -> myapp] <config>
[init -> myapp] <parent-provides>
[init -> myapp] <service name="IRQ"/>
[init -> myapp] <service name="IO_MEM"/>
[init -> myapp] <service name="ROM"/>
[init -> myapp] <service name="PD"/>
[init -> myapp] <service name="RM"/>
[init -> myapp] <service name="CPU"/>
[init -> myapp] <service name="LOG"/>
[init -> myapp] <service name="Timer"/>
[init -> myapp] <service name="Uplink"/>
[init -> nic_router] [downlink] drop packet (gratuitous ARP request)
[init -> myapp] </parent-provides>
[init -> myapp]
[init -> myapp] <default caps="100"/>
[init -> myapp]
[init -> myapp] <service name="Nic">
[init -> myapp] <default-policy> <child name="nic"/> </default-policy> </service>
[init -> myapp]
[init -> myapp] <start name="platform" caps="150" ram="1M" managing_system="yes">
[init -> myapp] <binary name="imx8mp_platform"/>
[init -> myapp] <provides> <service name="Platform"/> </provides>
[init -> myapp] <config>
[init -> myapp] <policy label="nic -> " info="yes"> <device name="fec"/> </policy>
[init -> myapp] </config>
[init -> myapp] <route> <any-service> <parent/> </any-service> </route>
[init -> myapp] </start>
[init -> myapp]
[init -> myapp] <start name="nic" caps="180" ram="20M">
[init -> myapp] <binary name="fec_nic"/>
[init -> myapp] <route>
[init -> myapp] <service name="ROM" label="nic.dtb"> <parent label="fec_nic-imx8mp_armstone.dtb"/> </service>
[init -> myapp] <service name="Uplink"><parent/> </service>
[init -> myapp] <service name="ROM"> <parent/> </service>
[init -> myapp] <service name="PD"> <parent/> </service>
[init -> myapp] <service name="RM"> <parent/> </service>
[init -> myapp] <service name="CPU"> <parent/> </service>
[init -> myapp] <service name="LOG"> <parent/> </service>
[init -> myapp] <service name="Timer"> <parent/> </service>
[init -> myapp] <service name="Platform"> <child name="platform"/> </service>
[init -> myapp] </route>
[init -> myapp] </start>
[init -> myapp] </config>
[init -> nic_router] [downlink] drop packet (gratuitous ARP request)
[init -> nic_router] [downlink] drop packet (DHCP request with broken message type)
We are also reviewing every commit between Genode 25.02 and 25.05 to determine the root cause of the issue. However, we believe that the Genode community might be more familiar with the version upgrade process and could offer more direct help. Any discussion or suggestions would be greatly appreciated.
Thank you in advance for your time and assistance!
2025-08-10T16:00:00Z