Read Rust

Tag: riscv

Posts

My previous blog post introduced my work to improve Rust's support for RISC-V Linux systems. Since then I fixed a couple of interesting compiler bugs. This blog post is more technical - describing these bugs and explaining some rustc internals along the way. I conclude by reporting on movement in the broader Rust community regarding RISC-V. I assumed that the reader is comfortable with programming terminology. This blog post contains Rust code samples but the reader is not expected to be fluent in Rust.

riscv

Diosix 2.0 strives to be a lightweight, fast, and secure multiprocessor bare-metal hypervisor for 32-bit and 64-bit RISC-V systems. It is written in Rust, which is a C/C++-like systems programming language focused on memory and thread safety as well as performance and reliability.

The ultimate goal is to build fully open-source packages containing everything needed to configure FPGA-based systems with RISC-V cores and peripheral controllers, and boot a stack of software customized for a particular task, all generated on demand if necessary. This software should also run on supported ASICs and system-on-chips.

Right now, Diosix is a work in progress. It can bring up a RISC-V system, load a Linux kernel and minimal filesystem into a virtualized environment called a capsule, and begin executing it.

riscv

This is the moment we've all been waiting for. Ten chapters of setup have led us to this moment--to finally be able to load a process from the disk and run it. The file format for executables is called ELF (executable and linkable format). I will go into some detail about it, but there are plenty of avenues you can explore with this one file type.

riscv

Storage is an important part of an operating system. When we run a shell, execute another program, we're loading from some sort of secondary storage, such as a hard drive or USB stick. We talked about the block driver in the last chapter, but that only reads and writes to the storage. The storage itself arranges its 0s and 1s in a certain order. This order is called the file system. The file system I opted to use is the Minix 3 filesystem, which I will describe the practical applications here. For more overview of the Minix 3 file system or file systems in general, please refer to the course notes and/or video that I posted above.

I will go through each part of the Minix 3 file system, but the following diagram depicts all aspects and the structure of the Minix 3 file system.

riscv

The VirtIO protocol is a way to communicate with virtualized devices, such as a block device (hard drive) or input device (mouse/keyboard). For this post, I will show you how to write a block driver using the VirtIO protocol.

The first thing we must understand is that VirtIO is just a generic I/O communication protocol. Then, we have to look at the block device section to see the communication protocol specifically for block devices.

riscv

Now that we developed a high-level Servo trait that allows controlling servo motors, we can start writing code that will animate our spider bot by rotating multiple motors synchronously. The idea is that the robot’s movement takes some fixed amount of time during which each moving motor may travel a different angle. Importantly, all moving motors should start and stop at the same time, and therefore, they will have different angular speeds. Such movements then are sequenced one after another to appear like a well-coordinated action.

To implement this in Rust, we introduce the Move structure that captures a reference to a servo motor and the desired degrees where it should be at the end of the animation.

riscv

In the previous part, we were able to control the servo motor by writing to PWM registers of the FE310 microcontroller. Now it’s time to have more fun with Rust by writing high-level servo motor abstraction that is suitable for controlling multiple servo motors in a uniform fashion.

riscv

The ALLBOT spider uses the 9G servo motors to animate its legs. The Arduino implementation uses a built-in servo library that allows assigning servo instance to a pin and then writing desired orientation degrees between 0 and 180. The e310x HAL does not have servo implementation, nor the Embedded HAL have the servo trait. Time to face the hardware at the lowest level!

The first thing is to find the datasheet for the 9G servo motor. The datasheet summarizes the entire servo interface in one simple diagram!

riscv

After reading The Rust Programming Language book and falling in love with the language, I was on the lookout for my first Rust project. In the “old hardware projects” box, I had a HiFive1 board with SiFive FE310 RISC-V microcontroller, and Velleman’s Arduino based ALLBOT spider robot. Replacing Arduino with HiFive1 and rewriting ALLBOT’s C-based firmware from the ground up in Rust felt exciting!

riscv

Starting a process is what we've all been waiting for. The operating system's job is essentially to support running processes. In this post, we will look at a process from the OS's perspective as well as the CPU's perspective.

We looked at the process memory in the last chapter, but some of that has been modified so that we have a resident memory space (on the heap). Also, I will show you how to go from kernel mode into user mode. Right now, we've erased supervisor mode, but we will fix that when we revisit system calls in order to support processes.

riscv

What do Rust, Risc-V, and SpinalHDL all have in common? They can all run on the Hackaday Supercon 2019 badge! In this rather lengthy post, I go through how to get started with SpinalHDL on the badge, how to setup a Risc-V soft core using VexRiscv, how to assemble a basic program for it, and finally how to target and build embedded Rust for it.

riscv

This is chapter 6 of a multi-part series on writing a RISC-V OS in Rust. Processes are the whole point of the operating system. We want to start doing "stuff", which we'll fit into a process and get it going. We will update the process structure in the future as we add features to a process. For now, we need a program counter (which instruction is executing), and a stack for local memory.

We will not create our standard library for processes. In this chapter, we're just going to write kernel functions and wrap them into a process. When we start creating our user processes, we will need to read from the block device and start executing instructions. That's quite a ways a way, since we will need system calls and so forth.

riscv

RISC-V ("risk five") and the Rust programming language both start with an R, so naturally they fit together. In this blog, we will write an operating system targeting the RISC-V architecture in Rust (mostly). If you have a sane development environment for RISC-V, you can skip the setup parts right to bootloading. Otherwise, it'll be fairly difficult to get started.

This tutorial will progressively build an operating system from start to something that you can show your friends or parents -- if they're significantly young enough. Since I'm rather new at this I decided to make it a "feature" that each blog post will mature as time goes on. More details will be added and some will be clarified.

riscv

View all tags