Is riscv still supported?

Hello there!

I’d like to try to add support for my mlikv mergez, but it seems that genode-riscv doesn’t compile anymore or I’m doing something very wrong:

bogdan@fractal:~/work/mk/gen/genode/build/riscv$ make BOARD=migv core
  Library base-hw-common.lib.a
    COMPILE  allocator_avl.o
    COMPILE  avl_tree.o
....
  Library core-hw-migv.lib.a
make[2]: *** No rule to make target '/home/bogdan/work/mk/gen/genode/repos/base-hw/src/lib/hw//memory_consts.s', needed by 'hw/memory_consts.h'.  Stop.
make[1]: *** [var/libdeps:80: core-hw-migv.lib.a] Error 2
make: *** [Makefile:351: gen_deps_and_build_targets] Error 2

different issues for bootstrap target:

bogdan@fractal:~/work/mk/gen/genode/build/riscv$ make BOARD=migv bootstrap
  Library cxx.lib.a
    COMPILE  unwind.o
    MERGE    cxx.lib.a
  Program bootstrap/board/migv/bootstrap-sram-migv
    COMPILE  bootstrap_sdram.o
    ASSEMBLE crt0.o
    COMPILE  lib/base/allocator_avl.o
    COMPILE  hw/capability.o
    COMPILE  lib/base/avl_tree.o
    COMPILE  lib/base/heap.o
    COMPILE  lib/base/log.o
    COMPILE  lib/base/output.o
    COMPILE  lib/base/raw_output.o
    COMPILE  lib/base/registry.o
    COMPILE  lib/base/slab.o
    COMPILE  lib/base/sleep.o
    COMPILE  lib/startup/_main.o
/home/bogdan/work/mk/gen/genode/repos/base/src/lib/base/raw_output.cc:19:10: fatal error: base/internal/raw_write_string.h: No such file or directory
   19 | #include <base/internal/raw_write_string.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [/home/bogdan/work/mk/gen/genode/repos/base/mk/generic.mk:73: lib/base/raw_output.o] Error 1
