Building the Toolchain
With QEMU the process becomes somewhat simpler than the Clang way. Whereas you might experience some bizarre linker errors using Clang, we can circumvent that by tricking the software into thinking that it is running on a regular RISCV machine.
Required Sources
- QEMU
- Ubuntu for RISCV
- You will need to download this image instead of the one specified in the tutorial
- The Ubuntu tutorial
- LLVM
Setup your VM
First thing you need to do is create your virtual machine. In this case, we will need the riscv version of qemu, you can find out how to install that on the QEMU website.
You will also need to install opensbi
and uboot
, both of which are on the apt package repository.
Once installed, you need to configure the virtual machine and optionally enable ssh (so that you can easily transfer files using sftp). To do this we use a qemu setup script.
Configuring the Virtual Machine
First, lets download a linux distribution for riscv. You can find the easiest one to set up (or at least the one I know how to set up) above.
The script provided to us by the Ubuntu tutorial works good for a start:
qemu-system-riscv64 \
-machine virt -m 2048 -smp 4 -nographic \
-bios /usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.bin \
-kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \
-device virtio-net-device,netdev=eth0 \
-netdev user,id=eth0,hostfwd=tcp::2222-:22 \
-device virtio-rng-pci \
-drive file=ubuntu-24.04-preinstalled-server-riscv64.img,format=raw,if=virtio,id=hr
# change the file name to match with the image I told you to download
Let's take a walk through what this all means:
qemu-system-riscv64
: This indicates that we are using the full system emulation version of QEMU for riscv64, kind of reads like english-machine virt
: This option indicates we will use the generic virtual machine as the base for our emulated system. This will populate the machine with standard virtual versions of GPIO, disk and other peripheral ports. More on those later-m 2048
: Indicates we will allocate 2048 MB of RAM to the system, you can specify this in GB as well.-smp 4
: The number of CPU's initially present on your system. (This can be changed at runtime if you specify some options)-nographic
: Inhibits the GUI from opening, this is useful for ssh'ing into a machine and then starting the vm there.-bios ...
: Technically this option can be omitted in QEMU 7+, but this specifies that we want to use the opensbi firmware as our bios controller.-kernel ...
: TODO I think this refers to the linux kernel you want to use in the system, however uboot is a bootloader, so I'm not sure exactly why this should be specified in the kernel option...-device
: Allows you to add an arbitrary device to your board. This has the syntax-device <type>,[options]*
where the options are seperated by a comma.- In this configuration, we add two devices, the network card and the drive.
The network card allows us to ssh into the machine (on localhost:2222
) to perform our commands remotely, cause vm's are somewhat slow when not configured correctly, and I need to do a lot more work to configure this one correctly...
There are many more options, but you should explore the QEMU documentation for more information.
After you run that command, you should see your console booting into ubuntu linux.
For the purists out there who believe that ubuntu is a corporate scam and that the only 'free' linux is like Arch or something (also those of you who are Nix fanatics), I don't want to force you to try to cross-compile a full linux distro before even figuring out how to cross compile. If you really refuse to use ubuntu, then go ahead, be my guest and compile arch or nix for rv64, but I can give you no guidance. In fact, if you do it, I will ask you to write about your experience so that I can replicate it and then put another page up here for how to do it.
Now, once you have booted into your linux environment, sign in:
- Username:
ubuntu
- Password:
ubuntu
Configuring your prereqs
In order to prepare for the compilation of clang
, you will need to install cmake
and gcc
and we will also get ssh setup for your ease of use.
Setting up ssh
is a piece of cake: sudo systemctl enable ssh && sudo systemctl start ssh
. Congrats, now you can use ssh on port 2222 of localhost (ssh -p2222 ubuntu@localhost
) to access the vm.
Installing cmake
and gcc
is of similar complexity: sudo apt install cmake gcc
Installing clang
sudo apt install clang-17
or whatever your preferred version is (in lab 4 I'm using v17).