模拟cpu成功运行

This commit is contained in:
2025-04-17 11:14:53 +08:00
parent ed0144b2ce
commit 1eb2785984
4 changed files with 183 additions and 11 deletions

View File

@@ -90,7 +90,7 @@
#define MEM_SIZE 1024*1024 #define MEM_SIZE 1024*1024
#define MEM_ADDR_BASE 0x100000000 #define MEM_ADDR_BASE 0x10000000
#define zero reg[0] #define zero reg[0]
#define ra reg[1] #define ra reg[1]
@@ -670,20 +670,24 @@ int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t r
riscv->rom = rom; riscv->rom = rom;
riscv->rom_size = rom_size; riscv->rom_size = rom_size;
riscv->rom_addr_base = rom_addr_base; riscv->rom_addr_base = rom_addr_base;
riscv->pc = 0; riscv->pc = riscv->rom_addr_base;
} }
int riscv_run(riscv_t* riscv) { int riscv_run(riscv_t* riscv) {
int ret = 0; int ret = 0;
while(1) { while(1) {
uint32_t instr = riscv->rom[riscv->pc >> 2]; uint32_t instr = riscv->rom[(riscv->pc-riscv->rom_addr_base) >> 2];
printf("pc: %08x instr: %08x\n", riscv->pc, instr);
riscv->pc += 4; riscv->pc += 4;
if(riscv->pc >= riscv->rom_addr_base + riscv->rom_size){ if(riscv->pc >= riscv->rom_addr_base + riscv->rom_size){
printf("riscv run out of rom"); printf("riscv run out of rom\n");
break; break;
} }
ret=riscv_decode(riscv, instr); ret=riscv_decode(riscv, instr);
for (int i = 0;i < 32;i++) {
printf("reg[%d]: %08x\n", i, riscv->reg[i]);
}
if(ret){ if(ret){
break; break;
} }
@@ -729,12 +733,14 @@ int thread_fun(void* t)
printf("open file error\n"); printf("open file error\n");
return -1; return -1;
} }
riscv.rom_size=get_file_size(file); riscv.rom_size = get_file_size(file);
riscv.rom=calloc((riscv.rom_size+3)/4,4); printf("rom size: %d\n", riscv.rom_size);
riscv.rom = calloc((riscv.rom_size + 3) / 4, 4);
fread(riscv.rom, 1, riscv.rom_size, file); fread(riscv.rom, 1, riscv.rom_size, file);
fclose(file); fclose(file);
riscv_init(&riscv,riscv.rom,0x80000000,riscv.rom_size); riscv_init(&riscv, riscv.rom, 0x80000000, riscv.rom_size);
riscv_run(&riscv);
return 0; return 0;
} }

View File

@@ -8,7 +8,8 @@ import time
CC="riscv64-unknown-elf-gcc" CC="riscv64-unknown-elf-gcc"
OBJ="riscv64-unknown-elf-objcopy" OBJCPY="riscv64-unknown-elf-objcopy"
OBJDUMP="riscv64-unknown-elf-objdump"
CFLAG=[ CFLAG=[
"-march=rv32i", "-march=rv32i",
@@ -27,11 +28,15 @@ CFLAG=[
] ]
SRC=[ SRC=[
"riscv/main.c" "riscv/main.c",
"riscv/start.S"
] ]
LD_FILE="riscv.ld"
TARGET="riscv" TARGET="riscv"
if __name__ == "__main__": if __name__ == "__main__":
os.system(f"{CC} {' '.join(CFLAG)} {' '.join(SRC)} -o {TARGET}.elf") os.system(f"{CC} {' '.join(CFLAG)} {' '.join(SRC)} -T{LD_FILE} -Wall -Wextra -nostartfiles -Wl,-Map,\"{TARGET}.map\" -o {TARGET}.elf")
os.system(f"{OBJ} -O binary {TARGET}.elf {TARGET}.bin") os.system(f"{OBJCPY} -O binary {TARGET}.elf {TARGET}.bin")
os.system(f"{OBJDUMP} -d {TARGET}.elf > {TARGET}.lst")

153
riscv.ld Normal file
View File

@@ -0,0 +1,153 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
flash (rxai!w) : ORIGIN = 0x80000000, LENGTH = 1024K
dram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 1024K
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init :
{
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash
.text :
{
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >flash AT>flash
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >flash AT>flash
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
} >flash AT>flash
. = ALIGN(4);
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >flash AT>flash
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >flash AT>flash
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >flash AT>flash
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >flash AT>flash
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >flash AT>flash
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >flash AT>flash
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >dram AT>flash
.data :
{
*(.data .data.*)
*(.gnu.linkonce.d.*)
PROVIDE( _gp = . + 0x800 );
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
} >dram AT>flash
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >dram AT>dram
. = ALIGN(8);
PROVIDE( _end = . );
PROVIDE( end = . );
PROVIDE( _heap_start = . );
.stack ORIGIN(dram) + LENGTH(dram) - __stack_size :
{
PROVIDE( _heap_end = . );
. = __stack_size;
PROVIDE( _sp = . );
} >dram AT>dram
}

8
riscv/start.S Normal file
View File

@@ -0,0 +1,8 @@
.section .init
.globl _start
.type _start,@function
_start:
la sp, _sp