feat[bsp][xuantie]: c908 support rt-smart #11719

This commit is contained in:
BadmintonMaster
2026-08-28 12:25:32 +08:00
committed by GitHub
parent 0ae80cc79c
commit bf38ee2130
27 changed files with 4108 additions and 22 deletions
+2 -1
View File
@@ -541,7 +541,8 @@
"RTT_BSP": "xuantie-smart",
"RTT_TOOL_CHAIN": "sourcery-Xuantie-900-gcc-linux-musl",
"SUB_RTT_BSP": [
"xuantie/virt64/c906"
"xuantie/virt64/c906",
"xuantie/virt64/c908"
]
},
{
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
mainmenu "RT-Thread Project Configuration"
RTT_DIR := ../../../..
PKGS_DIR := packages
source "$(RTT_DIR)/Kconfig"
osource "$PKGS_DIR/Kconfig"
rsource "board/Kconfig"
config BOARD_QEMU_VIRT_RV64
bool
select ARCH_RISCV64
select ARCH_USING_RISCV_COMMON64
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
select RT_USING_CACHE
select ARCH_MM_MMU
select ARCH_REMAP_KERNEL
default y
config ENABLE_FPU
bool "Enable FPU"
select ARCH_RISCV_FPU
default y
config ENABLE_VECTOR
bool "Enable Vector"
select ARCH_RISCV_VECTOR
default y
config __STACKSIZE__
int "stack size for interrupt"
default 8192
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+15
View File
@@ -0,0 +1,15 @@
# for module compiling
import os
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')
+70
View File
@@ -0,0 +1,70 @@
import os
import sys
import rtconfig
from SCons.Script import *
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../../../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
try:
from building import *
except:
print('Cannot found RT-Thread root directory, please check RTT_ROOT')
print(RTT_ROOT)
exit(-1)
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
env['ASCOM'] = env['ASPPCOM']
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
stack_size = 4096
if GetDepend('RT_USING_SMART'):
# use smart link.lds
env['LINKFLAGS'] = env['LINKFLAGS'].replace('link.lds', 'link_smart.lds')
stack_lds = open('link_stacksize.lds', 'w')
if GetDepend('__STACKSIZE__'): stack_size = GetDepend('__STACKSIZE__')
stack_lds.write('__STACKSIZE__ = %d;\n' % stack_size)
stack_lds.close()
# Obtain the number of harts from rtconfig.h and write
# it into link_cpus.lds for the linker script
try:
with open('rtconfig.h', 'r') as f:
rtconfig_content = f.readlines()
except FileNotFoundError:
cpus_nr = 1
else:
cpus_nr = 1 # default value
for line in rtconfig_content:
line = line.strip()
if line.startswith('#define') and 'RT_CPUS_NR' in line:
parts = line.split()
if len(parts) >= 3 and parts[2].isdigit():
cpus_nr = int(parts[2])
break
with open('link_cpus.lds', 'w') as cpus_lds:
cpus_lds.write(f'RT_CPUS_NR = {cpus_nr};\n')
# make a building
DoBuilding(TARGET, objs)
@@ -0,0 +1,10 @@
import rtconfig
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#include <rthw.h>
#include <string.h>
int main(void)
{
rt_kprintf("Hello RISC-V C908\n");
return 0;
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021/08/19 bernard the first version
*/
#include <rtthread.h>
#ifdef RT_USING_DFS
#include <dfs_fs.h>
#include <rtdbg.h>
int mnt_init(void)
{
if (rt_device_find("virtio-blk0"))
{
/* mount virtio-blk as root directory */
if (dfs_mount("virtio-blk0", "/", "elm", 0, RT_NULL) == 0)
{
rt_kprintf("file system initialization done!\n");
}
else
{
if (dfs_mount("virtio-blk0", "/", "ext", 0, RT_NULL) == 0)
{
rt_kprintf("file system initialization done!\n");
}
else
{
rt_kprintf("file system initialization fail!\n");
}
}
}
return 0;
}
INIT_ENV_EXPORT(mnt_init);
#endif
+15
View File
@@ -0,0 +1,15 @@
menu "RISC-V QEMU virt64 configs"
config BSP_USING_VIRTIO
bool "Using VirtIO"
default y
depends on RT_USING_DEVICE_OPS
config BSP_USING_VIRTIO_BLK
bool "Using VirtIO BLK"
select RT_USING_LEGACY_VIRTIO
select RT_USING_VIRTIO_BLK
default y
depends on BSP_USING_VIRTIO
endmenu
+10
View File
@@ -0,0 +1,10 @@
import rtconfig
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+112
View File
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-04-23 Wangshun first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"
#include "mm_aspace.h"
#include "tick.h"
#include "drv_uart.h"
#include "encoding.h"
#include "stack.h"
#include "sbi.h"
#include "riscv.h"
#include "plic.h"
#include "stack.h"
#ifdef RT_USING_SMART
#include "riscv_mmu.h"
#include "mmu.h"
#include "page.h"
#include "lwp_arch.h"
rt_region_t init_page_region = { (rt_size_t)RT_HW_PAGE_START, (rt_size_t)RT_HW_PAGE_END };
extern size_t MMUTable[];
struct mem_desc platform_mem_desc[] = {
{ KERNEL_VADDR_START, (rt_size_t)RT_HW_PAGE_END - 1, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM },
};
#define NUM_MEM_DESC (sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]))
#endif
rt_uint64_t rt_hw_get_clock_timer_freq(void)
{
return 10000000ULL;
}
void primary_cpu_entry(void)
{
/* disable global interrupt */
rt_hw_interrupt_disable();
entry();
}
#define IOREMAP_SIZE (1ul << 30)
#ifndef ARCH_REMAP_KERNEL
#define IOREMAP_VEND USER_VADDR_START
#else
#define IOREMAP_VEND 0ul
#endif /* ARCH_REMAP_KERNEL */
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
/* init data structure */
rt_hw_mmu_map_init(&rt_kernel_space, (void *)(IOREMAP_VEND - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, PV_OFFSET);
/* init page allocator */
rt_page_init(init_page_region);
/* setup region, and enable MMU */
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, NUM_MEM_DESC);
#endif
#ifdef RT_USING_HEAP
/* initialize memory system */
rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
#endif
plic_init();
rt_hw_interrupt_init();
rt_hw_uart_init();
#ifdef RT_USING_CONSOLE
/* set console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif /* RT_USING_CONSOLE */
rt_hw_tick_init();
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#ifdef RT_USING_HEAP
rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t)RT_HW_HEAP_BEGIN, (rt_ubase_t)RT_HW_HEAP_END);
#endif /* RT_USING_HEAP */
}
void rt_hw_cpu_reset(void)
{
sbi_shutdown();
while (1);
}
MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-30 lizhirui first version
*/
#ifndef BOARD_H__
#define BOARD_H__
#include <rtconfig.h>
extern unsigned int __bss_start;
extern unsigned int __bss_end;
#ifndef RT_USING_SMART
#define KERNEL_VADDR_START 0x0
#endif
#define VIRT64_SBI_MEMSZ (0x200000)
#define RT_HW_HEAP_BEGIN ((void *)&__bss_end)
#define RT_HW_HEAP_END ((void *)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024))
#define RT_HW_PAGE_START RT_HW_HEAP_END
#define RT_HW_PAGE_END ((void *)(KERNEL_VADDR_START + (256 * 1024 * 1024 - VIRT64_SBI_MEMSZ)))
void rt_hw_board_init(void);
void rt_init_user_mem(struct rt_thread *thread, const char *name,
unsigned long *entry);
#endif
+165
View File
@@ -0,0 +1,165 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtdevice.h>
#include <rtthread.h>
#include "board.h"
#include "drv_uart.h"
#include <stdio.h>
#ifdef RT_USING_SMART
#include <ioremap.h>
#endif
#include "sbi.h"
struct device_uart
{
rt_ubase_t hw_base;
rt_uint32_t irqno;
};
void *uart0_base = (void *)0x10000000;
struct rt_serial_device serial0;
struct device_uart uart0;
void uart_init(void)
{
rt_uint32_t div = UART_REFERENCE_CLOCK / (UART_DEFAULT_BAUDRATE * 16);
write8_uart0(UART_IER, 0x00);
write8_uart0(UART_LCR, UART_LCR_BAUD_LATCH);
// LSB
write8_uart0(0, div & 0xff);
// MSB
write8_uart0(1, (div >> 8) & 0xff);
// set word length to 8 bits, no parity
write8_uart0(UART_LCR, UART_LCR_EIGHT_BITS);
write8_uart0(UART_FCR, UART_FCR_FIFO_ENABLE | UART_FCR_FIFO_CLEAR);
return;
}
static rt_err_t _uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
return (RT_EOK);
}
static rt_err_t _uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
struct device_uart *uart = (struct device_uart *)serial->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
{
rt_uint8_t value = read8_uart0(UART_IER);
write8_uart0(UART_IER, value & ~UART_IER_RX_ENABLE);
}
break;
case RT_DEVICE_CTRL_SET_INT:
if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
{
rt_uint8_t value = read8_uart0(UART_IER);
write8_uart0(UART_IER, value | UART_IER_RX_ENABLE);
}
break;
}
return (RT_EOK);
}
static int _uart_putc(struct rt_serial_device *serial, char c)
{
struct device_uart *uart;
uart = (struct device_uart *)serial->parent.user_data;
// wait for Transmit Holding Empty to be set in LSR.
while ((read8_uart0(UART_LSR) & UART_LSR_TX_IDLE) == 0);
write8_uart0(UART_THR, c);
return (1);
}
static int _uart_getc(struct rt_serial_device *serial)
{
struct device_uart *uart;
volatile rt_uint32_t lsr;
int ch = -1;
uart = (struct device_uart *)serial->parent.user_data;
lsr = read8_uart0(UART_LSR);
if (lsr & UART_LSR_RX_READY)
{
ch = read8_uart0(UART_RHR);
}
return ch;
}
const struct rt_uart_ops _uart_ops = {
_uart_configure,
_uart_control,
_uart_putc,
_uart_getc,
// TODO: add DMA support
RT_NULL
};
static void rt_hw_uart_isr(int irqno, void *param)
{
rt_ubase_t level = rt_hw_interrupt_disable();
struct rt_serial_device *serial = (struct rt_serial_device *)param;
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
rt_hw_interrupt_enable(level);
}
/*
* UART Initiation
*/
int rt_hw_uart_init(void)
{
struct rt_serial_device *serial;
struct device_uart *uart;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#ifdef RT_USING_SMART
uart0_base = rt_ioremap(uart0_base, 4096);
#endif
// register device
serial = &serial0;
uart = &uart0;
serial->ops = &_uart_ops;
serial->config = config;
serial->config.baud_rate = UART_DEFAULT_BAUDRATE;
uart->hw_base = (rt_ubase_t)uart0_base;
uart->irqno = 0x0a;
rt_hw_serial_register(serial,
RT_CONSOLE_DEVICE_NAME,
RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart);
rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, RT_CONSOLE_DEVICE_NAME);
rt_hw_interrupt_umask(uart->irqno);
return 0;
}
/* WEAK for SDK 0.5.6 */
rt_weak void uart_debug_init(int uart_channel)
{
}
+62
View File
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
#include "riscv_io.h"
/**
* uart ns16550a
* http://byterunner.com/16550.html
*/
/* TRANSMIT AND RECEIVE HOLDING REGISTER */
#define UART_RHR 0
#define UART_THR 0
/* INTERRUPT ENABLE REGISTER */
#define UART_IER 1
#define UART_IER_RX_ENABLE (1 << 0)
#define UART_IER_TX_ENABLE (1 << 1)
/* FIFO CONTROL REGISTER */
#define UART_FCR 2
#define UART_FCR_FIFO_ENABLE (1 << 0)
#define UART_FCR_FIFO_CLEAR (3 << 1)
/* INTERRUPT STATUS REGISTER */
#define UART_ISR 2
/* LINE CONTROL REGISTER */
#define UART_LCR 3
#define UART_LCR_EIGHT_BITS (3 << 0)
// special mode to set baud rate
#define UART_LCR_BAUD_LATCH (1 << 7)
/* LINE STATUS REGISTER */
#define UART_LSR 5
// input is waiting to be read from RHR
#define UART_LSR_RX_READY (1 << 0)
// THR can accept another character to send
#define UART_LSR_TX_IDLE (1 << 5)
#define UART_REFERENCE_CLOCK 1843200
#define UART_DEFAULT_BAUDRATE 115200
extern void *uart0_base;
#define write8_uart0(idx, value) __raw_writeb(((rt_uint8_t)value), (void *)((size_t)uart0_base + (idx)))
#define read8_uart0(idx) __raw_readb((void *)((size_t)uart0_base + (idx)))
void rt_hw_uart_start_rx_thread();
int rt_hw_uart_init(void);
void drv_uart_puts(char *str); // for syscall
#endif /* __DRV_UART_H__ */
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-11-11 GuEe-GUI the first version
*/
#include <rtthread.h>
#include <virt.h>
#ifdef BSP_USING_VIRTIO
#include <virtio.h>
#ifdef BSP_USING_VIRTIO_BLK
#include <virtio_blk.h>
#endif
#include <board.h>
static virtio_device_init_handler virtio_device_init_handlers[] = {
#ifdef BSP_USING_VIRTIO_BLK
[VIRTIO_DEVICE_ID_BLOCK] = rt_virtio_blk_init,
#endif
[VIRTIO_DEVICE_TYPE_SIZE] = RT_NULL
};
int rt_virtio_devices_init(void)
{
int i;
rt_uint32_t irq = VIRTIO_IRQ_BASE;
rt_ubase_t mmio_base = VIRTIO_MMIO_BASE;
struct virtio_mmio_config *mmio_config;
virtio_device_init_handler init_handler;
if (sizeof(virtio_device_init_handlers) == 0)
{
/* The compiler will optimize the codes after here. */
return 0;
}
#ifdef RT_USING_SMART
mmio_base = (rt_ubase_t)rt_ioremap((void *)mmio_base, VIRTIO_MMIO_SIZE * VIRTIO_MAX_NR);
if (mmio_base == RT_NULL)
{
return -RT_ERROR;
}
#endif
for (i = 0; i < VIRTIO_MAX_NR; ++i, ++irq, mmio_base += VIRTIO_MMIO_SIZE)
{
mmio_config = (struct virtio_mmio_config *)mmio_base;
if (mmio_config->magic != VIRTIO_MAGIC_VALUE ||
mmio_config->version != RT_USING_VIRTIO_VERSION ||
mmio_config->vendor_id != VIRTIO_VENDOR_ID)
{
continue;
}
init_handler = virtio_device_init_handlers[mmio_config->device_id];
if (init_handler != RT_NULL)
{
init_handler((rt_ubase_t *)mmio_base, irq);
}
}
return 0;
}
INIT_DEVICE_EXPORT(rt_virtio_devices_init);
#endif /* BSP_USING_VIRTIO */
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-17 GuEe-GUI the first version
*/
#ifndef DRV_VIRTIO_H__
#define DRV_VIRTIO_H__
#endif
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-02-17 GuEe-GUI the first version
*/
#ifndef VIRT_H__
#define VIRT_H__
#include <rtdef.h>
#ifdef RT_USING_SMART
#include <mmu.h>
#include <ioremap.h>
#endif
/* VirtIO */
#define VIRTIO_MMIO_BASE 0x10001000
#define VIRTIO_MMIO_SIZE 0x00001000
#define VIRTIO_MAX_NR 8
#define VIRTIO_IRQ_BASE 1
#define VIRTIO_VENDOR_ID 0x554d4551 /* "QEMU" */
#define MAX_HANDLERS 128
#endif
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
RT_CPUS_NR = 2;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
__STACKSIZE__ = 16384;
File diff suppressed because it is too large Load Diff
+51
View File
@@ -0,0 +1,51 @@
import os
# toolchains options
ARCH ='risc-v'
CPU ='virt64'
CROSS_TOOL ='gcc'
RTT_ROOT = os.getenv('RTT_ROOT') or os.path.join(os.getcwd(), '..', '..')
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
else:
print('Please make sure your toolchains is GNU GCC!')
exit(0)
BUILD = 'debug'
if PLATFORM == 'gcc':
# toolchains
PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-unknown-elf-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcmodel=medany -march=rv64imafdcv -mabi=lp64d '
CFLAGS = DEVICE + '-ffreestanding -flax-vector-conversions -Wno-cpp -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fdiagnostics-color=always'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__ '
LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds' + ' -lsupc++ -lgcc -static'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -ggdb -fvar-tracking '
AFLAGS += ' -ggdb'
else:
CFLAGS += ' -O2 -Os'
CXXFLAGS = CFLAGS
DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtthread.asm\n'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
usage ()
{
echo "Usage:"
echo "./run.sh [<path_to_image>]"
echo "Note: if <path_to_image> is not provided, will create a 'sd.bin'"
echo "in the current directory and load it by default."
}
path_image=${1}
if [ -z $path_image ]; then
path_image="./sd.bin"
if [ ! -f $path_image ]; then
dd if=/dev/zero of=$path_image bs=1024 count=65536
mkfs.fat $path_image
fi
fi
if [ ! -f $path_image ]; then
echo "ERROR: $path_image does not exist!"
usage
exit
fi
QEMU_CMD="qemu-system-riscv64 -nographic -machine virt -m 256M -kernel rtthread.bin -cpu c908v"
if grep -q "#define RT_USING_SMP" ./rtconfig.h 2>/dev/null; then
hart_num=$(grep "RT_CPUS_NR = [0-9]*;" ./link_cpus.lds 2>/dev/null | awk -F'[=;]' '{gsub(/ /, "", $2); print $2}')
if [ -z "$hart_num" ] || [ "$hart_num" -lt 1 ]; then
echo "Warning: Invalid or missing RT_CPUS_NR, defaulting to 1"
hart_num=1
fi
QEMU_CMD="$QEMU_CMD -smp $hart_num"
fi
QEMU_CMD="$QEMU_CMD \
-drive if=none,file=$path_image,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \
-netdev user,id=tap0 -device virtio-net-device,netdev=tap0,bus=virtio-mmio-bus.1 \
-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0"
eval $QEMU_CMD
File diff suppressed because it is too large Load Diff