assembly 如何使用qemu-system-riscv 32和gdb-multiarch运行和调试一个简单的riscv 32裸机程序集(编译成elf)?(链接器定义问题?)

cyej8jka  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(164)

我正在尝试创建一个简单的汇编程序,将其编译为.elf可执行文件,并使用qemu-system-riscv32gdb-multiarch运行+调试它。
每当我尝试运行我的.elf时,我会遇到两个问题:

  1. qemu抱怨内存部分重叠:The following two regions overlap (in the memory address space): out/hello_world.elf ELF program header segment 1 (addresses 0x000000007ffff000 - 0x0000000080000050)/usr/local/bin/../share/qemu/opensbi-riscv32-generic-fw_dynamic.bin (addresses 0x0000000080000000 - 0x000000008001e0c0)
    1.而且当我试图修复重叠问题时,我的main从未进入(和qemu存在)。GDB显示程序计数器/ PC开始时为0x 1004。当我继续的时候,我的b main永远不会被击中。当I CTRL+C gdb指示qemu进程已退出,但除了远程gdb会话连接已丢失外,没有其他错误。
    如前所述,我尝试在链接器定义文件中更改内存范围/入口点,使其不与risc-v中的opensbi重叠。
    为了说明我的设置,这是我的hello_world.s:
.globl main
.type  main, @function
main:
  li a1, 1337
  mv a0, zero
  ret

  .size  main, .-main

qemu.s:

.section .init, "ax"
.global _start
_start:
    .cfi_startproc
    .cfi_undefined ra
    .option push
    .option norelax
    la gp, __global_pointer$
    .option pop
    la sp, __stack_top
    add s0, sp, zero
    #jal zero, _start_continue
    call main
    .cfi_endproc
    .end

Makefile:

CROSS_PREFIX=riscv32-unknown-elf-
INC=-I./src/

clean:
    rm -f out/*.o out/*.elf

%:
    # create output dir
    mkdir -p out
    # compile the assembly specified in the name
    $(CROSS_PREFIX)as $(INC) -g -c src/qemu.s -o out/qemu.o
    $(CROSS_PREFIX)as $(INC) -g -c src/$@.s -o out/$@.o
    # link the assembly
    $(CROSS_PREFIX)ld -Triscv32-virt.ld out/qemu.o out/$@.o -o out/$@.elf

我的调试脚本:

#!/usr/bin/env bash
SEQUENCE=$1
make ${SEQUENCE}
qemu-system-riscv32 -kernel out/${SEQUENCE}.elf -nographic -s -S -m 512M &
CHILD_PID=$!
gdb-multiarch -tui -q -ex "file out/${SEQUENCE}.elf" -ex "target remote 127.0.0.1:1234" -ex "layout asm" -ex "b main" -ex "ni"
kill -9 ${CHILD_PID}

(due对于ni命令,GDB显示PC在0x 1004而不是0x 1000,但为什么qemu在0x 1000而不是ELF入口地址进入我的应用程序?)
我在以下答案的帮助下创建了ld文件:How to debug cross-compiled QEMU program with GDB?
这导致了这样一个文件:
riscv32-virt.ld:

/* Script for -z combreloc */
/* Copyright (C) 2014-2023 Free Software Foundation, Inc.
   Copying and distribution of this script, with or without modification,
   are permitted in any medium without royalty provided the copyright
   notice and this notice are preserved.  */
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv",
          "elf32-littleriscv")
