riscvarchive / riscv-qemu

QEMU with RISC-V (RV64G, RV32G) Emulation Support
387 stars 154 forks source link

Hello-world user space not working in qemu and current gnu toolchain ? #148

Open anon63github opened 6 years ago

anon63github commented 6 years ago

Dear all,

I post this here in riscv-qemu and in riscv-gnu-toolchain.

Can someone explain me simply how to make the user-space hello-world init working in qemu-system-riscv64 :

#include <stdio.h>
void main (void)
{
    printf("\nHello World user space init !\n");
    while (1) {
        ;
    }
}

compiled statically as we do when we test with busybox

riscv-linux is compiled with allnoconfig + printk + tty + 8250_serial port + 8250/16550 console + elf + script beginning with #! + proc / sysfs pseudofilesystem , initramfs with the initramfs source name provided directly

It's trivial with x86_64 :

gcc -static hello.c -o root-x8664/init mkdir dev/ sudo mknod dev/console c 5 1 find . | cpio --quiet -o -H newc > initramfs.cpio

It's trivial with arm64 with the compiler command replaced by aarch64-linux-gnu-gcc -static hello.c -o init and the ARM AMBA PL011 + support console serial port instead of 8250 serial port

I just cannot make it work with riscv... :(

I read carefully

https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt https://www.cnx-software.com/2018/03/16/how-to-run-linux-on-risc-v-with-qemu-emulator/ https://github.com/riscv/riscv-tools/issues/70 https://mgalgs.github.io/2015/05/16/how-to-build-a-custom-linux-kernel-for-qemu-2015-edition.html

these made the hello-world userspace init really easy for the x8664 and arm64 cases.... but impossible for me with riscv... (and I have not been able to do the busybox or busybear stuff either)

What did I miss ?? Is it supposed to work with the following riscv-gnu-toolchain ?

$ git submodule status 8db5daf9efe8a6174d3b10ac7bba8c178836e9ce riscv-binutils (remotes/origin/riscv-binutils-2.30) 2e99dc08d8e5e16f07627bd52a192906abfa9a5c riscv-dejagnu (2e99dc0) af8bbdf198a7cd619efd7c9a7aef2f86d5590aae riscv-gcc (remotes/origin/riscv-gcc-8.1.0) 635c14ec58512380f28fc80447a427de9341293d riscv-gdb (heads/riscv-binutils-2.29) 2f626de717a86be3a1fe39e779f0b179e13ccfbb riscv-glibc (2f626de717) 320b28ea27c71df7afe62b21a220f77aef9eb88a riscv-newlib (newlib-3.0.0-12-g320b28ea2) ff36f2f77ec3e6a6211c63bfe1707ec057b12f7d riscv-qemu (pull-tcg-20160920-410-gff36f2f77e)

and current riscv-all branch of riscv-qemu ? (I wasnt able to do it, even before the recent bump risc-gcc-8.1.0, binutils 2.30)

Did I miss some config options in the kernel ?(Virtual driver, ...) Is it not working with the -machine virt of qemu-riscv ? Did I miss some mknod dev/ttyS0 ? dev/null ? as in the busybear repository ?

My logs in x86_64

Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled serial8250: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A random: get_random_bytes called from 0xffffffff8102a4cf with crng_init=0 sched_clock: Marking stable (220548325, 0)->(309622973, -89074648) Freeing unused kernel memory: 1916K Write protecting the kernel read-only data: 8192k Freeing unused kernel memory: 2032K Freeing unused kernel memory: 1876K

Hello World user space init ! clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x299d3fceb90, max_idle_ns: 440795232838 ns clocksource: Switched to clocksource tsc

My logs in arm64

Serial: AMBA PL011 UART driver 9000000.pl011: ttyAMA0 at MMIO 0x9000000 (irq = 39, base_baud = 0) is a PL011 rev1 console [ttyAMA0] enabled clocksource: Switched to clocksource arch_sys_counter workingset: timestamp_bits=62 max_order=15 bucket_order=0 cacheinfo: Unable to detect cache hierarchy for CPU 0 random: get_random_bytes called from 0xffffff8008092a04 with crng_init=0 Freeing unused kernel memory: 1280K

Hello World user space init !

My deceptive logs in riscv64 (with vmlinux as bbl payload) :

Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled irq: no irq domain found for interrupt-controller@c000000 ! console [ttyS0] disabled 10000000.uart: ttyS0 at MMIO 0x10000000 (irq = 0, base_baud = 230400) is a 16550A console [ttyS0] enabled random: get_random_bytes called from 0xffffffe0008ed018 with crng_init=0 Freeing unused kernel memory: 9120K This architecture does not have kernel memory protection. qemu-system-riscv64: Trying to execute code outside RAM or ROM at 0xffffffe0008e8bf8 This usually means one of the following happened:

(1) You told QEMU to execute a kernel for the wrong machine type, and it crashed on startup (eg trying to run a raspberry pi kernel on a versatilepb QEMU machine) (2) You didn't give QEMU a kernel or BIOS filename at all, and QEMU executed a ROM full of no-op instructions until it fell off the end (3) Your guest kernel has a bug and crashed by jumping off into nowhere

This is almost always one of the first two, so check your command line and that you are using the right type of kernel for this machine. If you think option (3) is likely then you can try debugging your guest with the -d debug options; in particular -d guest_errors will cause the log to include a dump of the guest register state at this point.

Execution cannot continue; stopping here.

Sometimes I have no messages at all after the linux logs. It seems that sometimes I get in the function because If I don't do the infinite while loop, linux tells me that init was killed (init returned) so I may have forgotten something really simple with tty or the serial driver....

Thanks for your help (if it's not a bug) !

michaeljclark commented 6 years ago

Here's a simple baremetal program for all riscv-qemu machines: spike, sifive_e, sifive_u and virt

Please try it out and if it is satisfactory, then you can close this issue. It should work for both rv32 and rv64.