Archives For FreeBSD

FDT overlay is an extension to FDT format that lets user to modify base FDT run-time: add new nodes, add new properties to existing nodes or modify existing properties. It’s useful when you have base board and some extension units like cape/shield for Pi/BBB or loadable FPGA logic for Zynq. I will not go into details you can find internals described on Adafruit or Raspberry Pi websites.

When dealing with overlays there are two options where to handle them: loader or kernel. Managing overlays at kernel level gives more flexibility but requires more related logic, e.g. re-init pinmux after applying overlay, re-run newbus probe/attach. On the other hand loader-level support is quite straightforward and involves nothing but DTB modifications and it’s a natural first step to adding FDT overlays to FreeBSD.

Proposed solution is to add fdt_overlays variable that contains coma-separated list of dtbo files, e.g.: “bbb-no-hdmi.dtbo,bbb-4dcape-43.dtbo”. This variable can be defined either as a loader(8) variable or as a u-boot env variable. During the boot ubldr load base DTB and right before passing control to the kernel it would go through files, load them from /boot/dtb/ direсtory on root partition and apply to the base blob. Final DTB would be passed to kernel.

You can find patch and review comments to it on Differential site: D3180. It contains:
- Extension to dtc to generate dynamic symbols and fixup info.
- ubldr fdt_overlays support

As Warner Losh mentioned it’s not clear yet how to deal with dynamic symbols support patch. It’s not part of official dtc tree though it’s accepted by RPi and BBB communities.

Qt5 for FreeBSD/Pi

January 14, 2015 — Leave a comment

Build SD card image using crochet-freebsd with option VideoCore enabled. Mount either SD card itself of image to build host

mount /dev/mmcsd0s2a /pi

Checkout Qt5 sources and patch them

cd /src
git clone git://gitorious.org/qt/qt5.git qt5
cd qt5
git checkout 5.4.0
MODULES=qtbase,qtdeclarative,qtgraphicaleffects,qtimageformats,qtquick1,qtquickcontrols,qtscript,qtsvg,qtxmlpatterns
./init-repository --module-subset=$MODULES

fetch -q -o - http://people.freebsd.org/~gonzo/arm/rpi/qt5-freebsd-pi.diff | patch -p1

Configure, build and install Qt5 to SD card

./configure -platform unsupported/freebsd-clang -no-openssl -opengl es2 -device freebsd-rasp-pi-clang -device-option CROSS_COMPILE=/usr/armv6-freebsd/usr/bin/ -sysroot /pi/ -no-gcc-sysroot -opensource -confirm-license -optimized-qmake -release -prefix /usr/local/Qt5 -no-pch -nomake tests -nomake examples -plugin-sql-sqlite

gmake -j `sysctl -n hw.ncpu`
sudo gmake install

You need BSD-specific plugins to enable mouse and keyboard input in EGLFS mode

cd /src/
git clone https://github.com/gonzoua/qt5-bsd-input.git
cd qt5-bsd-input
/src/qt5/qtbase/bin/qmake
gmake
sudo gmake install

Build application you’d like run and install it. I use one of the examples here

cd /src/qt5/qtbase/examples/opengl/cube
/src/qt5/qtbase/bin/qmake
gmake
sudo gmake install

Unmount SD card, boot Pi, make sure vchiq is loaded

root@raspberry-pi:~ # kldload

Start application

root@raspberry-pi:~ # /usr/local/Qt5/examples/opengl/cube/cube -plugin bsdkeyboard -plugin bsdsysmouse

If you see something like this:

EGL Error : Could not create the egl surface: error = 0x3003

Or this:

QOpenGLFramebufferObject: Framebuffer incomplete attachment.

It means you need to increase GPU memory by setting gpu_mem in config.txt. Amount depends on framebuffer resolution. 128Mb works for me on 1920×1080 display.

bsdsysmouse plugin uses /dev/sysmouse by default, so you either should have moused running or specify actual mouse device, e.g.:

root@raspberry-pi:~ # cube -plugin bsdkeyboard -plugin bsdsysmouse:/dev/ums0

bsdkeyboard uses STDIN as input device, so if you’re trying to start app from serial console it should be something like this:

root@raspberry-pi:~ # cube -plugin bsdkeyboard -plugin bsdsysmouse < /dev/ttyv0

Audio on Raspberry Pi

January 9, 2015 — Leave a comment

