Network diver error in Goa

Hello everyone,

I am currently trying to convert a working Genode .run scenario into a Goa project.
The original .run file (single_hello.run) executes correctly when used with the standard Genode build system.

However, after translating this setup into a Goa runtime file, I encounter several issues at runtime, especially:

The original Genode .run file is:

#
# 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

build { core init timer single_hello}

#
# Generate config
#

install_config {
<config>
	<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-route>
		<any-service> <parent/> <any-child/> </any-service>
	</default-route>

	<default caps="2000"/>

    <start name="timer">
        <resource name="RAM" quantum="2M"/>
        <provides> <service name="Timer"/> </provides>
    </start>

    <start name="drivers"  caps="1200">
        <resource name="RAM" quantum="256M"/>

        <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="400">
        
        <resource name="RAM" quantum="128M"/>
        <provides>
            <service name="Nic"/>
            <service name="Uplink"/>
        </provides>
        <config verbose_domain_state="yes">

            <policy label_prefix="single_hello" domain="downlink"/>
            <policy label_prefix="drivers" domain="uplink"/>

            <domain name="uplink">

                <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="single_hello">
		<resource name="RAM" quantum="50M"/>

		<config>
            <vfs>
                <dir name="dev"> <log/> </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 "

run_genode_until forever

The Goa runtime file is:

<runtime ram="6000M" caps="3000" binary="init">
    <requires>
        <timer/> 
        <rtc/> 
        <irq/> 
        <io_mem/> 
        <io_port/> 
    </requires>

    <config>
        <parent-provides>
            <service name="LOG"/>
            <service name="PD"/>
            <service name="CPU"/>
            <service name="ROM"/>
            <service name="RM"/>
            <service name="Timer"/>
            <service name="RTC"/>
            <service name="IRQ"/>  
            <service name="IO_MEM"/> 
            <service name="IO_PORT"/>  
        </parent-provides>

        <default-route>
            <any-service> <parent/> <any-child/> </any-service>
        </default-route>

        <start name="drivers"  caps="1200">
            <binary name="init"/>
            <resource name="RAM" quantum="256M"/>

            <provides>
                <service name="Nic"/> <!-- drivers 必须对外提供 Nic 服务 -->
            </provides>

            <route>
                <service name="ROM" label="config"> <parent label="drivers.config"/> </service>
                <service name="Timer"> <parent/> </service>
                <service name="Uplink"> <child name="nic_router"/> </service>
                <any-service> <parent/> </any-service>
            </route>
        </start>

        <start name="nic_router" caps="400">
            <resource name="RAM" quantum="128M"/>

            <provides>
                <service name="Nic"/>
                <service name="Uplink"/>
            </provides>

            <config verbose_domain_state="yes">

                <policy label_prefix="single_hello" domain="downlink"/>
                <policy label_prefix="drivers" domain="uplink"/>

                <domain name="uplink">

                    <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>

            <route>
                <service name="Nic"> <child name="drivers"/> </service>
                <any-service> <parent/> </any-service>
            </route>

        </start>


        <start name="single_hello" caps="1200">
            <binary name="single_hello"/>
            <resource name="RAM" quantum="500M"/>

            <config>
                <vfs>
                    <dir name="dev"> <log/> </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>

    <content>
        <rom label="init"/>
        <rom label="nic_router"/>
        <rom label="single_hello"/>

        <rom label="linux_nic_drv"/>

        <rom label="libc.lib.so"/>
        <rom label="libm.lib.so"/>
        <rom label="posix.lib.so"/>
        <rom label="vfs.lib.so"/>
        <rom label="vfs_lwip.lib.so"/>
        <rom label="vfs_pipe.lib.so"/>
        <rom label="stdcxx.lib.so"/>

        <inline label="drivers.config">
            <config>
                <parent-provides>
                    <service name="ROM"/>
                    <service name="PD"/>
                    <service name="RM"/>
                    <service name="CPU"/>
                    <service name="LOG"/>
                    <service name="Timer"/>
                    <service name="IRQ"/>
                    <service name="IO_MEM"/>
                    <service name="IO_PORT"/>
                </parent-provides>

                <start name="nic_drv" caps="150">
                    <binary name="linux_nic_drv"/>
                    <resource name="RAM" quantum="20M"/>
                    <provides> <service name="Nic"/> </provides>
                    <config/> 
                    <route>
                        <any-service> <parent/> </any-service>
                    </route>
                </start>
            </config>
        </inline>

    </content>
</runtime>

By the way, the “linux_nic_drv” related content in Goa runtime file is recommended to be added by GPT.

I want to know why the red error occured? How can I connect network in Goa? Meanwhile, after successfully running a networked application with Goa, I want to compile a binary for ARM architecture and run it on an iMX8 development board. Is this possible?

Any help would be greatly appreciated.

Never trust GPT. I’d like to encourage you to have a look at the documentation. There is an entire book featuring a step-by-step “hello world” tutorial (Section 2.2) and detailing the networking use case (Section 3.4.3). In brief summary: You don’t need to add drivers to the project runtime since Goa will take care of this.

Meanwhile, after successfully running a networked application with Goa, I want to compile a binary for ARM architecture and run it on an iMX8 development board. Is this possible?

If you have Sculpt OS running on your development board or any custom Genode-system that is able to deploy archives from a Genode depot: yes.

1 Like

Thank you for your suggestion, but I would like to explain more clearly. Here is a task I finished previously: I previously built a project in Goa and then used the command “goa build --arch arm_v8a” to compile a binary executable. Afterward, I compiled that file into a uImage in Genode, and successfully booted the uImage on the imx8 development board, running the executable that was compiled in Goa. My development board does not have the Sculpt system.

I would like to ask, if the network is successfully connected following the method in the Goa tutorial, can this network run on the development board like the project I did before?

So, you exported your Goa project into your depot and using a run-script and the Genode build system to create the uImage, right? That is also a reasonable approach.

Integrating a network driver into the runtime of your Goa project, however, is a dead end as this renders the runtime platform-specific. As I wrote before: When executing goa run, Goa takes care of adding all the drivers needed to execute your project on the Linux host. It basically automates the config generation that you do manually when writing a run-script for the Genode build system.

Thus, in order to run your network application on your development board, you need to add the corresponding drivers and nic_router to your run-script, which - according to the .run file you posted - you did already.

In summary: You can test networking for your project in Goa without adding linux_nic_drv or nic_router to the project’s runtime file. Please have a look at goa help targets for how to add port forwarding rules to the nic_router config managed by Goa. For running your project on the development board, you need to manage the driver and nic_router config manually in your .run file.

1 Like

Thanks. Can I understand it this way: drivers should never be added in the runtime file, but must be added in the .run file? Otherwise, it will trigger an error?

In general, yes. For instance, if you integrated the linux_nic_drv into the runtime, you would render the exported pkg archive incompatible with other platforms than Linux because the binary of linux_nic_drv is a hybrid Genode/Linux component that requires the Linux kernel running. Moreover, the binary is compiled for x86. Your target platform, however is an ARM board that runs Genode (not Linux).

Note that Goa does not prevent you from adding driver components (or more generally platform-specific components) to your runtime file. The error you previously encountered was a mere configuration error because you did not provide a drivers.config ROM. You tried this with an <inline> node within <content>. This is not supported. The way to go would either to re-use the drivers.config from another depot archive or to create the file under raw/drivers.config in your Goa project.