The Snowball board is a tiny energy-efficient but surprisingly complete development board from Calao Systems. Although the board is discontinued, there are still a good thousand boards in stock. In Europe these boards can be obtained (with a minimum order of 5 pieces) for around €40,= including shipping, making them an interesting alternative to the Raspberry Pi. With a dual-core ARM Cortex A9 processor the processing capabilities can be up to 6 times as high as the RPi.
Some of the boards features: 1GB of RAM, 4GB (SDK) or 8GB(PDK) storage on-board (eMMC), 10/100 ethernet, on-board Wifi-Bluetooth-GPS(full version), HDMI out and several other connectors including audio, uSD, serial console over USB. When the radio functions are not required, it can be powered over a standard USB port, otherwise an external 5V adapter is required.
Purpose of this page
This wiki page documents the work-in-progress on making Linux, and Fedora in particular, run on the Calao Snowball board. In particular this should cover technical documentation and notes about the eMMC flashing tool, the U-boot boot loader and the Linux kernel plus device drivers.
Eventually this work should lead to a single Fedora image that can be uploaded to the eMMC containing a fresh U-boot, a recent kernel containing many OSS drivers and a user-space useful and expandable in the Fedora fashion. Reaching this final goal depends on the redistributability of the boot-loader binaries provided by ST-Ericsson, which I currently treat as a later concern. If no complete image could be provided due to licensing constraints, at least we should aim for good installation instructions.
Riff
The Snowball board contains an embedded 8GB MMC chip, or eMMC, that off-the-shelve contains several first-stage bootloader binaries, U-Boot 2009.11, and a Linaro 11.09 installation. The eMMC can be overwritten either from inside the system, or externally through a USB cable using the Riff tool.
Compilation is a bit painful by default, because the tool is abandoned and designed with a different distro in mind. Specific problems include expectations on the filenames for Xalan-j2, a seemingly non-working install make target and poor instructions in the README files.
U-Boot
U-boot is situated on the eMMC at offset 0x120000. Riff can be used to write a new build of the bootloader to this address. The size of U-boot is stored in a 4-byte integer at 0x200a4. Upstream U-Boot can be used on the Snowball board, but loading a kernel from the eMMC does not work due to a regression introduced in:
e95504497ecac46907204b0ee3460b708a2981ac mmc: Split device init to decouple OCR-polling delay
Reverting this commit makes U-boot work. By default the upstream U-boot has no support for Device Tree or network boot. The latter is supported by the preloaded image.
Replacing U-Boot using riff
After successfully building U-Boot, it can be flashed onto the eMMC from a host machine using riff.
0. Make a back-up of your eMMC so that you can restore it later in case something goes wrong
# sudo ./riff -m dump -l 38000000 -d /path/to/dumpfile.bin
1. Build U-Boot (u-boot.bin) for snowball. Specify the config with the following command for version up to 2014.07 included:
# ARCH=arm make snowball_config
and the following for versions 2014.10 on:
# ARCH=arm make snowball_defconfig
Finally build with:
# ARCH=arm make
2. Create a 4-byte file, blsize.txt, using a hex-editor containing the size of the bootloader in big endian format.
3. Flash it onto the eMMC using the following commands
# sudo ./riff -f u-boot.bin -a 120000 -m flash # sudo ./riff -f blsize.txt -a 200a4 -m flash
Kernel and drivers
Component | Purpose | Module | Works | Upstream kernel | FDT | Firmware required? | Notes |
---|---|---|---|---|---|---|---|
U8500 | CPU | dbx500-cpufreq | X | X | X | loop delay calibration fails, boot with lpj=7970816
Must build SMP kernel | |
Perf. Counters | pmu-a9 | X | X | X | |||
DMA | dma40 | X | X | X | |||
AMBA SSP | ssp-pl022 | X | X | ? | |||
AB8500 RTC | Real-time clock | rtc-ab8500 | X | X | X | ||
AB8500 | Thermal sensor | ab8500 | - | X | X | Pagefault, see below | |
UART | Serial port | amba-pl011 | X | X | X | Debug console may not be 2 or boot will hang trying to enable output console | |
L310 | L2 Cache | l2x0 | X | X | X | ||
Nomadik I2C | I2C | nmk-i2c | X | X | X | ||
L138 USB OHCI | USB Host | db8500-musb | X | X | |||
ARM Mali | GPU | lima | No DRM driver yet | ||||
AV8100 | HDMI output | av8100_hdmi | X | Needs port to DRM | |||
? | CVBS output | ||||||
PL180 | (e)MMC | armmmci | - | X | X | Fails DMA transfers to RPMB, sdhci needs fix for command blocks/idling | |
SMC9121 | Ethernet | smsc911x | X | X | X | Odd MMIO layout, register location shifted
Powered on by U-Boot | |
CW1200 | Wifi | cw1200 | X | X | GPIO 170 powers it on | ||
CG2900 | Bluetooth+GPS | cg2900 | |||||
MOP500 | Audio | snd-soc-mop500 | X | X | |||
LP5521 | LED driver | ||||||
LSM 303DLH | Accelerometer/Magnometer | - |
This wiki page has a lot more info on the "smaller" devices on this board (sensors, GPIO ports, LED drivers..)
Backlog for db8500-thermal
[ 1.772277] genirq: Flags mismatch irq 181. 00006000 (dbx500_temp_low) vs. 00006000 (dbx500_temp_low) [ 1.781524] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc2 #15 [ 1.787902] [<c0017908>] (unwind_backtrace+0x0/0x140) from [<c0013814>] (show_stack+0x20/0x24) [ 1.796508] [<c0013814>] (show_stack+0x20/0x24) from [<c0692288>] (dump_stack+0x84/0xb8) [ 1.804595] [<c0692288>] (dump_stack+0x84/0xb8) from [<c0074c6c>] (__setup_irq+0x494/0x4cc) [ 1.812957] [<c0074c6c>] (__setup_irq+0x494/0x4cc) from [<c0074df8>] (request_threaded_irq+0xbc/0x13c) [ 1.822265] [<c0074df8>] (request_threaded_irq+0xbc/0x13c) from [<c0076d14>] (devm_request_threaded_irq+0x70/0xb4) [ 1.832611] [<c0076d14>] (devm_request_threaded_irq+0x70/0xb4) from [<c0419f2c>] (db8500_thermal_probe+0x2c8/0x4a0) [ 1.843048] [<c0419f2c>] (db8500_thermal_probe+0x2c8/0x4a0) from [<c0334848>] (platform_drv_probe+0x28/0x58) [ 1.852874] [<c0334848>] (platform_drv_probe+0x28/0x58) from [<c0332a4c>] (driver_probe_device+0x160/0x398) [ 1.862640] [<c0332a4c>] (driver_probe_device+0x160/0x398) from [<c0332d74>] (__driver_attach+0x9c/0xa0) [ 1.872100] [<c0332d74>] (__driver_attach+0x9c/0xa0) from [<c0330a78>] (bus_for_each_dev+0x70/0xa4) [ 1.881164] [<c0330a78>] (bus_for_each_dev+0x70/0xa4) from [<c03323b8>] (driver_attach+0x2c/0x30) [ 1.890014] [<c03323b8>] (driver_attach+0x2c/0x30) from [<c0331f8c>] (bus_add_driver+0x170/0x22c) [ 1.898895] [<c0331f8c>] (bus_add_driver+0x170/0x22c) from [<c033342c>] (driver_register+0x88/0x108) [ 1.908020] [<c033342c>] (driver_register+0x88/0x108) from [<c0334818>] (__platform_driver_register+0x64/0x6c) [ 1.918029] [<c0334818>] (__platform_driver_register+0x64/0x6c) from [<c09a5a5c>] (db8500_thermal_driver_init+0x1c/0x20) [ 1.928894] [<c09a5a5c>] (db8500_thermal_driver_init+0x1c/0x20) from [<c00088f0>] (do_one_initcall+0x110/0x1bc) [ 1.938995] [<c00088f0>] (do_one_initcall+0x110/0x1bc) from [<c096fddc>] (kernel_init_freeable+0x1cc/0x26c) [ 1.948730] [<c096fddc>] (kernel_init_freeable+0x1cc/0x26c) from [<c068cda8>] (kernel_init+0x1c/0x130) [ 1.958038] [<c068cda8>] (kernel_init+0x1c/0x130) from [<c000f838>] (ret_from_fork+0x14/0x20) [ 1.966705] db8500-thermal 801573c0.thermal: Failed to allocate temp low irq. [ 1.973876] db8500-thermal: probe of 801573c0.thermal failed with error -16
MMCI idle/block command
timed out sending SET_BLOCK_COUNT command, card status 0x400e00
The status indicates it's not an actual time-out but an error rather: trying to execute SET_BLOCK_COUNT while the state of the card is "prg". Transition to "tran" state should be done on operation completion, but something prevents this from happening on eMMC. Seems to be a timing issue; inflating time in mmci_request_end increases the likelihood of this error occuring. Maybe related to the suspend routines.