With stable VCHIQ driver next obvious target was to add VCHIQ-based audio support. So let me introduce to you: vchiq_audio, first take. It’s part of vchiq-freebsd repo so if you use Crochet to build SD card image just enable option VideoCore in config file and module will be automatically included.

From shell run kldload vchiq_audio and you’re good to do. I believe that audio output is picked up automatically by VideoCore so if you have HDMI connected it’s probably going to be HDMI. I do not have device to confirm this. Adding knob to control audio output (auto, headphones, HDMI) is on my ToDo list.

Quality is not ideal though. From quick tests it seems to work fine on system with rootfs on NFS but there are audio drops on SD-based system while playing mp3 over NFS. I’m going to debug and stresstest it more thoroughly next week.

Short instruction on how to install mpg321 package on RPi:

env PACKAGESITE=http://chips.ysv.freebsd.org/packages/11armv6-11armv6/ SIGNATURE_TYPE=none pkg bootstrap

mkdir -p /usr/local/etc/pkg/repos
cd /usr/local/etc/pkg/repos
echo 'FreeBSD: { enabled: no }' > FreeBSD.conf

cat > chips.ysv.conf <<__EOF__
chips.ysv: {
  url: "http://chips.ysv.freebsd.org/packages/freebsd:11:armv6:32:el:eabi:softfp",
  mirror_type: "http",
  signature_type: "none",
  enabled: yes
}
__EOF__

pkg install mpg321

QEMU support in FreeBSD/armv6 regressed since I tried it last time few months back. Changes in FreeBSD kernel and in QEMU itself revealed bugs that were masked by previous behaviour.

In FreeBSD it was r248467: the way memory/IO resources are activated on FDT bus has been changed and it triggered bug in versatile_pci.c

The other issue is more complex. It seems that PCI IRQ routing in QEMU was out of sync with real hardware. So after commit 66a96d7018b9cbabb73c9b87b62a37e4cc46580a IRQ numbers assigned to PCI devices by FreeBSD kernel by default were invalid. Authors of QEMU eventually added compatibility knob to fall back to previous logic. So if you’re using QEMU 1.5 or later add this option to your command line:

-global versatile_pci.broken-irq-mapping=1

Quick hint. If you did not disable “device sc” in kernel config all the message from kernel go to video console. But if something bad happened after kernel started and before framebuffer driver is activated all you’ll see would be “Kernel args: (null)” message on serial console which is not very helpful. So in order to debug this problem and have kernel boot messages on both monitor and serial port without recompiling kernel just add following line to /boot/loader.rc on SD card:

set boot_multicons="YES"

I’m trying to wrap up some project I started working on quite some time ago and this is first chunk of clean-up.

Patch contains:

  • Kernel config for AM335x EVM
  • dts file for AM335x EVM with TFT panel info
  • LCD controller driver with some functionality missing: only 24/32 bit depth and only TFT mode is supported
  • Really simple PWM driver. LCD backlight is controlled through eCAS submodule of PWMSS0 module.

I tested it only on evaluation module, although I think with proper panel/pinmux configuration it should work with BeagleBone’s LCD caps too.
Parts missing: adjusting clock to proper pixel frequency, proper allocation of framebuffer memory.

Writing new driver for FDT-based device always involves several simple steps:

  • writing generic newbus driver skeleton
  • Checking for compatibility of node in probe routine
  • Allocate memory/IRQ resources in attach routine

I can’t say for other developers but I just copy existing driver, remove all device-specific stuff and rewrite generic stuff. Which is less time-consuming then writing it from scratch but time-consuming it is. Being huge fan of automation of any kind I decided to let computer do all this dumb work and leave creative part (copy-pasting registers definition from spec to code) to myself. the result is this script.

Developer feeds driver description in YAML format to the script and gets driver skeleton that requires minimal amount of editing to get it compiled. Driver description includes author name, prefix for macroses, prefix for newbus method-functions, FDT compatibility string, driver name and number of IRQ/MEMORY resources. A minute saved is a minute earned.

YAML example:

AUTHOR: Oleksandr Tymoshenko <gonzo@freebsd.org>
PREFIX: am335x_pwm
MACRO_PREFIX: PWM
DRIVER: am335x_pwm
FDT_COMPATIBLE: ti,am335x-pwm
IRQ_RESOURCES: 0
MEM_RESOURCES: 4

