Mike's blog about random software stuff

Hacking the kernel with Yocto

For the past few weekends I’ve been playing with my stm32mp157f-dk2 board, trying to use the GPIO expansion connector.

I didn’t really have any use for the GPIO, but the goal was just to control it. Well, actually my main goal was to learn a bit more about modifying the device tree (DT), and adding the GPIO controller to the device tree worked well as a project for that.

First attempts

I started by watching a few lectures by Bootlin and Digikey, and reading the ST wiki and Yocto manuals.

First I used the same approach as in the Digikey video, and created a patch to the DT. At first, I created a patch for the dtsi (device tree source include file) file I wanted to modify, and added it to a recipe just like in the Digikey tutorial.

The patch I needed and the file I wanted to modify was found by reading the ST wiki on controlling GPIO in kernel space. The DT file I created the patch for was named stm32mp151.dtsi. I also added the dummy driver to a new recipe in my Yocto playground layer.

After many failed attempts that included modifying the wrong file, adding the patched code to a wrong place in the file and not getting the patch installed due to typos, I was finally able to get the new kernel code running.

The default wiki code blinked a green LED in the board. This was good progress, but not yet what I wanted to do. Next I wanted to find out how do I need to modify the example DT code to control the GPIO14 in the GPIO expansion slot. The GPIO14 was connected to the STM32 pin PB10. I’m not yet sure if this was just by pure luck, but I attempted changing the gpioa 14 from the example code to gpiob 10 based on the pin name. I added the changes, measured the GPIO pin with a multi-meter, and noticed that it worked!

I was happy to see that everything that I wanted to work was working, but I felt like I wanted to try doing this in another way too.

Forking the BSP layer and the Linux kernel

Note: This is my first attempt at adding a custom kernel version to a Yocto build. If you’re for some reason learning how to do this by following my blog, please don’t assume that this is some best practice way of doing this

I wanted to try working with a custom version of the kernel instead of just patching it. I forked a GitHub mirror of the Linux kernel and checked out to version 6.1.28 which was used by the meta-st-stm32mp layer. I added the ST patches directly to this version of the kernel, so the patches from the BSP could be removed. I also added my DT patch directly to the kernel source.

I also forked the ST BSP layer and modified the recipes-kernel to use my version of the kernel

I was almost surprised how easy it was to hack my kernel version to the layer, when usually making modifications to Yocto layers seem to take me a couple of weekends of googling and reading the docs. I guess I’m getting better at this, or (more likely) have done something terribly wrong and will start to see strange bugs and errors when I try to add more modifications in the future. Well, we’ll see if that happens in the future.

After deleting the tmp directory of my Yocto build, I was able to build the new kernel from my GitHub source. I flashed the image to an SD card, booted my board, and ran the command modprobe dummy_driver. The green LED started blinking again, and I was pretty happy!

Finally, I changed the Green LED pin back to the GPIO14 pin in my custom kernel DT file, compiled my image again, and was able to measure the voltage changing again in the GPIO pin I wanted.

I guess next I’ll just need to find some device I want to control with GPIO, and write some driver for it.

Mike