March 21, 2017 - Mauro Carvalho Chehab

How to use V4L2 Cameras on the Raspberry Pi 3 with an Upstream Kernel

A V4L2 staging driver for the Raspberry Pi (RPi) was recently merged into the Linux kernel 4.11. While this driver is currently under development, I wanted to test it and to provide help with V4L2-related issues. So, I took some time to build an upstream kernel for the Raspberry Pi 3 with V4L2 enabled. This isn’t a complex process, but it requires some tricks for it to work; this article describes the process.

Prepare an Upstream Kernel

The first step is to prepare an upstream kernel by cloning a git tree from the kernel repositories. Since the Broadcom 2835 camera driver (bcm2835-v4l2) is currently under staging, it’s best to clone the staging tree because it contains the staging/vc04_services directory with both ALSA and V4L2 drivers:

There’s an extra patch that it is required for DT to work with the bcm2835-v4l2 driver:

You need to apply this to the git tree, in order for the vciq driver to work.

Prepare a Cross-Compile Make Script

While it’s possible to build the kernel directly on any RPi, building it using a cross-compiler is significantly faster. For such builds, I do this with a helper script, rather than “make,” to set the needed configuration environment.

Before being able to cross-compile, you need to install a cross compiler on your local machine; several distributions come with cross-compiler patches, or you can download an arm cross-compiler from In my case, I installed the toolchain at /opt/gcc-4.8.1-nolibc/arm-linux/.

I named my make script rpi_make; it not only sets the cross-compiler and defines a place to install the final output files. It has the following content:

Please note, you need to change the CROSS_CC_PATH var to point to the directory where you installed the cross-compiler. You may also need to change the CROSS_CC variable on this script to match the name of the cross-compiler. In my case, the cross-compiler is called /opt/gcc-4.8.1-nolibc/arm-linux/bin/arm-linux-gcc. The ROOTDIR contains the PATH where driver, firmware, headers and documentation will be installed. In this script it’s set to /devel/arm_rootdir.

Prepare a Build Script

There are a number of drivers that are needed in.config to build the kernel, and new configuration data may be needed as kernel development progresses. Also, although RPi3 supports 64-bit kernels, the userspace provided with the NOOBS distribution is 32 bits. There’s also a TODO for the bcm2835 mentioning that it should be ported to work on arm64. So, I opted to build a 32 bit kernel; this required a hack because the device tree files for the CPU used in the RPi3 (Broadcom 2837) exist only under arch/arm64 directory. So, my build procedure had to change the kernel build systems to build it for 32 bit as well.

Instead of manually handling the required steps, I opted to use a build script, called build, to set the configuration using the scripts/config script. The advantage of this approach is that it makes it easier to maintain as newer kernel releases are added.

Please note, the script had to disable the VC4 DRM driver and use the simplefb driver instead. This is because the firmware is currently not compatible with both the bcm2835-v4l2 driver and vc4 driver. Also, as I wanted the ability to test a bunch of V4L2 and DVB hardware on it so I’ll be enabling several media drivers.

In order to build the kernel, I simply call:

Install the New Kernel on the Raspberry Pi3

I used an RPi3 with a NOOBS distribution pre-installed on its micro-SD card. I used the normal procedure to install Raspbian on it, but any other distribution should do the job. In order to make it easy to copy the kernel to it, I also connected it to my local network via WiFi or Ethernet. Please note, I’ve not yet been able to get the WiFi driver to work with the upstream kernel. So, if you want to have remote access after running the upstream kernel you should opt to use the Ethernet port.

Once the RPi3 is booted, set it up to run an SSH server; this can be done by clicking on the Raspberry Pi icon in the top menu, and selecting the Raspberry Pi Configuration application from the Preferences menu.  Switch to the Interfaces tab, select SSH, and click the button.

Then, from the directory where you compiled the kernel on your local machine, you should run:

Another alternative is to setup the ssh server to accept root logins and copy the ssh keys to it, with

If you opt for this method, you could call this small script after building the kernel:

This logic is included in the rpi_make script. So, you can call:

Adjust the RPi Config to Boot the New Kernel

Changing the RPi to boot the new kernel is simple. All you need to do is to edit the /boot/config.txt file and add the following lines:

Use Serial Console on RPi3

Raspberry Pi3 has a serial console via its GPIO connector. If you want to use it, you’ll need to have a serial to USB converter capable of working with 3.3V. For it to work, you need to wire the following pins:

Pin 1 – 3.3V power reference
Pin 6 – Ground
Pin 8 – UART TX
Pin 10 – UART RX

This image shows the RPi pin outs. Once wired up, it will look like the following image.

Raspberry Pi 3 with camera module v2

Raspberry Pi 3 with camera module v2

You should also change the Kernel command line to use ttyS0, e. g. setting /boot/cmdline.txt to:

Use the bcm2835-v4l2 Driver

The bcm2835-v4l2 driver should be compiled as a module that’s not loaded automatically. So, to use it run the following command.

You can then use your favorite V4L2 application. I tested it with qv4l2, camorama and cheese.

Current Issues

I found some problems with upstream drivers on the Raspberry Pi 3 with kernel 4.11-rc1 + staging (as found on March, 16):

  • The WiFi driver didn’t work, despite brcmfmac driver being compiled.
  • The UVC driver doesn’t work properly: after a few milliseconds it disconnects from the hardware.

That’s it. Enjoy!

About Mauro Carvalho Chehab

Mauro is the upstream maintainer of the Linux kernel media and EDAC subsystems, and also a major contributor for the Reliability Availability and Serviceability (RAS) subsystems. Mauro also maintains Tizen on Yocto packages upstream. He works for the Samsung Open Source Group since 2013. Has worked during 5 years at the Red Hat RHEL Kernel team, having broad experience in telecommunications due to his work at some of the Brazilian largest wired and wireless carriers.

Linux / Open Source Infrastructure Linux Kernel / Raspberry Pi / V4L2 / Video / video4linux /


  • Dave Stevenson says:

    Thanks for the step-by-step guide – I’ll be following it myself when I get some spare cycles.

    The firmware from 18th March 2017 (3845593 at onwards should be compatible with the full VC4 display side, so no need for the simplefb mod.
    The AWB algorithm now checks if the QPUs (part of the V3D block) are available or not before jumping in and using them.

Leave a Reply to Dave Stevenson Cancel reply

Your email address will not be published. Required fields are marked *

Comments Protected by WP-SpamShield Anti-Spam