U-Boot is a boot loader. Its task is to get kernel into memory and pass control to it. I will cover only parts of it related to netboot.

kernel or kernel.bin

But before we start loading something we need to know what to load. In previous post I mentioned that there are kernel, kernel.bin, and ubldr files. Let’s get into details. First of all: ubldr requires its own post. So there will be one more covering just ubldr. Now kernel and kernel.bin.

kernel is ELF executable. It means that it’s a self-contained file with all the information required to layout its bits in memory. e.g.: this data in file should be copied to address A, and N bytes at address B should be set to zero, code intry point is address X. All this auxiliary information is stored alongside to raw code and data. U-boot (or any other bootloader) reads it, lays out data/code accordingly and passes control to entry point. U-Boot’s command for it is bootelf.

Now, bootelf or ELF support in general is not always available in boot loaders. In this case we load ELF on host machine. Technically it’s called “convert to binary format” but essentially what objcopy utility does is it simulates loading of ELF file into memory and dumps memory region from the lowest address that belongs to loaded executable to the highest one into the kernel.bin file. No auxiliary information is saved – only raw code and data. Without this information it’s users responsibility to point which address this memory dump should be loaded at and where to start execution.

That’s theory in a nutshell. Back to practice.

U-Boot

Network initialization routine depends on the board you’re working with. If the ethernet card connected to board over USB (like on Raspberry Pi or Pandaboard) you might need to initialize USB first:

U-Boot> usb start
(Re)start USB...
USB0:   Core Release: 2.80a
scanning bus 0 for devices... 3 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
       scanning usb for ethernet devices... 1 Ethernet Device(s) found

At this point you can either get network settings via DHCP or set them manually.
Manual control over network is performed by setting U-Boot environment variables:

U-Boot> setenv ipaddr 192.168.10.21
U-Boot> setenv netmask 255.255.255.0
U-Boot> setenv gatewayip 192.168.10.1

DHCP also provides information about TFTP server and boot file, we can set them manually too:

U-Boot> setenv bootfile kernel
U-Boot> setenv serverip 192.168.10.1

And now load it

U-Boot> tftpboot 0x8000

and boot

U-Boot> bootelf 0x8000

By default tftpboot and bootelf would use loadaddr env variable if it’s set so you can combine last two commands to

U-Boot> setenv loadaddr 0x8000
U-Boot> tftpboot
U-Boot> bootelf

With DHCP everything above is combined into three commands:

U-Boot> setenv loadaddr 0x8000
U-Boot> dhcp
U-Boot> bootelf

If you’re booting ELF loadaddr can be any valid address because bootelf will relocate kernel to proper location. Valid range for addresses depends on the board in use.

With kernel.bin though you have to specify specific value as a loadaddr. Usually it’s KERNPHYSADDR option in kernel config file for ARM and KERNLOADADDR value for MIPS. U-Boot commands sequence would look like:

U-Boot> setenv bootfile kernel.bin
...
U-Boot> setenv loadaddr 0x00100000
U-Boot> dhcp
U-Boot> go 0x00100000

uImage, ubldr

This is basic stuff I’ve been using for several years in my development environment. There are more options though: u-boot application images and bootm command and ubldr. Former is well-documented on Internet and about latter I’ll post some information soon.

VCHIQ drivers work again

January 13, 2013 — 7 Comments

I synced both vchiq-freebsd and userland to latest and greatest.

As I mentioned earlier – OS compatibility shim was removed from upstream sources so I had to create Linux KPI implementation layer which turned out not that awful task because I managed to reuse a lot of code from Max Khon’s DAHDI port. I had to implement (in somewhat hackish fashion) kthread API, re-implement semaphores support using condvar and mutex in order to get _interruptible part of API working properly and create dumb implementation of rather small subset of Linux list.h API.

With latest code I got pretty much all demos in hello_pi working except hello_jpeg(crashes system) and hello_encode(didn’t test). The most exciting bit for me was watching H.264 video playing on Raspberry Pi in hello_video demo. Network throughput still sucks so I had to copy file to tmpfs partition in order to get smooth playback though.

If you want to test VCHIQ – in addition to sources you’ll need latest firmware files. For demos you’ll also have to install freetype2 and manually hack Makefile.include in hello_pi. I’m planning to create ports/packages for both drivers and userland some time next week.

