ROCK Pi X - Custom/tuned Linux kernel

I started putting together a custom Linux kernel for the ROCK Pi X.

The kernel:

  • Is specifically tuned for Intel Silvermont processors, including Cherry Trail (Z8350)
  • Is built with the newest version of GCC compiler (10.2.0)
  • Is largely stripped down (tuned for embedded processors by removing server features like NUMA-awareness, only contains kernel modules for hardware components on this device, etc.)
  • Is built from the latest stable Linux kernel source code to date (Linux 5.9.8)

In short, it is about as bleeding-edge as you can get and about as optimized as possible for this SBC. Based on community feedback and testing, I may add more things where sensible and as time permits.

I was able to drive a 4k display with it over HDMI, connect to my wireless router and play YouTube videos, view SBC power consumption via reading of the onboard AXP288 PMIC, launch a virtual machine (VM), etc… So, it supports most, if not all, directly embedded hardware components of the device.

You can download and install the kernel as follows:

dpkg -i linux-image-5.9.8_5.9.8-1_amd64.deb firmware-rockpix_20200907-1_amd64.deb

Known issues at this time:

  • Bluetooth works, but performance is very “choppy”. If you use it for audio, it will stutter in and out, for example. Suspect firmware problem?
  • [fix in progress] WLAN MAC changes often when soft rebooting the system. When the SBC is hard rebooted, it always defaults to the expected MAC address again. Suspect firmware problem? Can likely workaround by adminstratively setting the WLAN MAC using iw if you need the MAC address to be consistent.

Reproducing builds (patches on top of prescribed kernel version from



The wifi/bt firmware can be downloaded from:

WiFi firmware version is fw_bcm43455c0_ag., with Kr00k vulnerability fix.


Could you release the instructions for building this, as I’d like to use it with Arch linux, and I’d rather not do double effort.

How you would build on each distro is different.

The kconfig is mostly what you need for building with Arch, and that can be extracted from the deb file with ar(1).

This is the only patch I used on the Linux 5.8.5 source code itself so far (to be used in conjunction with the supplied kconfig):

--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -336,7 +336,7 @@
 	def_bool y
 	def_bool y
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -124,8 +124,8 @@
         cflags-$(CONFIG_MCORE2) += \
                 $(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
-	cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \
-		$(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
+	cflags-$(CONFIG_MATOM) += $(call cc-option,-march=silvermont) \
+		$(call cc-option,-mtune=silvermont,$(call cc-option,-mtune=generic))
         cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
         KBUILD_CFLAGS += $(cflags-y)

Most excellent, thanks! Glad to see WiFi will be very secure in addition to having the coex parameters for this SBC.

This is fantastic, thanks for your contribution. What distribution(s) have you tested this with?

Right now, I have only tested with Debian/GNU Linux. However, due to how the package was crafted and due to the fact it has no dependencies, this package and kernel should work fine on any system uses dpkg to install packages (Ubuntu, Elementary, Pop!, Mint, etc.)

If there are issues with the kernel, it is most likely due to a feature that was stripped out of the kernel. Maybe user wants to use a particular filesystem or something… that’s easy to add back into the kconfig and rebuild on a case-by-case basis, though.

Some good news today. Tried WiFi/BT firmware from Jack. I was able to connect to some bluetooth headphones and play music out of them now. However, audio was “choppy”… I am not sure of the cause yet.

WiFi performance is pretty darn good, though. I see about 100mbps up/down using the (smaller) antenna included, no problem:

$ speedtest-cli 
Retrieving configuration...
Testing from Verizon Fios (REDACTED)...
Retrieving server list...
Selecting best server based on ping...
Hosted by DediPath (REDACTED) [35.44 km]: 13.071 ms
Testing download speed................................................................................
Download: 88.06 Mbit/s
Testing upload speed......................................................................................................
Upload: 114.95 Mbit/s

Had some issues with WiFi, most issues seem resolved after cherry-picking more recent commits. New patch for WiFi:

Also added back code pages for other languages.

So far, only issues are related to BCM43455 chipset. I updated original post with the issues.

I’ll admit I don’t really have much experience building a kernel, but I guess now’s as good a time as any.

@jack - can you comment further on this?

Dynamic MAC is a deal breaker for us as some of our services require the MAC to never change. We must identify the boards somehow and MAC is the method we have picked.

Would be great if a BIOS/EFI update could fix this problem.


1 Like

WLAN MAC should be stored in the module itself, it might be the firmware issue. We will check on our side.

To my knowledge, best practice is not to trust the chipset PRNG.

Another suggestion I have, is to use modprobed-db to help trim down the exact modules that are needed for this board.

I think the hardware PRNG is fine. There’s rdrand accelerations on the CPU and the TPM also has a RNG (and both should be leveraged IMO). At the end of the day, all of this stuff and more should be getting mixed into the entropy pool – there’s not one source of entropy.

Thanks for the modprobed-db suggestion. It’s hard, because to a certain degree you have to anticipate what users might use that’s not necessarily loaded right now. SATA hats, USB peripherals, etc.

A lot of the optimizations were not necessarily trimming modules, too, but rather targeting uarch-specific items that cannot easily be detected by modprobed-db.

Updated to Linux 5.8.6 tonight.

I found issue with WLAN MAC changing. It is indeed firmware related. It is necessary to edit the contents of /lib/firmware/brcm/brcmfmac43455-sdio.txt (WLAN firmware NVRAM file) and replace macaddr= line with the MAC address of the WLAN interface observed the first time the Rock Pi X boots up from cold power cycle.

To put in simpler terms:

  • On warm reboots, the WLAN interface MAC address will be whatever is listed in the WLAN firmware NVRAM file.
  • On cold reboots, the WLAN interface MAC address will be whatever is “burned into the WLAN chip”.

Now that I have edited macaddr= in the WLAN firmware NVRAM file to the MAC address I usually see associated with my WLAN interface on cold boots, I have been able to reboot at least a dozen times with no changing WLAN MAC!

I will add a postinst script to the firmware package in the first post to update the macaddr= line in the WLAN firmware NVRAM file when installing the package. But I really don’t like this part of the WLAN firmware, it admittedly seems kind of silly…

Hello tjcs90,

What happens when you remove the macaddr= parameter from the NVRAM file?
Does the system always default to the MAC which is saved on the wifi chipset?


wlan does not initialize when doing that. I tried it.

I guess the workaround would be to create a system startup script which would:

a) load the ‘brcmfmac’ driver

b) check the MAC which is saved on the wifi chipset:
cat /sys/class/net/wlan0/address

c) update the NVRAM file (using ‘echo’ or ‘sed’) with the chipset MAC

d) reload the ‘brcmfmac’ driver

This is a system level solution which should work for all RockPi X boards.
Individual users could always put certain MAC in their NVRAM file and do not bother with creating the startup script.

Unless there is a more elegant solution which could be implemented directly on the firmware level. That would be preferred.

Seomething like:

I tried to install your custom kernel from .deb on my Lubuntu 20.04 system, but it was not loading at all, I had an error message regarding EFI compliancy.

I also had issues installing the firmware package, it was conflicting with the default one.

What kind of system do you recommend for testing this kernel? From what I’ve understood I2S on 40-pin header should be working.