Skip to content

Commit

Permalink
Merge pull request #732 from Daft-Freak/patch-3
Browse files Browse the repository at this point in the history
Start documenting the firmware/launcher/PIC magic
  • Loading branch information
Gadgetoid authored Nov 29, 2021
2 parents 963e5e2 + e65aa9a commit a3a229c
Showing 1 changed file with 103 additions and 0 deletions.
103 changes: 103 additions & 0 deletions docs/Firmware-Internals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# 32blit STM32 Firmware Internals <!-- omit in toc -->

- [PIC](#pic)
- [.blit File Format](#blit-file-format)
- [Relocation header](#relocation-header)
- [The Executable](#the-executable)
- [Game Metadata](#game-metadata)
- [The Firmware](#the-firmware)
- [The Launcher](#the-launcher)

## 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](https://github.com/32blit/stdlibs/).

## .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:

```c
{
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](https://github.com/32blit/32blit-tools/blob/master/src/ttblit/tool/relocs.py) 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:


```c
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](https://github.com/32blit/32blit-tools/blob/master/src/ttblit/tool/metadata.py) from the `metadata.yml` file.

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

```c
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`](https://github.com/32blit/32blit-sdk/blob/master/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](https://github.com/Daft-Freak/32blit-misc/tree/main/launcher-test).

0 comments on commit a3a229c

Please sign in to comment.