Skip to content
oldmaga edited this page Jun 7, 2026 · 5 revisions

Multiboot

It is possible to boot MiniDexed and other compatible bare-metal synthesizer engines than MiniDexed, e.g., https://github.com/giulioz/mini-jv880, from the same Raspberry Pi SD card.

Depending on which button you are pressing during boot, you can boot into another synthesizer. See https://github.com/probonopd/MiniDexed/discussions/726#discussioncomment-17178184 for an example.

This method is not a custom bootloader. It uses the Raspberry Pi firmware config.txt mechanism:

  • one shared FAT boot partition;
  • common Raspberry Pi boot files in the SD-card root;
  • one kernel image per synthesizer engine, placed in its own subdirectory;
  • one or more GPIO inputs read by the Raspberry Pi firmware at boot time;
  • different kernel= lines selected by [gpioXX=0] conditional filters.

This has been tested on Raspberry Pi 4 with MiniDexed and MiniJV880. It can also be extended to more than two engines by adding more GPIO selector buttons.

Basic idea

Default boot:

/minidexed/kernel8-rpi4.img

Alternative boot when a button is held during power-on:

/minijv880/kernel8-rpi4.img

Additional engines can be added in the same way, for example:

/dreamdexed/kernel8-rpi4.img
/test/kernel8-rpi4.img

The selected GPIO is configured as an input with pull-up. The selector button connects the GPIO to GND when pressed.

So:

GPIO high/default  -> default kernel
GPIO low/button    -> alternative kernel

Example SD-card layout

Example for MiniDexed + MiniJV880 + DreamDexed:

SD boot partition
├── config.txt
├── armstub8-rpi4.bin
├── start4.elf
├── fixup4.dat
├── overlays/
│
├── minidexed.ini   (*)
├── minijv880.ini
├── performance.ini
├── ...
│
├── minidexed/
│   └── kernel8-rpi4.img
│
├── minijv880/
│   └── kernel8-rpi4.img
│
└── dreamdexed/
    └── kernel8-rpi4.img

(*) see para: ## Configuration files shared by multiple engines

The exact set of files in the SD-card root depends on the projects you are combining. The important point is that the kernels are separated into different directories, while the boot firmware files remain shared in the SD-card root.

Minimal dualboot example

This example boots MiniDexed by default and MiniJV880 when GPIO12 is held low during power-on.

'[all] boot_delay=0 disable_splash=1 force_eeprom_read=0 gpu_mem=16 disable_overscan=0

# GPIO12 is used as boot selector.
# Configure it as input with pull-up.
# Button pressed = GPIO12 connected to GND = low.
gpio=12=ip,pu

[pi4]
arm_64bit=1
armstub=armstub8-rpi4.bin

# Default boot target
kernel=/minidexed/kernel8-rpi4.img

# GPIO12 low at boot: boot MiniJV880
[gpio12=0]
kernel=/minijv880/kernel8-rpi4.img

[all]'

With this setup:

No button held at power-on  -> MiniDexed
GPIO12 button held          -> MiniJV880

Multiboot example with more than two kernels

You can add more GPIO selector buttons.

Example:

[all]
boot_delay=0
disable_splash=1
force_eeprom_read=0
gpu_mem=16
disable_overscan=0

# Multiple boot selector GPIOs.
# Each button should connect its GPIO to GND when held.
gpio=12,13,16=ip,pu

[pi4]
arm_64bit=1
armstub=armstub8-rpi4.bin

# Default boot target
kernel=/minidexed/kernel8-rpi4.img

# GPIO12 low: MiniJV880
[gpio12=0]
kernel=/minijv880/kernel8-rpi4.img

[all]

# GPIO13 low: DreamDexed
[gpio13=0]
kernel=/dreamdexed/kernel8-rpi4.img

[all]

# GPIO16 low: test/recovery kernel
[gpio16=0]
kernel=/test/kernel8-rpi4.img

[all]

Recommended use:

