Last time (Prepare RISC-V development environment with buildroot and crosstool-ng), the kernel was started with qemu, so this time it works on the Web browser. Try starting it with TinyEMU (https://bellard.org/tinyemu/), which is a RISC-V emulator.
Seen from the parent kernel panic.
tl;dr
This time, I did not use TinyEMU standard I / O library at all, but tried to configure and start a VM from the C language side of Emscripten.
-** The boot loader must be the one that comes with TinyEMU **. The attached loader has been modified, and the console does not come out with a normal loader. --The build itself just builds with Emscripten 2.0.2 ʻemcc` and works with Emscripten standard HTML output.
The build itself is not particularly difficult, and if you compile and output * .c
appropriately, you can make something that works.
emcc jsemu.c softfp.c virtio.c fs.c fs_net.c fs_wget.c fs_utils.c simplefb.c pci.c ^
json.c block_net.c iomem.c cutils.c aes.c sha256.c riscv_cpu.c riscv_machine.c machine.c ^
--llvm-opts 2 -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -MMD -fno-strict-aliasing ^
-DCONFIG_FS_NET -O3 --memory-init-file 0 --closure 0 -s NO_EXIT_RUNTIME=1 ^
-s "EXPORTED_FUNCTIONS=['_console_queue_char','_vm_start','_fs_import_file','_display_key_event','_display_mouse_event','_display_wheel_event','_net_write_packet','_net_set_carrier','_main']" ^
-s "EXTRA_EXPORTED_RUNTIME_METHODS=[\"ccall\", \"cwrap\"]" ^
--js-library js/lib.js -s WASM=1 -s TOTAL_MEMORY=67108864 -s ALLOW_MEMORY_GROWTH=1 ^
-DMAX_XLEN=32 -DCONFIG_RISCV_MAX_XLEN=32 -s ASSERTIONS=1 --emrun -g4 ^
--source-map-base http://localhost:6931/ --preload-file kernel --preload-file bbl32.bin emmain.c -o run.html
main
)In normal TinyEMU, VM setting is done from the JavaScript side, but it was a little inconvenient to unify with the native version, so I decided to prepare the main
function.
The boot loader bbl32.bin
and the Linux kernel kernel
are once embedded in Emscripten's --preload-file
application side and read by C language file I / O.
You can use the kernel
built last time (https://qiita.com/okuoku/items/3133c75d26c57394fd1a) as it is, but the boot loader bbl32.bin
comes with TinyEMU (https://bellard.org/tinyemu). You must use the one from /diskimage-linux-riscv-2018-09-23.tar.gz).
TinyEMU does not emulate so-called UART devices, but implements HTIF (Host-Target IF), which was implemented by Spike (RISC-V official emulator).
However, unlike other implementations such as qemu, TinyEMU's HTIF implementation has a fixed address, and the bootloader is patched to convey the address.
0x40008000
.#define HTIF_BASE_ADDR 0x40008000
diff --git a/bbl/bbl.lds b/bbl/bbl.lds
index 26f5816..615c3dc 100644
--- a/bbl/bbl.lds
+++ b/bbl/bbl.lds
@@ -43,15 +43,10 @@ SECTIONS
_etext = .;
/*--------------------------------------------------------------------*/
- /* HTIF, isolated onto separate page */
+ /* HTIF I/Os */
/*--------------------------------------------------------------------*/
- . = ALIGN(0x1000);
- .htif :
- {
- PROVIDE( __htif_base = .);
- *(.htif)
- }
- . = ALIGN(0x1000);
+ tohost = 0x40008000;
+ fromhost = 0x40008008;
A patch to this linker script fixes the addresses of tohost
and fromhost
.
tohost`` fromhost
in the bootloadervolatile uint64_t tohost __attribute__((section(".htif")));
volatile uint64_t fromhost __attribute__((section(".htif")));
Originally, these addresses are acquired when the emulator loads.
In the first place, HTIF itself is an old specification, so it may not matter now, but I also want a more serious protocol.
Since HTIF is a 64-bit wide interface, it cannot be used with a 32-bit architecture. (If writing conflicts with two or more CPUs, it cannot be processed safely)
Since TinyEMU does not support multiprocessors, it seems that this area is not particularly concerned, ** By declaring the register with 32 bit width and making it a code that is activated at the timing when the upper word is written ** 32 bit / 64 bit Both are supported.
... qemu supports multiprocessors, so I don't think the same policy will work. ..
I was prepared that the RISC-V 32bit environment was prepared too recently and it is variously behind 64bit, but it is a bit that pure debugging I / F like HTIF does not support 32bit. It was unexpected.
TODO: You have to set -s SINGLE_FILE = 1
to distribute with npm, and make the kernel and bootloader provided externally.
Recommended Posts