OUTPUT_ARCH(riscv)
MEMORY
{
   RAM (rwx) : ORIGIN = 0x80020000, LENGTH = 511M
   RAM2 (rwx) : ORIGIN = 0x80000000, LENGTH = 128K
}
ENTRY(_start)
SECTIONS
{
  /* Read-only sections, merged into text segment: */
  PROVIDE (__executable_start = SEGMENT_START("text-segment", ORIGIN(RAM))); . = SEGMENT_START("text-segment", ORIGIN(RAM)) + SIZEOF_HEADERS;
  PROVIDE(__stack_top = ORIGIN(RAM) + LENGTH(RAM));
  .interp         : { *(.interp) }
  .note.gnu.build-id : { *(.note.gnu.build-id) }
  .hash           : { *(.hash) }
  .gnu.hash       : { *(.gnu.hash) }
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .rela.dyn       :
    {
      *(.rela.init)
      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
      *(.rela.fini)
      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
      *(.rela.ctors)
      *(.rela.dtors)
      *(.rela.got)
      *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
      *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
      *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
      *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
      *(.rela.ifunc)
    }
  .rela.plt       :
    {
      *(.rela.plt)
      PROVIDE_HIDDEN (__rela_iplt_start = .);
      *(.rela.iplt)
      PROVIDE_HIDDEN (__rela_iplt_end = .);
    }
  .init           :
  {
    KEEP (*(SORT_NONE(.init)))
  }
  .plt            : { *(.plt) *(.iplt) }
  .text           :
  {
    *(.text.unlikely .text.*_unlikely .text.unlikely.*)
    *(.text.exit .text.exit.*)
    *(.text.startup .text.startup.*)
    *(.text.hot .text.hot.*)
    *(SORT(.text.sorted.*))
    *(.text .stub .text.* .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf.em.  */
    *(.gnu.warning)
  }
  .fini           :
  {
    KEEP (*(SORT_NONE(.fini)))
  }
  PROVIDE (__etext = .);
  PROVIDE (_etext = .);
  PROVIDE (etext = .);
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  .rodata1        : { *(.rodata1) }
  .sdata2         :
  {
    *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
  }
  .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
  .eh_frame_hdr   : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
  .sframe         : ONLY_IF_RO { *(.sframe) *(.sframe.*) }
  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
  .gnu_extab   : ONLY_IF_RO { *(.gnu_extab*) }
  /* These sections are generated by the Sun/Oracle C++ compiler.  */
  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges*) }
  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
  /* Exception handling  */
  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
  .sframe         : ONLY_IF_RW { *(.sframe) *(.sframe.*) }
  .gnu_extab      : ONLY_IF_RW { *(.gnu_extab) }
  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges*) }
  /* Thread Local Storage sections  */
  .tdata      :
   {
     PROVIDE_HIDDEN (__tdata_start = .);
     *(.tdata .tdata.* .gnu.linkonce.td.*)
   }
  .tbss       : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  .preinit_array    :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }
  .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 = .);
  }
  .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 = .);
  }
  .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))
  }
  .dtors          :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }
  .jcr            : { KEEP (*(.jcr)) }
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
  .dynamic        : { *(.dynamic) }
  . = DATA_SEGMENT_RELRO_END (0, .);
  .data           :
  {
    __DATA_BEGIN__ = .;
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1          : { *(.data1) }
  .got            : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
  /* We want the small data sections together, so single-instruction offsets
     can access them all, and initialized data all before uninitialized, so
     we can shorten the on-disk segment size.  */
  .sdata          :
  {
    __SDATA_BEGIN__ = .;
    *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
    *(.sdata .sdata.* .gnu.linkonce.s.*)
  }
  _edata = .; PROVIDE (edata = .);
  . = .;
  __bss_start = .;
  .sbss           :
  {
    *(.dynsbss)
    *(.sbss .sbss.* .gnu.linkonce.sb.*)
    *(.scommon)
  }
  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we do not
      pad the .data section.  */
   . = ALIGN(. != 0 ? 32 / 8 : 1);
  }
  . = ALIGN(32 / 8);
  . = SEGMENT_START("ldata-segment", .);
  . = ALIGN(32 / 8);
  __BSS_END__ = .;
    __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,
                    MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
  _end = .; PROVIDE (end = .);
  . = DATA_SEGMENT_END (.);
  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1.  */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions.  */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2.  */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2.  */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions.  */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* DWARF 3.  */
  .debug_pubtypes 0 : { *(.debug_pubtypes) }
  .debug_ranges   0 : { *(.debug_ranges) }
  /* DWARF 5.  */
  .debug_addr     0 : { *(.debug_addr) }
  .debug_line_str 0 : { *(.debug_line_str) }
  .debug_loclists 0 : { *(.debug_loclists) }
  .debug_macro    0 : { *(.debug_macro) }
  .debug_names    0 : { *(.debug_names) }
  .debug_rnglists 0 : { *(.debug_rnglists) }
  .debug_str_offsets 0 : { *(.debug_str_offsets) }
  .debug_sup      0 : { *(.debug_sup) }
  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

可以注意到,我将内存扩展到了512 M(因为我的测试需要这么多)。为此,我将-m 512M赋值给qemu,并在链接器定义文件中更改它。
一开始我有这个:

MEMORY
{
   RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 512M
}

但这造成了重叠误差。所以我尝试将ORIGIN移动到0x80020000,但这使得我的代码在gdb会话期间永远不会输入。这同样适用于当前代码(因为可能qemu期望0x80000000位置被Map):

