{"id":71,"date":"2024-09-27T08:30:23","date_gmt":"2024-09-27T08:30:23","guid":{"rendered":"https:\/\/haco.club\/?p=71"},"modified":"2024-09-27T08:30:23","modified_gmt":"2024-09-27T08:30:23","slug":"risc-v-simulation-with-qemu","status":"publish","type":"post","link":"https:\/\/haco.club\/?p=71","title":{"rendered":"RISC-V simulation with Qemu"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><a href=\"https:\/\/medium.com\/@e1d1\/risc-v-simulation-with-qemu-61ea8f2d8f4b\">https:\/\/medium.com\/@e1d1\/risc-v-simulation-with-qemu-61ea8f2d8f4b<\/a><\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Installation of Qemu<\/h2>\n\n\n\n<p>On the Qemu website, you can find a lot of information on how to get it running. But for the specific purpose of this tutorial, a few important extra steps are needed.<\/p>\n\n\n\n<p>In order to use the user mode simulation, your host system must be Linux. I recommend installing from source as described on this\u00a0<a href=\"https:\/\/www.qemu.org\/download\/\" data-type=\"link\" data-id=\"https:\/\/www.qemu.org\/download\/\">site<\/a>\u00a0using configure with\u00a0&#8211;target-list= riscv32-linux-user,riscv64-linux-user, riscv32-softmmu,riscv64-softmmu\u00a0as a configuration. I assume you have a RV toolchain running, if not,\u00a0<a href=\"https:\/\/github.com\/riscv-collab\/riscv-gnu-toolchain\" data-type=\"link\" data-id=\"https:\/\/github.com\/riscv-collab\/riscv-gnu-toolchain\">here<\/a> is how.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">User-Mode<\/h2>\n\n\n\n<p>The simplest way of getting an environment for RV programming is the user mode of Qemu. You cross compile your program as if it were on an RV system running Linux. Then you run your program with Qemu user mode.<\/p>\n\n\n\n<p>To illustrate, I give a short example of compiling and running a C program. I assume you have a running set up for Linux.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>echo -e '#include &lt;stdio.h>\\nint main(){\\n printf(\"hi\\\\n\");\\n return 0;\\n}' > hi.c\nriscv64-unknown-elf-gcc -o hi hi.c \nqemu-riscv64-static hi<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">System-Mode<\/h2>\n\n\n\n<p id=\"bc71\">The system mode of Qemu lets you simulate a complete operating system. For example, you can run Linux inside this simulation. You can change (e.b. log in) to this guest system, install all tools you need and run your own RV programs. However, depending on the system chosen, you might need to cross compile your program on your host and transfer your program to the simulated guest system.<\/p>\n\n\n\n<p id=\"e72f\">To make these steps a bit easier, I will show you how to get a Linux system up for an RV32 using&nbsp;<a href=\"https:\/\/buildroot.org\/\" rel=\"noreferrer noopener\" target=\"_blank\">Buildroot<\/a>&nbsp;and for an RV64 using&nbsp;<a href=\"https:\/\/www.debian.org\/index.de.html\" rel=\"noreferrer noopener\" target=\"_blank\">Debian<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">RV32: Linux using Buildroot<\/h2>\n\n\n\n<p>This is very easy to achieve. Get Buildroot and build:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/git.buildroot.net\/buildroot\nmake qemu_riscv32_virt_defconfig\nmake<\/code><\/pre>\n\n\n\n<p>Note, you can customize your Buildroot system before\u00a0<code>make<\/code>\u00a0with\u00a0<code>make menuconfig<\/code>, for example, to install\u00a0<code>gdbserver<\/code>. Then run Qemu with<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qemu-system-riscv32 \\\n   -M virt \\\n   -bios output\/images\/fw_jump.elf \\\n   -kernel output\/images\/Image \\\n   -append \"root=\/dev\/vda ro\" \\\n   -drive file=output\/images\/rootfs.ext2,format=raw,id=hd0 \\\n   -device virtio-blk-device,drive=hd0 \\\n   -netdev user,id=net0 -device virtio-net-device,netdev=net0<\/code><\/pre>\n\n\n\n<p id=\"faf0\">These options do the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>-M virt<\/code>: emulated machine is of type\u00a0<code>virt<\/code>\u00a0which is just a general machine type for simulation.<\/li>\n\n\n\n<li><code>-bios output\/images\/fw_jump.elf<\/code>: bios image generated by Buildroot.<\/li>\n\n\n\n<li><code>-kernel output\/images\/Image<\/code>: kernel image generated by Buildroot.<\/li>\n\n\n\n<li><code>-append \"root=\/dev\/vda ro\"<\/code>: command line for the kernel which defines the root filesystem\u00a0<code>\/dev\/vda<\/code>\u00a0read-only, which is the virtualized hard drive.<\/li>\n\n\n\n<li><code>-drive file=output\/images\/rootfs.ext2,format=raw,id=hd0\u00a0<\/code>: specifies the drive\u00a0<code>hd0<\/code>\u00a0from the file generated by Buildroot in raw format.<\/li>\n\n\n\n<li><code>-device virtio-blk-device,drive=hd0<\/code>: adds the device driver for the drive\u00a0<code>hd0<\/code>.<\/li>\n\n\n\n<li><code>-netdev user,id=net0<\/code>: network user mode with id\u00a0<code>net0<\/code>.<\/li>\n\n\n\n<li><code>-device virtio-net-device,netdev=net0<\/code>: specifies the network driver for\u00a0<code>net0<\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">RV64: Linux using Debian<\/h2>\n\n\n\n<p>Fortunately, there are a Debian pre-baked images available\u00a0<a href=\"https:\/\/people.debian.org\/~gio\/dqib\/\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>. Just download the RV64 image, extract and run with Qemu. In the extracted folder, you can follow the instructions of the\u00a0<code>readme.txt<\/code>\u00a0file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qemu-system-riscv64 -machine virt -cpu rv64 -m 1G -device virtio-blk-device,drive=hd -drive file=image.qcow2,if=none,id=hd -device virtio-net-device,netdev=net -netdev user,id=net,hostfwd=tcp::2222-:22 -bios \/usr\/lib\/riscv64-linux-gnu\/opensbi\/generic\/fw_jump.elf -kernel \/usr\/lib\/u-boot\/qemu-riscv64_smode\/uboot.elf -object rng-random,filename=\/dev\/urandom,id=rng -device virtio-rng-device,rng=rng -nographic -append \"root=LABEL=rootfs console=ttyS0\"<\/code><\/pre>\n\n\n\n<p id=\"1deb\">Many options are explained above. Further options are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>-cpu rv64<\/code>: RV64 processor simulation.<\/li>\n\n\n\n<li><code>-m 1G<\/code>: use 1GB RAM.<\/li>\n\n\n\n<li><code>-drive file=image.qcow2,if=none,id=hd<\/code>: defines the\u00a0<code>image.qcow2<\/code>\u00a0as hard drive with interface none.<\/li>\n\n\n\n<li><code>... ,hostfwd=tcp::2222-:22<\/code>: forwards the port 2222 of the host to the port 22 of the guest. This enables ssh login.<\/li>\n\n\n\n<li><code>-object rng-random,filename=\/dev\/urandom,id=rng<\/code>: creates the object\u00a0<code>rng-random<\/code>\u00a0with id\u00a0<code>rng<\/code>.<\/li>\n\n\n\n<li><code>-device virtio-rng-device,rng=rng<\/code>: defines the type of id\u00a0<code>rng<\/code>.<\/li>\n<\/ul>\n\n\n\n<p id=\"9188\">As you can see, you might need&nbsp;<a href=\"https:\/\/github.com\/riscv\/opensbi\" rel=\"noreferrer noopener\" target=\"_blank\">OpenSBI<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/www.denx.de\/wiki\/U-Boot\/\" rel=\"noreferrer noopener\" target=\"_blank\">U-Boot<\/a>&nbsp;for Qemu. However, Linux distributions like Debian already have packages for this (<code>opensbi<\/code>,&nbsp;<code>u-boot-qemu<\/code>).<\/p>\n\n\n\n<p id=\"af6d\">Other options you might find useful are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>-device VGA<\/code>: for getting graphics, e.g. X11.<\/li>\n\n\n\n<li><code>-vnc :1<\/code>: for remote login with vnc using display\u00a0<code>:1<\/code>\u00a0of your host.<\/li>\n\n\n\n<li><code>-device virtio-keyboard,serial=virtio-keyboard<\/code>: for getting a keyboard using X11.<\/li>\n\n\n\n<li><code>-device virtio-mouse-pci<\/code>: for a mouse with X11.<\/li>\n\n\n\n<li><code>-serial pty<\/code>: for a serial interface with\u00a0<code>\/dev\/pty<\/code>\u00a0of your host, the number will be displayed by start.<\/li>\n\n\n\n<li><code>-fsdev local,id=sf,path=\/tmp\/mnt,security_model=mapped-file<\/code>\u00a0for a shared folder using\u00a0<code>\/tmp\/mnt\/<\/code>\u00a0of your host with id\u00a0<code>sf<\/code>.<\/li>\n\n\n\n<li><code>-device virtio-9p-pci,fsdev=sf,mount_tag=sf_tag<\/code>\u00a0for defining a mount tag for sharing using\u00a0<code>mount -t 9p sf_tag \/mymount\/point<\/code>.<\/li>\n<\/ul>\n\n\n\n<p id=\"386a\">You can quit Qemu with Ctrl-A X and switch between its monitor and the simulation with Ctrl-A C.<\/p>\n\n\n\n<p id=\"6ef8\">For example, the following command lets you share files from the host (<code>\/tmp\/host\/)<\/code>\u00a0to the guest system (<code>mount -t 9p sf_tag \/tmp\/guest\/<\/code>), forward two ports (22 and 1234) and login via vnc:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qemu-system-riscv64 -device VGA -machine virt   -cpu rv64   -smp 4   -m 4G   -kernel \/usr\/lib\/u-boot\/qemu-riscv64_smode\/uboot.elf   -device virtio-blk-device,drive=hd   -drive file=image.qcow2,if=none,id=hd   -device virtio-net-device,netdev=net -netdev user,id=net,hostfwd=tcp::2222-:22,hostfwd=tcp::12345-:1234   -object rng-random,filename=\/dev\/urandom,id=rng   -device virtio-rng-device,rng=rng   -append \"root=LABEL=rootfs console=ttyS0\" -device virtio-keyboard,serial=virtio-keyboard  -device virtio-mouse-pci -serial pty -fsdev local,id=sf,path=\/tmp\/host,security_model=mapped-file -device virtio-9p-pci,fsdev=sf,mount_tag=sf_tag -vnc :1<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/medium.com\/@e1d1\/risc-v-simulation-with-qemu-61ea8f2d8f4b Installation of Qemu On the Qemu website, you can [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[11,8],"class_list":["post-71","post","type-post","status-publish","format-standard","hentry","category-tutotial","tag-qemu","tag-riscv"],"_links":{"self":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/71","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=71"}],"version-history":[{"count":1,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/71\/revisions"}],"predecessor-version":[{"id":72,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/71\/revisions\/72"}],"wp:attachment":[{"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=71"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=71"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=71"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}