openhwgroup / cva6

The CORE-V CVA6 is an Application class 6-stage RISC-V CPU capable of booting Linux
https://docs.openhwgroup.org/projects/cva6-user-manual/
Other
2.29k stars 691 forks source link

GDB debugging with JTAG on Genesys 2 #623

Closed davidmallasen closed 3 years ago

davidmallasen commented 3 years ago

Hi,

I've been having some problems trying to run a hello_world on the Genesys 2. I have linux booting on the Genesys 2 and I have been able to sucessfully follow the steps listed in the readme for debugging using OpenOCD up to the point of executing the .elf with gdb.

In this post from the pulp platform forums someone had a similar problem to mine, although the solution shown there is not working in my case. When trying to fix the hello_world binary (same as in the readme) to start at 0x80000000 I get an error with riscv64-unknown-elf-gcc. I am using the same linker.lds file as in that post:

ENTRY(main)

SECTIONS
{
    ROM_BASE = 0x80000000; /* ... but actually position independent */

    . = ROM_BASE;

    .text.init : { *(.text.init) }

    .text : ALIGN(0x100) {
    _TEXT_START_ = .;
        *(.text)
    _TEXT_END_ = .;
    }

    PROVIDE( __global_pointer$ = . + (4K / 2) );    /* This is modified */
    .data : ALIGN(0x100) {
    _DATA_START_ = .;
        *(.data)
    _DATA_END_ = .;
    }

    PROVIDE(_data = ADDR(.data));
    PROVIDE(_data_lma = LOADADDR(.data));

    _edata = .;                                     /* This is modified */
    PROVIDE(_edata = .);

    .bss : ALIGN(0x100) {
    _BSS_START_ = .;
        *(.bss)
    _BSS_END_ = .;
    }

    .rodata : ALIGN(0x100) {
    _RODATA_START_ = .;
        *(.rodata)
        *(.dtb*)
        *(.rodata*)
    _RODATA_END_ = .;
    }

    PROVIDE(_end = .);                          /* This is modified */
}

When running riscv64-unknown-elf-gcc hello.c -Tlinker.lds -o hello.elf the output is:

/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/crtbegin.o: in function `__do_global_dtors_aux':
crtstuff.c:(.text+0x0): relocation truncated to fit: R_RISCV_HI20 against `completed.1'
/tmp/ccuMMisx.o: in function `main':
hello.c:(.text+0x12): relocation truncated to fit: R_RISCV_HI20 against `.LC0'
/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-exit.o): in function `exit':
exit.c:(.text+0xe): relocation truncated to fit: R_RISCV_HI20 against symbol `_global_impure_ptr' defined in .srodata section in /home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-impure.o)
/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-puts.o): in function `_puts_r':
puts.c:(.text+0x12): relocation truncated to fit: R_RISCV_HI20 against `.LC0'
/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-strlen.o): in function `.L2':
strlen.c:(.text+0x8): relocation truncated to fit: R_RISCV_HI20 against `.LC0'
/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-__call_atexit.o): in function `__call_exitprocs':
__call_atexit.c:(.text+0x2): relocation truncated to fit: R_RISCV_HI20 against symbol `_global_impure_ptr' defined in .srodata section in /home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-impure.o)
/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-__call_atexit.o): in function `register_fini':
__call_atexit.c:(.text.startup+0x6): relocation truncated to fit: R_RISCV_HI20 against symbol `__libc_fini_array' defined in .text section in /home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-fini.o)
/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-findfp.o): in function `_cleanup_r':
findfp.c:(.text+0x4): relocation truncated to fit: R_RISCV_HI20 against symbol `_fclose_r' defined in .text section in /home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-fclose.o)
/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-mallocr.o): in function `_malloc_r':
mallocr.c:(.text+0x3c): relocation truncated to fit: R_RISCV_HI20 against symbol `__malloc_av_' defined in .data section in /home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-mallocr.o)
/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-memchr.o): in function `.L6':
memchr.c:(.text+0x58): relocation truncated to fit: R_RISCV_HI20 against `.LC0'
/home/david/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/lib/libc.a(lib_a-reallocr.o): in function `.L5':
mallocr.c:(.text+0x56): additional relocation overflows omitted from the output
collect2: error: ld returned 1 exit status

I have sucessfully been able to compile it setting the ROM_BASE to 0x8000000 (6 zeros instead of 7) or something lower than 0x80000000 (7). However, when running it with gdb on the Genesys 2, again the address seems to not be writable. Trying to set the ROM_BASE to something higher than 0x80000000 (7) shows the same error as above.

Has something changed since the solution shown in that post? I have tried to look into the bootrom files but I still see address 0x80000000 (7) as the start of the writable space.

Any help or clarification would be much appreciated. Thanks!

niwis commented 3 years ago

Hello David,

no, this has not changed. Per default, the RAM is still mapped to 0x80000000 - 0xBFFFFFFF (https://cva6.readthedocs.io/en/latest/cva6_soc.html). Linking your executable to any other physical memory region will most likely not work. Please note that the hello_world program from the README uses the RISC-V proxy kernel, which is currently not supported for the FPGA flow. To create a stand-alone bare-metal application, I would suggest you to check out the Bootrom (https://github.com/openhwgroup/cva6/tree/master/fpga/src/bootrom/src) - there you can also find a minimal UART driver.

Best, Nils

davidmallasen commented 3 years ago

Hello Nils,

Thanks for your answer. I didn't catch the need for the proxy kernel for the system calls. Instead of creating a bare-metal application, since I could run the linux image on the Genesys 2, is there some way of copying the elf generated by riscv64-unknown-elf-gcc hello.c -Tlinker.lds -o hello.elf to the SD card and then running it from there? I imagine that having the OS in this situation would mean that there is no need for the pk.

In any case, linking the code to 0x80000000 or higher is giving me the error I posted before when creating the executable and I can't seem to figure out why that is happening. Setting that value to something lower than 0x80000000 does create some executable. I think I will need this even if I try the bare-metal approach. Do you know if there is some extra step that I am missing?

niwis commented 3 years ago

Hello David, when you're compiling for Linux, you do not want to map to 0x80000000, as you're running on virtual (not physical) memory. For an example build flow for a Linux application and how to include it into your Linux image, check out the tetris application in https://github.com/pulp-platform/ariane-sdk. Best, Nils

davidmallasen commented 3 years ago

True, my bad there. I will look into that. Thanks!