Simulate GPIO pins on Linux with gpio_mockup module

Recently I wanted to automate a test suite which takes inputs from GPIO pins. This is a little guide I've put together from various sources on how to compile the gpio_mockup kernel module and use it to simulate virtual GPIO pins.

First, you need to fetch the kernel sources for your particular kernel. Your distribution may provide a package for this, but I prefer just downloading it from kernel.org. Find your kernel version using uname -r. The output will look something like this: 6.5.9-arch2-1. Download the respective kernel source version:

wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.5.9.tar.xz
tar xf linux-6.5.9.tar.xz
This should create a directory "linux-6.5.9". You can also clone the git repository and get the needed version but I prefer downloading a tarball, as it saves bandwidth. Next, make sure you have a clean work tree and get a config file from your current kernel:
make mrproper
zcat /proc/config.gz > .config
make oldconfig
make EXTRAVERSION=-arch2 LOCALVERSION=-1 modules_prepare
cp /usr/lib/modules/6.5.9-arch2-1/build/Module.symvers .
Note the EXTRAVERSION variable: it is recommended to set it according to output of uname -r. Since our version was 6.5.9-arch2-1, we set it to -arch2. Similarly, set LOCALVERSION according to your kernel version, it is the last component of the version string, in this case: -1. If the Module.symvers file is missing from your filesystem, make sure you have installed the necessary package (usually it is called linux-headers).

I prefer to have a separate build directory when making modules, it helps understand what is really happening.

mkdir ~/gpio-mockup # our build directory, can be anywhere
# copy module from linux kernel source to our directory
cp drivers/gpio/gpio-mockup.c drivers/gpio/gpiolib.h ~/gpio-mockup
cd ~/gpio-mockup
# This line is all that's needed for building
echo "obj-m += gpio-mockup.o" > Makefile
# The argument to -C should be the path to your downloaded kernel directory
make -j -C ~/linux-6.5.9/ M=$(pwd) modules

If all goes well, you should see a gpio_mockup.ko file appear in your build directory.

Running the gpio_mockup module

To load your compiled module and create a GPIO device with 8 lines, use insmod (you will need root permissions for this step)

insmod ~/gpio-mockup/gpio-mockup.ko gpio_mockup_ranges=-1,8
You should see the new virtual GPIO device appear as /dev/gpiochip0 or similar. For actually toggling the new GPIO device, run
echo 1 >/sys/kernel/debug/gpio-mockup/gpiochip0/3
where 1 is the value you want to set (1 means on, 0 means off) gpiochip0 is the chip name and 3 is the line you want to toggle. You can verify the changes in the GPIO state with gpiomon:

# gpiomon /dev/gpiochip0 {0..7}
event:  RISING EDGE offset: 3 timestamp: [   58276.141833840]