No button held   -> MiniDexed
Hold GPIO12      -> MiniJV880
Hold GPIO13      -> DreamDexed
Hold GPIO16      -> test/recovery kernel

It is best to press only one selector button at a time during boot. If several GPIO selectors are held at the same time, the result may depend on config.txt parsing order and should not be relied on.

Hardware wiring

For each selector:

GPIO pin ---- button ---- GND

The config.txt line:

gpio=12=ip,pu

configures GPIO12 as input with pull-up.

So the normal state is high, and pressing the button pulls it low.

You can use another suitable GPIO instead of GPIO12. The GPIO does not necessarily have to be unused by the final firmware. It can also be an existing front-panel button, as in the MiniJV880 example where GPIO12 is the DATA button. Make sure that the chosen GPIO is not electrically conflicting with your hardware during the boot-selection phase. What matters is that, during the Raspberry Pi firmware boot stage, the GPIO can be safely read as a passive input:

  • normal state: high, usually through pull-up;
  • button pressed: connected to GND, low;
  • not actively driven by another circuit during boot;
  • not required by another device in a way that would conflict with this boot-time pull-up/input use.

After the selected kernel has started, that same GPIO can be used normally by the booted firmware.

CAUTION: do not connect Raspberry Pi GPIOs to 5 V.

Configuration files shared by multiple engines

This method works best when the booted systems use compatible SD-card layouts.

Some projects use different configuration files, which is easy to handle. For example:

MiniDexed:   minidexed.ini
MiniJV880:   minijv880.ini

Both files can simply coexist in the SD-card root.

Other projects may use the same configuration filename. For example, DreamDexed uses minidexed.ini too, with some additional variables. In that case, use a combined minidexed.ini containing the settings required by both systems.

Example strategy:

  1. Start from a working MiniDexed minidexed.ini.
  2. Add the DreamDexed-specific variables.
  3. Keep the MiniDexed variables unchanged unless you know they are compatible.
  4. Test MiniDexed.
  5. Test DreamDexed.
  6. Keep a backup of the last known-good .ini.

A combined MiniDexed/DreamDexed minidexed.ini has been tested successfully with this approach.

NOTE: if two systems use the same key names with incompatible meanings, then this simple multiboot method may not be enough without code changes in one of the projects. This is, for the moment, a limitation to be taken into account.

Suggested setup procedure

  1. Start with a known-good MiniDexed SD card.

  2. Create one directory per additional engine:

    /minijv880/
    /dreamdexed/
    /test/
    
  3. Move or copy each engine kernel into its own directory:

    /minidexed/kernel8-rpi4.img
    /minijv880/kernel8-rpi4.img
    /dreamdexed/kernel8-rpi4.img
    
  4. Edit config.txt and set the default kernel:

    kernel=/minidexed/kernel8-rpi4.img
    
  5. Add one GPIO selector first:

    gpio=12=ip,pu
    
    [gpio12=0]
    kernel=/minijv880/kernel8-rpi4.img
    
    [all]
    
  6. Test:

    No button held -> default engine boots
    Button held    -> alternative engine boots
    
  7. Add more GPIO selectors only after the first one works.

  8. Keep a recovery copy of the previous working config.txt.

Known working example

A tested MiniDexed/MiniJV880 example is available here:

https://github.com/oldmaga/MiniJV880-CardRAM-public/releases/tag/v2.4.0-public-clean.10

Relevant file:

src/config-dualboot-data-gpio12.txt

That setup uses:

/minijv880/kernel8-rpi4.img
/minidexed/kernel8-rpi4.img
GPIO12 as boot selector
default/high -> MiniJV880
GPIO12 low   -> MiniDexed

The same principle can be reversed or extended to more kernels.

Summary

In short:

Single FAT boot partition
Shared Raspberry Pi boot files
One subdirectory per engine
One kernel8-rpi4.img per engine
Raspberry Pi config.txt GPIO filters select which kernel to boot

This allows simple dualboot or multiboot setups without adding a custom bootloader.

Clone this wiki locally