32blit STM32 Firmware Internals

PIC

To allow multiple games to be “installed” in the 32MB flash memory at the same time, all games are built as position-independent code with these flags: -fPIC -mno-pic-data-is-text-relative -mno-single-pic-base. A relocation header is appended and the firmware relocates games while writing to flash.

This also requires custom builds of newlib/libstdc++ with the same flags, which are provided here.

.blit File Format

The .blit format has three parts, there's a relocation header, the executable and the game metadata.

Relocation header

The relocation header is a list of offsets in the executable that get an offset added to them as the game is written to flash (through the serial port or using the launcher to “run” from SD).

For example, if a game is written to the second “block” of flash, 0x10000 will be added to each listed offset in the binary.

The format of this header is:

{
  uint32_t magic;      // "RELO"
  uint32_t num_relocs; // Number of relocation entries
  uint32_t relocs[];   // the addresses to relocate
}

This header is generated by the relocs tool in 32blit-tools and is not written to flash when a game is installed.

The Executable

The raw game binary generated with arm-none-eabi-objcopy -O binary .... It has a small header created by the linker:

struct BlitGameHeader {
  uint32_t magic;            // "BLIT"

  BlitRenderFunction render; // pointer to the render function
  BlitTickFunction tick;     // pointer to blit::tick, which calls update and updates timers/tweens
  BlitInitFunction init;     // pointer to the init function

  uint32_t end;              // the address of the end of the game binary (0x90000000 + the size of the binary)
  uint32_t start;            // the address of the start of the game (always 0x90000000, not used)
};

The end address is used to locate the metadata.

Game Metadata

The metadata is appended to the end and has the info generated by the metadata tool from the metadata.yml file.

There are multiple parts to this as the format has been extended.

struct RawMetadata {
  char[8] magic;        // "BLITMETA"
  uint16_t size;        // size of entire metadata

  uint32_t crc32;       // these two are generated by the tools
  char datetime[16];    //
  char title[25];
  char description[129];
  char version[17];
  char author[17];
};

// Prefixed with "BLITTYPE". Extended metadata - older .blits may not have this
struct RawTypeMetadata {
  char category[17];     // the "launcher" category has special meaning
  char url[129];         // can be anything, but points to the GitHub repo most of the time
  uint8_t num_filetypes; // used for launcher file associations
  char filetypes[][5];   //
};

Two packed images usually follow these for the icon/splash. This is the same format as generated for images by the asset packer and starts with either “SPRITERW”, “SPRITEPK” or “SPRITERL”.

The Firmware

The firmware is installed to the “internal” handles all the hardware stuff, including flashing games and switching between them. It also handles the system menu.

At startup, the firmware scans through “external” flash to find installed games and builds a list of “games” with file associations. This can be used for interpreters (like 32blit-lua), or emulators (DaftBoy32).

The interface between the games/firmware is in 32blit/engine/api_private.hpp.

The Launcher

The launcher is actually mostly a regular game, with a category of “launcher”. The firmware switches to this whenever a game is not running.

It uses some “semi-private” firmware API to handle launching/flashing games. It's possible to replace the launcher entirely, like this extremely basic one.

Memory Layout

SectionAddressSizeUsage
ITCM0000000064kfast code, not currently used
Internal flash08000000128kfirmware .text/.rodata
DTCM20000000128k.data, stack
D1 RAM24000000512k362k game heap/.bss, 150k for LTDC (screen)
D2 RAM30000000288kfirmware heap/.bss, 225k for framebuffer
D3 RAM3800000064ksome used by firmware, mostly unused
External flash9000000032Mgame .text/.rodata/metadata, 4MB reserved