This week, I finally get the RISC-V Angel Simulator to run the C/C++ code compiled from the default RISC-V GNU compiler, which is specifically designed to compile files into ELF file that to be used with the RISC-V Spike and Proxy Kernel. I had verified that the bootloader extracted from proxy kernel is usable.
How Software Works
The RISC-V Angel Bug
Since the problem had persisted, I try to decode the instruction line by line, checking for register values and results. Initially, I noticed that there were 2 weird circumstances when tested with the
iostream library, which are the wrong value passed into the return address (ra) register causes the address to be loaded wrongly, and the redefinition of the memory arrays (RAM) which overwrites the default instruction value. After discussed with my supervisor, he urged me to decode the instruction line by line. As I proceed with it, I found that all the programs that worked properly without the
iostream library, stores the memory in other addresses, which does not overwrite the instruction in the addresses that had been pre-allocated for the ELF file.
Thus, I saved the output log of the whole instructions that had been run for, and I trace the instruction one by one, I found that the AUIPC instruction might not be doing the right thing as stated in the ISA documentation. To prove that my thought would be correct, I compared the instructions from the log with the log I got from the Spike and proxy kernel. Using the command
reg 0 gp from the RISC-V Spike, the instruction of AUIPC is found to be written wrongly. It should have been 0xFFFFFFFF instead of a 0xFFFFF000 in the extraction to Program Counter (PC). Since I am trying to run it in bare metal without showing anything, I changed the SCALL ISA as well, so that it will just operate as a NOP instruction. And everything works fine after these 2 modifications, which solved the issue of undefined error 0 previously. This also proven that the RISC-V Angel can actually run ELF file created, in bare metal mode, without system calls features in it.
A Simple Usage of GDB on other files
From my previous post, I mentioned that GDB is useful when debugging files, such as it could have the Step In, breakpoint and etc features. But the problem that I faced was gathering GDB information on other source file instead of the main source file. So what I did was, to compile the main source file into object file with the -c flag during compilation. And compile the file that I wanted with the -g flag. For example,
riscv32-unknown-elf-g++ test.c main.o -g -o test -m32 This could gather the GDB information on the test.c source file instead of the main.c source file, which I found to be useful when debugging other source file.