MEMORY
{
   RAM (rwx) : ORIGIN = 0x80020000, LENGTH = 511M
   RAM2 (rwx) : ORIGIN = 0x80000000, LENGTH = 128K
}

我用readelf做了双重检查,检查条目地址是否正确,它确实正确!:

Elf file type is EXEC (Executable file)
Entry point 0x80020000
There are 2 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  RISCV_ATTRIBUT 0x001050 0x00000000 0x00000000 0x0004c 0x00000 R   0x1
  LOAD           0x000000 0x8001f000 0x8001f000 0x01050 0x01050 R E 0x1000

 Section to Segment mapping:
  Segment Sections...
   00     .riscv.attributes
   01     .init .text .eh_frame

相关软件的版本:

# make --version
GNU Make 4.3
Built for x86_64-pc-linux-gnu

# readelf --version
GNU readelf (GNU Binutils for Ubuntu) 2.38

# qemu-system-riscv32 --version
QEMU emulator version 8.0.2 (v8.0.2)

# gdb-multiarch --version
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1

# riscv32-unknown-elf-as --version
GNU assembler (GNU Binutils) 2.40.0.20230214

# riscv32-unknown-elf-ld --version
GNU ld (GNU Binutils) 2.40.0.20230214

# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.2 LTS
Release:        22.04
Codename:       jammy

这是在Windows 10 21 H2 19044.2604上的WSL 2上运行的。
我做错了什么,qemu不会进入我的入口点,也不会执行我的代码?
当我进入GDB时,我偶然发现了一条有趣的信息:

