From 1eb278598463bc67c4fc70d662f0b273e833f46c Mon Sep 17 00:00:00 2001 From: andy <1414772332@qq.com> Date: Thu, 17 Apr 2025 11:14:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E6=8B=9Fcpu=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cpu/riscv.c | 20 ++++--- make_riscv.py | 13 +++-- riscv.ld | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++ riscv/start.S | 8 +++ 4 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 riscv.ld create mode 100644 riscv/start.S diff --git a/cpu/riscv.c b/cpu/riscv.c index a4035ad..56dc3b3 100644 --- a/cpu/riscv.c +++ b/cpu/riscv.c @@ -90,7 +90,7 @@ #define MEM_SIZE 1024*1024 -#define MEM_ADDR_BASE 0x100000000 +#define MEM_ADDR_BASE 0x10000000 #define zero reg[0] #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_size = rom_size; riscv->rom_addr_base = rom_addr_base; - riscv->pc = 0; + riscv->pc = riscv->rom_addr_base; } int riscv_run(riscv_t* riscv) { int ret = 0; 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; if(riscv->pc >= riscv->rom_addr_base + riscv->rom_size){ - printf("riscv run out of rom"); + printf("riscv run out of rom\n"); break; } ret=riscv_decode(riscv, instr); + for (int i = 0;i < 32;i++) { + printf("reg[%d]: %08x\n", i, riscv->reg[i]); + } if(ret){ break; } @@ -729,12 +733,14 @@ int thread_fun(void* t) printf("open file error\n"); return -1; } - riscv.rom_size=get_file_size(file); - riscv.rom=calloc((riscv.rom_size+3)/4,4); + riscv.rom_size = get_file_size(file); + 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); 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; } diff --git a/make_riscv.py b/make_riscv.py index 6b79599..63dc155 100644 --- a/make_riscv.py +++ b/make_riscv.py @@ -8,7 +8,8 @@ import time CC="riscv64-unknown-elf-gcc" -OBJ="riscv64-unknown-elf-objcopy" +OBJCPY="riscv64-unknown-elf-objcopy" +OBJDUMP="riscv64-unknown-elf-objdump" CFLAG=[ "-march=rv32i", @@ -27,11 +28,15 @@ CFLAG=[ ] SRC=[ - "riscv/main.c" + "riscv/main.c", + "riscv/start.S" ] +LD_FILE="riscv.ld" + TARGET="riscv" if __name__ == "__main__": - os.system(f"{CC} {' '.join(CFLAG)} {' '.join(SRC)} -o {TARGET}.elf") - os.system(f"{OBJ} -O binary {TARGET}.elf {TARGET}.bin") + os.system(f"{CC} {' '.join(CFLAG)} {' '.join(SRC)} -T{LD_FILE} -Wall -Wextra -nostartfiles -Wl,-Map,\"{TARGET}.map\" -o {TARGET}.elf") + os.system(f"{OBJCPY} -O binary {TARGET}.elf {TARGET}.bin") + os.system(f"{OBJDUMP} -d {TARGET}.elf > {TARGET}.lst") diff --git a/riscv.ld b/riscv.ld new file mode 100644 index 0000000..f562070 --- /dev/null +++ b/riscv.ld @@ -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 +} diff --git a/riscv/start.S b/riscv/start.S new file mode 100644 index 0000000..4d2dad4 --- /dev/null +++ b/riscv/start.S @@ -0,0 +1,8 @@ + + .section .init + .globl _start + .type _start,@function + +_start: + + la sp, _sp \ No newline at end of file