make[2]: *** Waiting for unfinished jobs....
/home/bogdan/work/mk/riscv/src/bootstrap/board/migv/bootstrap_sdram.cc:22:1: error: expected class-name before ‘{’ token
   22 | {
      | ^
/home/bogdan/work/mk/riscv/src/bootstrap/board/migv/bootstrap_sdram.cc:26:30: error: expected template-name before ‘<’ token
   26 |         struct Rst : Register<0x4, 32>
      |                              ^
/home/bogdan/work/mk/riscv/src/bootstrap/board/migv/bootstrap_sdram.cc:26:30: error: expected ‘{’ before ‘<’ token
/home/bogdan/work/mk/riscv/src/bootstrap/board/migv/bootstrap_sdram.cc:26:30: error: expected unqualified-id before ‘<’ token
/home/bogdan/work/mk/riscv/src/bootstrap/board/migv/bootstrap_sdram.cc:31:34: error: expected template-name before ‘<’ token
....

I’m quite new to genode, but I really like to start using it.

Is there any quick start guide for beginners (for riscv/arm64 rpi) ?

E.g. how to build the “minimal” system? Is it possible to use genode/sculpt from command line only? If yes, how?

Thanks in advance!

1 Like

Welcome to the forum!

It looks like you missed specifying the KERNEL=hw argument.

For a quick start, I recommend getting you toe wet by using Qemu. E.g., build and run the simple log scenario at (repos/base/run/log.run) via

build/riscv$ make run/log KERNEL=hw BOARD=virt_qemu_riscv

To enable Genode on a new hardware platform, please consider giving the Genode Platforms book a read. Even though it might not be directly applicable to RISC-V, it will point you to the right places and give you a guiding rail of steps to follow.

1 Like

Thanks!

Sadly no joy, KERNEL=hw was already set in build/riscv/etc/build.conf

This is how build.conf looks like:

GENODE_DIR  := /home/bogdan/work/mk/gen/genode
BASE_DIR    := $(GENODE_DIR)/repos/base
CONTRIB_DIR := $(GENODE_DIR)/contrib
REPOSITORIES += $(GENODE_DIR)/repos/riscv

# enable parallel build
MAKE += -j40

# enable use of compiler cache
#CCACHE := yes


##
## Run-tool configuration
##

# create depot archives and update recipe versions automatically
#RUN_OPT += --depot-auto-update

# local variable for run-tool arguments used for running scenarios in Qemu
QEMU_RUN_OPT := --include power_on/qemu  --include log/qemu

# kernel to use
KERNEL ?= hw

# board to use (riscv_qemu)
BOARD  ?= virt_qemu_riscv

# local variable for run-tool arguments that depend on the used board
BOARD_RUN_OPT(virt_qemu_riscv) = $(QEMU_RUN_OPT)
ifdef BOARD
RUN_OPT += ${BOARD_RUN_OPT(${BOARD})}
endif

ifdef KERNEL
RUN_OPT += --include boot_dir/$(KERNEL)
endif

.....

Removing the ^ fixed the build ! :slight_smile:

It seems GitHub - genodelabs/genode-riscv: RISC-V board support is outdated and needs more love.

Sorry for the noise !

2 Likes

Hi,

I can build core and bootstrap for virt_qemu_riscv, as well as migv successfully using the referenced genodelabs/genode-riscv repository that is enabled within my build configuration. Maybe you’ve used incompatible branches in between genode and genode-riscv? Or what exactly do you meant by:

@bog_dan_ro: Yes, RISC-V support needs a little love. When I started this project ten years ago RISC-V looked very promising. As of today, we still have not come across a real life use case were RISC-V has been required or asked for. So in case you want to move RISC-V forward on Genode, I am all ears and willing to help where I can.

2 Likes

Hi,

I’m still struggling to build it for riscv :slight_smile: .

I have the feeling that my setup might be to blame so I create a Dockefile (based on genode-devel-docker/Dockerfile at main · skalk/genode-devel-docker · GitHub ) and a simple build script to be sure we all using the same setup. I uploaded them here GitHub - bog-dan-ro/genode-docker-build .

If you can check them to see what I’m doing wrong, it will help me a lot.

Thanks!

@bog_dan_ro: Okay, I have installed a Debian 13 VM and tried your genode-docker-build. For me there were two show stoppers in your build_genode.sh file

  1. I could not clone https://github.com/genodelabs/genode.git into the root directory (/) of the docker image, there was always some corruption. Therefore, I cloned everything to /home/test (this might work for you though)
  2. https://github.com/ssumpf/genode-riscv.git is my development branch from 5 years ago and it will not work. You need to change that to the official Genode repository
    https://github.com/genodelabs/genode-riscv.git which is where all the results of the development work go to.

After 1. and 2. make core bootstrap worked for me.

1 Like

It worked, thank you so much!

I’m such an idiot :slight_smile: .

...
kernel initialized
Genode 25.11-56-g8e6112c491 <local changes>
504 MiB RAM and 64536 caps assigned to init
[init -> test-log] hex range:          [0e00,1680)
[init -> test-log] empty hex range:    [0abc0000,0abc0000) (empty!)
[init -> test-log] hex range to limit: [f8,ff]
[init -> test-log] invalid hex range:  [f8,08) (overflow!)
[init -> test-log] negative hex char:  0xfe
[init -> test-log] positive hex char:  0x02
[init -> test-log] Alloc_error value:  OUT_OF_RAM
[init -> test-log] floating point:     1.70
[init -> test-log] multiarg string:    "parent -> child.7"
[init -> test-log] String(Hex(3)):     0x3
[init -> test-log] Very long messages:
[init -> test-log -> log] 1.....................................................................................................................................................................................................................................2
[init -> test-log] 3.....................................................................................................................................................................................................................................4
[init -> test-log] 5.....................................................................................................................................................................................................................................6
[init -> test-log] 
[init -> test-log] Test done.

Run script execution successful.

I’ll start reading Genode Platforms and get back to you when I’ll need more help.

Thanks again!

3 Likes

I started with a more simple riscv board (Duo | Milk-V) hopping that it will just work, but it wasn’t :slight_smile:.

It crashes after it starts the core:

Filename '/image-hw.elf'.
Load address: 0x80080000
Loading: #################################################################
         #################################################################
         ###############
         5.4 MiB/s
done
Bytes transferred = 2114608 (204430 hex)
cv180x_c906# bootelf
## Starting application at 0x81000000 ...
called from 0xffffffc00005112e

Kernel panic on CPU id=0 
Exception reason is page-fault

Register dump:
ip   = 0xffffffc000029b8e
ra   = 0xffffffc000029b74
sp   = 0xffffffe07000ff40
gp   = 0x81c09e30
tp   = 0x0
t0   = 0x40
t1   = 0x2
t2   = 0xffffffffffffffff
s0   = 0xffffffc0002d9000
s1   = 0xffffffc0002d9000
a0   = 0xffffffc0003e7000
a1   = 0x1000
a2   = 0xfffffffcaba5d820
a3   = 0x1d1e7642c78daa
a4   = 0xff26061300000617
a5   = 0xffffffe040001010
a6   = 0x0
a7   = 0x1
s2   = 0xffffffc0002d50d8
s3   = 0xffffffc0002d83c8
s4   = 0xffffffc0002d3000
s5   = 0x5000
s6   = 0xffffffc0002d50d8
s7   = 0xffffffc0002d3008
s8   = 0x0
s9   = 0x0
s10  = 0x0
s11  = 0x0
t3   = 0x3f
t4   = 0x40
t5   = 0xffffffffffffffff
t6   = 0x3f

Backtrace:
<< no backtrace >>
$ riscv64-linux-gnu-addr2line -e log.core.debug 0xffffffc00005112e
/home/bogdan/work/mk/gn/genode/repos/base-hw/src/core/kernel/main.cc:81

Here GitHub - bog-dan-ro/genode-riscv: RISC-V board support is my WIP.

I probably did something very stupid, but I can’t figure out what, any help will be highly appreciated.

BTW, on riscv, u-boot sets in a0 register the hart id and in a1 register the FDT(DTB) ptr.

Isn’t better to parse the FDT in bootstrap and get all the needed info (e.g. ram base, ram size, cpu count, interrupt controller, etc.) instead of hard-coding them?

Some riscv boards even supports ram sticks (e.g. Milk-V Titan ) which can’t be hard-coded…

Hi,

congratulations for already passing the bootstrap part, and finally executing within the kernel already :wink:.

That address is of minor interest. But the ip (instruction-pointer) of the above kernel panic’s register dump is probably interesting (0xffffffc000029b8e), as it lead to the page-fault.

When skimming through your enabling commit, I noticed that your RAM description in src/include/hw/spec/riscv/milkv_duo_board.h does not equal to the boards RAM definition in the device tree sources that you’ve commited too. I think it should be:

RAM_BASE = 0x80000000,
RAM_SIZE = 0x3f40000,
...

Or, are there other restriction that forced you to use this small chunk of ~28MiB?

It would be obviously more convenient to parse FDTs in bootstrap. Until now, we decided against it. For the very few information that we need in the kernel (Ram, Timer, Irq controller, Cpus), and which where always fixed (till now), the tradeoff in between having additional parsing routines or few lines of address definitions was answered with following the second path.
I wouldn’t be reluctant to support it in general, as long as the FDT parser is very simple, no moving target, and doesn’t affect the TCB much. Anyway, when comparing this convenience enhancement with other open issues, I’m hesitant to do any promises yet.

Thanks for your time!

I had more luck with milkv-megrez :wink: .

Autoboot in 5 seconds
=> run genode
ethernet@50400000 Waiting for PHY auto negotiation to complete..... done
BOOTP broadcast 1
DHCP client bound to address 192.168.0.159 (7 ms)
Using ethernet@50400000 device
TFTP from server 192.168.0.31; our IP address is 192.168.0.159
Filename '/image-hw.elf'.
Load address: 0x84000000
Loading: #################################################################
         #################################################################
         ###############
         9.6 MiB/s
done
Bytes transferred = 2114608 (204430 hex)
Automatic boot of image at addr 0x84000000 ...
Wrong Image Format for bootp command
ERROR: can't get kernel image!
## Starting application at 0x81000000 ...
Kernel: Hello from boostrap !

void Kernel::main_initialize_and_handle_kernel_entry()

kernel initialized
Genode 25.11-56-g8e6112c491 <local changes>
32760 MiB RAM and 64536 caps assigned to init
[init -> test-log] hex range:          [0e00,1680)
[init -> test-log] empty hex range:    [0abc0000,0abc0000) (empty!)
[init -> test-log] hex range to limit: [f8,ff]
[init -> test-log] invalid hex range:  [f8,08) (overflow!)
[init -> test-log] negative hex char:  0xfe
[init -> test-log] positive hex char:  0x02
[init -> test-log] Alloc_error value:  OUT_OF_RAM
[init -> test-log] floating point:     1.70
[init -> test-log] multiarg string:    "parent -> child.7"
[init -> test-log] String(Hex(3)):     0x3
[init -> test-log] Very long messages:
[init -> test-log -> log] 1.................................................................................................................................................................................................................................
....2
[init -> test-log] 3.....................................................................................................................................................................................................................................4
[init -> test-log] 5.....................................................................................................................................................................................................................................6
[init -> test-log] 
[init -> test-log] Test done.

There are a few problems which I’m going to investigate this weekend:

  1. It works with only one CPU. My hunch is it hangs because it assumes that the boot hart is always hart 0 which is not true, it can be any of the available harts.
  2. I need to figure out where TIMER_HZ is used and how important it is :slight_smile:. timer_accuracy hangs at startup same test-init
## Starting application at 0x81000000 ... 
Kernel: Hello from boostrap ! 
 
void Kernel::main_initialize_and_handle_kernel_entry() 
 
kernel initialized 
Genode 25.11-56-g8e6112c491 <local changes> 
32760 MiB RAM and 64536 caps assigned to init 
[init -> test-timer_accuracy] 
 
## Starting application at 0x81000000 ...
Kernel: Hello from boostrap !

void Kernel::main_initialize_and_handle_kernel_entry()

kernel initialized
Genode 25.11-56-g8e6112c491 <local changes>
32760 MiB RAM and 64536 caps assigned to init
[init -> test -> test-init] step 0 (sleep)

Yes, they are reserved see.

Regarding the FDT, IMHO parsing FDT in bootstrap will make the “core” part super portable, it will not need anything, it will also save people like me from a lot of pain and tears :slight_smile:

FDT should be quite simple, I’ll give it a try and come back to you with a Merge Request.

Last but not least, is it possible to create a more complex image, with some command line tools (e.g.shell) ?

Yes, supporting several cpus was not addressed yet when doing the initial port to this architecture. At that time, if I remember correctly the FPGA-based hardware only had one cpu core.

The TIMER_HZ is used in the kernel timer implementation for riscv, which uses the rdtime instruction. The timer frequency is hardcoded using the TIMER_HZ variable. If its value is wrong, kernel time will be misleading, which is used via syscall for the userland timer too.

Wow, more memory reserved than available :wink:

Well, in general yes. Our libc and lwIP library ports are riscv-ready and tested nightly. For the qemu riscv “board” we also have a bunch of drivers ready to run interactive and network scenarios. But for your board target you will need either some drivers for input and framebuffer, or at least a network driver to support more sophisticated scenarios.
I just tried the bash.run and vim.run scripts using qemu, which in general work. (Although I noticed that the “cap” quota for the terminal is to low in both examples using this platform) For both examples you need a drivers_interactive-[board] depot package, which spawns a sub-system running input and framebuffer driver. You can have a look at similarily labeled packages as blueprint.

1 Like