Setting up the C Compilation and Remote GDB Environment for the First Time on Duo CV1800B

Environment Setup

  1. Install necessary components with apt:

    sudo apt install dialog python3-dev make git bc gcc flex bison ninja-build libssl-dev rsync pkg-config device-tree-compiler squashfs-tools parted dosfstools
  2. Download a higher version of CMake:

  3. Fetch repo:

    • Note that you must add your public key to GitHub. If it’s a new Ubuntu system, you need to generate a public key with the ssh-keygen command and add it to your GitHub account, or you will encounter permission issues later.
    • Create a directory to store repo, and fetch repo from Tsinghua source:
    mkdir <path_to_repo>/duo-manifest
    curl -o repo
    • Grant permissions:
    chmod a+rx repo
  4. Fetch the SDK:

    • Create and navigate to a new directory.
    • Export the repo path above (as a good practice, avoid cluttering your bashrc and PATH).
    export PATH="<path_to_repo>/duo-manifest:${PATH}"
    • Point to Tsinghua source:
    export REPO_URL=''
    • Fetch the SDK:
    repo init -u -b main -m milk-v_duo_cv180xb_sdk.xml
    repo sync
  5. Compilation:

    • Specify the CMake path:
    export PATH="<path_to_cmake>/cmake-3.19.3-Linux-x86_64/bin:${PATH}"
    • Compile:
    source build/
    defconfig cv1800b_sophpi_duo_sd
  6. Burning

    sudo dd if=./install/soc_cv1800b_sophpi_duo_sd/sophpi-duo-<**>.img of=/dev/sda bs=32M status=progress oflag=direct
  7. Connect via UART interface

    • img
    • Start from the fourth pin from the bottom left corner, with a baud rate of 115200.
    • If you encounter gibberish, using 120000 might display bootloader output, typically indicating a failed boot.


  • To use GADGET, the configuration was modified before compilation:


    However, it seems that it did not take effect.

    [root@cvitek]~# ifconfig -a
    eth0      Link encap:Ethernet  HWaddr 0E:43:45:E2:0F:6E  
    		UP BROADCAST MULTICAST  MTU:1500  Metric:1
    		RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    		TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    		collisions:0 txqueuelen:1000 
    		RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
    lo        Link encap:Local Loopback  
    		inet addr:  Mask:
    		UP LOOPBACK RUNNING  MTU:65536  Metric:1
    		RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    		TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    		collisions:0 txqueuelen:1000 
    		RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    The firmware version from May 2023 already supports RADIS. It’s uncertain whether the code configuration for the latest version has been submitted to the repository.

    usb0      Link encap:Ethernet  HWaddr 62:56:94:45:C3:29  
    	inet addr:  Bcast:  Mask:
    	RX packets:35 errors:0 dropped:16 overruns:0 frame:0
    	TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
    	collisions:0 txqueuelen:1000 
    	RX bytes:6450 (6.2 KiB)  TX bytes:1608 (1.5 KiB)
  • The SPI device is not mounted.

    [root@cvitek]~# ls /dev/
    bus             cvi_vc_dec4     full            null
    console         cvi_vc_dec5     gpiochip0       ptmx
    cvi-base        cvi_vc_dec6     gpiochip1       pts
    cvi-dwa         cvi_vc_dec7     gpiochip2       random
    cvi-fast-image  cvi_vc_dec8     gpiochip3       rfkill
    cvi-mipi-rx     cvi_vc_enc0     gpiochip4       root
    cvi-rgn         cvi_vc_enc1     hwrng           shm
    cvi-rtos-cmdqu  cvi_vc_enc2     i2c-0           snd
    cvi-sys         cvi_vc_enc3     i2c-1           tty
    cvi-tpu0        cvi_vc_enc4     i2c-2           ttyS0
    cvi-vi          cvi_vc_enc5     ion             ttyS1
    cvi-vpss        cvi_vc_enc6     kmsg            ttyS2
    cvi_vc_dec0     cvi_vc_enc7     mem             ttyS3
    cvi_vc_dec1     cvi_vc_enc8     mmcblk0         ttyS4
    cvi_vc_dec2     cvitekaadc      mmcblk0p1       urandom
    cvi_vc_dec3     cvitekadac      mmcblk0p2       zero
  • It appears that there is an enabled SPI device in the device tree.

    &spi3 {
    	status = "okay";
    	num-cs = <1>;
    	spidev@0 {
    		compatible = "rohm,dh2228fv";
    		spi-max-frequency = <1000000>;
    		reg = <0>;


  • Given that the self-compiled system does not have RADIS, the official release image was used. In an Ubuntu 20 system, it automatically creates a virtual network card without drivers, and the PC can see it on the 192.168.42.x subnet. As mentioned earlier, the development board’s IP address is

  • SSH Connection

  • GDBserver

    • Locate the gdbserver in the SDK:
    find -name gdbserver
    • Download it using SCP:
    scp ./ramdisk/rootfs/public/gdbserver/riscv_musl/usr/bin/gdbserver root@
  • Compilation

    • There are three different toolchains: riscv64-elf, riscv64-linux-x86_64, and riscv64-linux-musl-x86_64. The programs compiled with the riscv64-elf toolchain can run directly, and system libraries are likely compiled with this toolchain. However, during debugging, the program cannot continue after hitting a breakpoint.
    <path_to_sdk>/duo-src/host-tools/gcc/riscv64-elf-x86_64/bin/riscv64-unknown-elf-gcc -o main main.c -g
    • There are two other toolchains, riscv64-linux-x86_64 and riscv64-linux-musl-x86_64. However, programs compiled with dynamic linking cannot run directly, so static compilation is preferred, but debugging can proceed normally.
    <path_to_sdk>/duo-src/host-tools/gcc/riscv64-elf-x86_64/bin/riscv64-unknown-elf-gcc -o main main.c -g -static
    • Download the program:
    scp main root@
  • Run the program:

    - ./main
  • Debug the program:

    - ./gdbserver :1234 main
  • Integrate it into VSCode:

  "name": "(gdb) Start",
  "type": "cppdbg",
  "request": "launch",
  "program": "${workspaceRoot}/main",
  "args": [],
  "stopAtEntry": false,
  "miDebuggerServerAddress": "", // Target board's IP address and port
  "cwd": "${workspaceRoot}",
  "environment": [],
  "externalConsole": false,
  "MIMode": "gdb",
  // "miDebuggerPath": "<path_to_sdk>/duo-src/host-tools/gcc/riscv64-elf-x86_64/bin/riscv64-unknown-elf-gdb",
  "miDebuggerPath": "<path_to_sdk>/duo-src/host-tools/gcc/riscv64-linux-x86_64/bin/riscv64-unknown-linux-gnu-gdb",
  "setupCommands": [
      "description": "Enable pretty printing for GDB",
      "text": "-enable-pretty-printing",
      "ignoreFailures": true
      "description": "Set disassembly flavor to Intel",
      "text": "-gdb-set disassembly-flavor intel",
      "ignoreFailures": true
  • Click F5 to start debugging.
  • Result: