Building a Linux Sega MegaDrive Emulator on Custom Octocopter Hardware
Let me tell you a story.
Last month, I was sitting in my workshop in Bangalore, staring at a pile of custom octocopter hardware I'd been testing for a client. We were pushing 200K events per second through our data pipeline at SIVARO, but my personal project had hit a wall. I wanted to play Sonic the Hedgehog 2 — not on my phone, not on my laptop — on actual hardware I'd built from scratch.
The problem? I'd designed the octocopter's flight controller around a Qualcomm Linux 2.0 board. It had a decent ARM processor, 4GB of RAM, and a GPU that could handle real-time sensor fusion. But could it run a Linux Sega MegaDrive emulator at full speed, with sound, while simultaneously processing gyroscope data?
Turns out, yes. But the path was ugly.
What We're Actually Building Here
Most people think emulating a Sega MegaDrive (or Genesis, if you're in North America) is a solved problem. Fire up RetroArch, download a ROM, done. That's true on x86 hardware running Ubuntu.
But when you're running on Qualcomm Linux 2.0 — a stripped-down embedded distro with no X server, no ALSA out of the box, and a custom kernel compiled for drone flight — things break in interesting ways.
The Linux Sega MegaDrive ecosystem has three layers:
- The emulator core (CPU interpreter or dynarec)
- The video/audio output layer
- The input system
On standard hardware, all three are abstracted away by desktop libraries. On embedded Linux? You're wiring every piece by hand.
Why Emulate on a Drone Controller?
I get this question a lot. "Nishaant, why not just use a Raspberry Pi?"
Because the Pi doesn't fly.
When you're building custom octocopter hardware, you need real-time control loops running at 400Hz, sensor fusion algorithms, and PID controllers. The Qualcomm Linux 2.0 board I was using had a dedicated DSP for flight control — leaving the main ARM cores free. And with 4GB of RAM and an Adreno GPU, it was overkill for just telemetry.
So here's the real question: Why waste that compute power?
I wanted to build a system where the octocopter could stream MegaDrive gameplay to a ground station, or even render it locally on an HDMI output for pre-flight entertainment. Call it stupid. Call it unnecessary. I call it making hardware work harder.
The Emulator Core: Choosing Your Fighter
You have three options for a Linux Sega MegaDrive emulator core:
PicoDrive — Lightweight, fast, but outdated. No dynarec on ARM. We'll skip it.
Genesis Plus GX — Accurate, maintained, but heavy. Uses 50MB+ RAM just for the core.
BlastEm — The dark horse. Written from scratch, supports dynarec on ARM64, and has a deliberately minimal dependency tree.
I tested all three on the Qualcomm Linux 2.0 board. BlastEm won by a mile. Here's why.
Most emulators assume you have libSDL2, libGL, and a compositor running. BlastEm can work with raw framebuffer and libasound directly. That's critical when you're running a custom distro.
Compiling it:
bash
git clone https://github.com/libretro/blastem
cd blastem
make -j4
That's it. No ./configure, no CMake, no apt-get install marathon. The makefile detects your architecture and compiles accordingly. On Qualcomm Linux 2.0, it auto-detected ARM64 and enabled the dynarec backend.
Video Output: The Hardest Part
Here's where most tutorials lie to you.
They say "just use the framebuffer." And yes, you can write directly to /dev/fb0. But the Qualcomm Linux 2.0 board's framebuffer is running at 16-bit color depth by default. The MegaDrive outputs at 9-bit color internally (3 bits per channel, if you're counting). Mapping that without banding requires dithering.
BlastEm supports a --fb flag for framebuffer output, but the default renderer assumes 32-bit. You'll get garbage colors. I spent three days debugging this.
The fix?
// In blastem/fbdev.c, force 16-bit mode
int fb_bpp = 16;
int fb_format = FB_FORMAT_RGB565;
Then rebuild:
bash
make clean && make -j4
The result? Smooth 60fps Sonic with proper sky gradients. But audio was still broken.
Audio: The Nightmare Nobody Talks About
The MegaDrive's YM2612 sound chip is a beast to emulate. Most desktop emulators use libSDL2 for audio buffering, which abstracts away the underlying ALSA or PulseAudio stack.
On Qualcomm Linux 2.0, ALSA works but has a 200ms buffer by default. That's fine for music playback. Terrible for game audio. You get lag between pressing jump and hearing the sound.
BlastEm has a --audio backend option, but it only supports SDL and ALSA directly. I tried ALSA with the direct plugin:
bash
blastem --audio alsa --audio-latency 16 sonic2.bin
16ms latency sounded terrible. Crackling. Underruns. The octocopter's real-time threads were stealing CPU cycles from the audio buffer.
The solution was dirty but effective. I pinned BlastEm to a dedicated core using taskset:
bash
taskset -c 2,3 blastem --audio alsa --audio-latency 32 sonic2.bin
But that still had occasional pops. So I ended up writing a small wrapper that increased the ALSA buffer size to 4096 frames but pre-filled it with silence:
bash
#!/bin/bash
echo "Pre-warming audio buffer..."
amixer set 'PCM' 95%
for i in {1..10}; do
aplay /dev/zero -d 1 > /dev/null 2>&1
done
taskset -c 2,3 blastem --audio alsa --audio-latency 48 sonic2.bin
Dirty. But it worked. Zero audio glitches at 60fps.
Input: Making an Xbox Controller Talk to Linux 2.0
The Qualcomm Linux 2.0 distro doesn't include joydev kernel module by default. It's built for drone joysticks (PWM input), not USB gamepads.
I had to recompile the kernel with CONFIG_INPUT_JOYDEV=y and CONFIG_INPUT_UINPUT=y. Then plugged in an Xbox One controller via USB OTG.
BlastEm supports evdev input natively, so mapping was straightforward:
bash
blastem --input evdev:/dev/input/event3 sonic2.bin
But the button mapping was wrong. The A button on the controller triggered the B button in-game. I edited blastem.cfg:
ini
[input]
evdev_device=/dev/input/event3
bind_a=evdev:BTN_A
bind_b=evdev:BTN_B
bind_start=evdev:BTN_START
Took 10 minutes. Not bad.
The Security Elephant in the Room
Here's where things get weird.
While I was testing input latency, I had my phone and the octocopter's ground station within Bluetooth range. AirDrop and Quick Share vulnerabilities were in the news — systematic vulnerability research showed that AirDrop and Quick Share protocols on Apple and Android devices could be crashed by attackers within 30 feet. The Hacker News reported that these flaws let attackers crash nearby devices simply by broadcasting malformed discovery packets.
But here's the contrarian take: For an embedded Linux device with no Bluetooth stack and no proximity transfer protocols, none of that matters. Over 5 billion iPhones and Android devices are potentially vulnerable to these attacks, but your custom hardware running Linux Sega MegaDrive emulation? Completely immune.
The point isn't that emulators are secure. The point is that building on embedded Linux with a stripped-down kernel eliminates an entire class of attack surface that consumer OSes inherit by default. When we talk about security at SIVARO, we don't just patch vulnerabilities — we design systems that don't have the vulnerabilities in the first place.
Performance Numbers
Here's what I measured on the Qualcomm Linux 2.0 board (Quad-core ARM Cortex-A76 @ 2.4GHz, Adreno 618 GPU):
| Game | FPS | Audio Latency | CPU Usage |
|---|---|---|---|
| Sonic the Hedgehog 2 | 60 | 48ms | 34% |
| Streets of Rage 2 | 60 | 48ms | 28% |
| Gunstar Heroes | 60 | 48ms | 42% |
| Comix Zone | 60 | 48ms | 22% |
The CPU usage was high but stable. Remember, this board was simultaneously running the flight controller at 400Hz. Total CPU load never exceeded 75%. The octocopter didn't crash. Neither did Sonic.
Building Your Own Linux Sega MegaDrive on Embedded Hardware
If you want to replicate this, here's the exact hardware stack I used:
- Board: Qualcomm Linux 2.0 reference platform (any Snapdragon 8cx Gen 3 board works)
- Display: HDMI output via USB-C to HDMI adapter, or raw framebuffer on a 5" TFT panel
- Input: Xbox One controller via USB OTG (or PS4 controller, also works)
- Storage: 64GB eMMC, microSD for ROMs
- Emulator: BlastEm v0.6.2 (git master as of June 2026)
The software stack:
bash
# Install dependencies
apk add alsa-lib-dev libglib-dev libpng-dev
# Build BlastEm
git clone https://github.com/libretro/blastem
cd blastem
make -j4
# Test
./blastem --list-cores
./blastem --help | grep audio
If you get "Cannot open /dev/fb0" errors, your kernel probably doesn't have framebuffer support compiled in. Rebuild with CONFIG_FB_CFB_FILLRECT=y.
Common Problems And Real Fixes
"The emulator crashes on launch"
Check your kernel's shm size. BlastEm allocates 64MB of shared memory for the dynarec cache. Default Qualcomm Linux 2.0 has shmall set to 4MB. Fix it:
bash
echo 65536 > /proc/sys/kernel/shmall
echo 67108864 > /proc/sys/kernel/shmmax
"Sound is choppy"
Don't use PulseAudio. Use ALSA directly. And increase the latency — I know 48ms sounds bad on paper, but for a platformer it's imperceptible. For rhythm games like ToeJam & Earl, you'll want to drop to 32ms and accept occasional pops.
"Graphics look wrong"
The MegaDrive has a weird pixel aspect ratio. Most emulators default to 4:3 output. On a 16:9 display, you'll get stretching. Add this to blastem.cfg:
ini
[video]
aspect_ratio=4:3
integer_scaling=1
The Bigger Picture: Why This Matters
I'm not writing this because I think everyone should emulate Sonic on a drone. Most people won't. You probably shouldn't.
But here's what I learned building custom octocopter hardware, data pipelines at SIVARO, and a Linux Sega MegaDrive emulator on the same board:
The boundaries between "embedded" and "general purpose" computing are dissolving.
That Qualcomm Linux 2.0 board? It runs the same ARM64 code as your phone. It has a GPU that can handle Vulkan. It has 4GB of RAM and NVMe storage. The only difference is the software stack.
Most people think embedded Linux is limited. They're wrong. With the right build system, you can run anything — from real-time flight control to retro game emulation — on the same hardware. The tradeoff is you have to write more glue code. The payoff is full control over what runs and when.
At SIVARO, we process 200K events per second through our data infrastructure. Every microsecond matters. That same mindset applies here. Optimize. Strip away layers. Understand your hardware.
FAQ
Q: Can I run ROMs I downloaded from the internet?
A: Legally? Only if you own the original cartridge. Practically? I'm not your lawyer. But the MegaDrive library is well-preserved at archive.org for research purposes.
Q: Will this work on a Raspberry Pi?
A: Yes, but BlastEm won't have dynarec support on ARMv7. You'll need to use Genesis Plus GX in RetroArch. Expect 50-55fps on a Pi 4.
Q: How do I transfer ROMs to the board?
A: SCP or USB mass storage. But turn off AirDrop and Quick Share first — those protocol vulnerabilities are real, and Security Boulevard reported that attackers can crash connected devices with malformed Wi-Fi Direct frames.
Q: Can I use Bluetooth controllers?
A: Yes, but the Qualcomm Linux 2.0 Bluetooth stack is experimental. I got an 8BitDo Pro 2 working after patching bluez to ignore the HID descriptor error. Not recommended unless you enjoy kernel debugging.
Q: What's the maximum resolution?
A: The MegaDrive outputs 320x224 internally. BlastEm can scale to 1080p with bilinear filtering. 4K works but the GPU starts thermal throttling after 20 minutes.
Q: Can I stream gameplay over Wi-Fi?
A: I built a simple GStreamer pipeline: gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! omxh264enc ! rtph264pay ! udpsink host=192.168.1.100 port=5000. 30fps at 720p with 80ms latency. Fine for watching, terrible for playing.
Q: Is this project practical?
A: No. But it's fun. And it taught me more about embedded Linux than any tutorial ever did.
Nishaant Dixit — Founder of SIVARO. Building data infrastructure and production AI systems since 2018. Built systems processing 200K events/sec.