Minimal Raspberry Pi VPU firmware
github.com
github.com
This is pretty awesome to see how much context the community has reverse engineered from the design - I remember making the first BCM2835 based project (the Roku 2) and spending _A LOT_ of time getting the ARM to startup reliably and boot into Linux as fast as possible. I've spotted 2 concepts in the open FW so far that misunderstood the implementation of the HW but are still working which is fun!
One advantage of the having the GPU start first (maybe the only advantage :) is that it can play a video for a splash screen instead of a static image. If you've ever used a Roku 2/3 or newer, this is a feature I hacked together for a demo to hide boot-up latency - now its a standard part of RokuOS (and is quite hard to replicate on traditional ARM/MIPS SoC's).
In theory, all the code and sequences for the BootROM, 2nd stage, ARM loader and peripheral control functions is available by disassembling the binaries (and extracting some code from the ROM with a mempcy) - it just requires reverse engineering / re-implementing inside and this is part of the fun / why this project is so great.
I might suggest they poke at the linux port and u-boot of the BCM2835 from Roku however :)
Of course no one in their right mind would use this reverse-engineered code here for any serious purpose. Instead, you dump the bastardized RPi platform (it's basically a video graphics card with an ARM bolted on) and use something actually free, like the BeagleBone.
1. A GPU
2. No binary blobs, no reverse engineering?
You might be interested in monitoring this list of what gets closest: https://www.fsf.org/resources/hw/single-board-computers
Also, the Novena mainboard has a chance of getting there, if you look at this page: https://www.kosagi.com/w/index.php?title=Novena_Main_Page and then note that the Vivante GPU is close to having free drivers: https://www.phoronix.com/scan.php?page=news_item&px=Etnaviv-...
And to get good use out of the GPU (one of the main selling points for this platform), you'll want to use the Nvidia proprietary driver.
And yes, CUDA isn't supported by the open drivers. Other than that, I've heard Nouveau works relatively well. Though I'm not still sure if the open source graphics community has figured out a way to get stacks like Xorg or Wayland/Weston running without hacking the source on architectures where rendering and scanout are done by different DRM devices.
https://github.com/NVIDIA/tegra-nouveau-rootfs
Using a completely open stack on the TK1, from u-boot to kernel (except for the USB firmware), I can run ARM virtual machines with QEMU/KVM.
If you want an ARM board: The "Sabre Lite - i.MX6 Quad Core" board is the nearest to this ideal that I know of. Traditionally Freescale has been very open with the specifications (though after NXP bought them this changed to worse). The GPU (Vivante™ GC2000) is not strictly in the category "No binary blobs, no reverse engineering", but I have read that this is among the GPUs found on ARM boards by far the most easy one to reverse engineer, thus there seems to exist a decent reverse-engineered driver:
> https://en.wikipedia.org/w/index.php?title=Free_and_open-sou...
(EDIT: For the situation for open Vivante drivers also see https://www.phoronix.com/scan.php?page=news_item&px=Etnaviv-... (from https://news.ycombinator.com/item?id=12743550)).
The SABRE Lite i.MX 6Quad has a similar price: On
> http://uk.farnell.com/nxp/mcimx6q-sl/i-mx6-quad-sabre-lite-d...
it costs £114.29 (about $140), on Mouser it is even $189.95.
Oh please, while you lose the VC4 firmware, you instead get a proprietary PowerVR GPU with no free drivers. Not to mention that the Beaglebone has a much worse CPU than the "bolted on ARM" of the RPi.
If you're going to dump the rpi for this reason, going to something like the imx6 used in the Cubieboard and Novena would make a lot more sense (edit: Cubox, not Cubieboard).
The Cubieboard uses an Allwinner SoC, which has a bad reputation among oppen source people since Allwinner violated the GPL multiple times in the past (though I heard the Linux support is decent; mainly because of the work of the Sunxi community: https://linux-sunxi.org/Main_Page). Novena (and "Sabre Lite - i.MX6 Quad Core"; cf. https://news.ycombinator.com/item?id=12743798) indeed use a Freescale (now bought by NXP) SoC.
The silver lining though is that the sunxi community has been working to mainline newer chips like the Allwinner H3 & has been doing a bang up job with minimal info, newer kernels can boot up & get most hardware onboard configured & ready to use.
What this is is a replacement VC4 operating system image which just fires up the ARM with an embedded image, sets it running, and then halts (assuming I'm understanding the docs correctly); so it can't (yet) actually load an OS into the ARM from disk or respond to RPCs etc.
In practical terms, this is the biggest, most difficult step forward towards running an almost completely open system on the RPi. (It could also be used as the core of a proper operating system running on the VC4 itself, which could be rather interesting.)
I knew that the bootloader worked that way but didn't think of it being that way until reading your comment. Interesting to think of the hierarchy that way.
Naively this makes me think that the ARM ISA could use something like UEFI (or BIOS) to unify the devices' bootstrapping logic around some common metaphor.
(I've heard that the only reason the ARM is there at all is that Broadcom had a royalty-free license and there was some spare silicon, so they thought, hey, why not, it might be useful...)
Traditionally ARMs have never used any kind of common boot process because they come out of the embedded world where every system is bespoke --- the focus is always on individual products, rather than building a platform.
There have been various efforts to fix this but AFAIAA they've never come to much. I think the current one is DeviceTree, but I don't believe there's much vendor support.
I don't think such a thing exists. Aren't dies made as small as possible to increase yield? I know the Cell processor in the ps3 had a spare spe core to significantly increase yield.
It was also clearly intended for possible use in mobile phones, as some of the patent diagrams have "baseband" on them: https://github.com/hermanhermitage/videocoreiv/wiki/VideoCor...
This is something I did not know. In the mobile world the boot happens in the UEFI mould right? So when someone licenses from ARM they get to design their own boot sequence?
Booting such a system is highly dependent upon the board configuration and the peripherals that are needed. Furthermore, vendors have different boot-up requirements. Some boot loaders perform proprietary system checks before loading the RTOS. Some boot loaders need to be able to upgrade firmware from an image on-chip, in flash, or fed into it over SPI or a UART. Some boot loaders are little more than a jump table decoder that just jumps to the currently active firmware image on the chip. Creating a universal boot loader with enough flexibility for each of these situations is harder than just implementing a boot loader for a particular electronics product or product family.
The Broadcom parts work like this for the VC4; the boot ROM can talk to an SD card, parse a FAT filesystem, and load and run the second-stage loader (bootcode.bin). But Allwinner chips do this too, and they're even smart enough to try several different media types (including SATA, IIRC!). Ditto Tegra parts.
I imagine that if you're a major customer you get to choose the contents of the boot ROM.
From a hacker perspective, it's brilliant, because the devices are completely unbrickable. It doesn't matter how broken they get, you can't change the ROM, which means that you always have ability to get something working. But, of course, they all have entirely different APIs. The VC4 just dumps an image into memory, sets a couple of registers, and jumps to it, and I imagine the others all do the same thing.
Even better, u-boot implements enough of it to boot a UEFI operating system. So on some new devices you'll get UEFI firmware, on everything else you can flash u-boot with UEFI support... and it's now part of their default configs.
Pretty cool. :-)
Hope it isn't another quirky "just enough to boot windows, with other OSs having to clone windows behaviour to work" thing.
Can secure boot be disabled on ARM?
The property whether it can be disabled depends on the concrete UEFI implementation.
https://github.com/hermanhermitage/videocoreiv/wiki/VideoCor...
In particular we are talking about "Scalar/Vector (VPU)" "Dual Core VideoCore IV® Multimedia Co-Processor" (Figure 3B). As far as I understand, that's the thing that boots the device and usually runs ThreadX OS in the closed-source bootloader. The VPU is a dual core processor with scalar and integer vector instructions.
The VPU is more-or-less independent of the GPU, although I'm not sure whether the VPU gets involved with some GPU scheduling tasks.
The GPU has four "QPU" QuadProcessor pipelines, which from memory can do floating-point vector processing.
It's a vector processor and a GPU. The vector processor is intended for video decoding and therefore has a very big SIMD capability. It has some nice gimmicks like the 'square' register file: you can access rows or columns for SIMD operations. The VPU is I believe what boots first and normally runs an RTOS called "ThreadX".
The GPU is OpenGL-capable.
But this firmware doesn't contain code to initialise the GPU, it does contain initialisation code for one rather important peripheral, which is the DRAM. The VC4 has been pretty well reverse engineered for a while (I did one of the early C compiler ports for it), but the big missing piece was figuring out how to initialise the RAM. Without that, everything had to fit in the 128kB of built-in SRAM.
This firmware's a huge step forward.
It doesn't seem like an unusual setup to me at all: the only unusual thing, I guess, is that the VC4 is capable of a lot more than the small ARC/ARM core inside Intel ME.
There isn't a fundamental difference in how Intel CPUs start up and how the Raspberry Pi starts up, as I sometimes see people implying.
The instruction set's here:
https://github.com/hermanhermitage/videocoreiv/wiki/VideoCor...
...but to summarise:
- 32 registers which can hold either integers or 32-bit floats;
- ARM-like 32-bit 3op instructions, with a limited set of 16-bit 2op instructions;
- integrated 32-bit floating point instructions, using the same registers as everything else;
- some 48 bit instruction forms (allowing a full 32-bit payload! No ghastly ARM constant pools or PowerPC-style split payloads!);
- two cores, with integrated interrupt handler;
- integrated DSP with 80-bit vector instructions working on a 64x64x8bit vector working area, which TBH looks like it was stolen from another processor completely and which I frankly don't understand;
- ARM-style conditional execution (for some instructions);
- ARM-style multiregister loads and saves (and pushes and pops);
- DSP-style saturated arithmetic and fixed-point support;
- no ALU-setting-condition-flags instructions, or add-with-carry or subtract-with-carry operations, which makes 64-bit arithmetic really painful (if you need cmp to set the condition flags, what's the carry flag even for?)
It's actually a really nice thing to write assembly for. It's orthogonal enough to be understandable, while quirky enough to allow some really satisfying optimisations. e.g. there's the addcmpb instruction, which while add a value to a register, compare with another register, and branch based on a condition code, all in a single 32-bit operation --- it's basically a loop in a box.
It's also the only time I've ever seen 6-bit floating point constants...
Initially the instructions did all set the status flags but it caused a tight feedback loop in the processor. The choice was between a higher clock frequency for all instructions or better 64-bit arithmetic.
None of the initial video applications needed 64-bit support so it lost out, although I did get to put in the divide instruction just so my Doom port could run faster :)
Are you allowed to tell us what the C compiler used internally was based on? I know there are some very easy to port proprietary compilers which commonly don't see the outside world, and I'm wondering whether it was one of those, or whether some poor sucker had to port gcc.
Well, it's 3D, so you pretty much need perspective divide at the very least…
As it happens, while we were waiting for this compiler to be made for us, I ported GCC to the architecture for my own use. I don't remember it being all that painful, just a few pages of machine description and everything seemed to work fine.
This only supported the scalar instruction set. However, when we needed an MP3 decoder I found that it really needed 32bit precision to meet the audio accuracy, so I also made a different port of gcc that targeted the vector processor. I changed the float data type so any mention of float actually represented 16 lanes of a 16.16 fixed point data type implemented on the vector processor. From what I recall, mp3 decode required 2MHz of the processor for stereo 44.1kHz.
While a port has been discussed, I don't think a port has been completed.