Running QEMU RISC-V Debian Linux on Mac Pro M3

I’ve been learning RISC-V Assembly while reading the fantastic book, RISC-V Assembly Language Programming: Unlock the Power of the RISC-V Instruction Set[^]

I had been doing all the work on my Linux desktop (runninng Ubuntu 22.04.4 LTS) but I wanted to be able to continue learning when I’m out & about or just downstairs away from my desktop.

Mac Pro M3

My recently purchased laptop is a Mac Pro M3 so I decided to go down the path to see if I could get QEMU running on it the same way I had with my Linux desktop.

Spoiler Alert: I Succeeded

I got the Debian (RISC-V build) running in QEMU on my Apple silicon Mac!! I can’t believe it.  Here are the steps and I hope they help you get yours set up.  If they do, leave a comment.

I discovered that you need to install Homebrew from the QEMU downloads page: Download QEMU – MacOS[^]

Everything You Need To Do

  1. Install Homebrew (so you can install QEMU) — I followed the steps at Homebrew — The Missing Package Manager for macOS (or Linux)[^]. Copy the terminal command they show and paste it int your terminal:  /bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)”
    It worked great for me (even though I had no idea what I was doing).
  2. Once homebrew is installed, I didn’t have a PATH to it, but I discovered that it installed homebrew at:

    /opt/homebrew/
    The exe is named brew and is found in the bin directory (/opt/homebrew/bin/)
    Now that you have homebrew installed, you can install QEMU

  3. In the same terminal window where you installed homebrew you can now run the following command: $ brew install qemu
    However, In my case, brew was not added to the PATH so I had to use the fully qualified path to brew to get it to run:
    $ /opt/homebrew/bin/brew install qemu
    You’ll see all kinds of things happening and racing down (up?) the terminal screen as the installation progresses.
    At this point I was stumped.  I couldn’t figure out where QEMU was installed.
    I Have No Idea What I'm Doing | Know Your Meme
  4. QEMU In Homebrew Directory
    I searched around on the internet trying to discover it and somehow I uncovered the fact that QEMU was installed into the /opt/homebrew/ directory at /opt/homebrew/qemu/. Again, underneath that directory you’ll find all the EXEs in the bin directory.
    You’ll find the QEMU executables for each of the platforms (mips,x86_64, etc.) and the one we need qemu-system-riscv64
    When I saw that I was really excited.  I knew I had a chance of getting this working.
  5. Now, we need to download the QEMU image files (just like we did in my previous article for linux).  Go to the main page where you get the images ( Debian Quick Image Baker pre-baked images[^]) and click the one labeled: Images for riscv64-virt
  6. Clicking that link will begin the download of the file with the long hash name.
  7. Once you get the file unzip it — there’s a main folder inside it that contains all the files we need for the RISC-V Debian image.  I put mine in ~/dev/riscv64-virt/
  8. We need two more files (required by QEMU) and you can download them from the GitHub repo for the RISC-V Assembly book (at top of this article).  The GitHub repo items we need are located at: RISC-V-Assembly-Language-Programming/Chapter 1/QEMU at main · Apress/RISC-V-Assembly-Language-Programming · GitHub[^]
    There are two files in that folder:
    a) fw_jump.elf
    b) uboot.elf
    To get those files you need to click on each one then click the [raw] link
    You have to make sure you get the raw file because GitHub will give you an odd converted file that won’t work properly.
  9. Once you download those, create a new directory named sbi in your main riscv64-virt folder.  Mine looks like ~/dev/riscv64-virt/sbi/
  10. Finally, we are ready to run the command to start the QEMU virtual machine running our RISC-V based Debian image.I put the following command in a shell script file (run_riscv.sh) and make it executable (chmod +x)
  11. /opt/homebrew/opt/qemu/bin/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 /Users/<username>/dev/riscv/riscv64-virt/sbi/fw_jump.elf \
    -kernel /Users/<username>/dev/riscv/riscv64-virt/sbi/uboot.elf \
    -object rng-random,filename=/dev/urandom,id=rng \
    -device virtio-rng-device,rng=rng \
    -nographic \
    -append "root=LABEL=rootfs console=ttyS0"

When you run that command, the QEMU will run and start the Debian image.

Now you can login – user: root and password: root

Install the build essential tools (no need to use sudo since you are root):
$ apt install build-essential

Once it’s done check that your assembler and linker are installed:

$ which as
$ which ld

Success!!

2 Comments

  1. Hello, thanks for the guide.
    I’ve managed to complete the setup following your steps. There was only one obstacle:
    The proper name for the package with build tools is “build-essential” 🙂

    • Thank you for reading my article and letting me know about the name of the build-essential package.
      I will make that change now.
      So glad you were able to get it all running. Really cool!

Leave a Reply

Your email address will not be published. Required fields are marked *