On the related note: Aleksandr Rybalko got XOrg working on Efika MX Smartbook so FreeBSD/Pi will get graphic interface soon :)

It’s been a while since last update on the project status so it might seem as there was no progress in this area. The reality is: there is a bunch of activities happening with various levels of success. So I decided to give kind of end-of-the-year round-up of ongoing projects, plans and obstacles ARM hackers face.

First of all we tried switching default cache type from write-through to write-back type. It should have increased performance but instead opened a can of worms. Memory corruption debugging led to L2 cache driver on Pandaboard, EHCI driver code and subsequently to busdma code. Whole process took quite a few days full of hair-pulling and nagging various people and ended up in committing USB fixes and Ian Lepore’s busdma patches. PL310 (L2 cache controller) driver is being tested at this very moment. Original issue (WB caches) still stands and postponed till next year.

Then there are two projects by Andrew Turner aimed at modernizing FreeBSD/armv6 subsystem: switching to EABI and clang support for ARM. Daisuke Aoyama took both of them and produced working image for Raspberry Pi. He also fixed two issues with event timers on Raspberry Pi so now the platform is much more stable. I ran buildkernel in a loop overnight and by the morning Pi had survived 7 cycles and still was alive and kicking. I also managed to get python built and working on it. Didn’t have 100% success with perl 5.14/5.16, ports were built but failed at install stage segfaulting in do_clean_objs function.

My Pandaboard survived overnight buildkernel loop with L2 cache disabled, but acting up if I enable it. Investigating.

Then there are also several platform bring-ups in progress. Alexander Rybalko works on getting FreeBSD running on Efika MX Smartbook. Ganbold Tsagaankhuu hacks on Allwinner 10. Alexander Dutkowski’s hardware of choice is BeagleBoard-xM.
Ruslan Bukin experiments with Exynos4412 and Thomas Skibo reported about FreeBSD running on Zedboard (Xilinx Zynq-7000).

But what about devices/platform we have in tree? I have limited knowledge about some platforms so here is summary of the ones I’m aware of. If you have more information on any of these targets (or any other ARM-related projects) – let me know, I’ll update post.

  • BCM2835 Raspberry Pi the most accessible and therefore the one that gets the most exposure and testing. Pretty stable, considering. Supported devices: USB, network, MMC, GPIO, framebuffer, GPU. The rest is on ToDo list. VCHIQ driver is BSD-licensed now and I’m planning on getting it to sys/contrib. Userland bits of OpenGL ES should be added as a port though.
  • (update) LPC32x0 No first hand experience but judging by the code it supports MMC, FB, GPIO and USB
  • Marvel Armada XP I don’t have information about this one, sorry
  • Nvidia Tegra2 Just barebone boot stuff.
  • TI AM335x Examples: BeagleBone, TI Sitara EVM. Network was reported working but unstable on BeagleBone. USB is not supported. Haven’t tested GPIO yet.
  • TI OMAP3 Example: BeagleBoard-xM. See Alexander Dutkowski’s project
  • TI OMAP4 The hw I have – Pandaboard ES. Supported devices: USB, network, MMC, GPIO. Some issues with L2 cache
  • Versatile Platform Board Exists only as emulation target for QEMU. Supported hardware: PCI, network, framebuffer. Seems to be fairly stable, no extensive testing performed.

BeagleBone, PandaBoard ad Raspberry Pi images can be built using Tim Kientzle’s scripts.

Not really stellar list of supported peripherals I’d say. I tend to blame several things.

First – experimental and unstable state of FreeBSD/armv6 in general. It’s no fun adding new hardware support when you’re not confident in underlying subsystems stability. “I flush cache for this TX descriptor but is it really gets flushed?”. Been there, no fun at all. That’s why I believe task #1 for nearest future is maximum performance and rock-solid stability of what we have.

Then there is the case of syscons. It’s old, it’s inflexible and it’s mostly i386-centric. Just until recently most of our so-called embedded targets were headless so there were no pressure from this side to reorganize things. My experience with coding two framebuffer drivers or trying to add PS/2 keyboard support on non-i386 platform was not very pleasant. It’s messy and there is a lot of code duplication. newsyscons project may be the way to go, I haven’t looked at it yet. We just need someone(tm) to finish it and get into the tree.

Fix these two issues should make bring-up process easier. It leaves us with question of GPU support. But it’s different story for different post…

Happy New Year, everybody!