I am posting this directly *from* my Hero4
Silver, while running Ubuntu Linux on it.
EDIT, from an actual laptop this time:
WARNING: DO NOT TRY THIS AT HOME.
You assume responsibility for all risk and all consequences of the information below. I have only tried this on a Hero4 Silver having a Panel ID ox 0xd5. I imagine this will do Very Bad Things to a Hero4 Black (and any other camera), due to these cameras having different PMIC configurations.
I was bored, so I figured it would be cool to get Linux running directly on a Hero4 Silver, complete with display, sdcard, X11, etc. The display is only 320x240, but it is in theory enough to at least "try" to run desktop applications on it, if for nothing other than comic effect.
The Linux kernel that I'm running on the camera is derived from the GPL release that GoPro made back in December 2014. I had to make a number of changes, including writing a framebuffer driver / backlight driver / panel ID driver, setting up the kernel to run directly on the metal, fixing a bunch of dual-core-related crap, rewriting Ambarella's multicore boot implementation, writing my own hardware bootstrap, fixing an annoying locking bug in Ambarella's GPIO code, implementing an ARM11-based loader for the A9s, figuring out how to bring the A9s out of reset, and a number of other things.
My kernel, and all my patches, can be found here: https://github.com/evilwombat/linux-her ... its/master
And, the tools to boot the kernel can be found here: https://github.com/evilwombat/gopro-usb-tools
TWO penguins, because we're running in dual-core mode! That's right, we're actually running on both of the Cortex A9 CPUs. By default, Linux draws a penguin for every CPU that is active in the system.
Firefox is running on Linux, directly on the camera. The entire GoPro firmware stack is completely bypassed - we use gpboot to load a Linux kernel (and a suitable initrd) directly into DDR and run it from there. I had to write a framebuffer driver for the color LCD on the back, as well as a few "stub" drivers for controlling the backlight (on the AS3715 PMIC, over I2C) detecting the LCD type (more on this later). The initrd contains basic stuff needed to get a shell going over telnet. Actual Ubuntu binaries, including X, Firefox, fluxbox, and the associated libraries, are all running off an ext4 filesystem on the sdcard. Network connectivity is provided over USB, which enumerates as a CDC Ethernet controller (similar to what we did on Hero2/Hero3). Internet access is provided to the camera through a host-side bridge. Keyboard and mouse input is similarly sent to the camera over the network, using an awesome little utility called 'synergy'. The ARM-targeted userspace was grabbed from http://releases.linaro.org/15.04/ubuntu ... ages/gnome
Since I don't have Ambarella's Vout specs, the LCD (which uses an ST7789 controller) is refreshed directly over SPI, at approximately like 5Hz. It's not the fastest thing on four legs, but it's a decent proof-of-concept. It looks like Hero4 Silver cameras might actually use several different types of LCD panels, and each panel has a different initialization sequence. How does the camera know what type of LCD it has? "Let's just read the panel ID from the LCD itself, right?" Yeah, that would make sense, except the LCD is wired in 3-wire SPI mode, meaning that it isn't actually possible to read data from it. So, how does the camera *really* identify the display type? "I know, let's read the panel ID from a TOUCHSCREEN register, yeah!" And that's what they do. Sigh... but, since my kernel has to support all panel types, I had to implement something similar. Fortunately, the -EPROBE_DEFER mechanism in Linux makes this only slightly heinous.
After adding basic Hero4 DDR support to gpboot (https://github.com/evilwombat/gopro-usb-tools
), I didn't do anything with USB-booting a Hero4 for something like eight months, due to intermittent bashing of head against the wall with respect to the boot flow. Then, I realized that in addition to the two Cortex A9s, the Hero4 also has a legacy ARM11 CPU, which is where the USB mode has been running the whole time. So, the code that I *thought* was doing crazy DDR remapping stuff, was actually just bringing the Cortex A9s out of reset! Once that became obvious, everything else started falling into place. And this is where we are now....
The above information might not be the cleanest, but I am about to travel overseas for two weeks and I wanted to get the code and information out there, in case something happens to me or to my system(s).
What does this demonstrate? That the only thing harder than bringing up Linux on a GoPro is taking even half-decent photos of the result.