(gdb) maintenance info sections
Exec file: `/mnt/c/Users/nxf75132/Desktop/qrv32/out/hello_world.elf', file type elf32-littleriscv.
 [0]      0x80020000->0x80020018 at 0x00001000: .init ALLOC LOAD READONLY CODE HAS_CONTENTS
 [1]      0x80020018->0x80020024 at 0x00001018: .text ALLOC LOAD READONLY CODE HAS_CONTENTS
 [2]      0x80020024->0x80020050 at 0x00001024: .eh_frame ALLOC LOAD READONLY DATA HAS_CONTENTS
 [3]      0x0000->0x004c at 0x00001050: .riscv.attributes READONLY HAS_CONTENTS
 [4]      0x0000->0x0040 at 0x000010a0: .debug_aranges READONLY HAS_CONTENTS
 [5]      0x0000->0x005b at 0x000010e0: .debug_info READONLY HAS_CONTENTS
 [6]      0x0000->0x0035 at 0x0000113b: .debug_abbrev READONLY HAS_CONTENTS
 [7]      0x0000->0x0097 at 0x00001170: .debug_line READONLY HAS_CONTENTS
 [8]      0x0000->0x0054 at 0x00001207: .debug_str READONLY HAS_CONTENTS

at部分似乎指示.init部分的0x00001000-我怀疑这可能是问题所在,但我如何修复这个问题?
当我执行gdb cat和此命令时,所有起始地址似乎都与at地址重叠(只有在某些情况下不匹配)。但是.init和.text部分采用预期格式,其中at是起始地址(第二列0x... ->)。
编辑:使用以下命令运行其他调试时:

# qemu-system-riscv32 -D ./log.txt -kernel "out/hello_world.elf" -m 512M -monitor stdio -d cpu,exec,in_asm,nochain -singlestep
QEMU 8.0.2 monitor - type 'help' for more information
(qemu) VNC server running on 127.0.0.1:5900
quit # after some time (e.g. one minute)

我在log.txt中得到额外的调试,第一个条目是:

----------------
IN: 
Priv: 3; Virt: 0
0x00001000:  00000297          auipc                   t0,0                    # 0x1000

Trace 0: 0x7f5940000100 [00000000/00001000/00109003/ff000201] 
 V      =   0
 pc       00001000
 mhartid  00000000
 mstatus  00000000
 mstatush 00000000
 hstatus  00000000
 vsstatus 00000000
 mip      00000080
 mie      00000000
 mideleg  00000000
 hideleg  00000000
 medeleg  00000000
 hedeleg  00000000
 mtvec    00000000
 stvec    00000000
 vstvec   00000000
 mepc     00000000
 sepc     00000000
 vsepc    00000000
 mcause   00000000
 scause   00000000
 vscause  00000000
 mtval    00000000
 stval    00000000
 htval    00000000
 mtval2   00000000
 mscratch 00000000
 sscratch 00000000
 satp     00000000
 x0/zero  00000000 x1/ra    00000000 x2/sp    00000000 x3/gp    00000000
 x4/tp    00000000 x5/t0    00000000 x6/t1    00000000 x7/t2    00000000
 x8/s0    00000000 x9/s1    00000000 x10/a0   00000000 x11/a1   00000000
 x12/a2   00000000 x13/a3   00000000 x14/a4   00000000 x15/a5   00000000
 x16/a6   00000000 x17/a7   00000000 x18/s2   00000000 x19/s3   00000000
 x20/s4   00000000 x21/s5   00000000 x22/s6   00000000 x23/s7   00000000
 x24/s8   00000000 x25/s9   00000000 x26/s10  00000000 x27/s11  00000000
 x28/t3   00000000 x29/t4   00000000 x30/t5   00000000 x31/t6   00000000

在此之后,PC上升到PC 0x 1014,在那里它执行jr,t0到0x 80000000。指令有时不对齐(例如,PC= 0x 8000004 e),这可能表明正在执行“垃圾”?
或者例如0x 8000005 e连续两次。
我让它运行了一段时间,它似乎陷入了0x 8000 d4 ca/0x 8000 d4 cc/0x 8000 d4 ce的某种循环(也在这个区域跳来跳去),从来没有到达我的main / startup代码。当我看到执行的指令时,对我来说它们没有逻辑意义:

0x00001000:  00000297          auipc                   t0,0                    # 0x1000
0x00001004:  02828613          addi                    a2,t0,40
0x00001008:  f1402573          csrrs                   a0,mhartid,zero
0x0000100c:  0202a583          lw                      a1,32(t0)
0x00001010:  0182a283          lw                      t0,24(t0)
0x00001014:  00028067          jr                      t0
0x80000000:  00050433          add                     s0,a0,zero
0x80000004:  000584b3          add                     s1,a1,zero
0x80000008:  00060933          add                     s2,a2,zero
0x8000000c:  2571              jal                     ra,1676                 # 0x80000698
0x80000698:  494255b7          lui                     a1,1229082624
0x8000069c:  34f58593          addi                    a1,a1,847
0x800006a0:  4208              lw                      a0,0(a2)
0x800006a2:  feb517e3          bne                     a0,a1,-18               # 0x80000690
0x800006a6:  4589              addi                    a1,zero,2
0x800006a8:  4248              lw                      a0,4(a2)
0x800006aa:  fea5c3e3          bgt                     a0,a1,-26               # 0x80000690
0x800006ae:  4589              addi                    a1,zero,2
0x800006b0:  00b54463          bgt                     a1,a0,8                 # 0x800006b8
0x800006b4:  4a48              lw                      a0,20(a2)
0x800006b6:  8082              ret                     
0x8000000e:  00050833          add                     a6,a0,zero
0x80000012:  00040533          add                     a0,s0,zero
0x80000016:  000485b3          add                     a1,s1,zero
0x8000001a:  00090633          add                     a2,s2,zero
0x8000001e:  58fd              addi                    a7,zero,-1
0x80000020:  01180463          beq                     a6,a7,8                 # 0x80000028
0x80000024:  0b051d63          bne                     a0,a6,186               # 0x800000de
0x80000028:  0001c817          auipc                   a6,114688               # 0x8001c028
0x8000002c:  fdc80813          addi                    a6,a6,-36
0x80000030:  4885              addi                    a7,zero,1
0x80000032:  0118282f          amoadd.w                a6,a7,(a6)
0x80000036:  0a081463          bnez                    a6,168                  # 0x800000de
0x8000003a:  0001c297          auipc                   t0,114688               # 0x8001c03a
0x8000003e:  fd228293          addi                    t0,t0,-46
0x80000042:  00000317          auipc                   t1,0                    # 0x80000042
0x80000046:  fbe30313          addi                    t1,t1,-66
0x8000004a:  0062a023          sw                      t1,0(t0)
0x8000004e:  0001c297          auipc                   t0,114688               # 0x8001c04e
0x80000052:  fc228293          addi                    t0,t0,-62
0x80000056:  0002a283          lw                      t0,0(t0)
0x8000005a:  405303b3          sub                     t2,t1,t0
0x8000005e:  0001ce17          auipc                   t3,114688               # 0x8001c05e
0x80000062:  fa2e0e13          addi                    t3,t3,-94
0x80000066:  007e2023          sw                      t2,0(t3)
0x8000006a:  0001d297          auipc                   t0,118784               # 0x8001d06a
0x8000006e:  06e28293          addi                    t0,t0,110
0x80000072:  0001e317          auipc                   t1,122880               # 0x8001e072
0x80000076:  04e30313          addi                    t1,t1,78
0x8000007a:  06628363          beq                     t0,t1,102               # 0x800000e0
0x8000007e:  a8a1              j                       88                      # 0x800000d6
0x800000d6:  02b1              addi                    t0,t0,12
0x800000d8:  fa5354e3          ble                     t0,t1,-88               # 0x80000080
0x80000080:  ff82af03          lw                      t5,-8(t0)
0x80000084:  4e0d              addi                    t3,zero,3
0x80000086:  01cf1b63          bne                     t5,t3,22                # 0x8000009c
0x8000008a:  ff42ae03          lw                      t3,-12(t0)
0x8000008e:  ffc2af03          lw                      t5,-4(t0)
0x80000092:  9f1e              add                     t5,t5,t2
0x80000094:  9e1e              add                     t3,t3,t2
0x80000096:  01ee2023          sw                      t5,0(t3)
0x8000009a:  a835              j                       60                      # 0x800000d6
0x800000dc:  a011              j                       4                       # 0x800000e0
0x800000e0:  0001c297          auipc                   t0,114688               # 0x8001c0e0
0x800000e4:  f2828293          addi                    t0,t0,-216
0x800000e8:  4305              addi                    t1,zero,1
0x800000ea:  0062a023          sw                      t1,0(t0)
0x800000ee:  0330000f          fence                   rw,rw
0x800000f2:  4081              mv                      ra,zero
0x800000f4:  2bb1              jal                     ra,1372                 # 0x80000650
0x80000650:  0000100f          fence.i                 
0x80000654:  4101              mv                      sp,zero
0x80000656:  4181              mv                      gp,zero
0x80000658:  4201              mv                      tp,zero
0x8000065a:  4281              mv                      t0,zero
0x8000065c:  4301              mv                      t1,zero
0x8000065e:  4381              mv                      t2,zero
0x80000660:  4401              mv                      s0,zero
0x80000662:  4481              mv                      s1,zero
0x80000664:  4681              mv                      a3,zero
0x80000666:  4701              mv                      a4,zero
0x80000668:  4781              mv                      a5,zero
0x8000066a:  4801              mv                      a6,zero
0x8000066c:  4881              mv                      a7,zero
0x8000066e:  4901              mv                      s2,zero
0x80000670:  4981              mv                      s3,zero
0x80000672:  4a01              mv                      s4,zero
0x80000674:  4a81              mv                      s5,zero
0x80000676:  4b01              mv                      s6,zero
0x80000678:  4b81              mv                      s7,zero
0x8000067a:  4c01              mv                      s8,zero
0x8000067c:  4c81              mv                      s9,zero
0x8000067e:  4d01              mv                      s10,zero
0x80000680:  4d81              mv                      s11,zero
0x80000682:  4e01              mv                      t3,zero
0x80000684:  4e81              mv                      t4,zero
0x80000686:  4f01              mv                      t5,zero
0x80000688:  4f81              mv                      t6,zero
(...)
nafvub8i

nafvub8i1#

“解决方案”(还是变通方案?)是使用另一个qemu“板”--机器,因为它被称为。默认值似乎不是Spike,我试过VirtIO:
更改debug.sh:

# (...)

qemu-system-riscv32 -cpu rv32 -device loader,file="out/${SEQUENCE}.elf",cpu-num=0 -nographic -s -S -m 512M -machine virt &
CHILD_PID=$!

gdb-multiarch -tui -q \
    -ex "file out/${SEQUENCE}.elf" \
    -ex "target remote 127.0.0.1:1234" \
    -ex "layout src" \
    -ex "layout regs" \
    -ex "b main" \
    -ex "focus cmd"

# (...)

以及链接器定义存储器部分定义:

MEMORY
{
   RAM (rwx)  : ORIGIN = 0x80000000, LENGTH = 510M
   RAM2 (rwx) : ORIGIN = 0xffff0000, LENGTH = 0xffff
}

我不知道 * 为什么 * 它工作,如果这是一个真实的的 * 解决方案 *,但现在它似乎是一个很好的解决方案。如果有人能插话,比我更有把握地纠正这些错误,我会接受这样的回答。
我的想法是绕过固件(根本没有任何固件)。我不知道缺乏固件的影响。

相关问题