Use gdb to download linux images and debug
Use gdb to download linux images and debug
This document guides customers how to download the image to the fpga board through jtag to run, to avoid burning flash every time debugging, especially the image that has just been transplanted, which may have more problems. Improve debugging efficiency.
If you want to port to your SoC based on this Nuclei Linux SDK, please see the following guidance:
- Porting Guide: https://github.com/Nuclei-Software/nuclei-linux-sdk#port-to-your-target
- SoC Configuration Generator with Nuclei Qemu Supported: https://github.com/Nuclei-Software/nuclei-linux-sdk/tree/dev_nuclei_5.10_v2/conf#linux-sdk-soc-configuration-generator
This is mainly for BOOT_MODE=flash mode, to avoid you have to download
freeloader.elfto flash for a long time due to flash programing is time costing for large sizefreeloader.elf
software:Nuclei Linux SDK dev_nuclei_5.10_v2 branch #2 hardware:ux900 bitfile + vcu118 or ku060
Here we just take one linux sdk branch and our evaluation board as example, you can take reference for your own development board.
You should always follow this guidance to port linux to your SoC, see #21
Compile SDK
- Assume you don't have a SPI can access to SDCard.
- Assume you are using a RV64 CPU.
- If you are using a RV32 CPU, need to change
uxtoufor below CORE settings
- If you are not using
evalsoc, please set SOC=, change <yoursoc>to the real soc name of yours - You have to choose
BOOT_MODE=flash, pass it in each make, or directly update it in Makefile - CORE parameter should be matched with your bitfile, if your bitfile is not support
double float, you should setCORE=ux900, otherwiseCORE=ux900fd - Then modify the Makefile's
BOOT_MODE,COREandSOCaccording to above settings - according to your hardware to set CPU frequency CPU_HZ
More detail info about compile sdk, please refer to Nuclei Linux SDK README
Before you build SDK, make sure you have not build SDK before with a different CORE and BOOT_MODE settings
Here I am using
evalsoc, so the work folder iswork/evalsoc
Here I assume you have modified the Makefile as request above.
IMPORTANT, if you need to change
CORE/SOC/BOOT_MODE, please renameworkfolder to other name such aswork_20240308, and build it again.
BOOT_MODE=flash is always required for this case.
make CPU_HZ=50000000 freeloader -j16
After compiling, you will see the output image in the nuclei-linux-sdk/work/evalsoc/freeloader/ directory:
nuclei-linux-sdk$ ls work/evalsoc/freeloader/
fdt.dtb freeloader.dasm freeloader.map kernel.bin opensbi.bin u-boot.bin
freeloader.bin freeloader.elf initrd.bin memory.lds
Maybe the first time you are not be able to bring up linux for your SoC using the freeloader.elf, you can try to use gdb to help to speed up your program speed via directly load opensbi/uboot/linux/dtb to ddr memory and can debug linux.
config gdb download script
[!NOTE]
- You must confirm with your hardware colleague to confirm that the ddr memory with addresses 8/16/32/64 for random and sequential read and write is ok. You can write a baremetal program to test it.
- The above must be done and confirmed ok before you do next steps of firmware debugging.
If you want to learn about how to use gdb, please see https://sourceware.org/gdb/documentation/ and https://github.com/hellogcc/100-gdb-tips
-
You can configure gdb download script based on your soc hardware.
-
the gdb script reset hardware before download image using
monitor reset halt -
restorecommand can fill image into ddr, if you don't want to download some image, you can add#to the beginning to the line to comment it.- eg. If you just want to download
opensbi,ubootanddtb, you can comment outkernelandrootfsimage - dtb is always required.
- eg. If you just want to download
-
generally focusing on below a few parameters:
- ddr_base: config your soc ddr base address
- thread_num: config your smp core numbers,core should be found by openocd, if openocd config file only connect 1 core, you should set thread_num to 1
- Please check the TODO items in the script file
[!NOTE] If you want to use smp cores, please update your openocd configuration file to support smp, contact with our AE for help in updating this smp openocd configuration file.
set $opensbi_base=$ddr_base + 0x0
set $uboot_base=$ddr_base + 0x200000
set $fdt_base=$ddr_base + 0x8000000
set $kernel_base=$ddr_base + 0x3000000
set $rootfs_base=$ddr_base + 0x8300000
- each image load address should be same with
nuclei-linux-sdk/freeloader/freeloader.S
if your change freeloader.S image load address, you should change gdb script accordingly.
download images to ddr
- place your gdb download script to
nuclei-linux-sdk/work/evalsoc/freeloader/directory
nuclei-linux-sdk/work/evalsoc/freeloader$ ls
fdt.dtb freeloader.dasm freeloader.map kernel.bin memory.lds u-boot.bin
freeloader.bin freeloader.elf initrd.bin load_image.gdb_init opensbi.bin
- startup gdb
NOTE: Each time, you have made changes to code, and want to reboot, you need to rebuild images, and download it again, and debug it.
[!NOTE] If you are still debugging it, we strongly recommend you execute the command list in the gdb script line by line for single core version(no need to have the while loop in it) to help you debug which command is failing.
First startup openocd, then execute gdb from nuclei-linux-sdk/work/evalsoc/freeloader/ directory to connect openocd.
load_image.gdb_initis modified based on gdb download script of previous steps
nuclei-linux-sdk/work/evalsoc/freeloader/$ riscv64-unknown-linux-gnu-gdb
GNU gdb (GDB) 13.2.90.20230712-git
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
# 192.168.40.52:3333 is my port, please change to your correct port
(gdb) target remote 192.168.40.52:3333
Remote debugging using 192.168.40.52:3333
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread
0xffffffff8000334e in ?? ()
(gdb) source load_image.gdb_init
JTAG tap: riscv.cpu tap/device found: 0x16000a6d (mfg: 0x536 (Nuclei System Technology Co Ltd), part: 0x6000, ver: 0x1)
init hardware....
[Switching to thread 1 (Thread 1)]
#0 0x0000000020000000 in ?? ()
[Switching to thread 2 (Thread 2)]
#0 0x0000000020000000 in ?? ()
[Switching to thread 1 (Thread 1)]
#0 0x0000000020000000 in ?? ()
load image ....
Restoring binary file opensbi.bin into memory (0x80000000 to 0x80041e98)
Restoring binary file u-boot.bin into memory (0x80200000 to 0x802678a0)
Restoring binary file fdt.dtb into memory (0x88000000 to 0x88001377)
Restoring binary file kernel.bin into memory (0x83000000 to 0x8342a885)
Restoring binary file initrd.bin into memory (0x88300000 to 0x88a71926)
start run ....
(gdb)
Above load_image.gdb_init script will do continue in the end of the script, you can remove it, if you want to execute it in gdb by yourself.
If you want to debug in IDE, you can refer to https://github.com/Nuclei-Software/nuclei-linux-sdk/wiki/Debug-Linuxsdk-using-NucleiStudio
If you are now able to execute in gdb, and successfully bring up linux with several tries, then you can rebuild freeloader and program the freeloader.elf, you may be able to bring up now.
FAQs
- If in your SoC, your harts' hartid higher bits(such as only lower 8 bits are real hart index) are not zero, please update opensbi code like this, then compile source code.
diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index ab33e11..01ec115 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -381,6 +381,8 @@ _start_warm:
/* Find HART id */
csrr s6, CSR_MHARTID
+ /* Real cpu id in this cluster is hartid & 0xff */
+ andi s6, s6, 255
/* Find HART index */
beqz s9, 3f
diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h
index 10f31a7..4820792 100644
--- a/include/sbi/riscv_asm.h
+++ b/include/sbi/riscv_asm.h
@@ -158,7 +158,7 @@ void csr_write_num(int csr_num, unsigned long val);
} while (0)
/* Get current HART id */
-#define current_hartid() ((unsigned int)csr_read(CSR_MHARTID))
+#define current_hartid() ((unsigned int)csr_read(CSR_MHARTID) & 0xff)
/* determine CPU extension, return non