I stopped working on this in February 2024 before having a fully working solution. More modern kernels are now available for the uConsole thanks to other members of the community. Start by reading this thread, and this GitHub repo
This page is likely outdated and may no longer be relevant
The uConsole by ClockworkPi is a handheld device based on the Raspberry Pi 4 Compute Module, featuring a built-in display, keyboard, and trackball to control the mouse. It looks like this:
The uConsole includes a pre-flashed SD card including a non-standard Linux Kernel. The standard instructions for installing the OS simply tell you to download their pre-generated image and flash your SD card with it: this also gives you the custom kernel.
This is fine for a lot of users, but raises some questions regarding how that kernel is made and what is different about it. Personally I don't want to use a kernel which a small company has made for me, especially if there is no transparency into the build process which is the situation here.
Worse still, the kernel version I was given on the SD card was outdated and I heard from others that updating the kernel prevented the built-in screen from working. I decided to spend some time researching their kernel modifications so that I could compile my own updated version.
First lets start by following the official instructions, which, for the Pi4 version, are:
git clone https://github.com/raspberrypi/linux.git cd linux wget https://raw.githubusercontent.com/clockworkpi/uConsole/master/Code/patch/cm4/20230630/0001-patch-cm4.patch git reset --hard 3a33f11c48572b9dd0fecac164b3990fc9234da8 git apply 0001-patch-cm4.patch KERNEL=kernel8 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig KERNEL=kernel8 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j2 mkdir ./modules rm -rf ./modules/* INSTALL_MOD_PATH=./modules make modules_install rm modules/lib/modules/*/build rm modules/lib/modules/*/source
To break this down, the above commands cause the following to happen:
Essentially this means it is not possible to run any kernel other than 5.10.17 using these instructions. Further research and effort is required for the end user (me, in this situation) to get a new kernel.
Before we can build a newer kernel, we need more information about the patch that ClockworkPi supplies. Looking through it, we can see that it adds the driver source code for the display used in 2 ClockworkPi devices (including the uConsole), configures some pin numbers for the Pi, configure the power management chip, and change some defaults for the Pi4.
The kernel build process uses a configuration file which can be generated using this command:
KERNEL=kernel8 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig
This pulls in configuration from the bcm2711_defconfig file which contains good defaults for the Pi4. Weirdly, the patch provided by ClockworkPi doesn't include the manual changes made to this file and instead includes the final auto-generated config file. This means that the patch will almost never be compatible with any version aside from 5.10.17 only. Luckily this can be reverse engineered easily so we can use it on other versions.
I determined what changes they had (manually) made to their build config by generating the config using the vanilla 5.10.17 kernel and then the patched kernel. It gave me this output:
diff .config-linux .config-uconsole-working 25c25 < CONFIG_LOCALVERSION="-v8" --- > CONFIG_LOCALVERSION="-v8-JHEWITT" 1853c1853 < CONFIG_REGMAP_I2C=m --- > CONFIG_REGMAP_I2C=y 2552,2554c2552,2554 < CONFIG_PPP=m < CONFIG_PPP_BSDCOMP=m < CONFIG_PPP_DEFLATE=m --- > CONFIG_PPP=y > CONFIG_PPP_BSDCOMP=y > CONFIG_PPP_DEFLATE=y 2556c2556 < CONFIG_PPP_MPPE=m --- > CONFIG_PPP_MPPE=y 2559,2560c2559,2560 < CONFIG_PPPOE=m < # CONFIG_PPTP is not set --- > CONFIG_PPPOE=y > CONFIG_PPTP=m 2562,2563c2562,2563 < CONFIG_PPP_ASYNC=m < CONFIG_PPP_SYNC_TTY=m --- > CONFIG_PPP_ASYNC=y > CONFIG_PPP_SYNC_TTY=y 2565c2565 < CONFIG_SLHC=m --- > CONFIG_SLHC=y 3032a3033 > CONFIG_INPUT_AXP20X_PEK=y 3251c3252 < CONFIG_I2C_BCM2835=m --- > CONFIG_I2C_BCM2835=y 3366a3368 > # CONFIG_PINCTRL_AXP209 is not set 3529a3532,3535 > CONFIG_CHARGER_AXP20X=m > CONFIG_BATTERY_AXP20X=m > CONFIG_AXP20X_POWER=m > # CONFIG_AXP288_FUEL_GAUGE is not set 3802c3808,3809 < # CONFIG_MFD_AXP20X_I2C is not set --- > CONFIG_MFD_AXP20X=y > CONFIG_MFD_AXP20X_I2C=y 3923a3931 > CONFIG_REGULATOR_AXP20X=y 4825a4834,4835 > CONFIG_DRM_PANEL_CWD686=m > CONFIG_DRM_PANEL_CWU50=m 4971a4982 > CONFIG_BACKLIGHT_OCP8178=m 6513a6525,6526 > CONFIG_AXP20X_ADC=m > # CONFIG_AXP288_ADC is not set 6535c6548 < # CONFIG_TI_ADC081C is not set --- > CONFIG_TI_ADC081C=m 7560c7573 < CONFIG_CRYPTO_LIB_ARC4=m --- > CONFIG_CRYPTO_LIB_ARC4=y 7616c7629 < CONFIG_CRC_CCITT=m --- > CONFIG_CRC_CCITT=y
Naturally the “JHEWITT” part was added by me, this was so I could differentiate the uConsole kernel with the vanilla kernel. The other changes were made by ClockworkPi.
There are some very unexpected changes here. Interestingly they made it so on their kernel some things related to VPNs and networking would be in the kernel rather than in modules. I'm not yet sure if or why this change is needed. The following parts are the most important (and the rest may or may not be important, still be to determined):
CONFIG_REGMAP_I2C=y CONFIG_INPUT_AXP20X_PEK=y CONFIG_CHARGER_AXP20X=m CONFIG_BATTERY_AXP20X=m CONFIG_AXP20X_POWER=m CONFIG_MFD_AXP20X=y CONFIG_MFD_AXP20X_I2C=y CONFIG_REGULATOR_AXP20X=y CONFIG_DRM_PANEL_CWU50=m CONFIG_BACKLIGHT_OCP8178=m CONFIG_AXP20X_ADC=m CONFIG_TI_ADC081C=m CONFIG_CRYPTO_LIB_ARC4=y CONFIG_CRC_CCITT=y
This ensures the display driver is included in the kernel as a module, in addition to ensuring the kernel supports their other custom hardware. Note in the snippet above I removed the display for their Devterm device which is unused on the uConsole. It seems to make no difference at all whether or not this is included.
Pasting this text above into your bcm2711_defconfig file should cause the build process to ensure the important custom parts of the kernel are actually included when compiled.
Also in the patch file were changes to various source files. I did the following in order to ensure all of the changes were included:
git apply --reject --whitespace=fix 0001-patch-cm4.patch
This will work on any kernel version and create .rej files containing all of the merge conflicts. If the kernel maintainers edited part of the source which ClockworkPi also modified, you will need to manually choose what to keep (tip: you probably want to keep the ClockworkPi change unless you know what you are doing). I suggest also opening their patch alongside your editor to see what exactly they wanted the file to look like.
Luckily ClockworkPi did not make many changes to existing files, since most of their changes are in their own files. You should only see a few conflicts in .rej files and most of it is related to the Makefiles. If you are targeting a kernel that is not 5.10.17, you should revert their config file change with:
git checkout -- arch/arm64/configs/bcm2711_defconfig
Once you've done that, paste in the changes listed above (starting with CONFIG_XXXXXXX=) for your config in bcm2711_defconfig.
Ensure you delete each .rej file once you have addressed the conflict it is referring to.
In my experience compiling on 6.1 kernels, I ran into a compilation error in their display drivers. I made the following change which fixed the compilation but the resulting kernel has a non-functioning display now:
static int cwu50_remove(struct mipi_dsi_device *dsi) { struct cwu50 *ctx = mipi_dsi_get_drvdata(dsi); mipi_dsi_detach(dsi); drm_panel_remove(&ctx->panel); return 0; }
to this:
static void cwu50_remove(struct mipi_dsi_device *dsi) { struct cwu50 *ctx = mipi_dsi_get_drvdata(dsi); mipi_dsi_detach(dsi); drm_panel_remove(&ctx->panel); }
Kernel 5.10.x versions work fine and this file does not need to be changed unless you are targeting a kernel newer than 5.10, such as 6.1.
I made the same change to their other display (cwd686) but excluded it from some of my kernel builds. This display is not used on the uConsole and it doesn't seem to make a difference whether you include it or not.
I personally found the ClockworkPi instructions to be slightly lacking, so here's what I came up with:
These instructions are designed for Debian based distros.
(If you did not already do so, edit bcm2711_defconfig to include something unique as the CONFIG_LOCALVERSION= value: it will show up in uname -a on your new OS so you can verify your kernel is running)
sudo apt install crossbuild-essential-arm64 build-essential gcc-aarch64-linux-gnu flex bison libncurses-dev libssl-dev libelf-dev KERNEL=kernel8 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig make -j8 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs sudo env PATH=$PATH make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/media/user/rootfs/ modules_install sudo cp arch/arm64/boot/Image /media/user/bootfs/kernel8.img sudo cp arch/arm64/boot/dts/broadcom/*.dtb /media/user/bootfs/ sudo cp arch/arm64/boot/dts/overlays/*.dtb* /media/user/bootfs/overlays/ sudo cp arch/arm64/boot/dts/overlays/README /media/user/bootfs/overlays/
Finally edit /media/bootfs/config.txt to match what ClockworkPi suggests, I use this:
disable_overscan=1 dtparam=audio=on [pi4] max_framebuffers=2 [all] ignore_lcd=1 dtoverlay=dwc2,dr_mode=host dtoverlay=vc4-kms-v3d-pi4,cma-384 dtoverlay=devterm-pmu dtoverlay=devterm-panel-uc dtoverlay=devterm-misc dtoverlay=audremap,pins_12_13 dtparam=spi=on gpio=10=ip,np gpu_mem=128
I successfully used the information above to get Kernel 5.10.17 and 5.10.110 onto my fresh Raspberry Pi OS (2023-05-03-raspios-bullseye-arm64) but ran into issues with a 6.1 kernel. I am still working on finding the cause of the problem and will update this page when the problem is resolved.
I made an updated patch which you can use to make a 5.10.110 kernel. Follow the instructions above or as documented by ClockworkPi but use commit hash 8e1110a580887f4b82303b9354c25d7e2ff5860e and my patch.
That should let you easily compile a more modern kernel than what ClockworkPi officially supports without much more effort from you.
I will continue working on this so we can have a nicer way of building the kernel without resorting to patches based upon specific kernel versions.