Xous: Support Tooling

3 min

As part of the Betrusted Project, I am working on an operating system to power the hardware. I’ve talked about the need for a new operating system for the project, which boils down to the need for software to be secure and small. I’ve been working on it for about a month now, and I’ve just had my first black triangle moment. The system isn’t much to look at from the outside, but there’s a lot of infrastructure in place and now the work can really begin.

Most of the infrastructure so far has involved the startup process. Xous needs to know where memory is located in order to load itself into the appropriate regions. It also needs to know which memory addresses are valid and which are not, in order to prevent you from mapping invalid regions. Additionally, the loader needs to know where the kernel is located, along with any initial programs to run.

The Xous solution to this is a tagged structure much like an IFF File. Each piece if data is prefixed by an 8-byte header that describes the data. If a parser doesn’t recognize some data, it can skip over it. Key differences from IFF include

  • the “size” field is 16-bits instead of 32-bits
  • the “size” field is in units of 32-bit words, not bytes
  • there is a crc16 present for each tag

The argument structure is documented in xous-docs, and each tag is prefixed with the following 8-byte struct:

struct Tag {
    /// Ascii-printable name, not null-terminated, in little endian format.
    tag: u32,

    /// CRC16 of the data section, using CCITT polynomial.
    crc16: u16,

    /// Size of the data section, in 4-byte words.
    size: u16,

The end result is a compact piece of binary data that can describe everything needed to boot. There are tags to describe the structure itself, tags to describe additional memory regions, and tags to describe the initial program data. These tags describe everything the boot sequence needs to know in order to get the system working.

These tags to not contain any sort of program data. The actual kernel and init binaries are stored elsewhere. In our case, they happen to be stored directly after the args structure, however that isn’t a fixed rule. This keeps the args structure small.

Managing these tags, ensuring they’re consistent, and generating the args file are all complicated tasks, and we haven’t even turned the system on!

Xous-tools is a collection of tools used to manage the operating system. As of this writing, it’s mostly concerned with the management, parsing, and generation of these tag structures. For example, the primary program create-image will generate an args file with a kernel and init programs appended to it. The read-tags program can be used to verify this image is correct, and copy-object can be used as a replacement for the venerable objcopy program.

By bundling the kernel, init programs, and arguments list together in a way that’s easy to manage, Xous becomes very easy to run, since all you need to do is load it in memory, set a register to point at it, and jump to the loader.

In the next post I’ll cover the stage1 loader, which sets up the MMU and the memory allocation list. For now, check out the current Xous-tools repository to follow progress on the tooling.