GPIO Kernel Module
#1
So, I would like to use the pinephone to learn more about device driver kernel modules in linux and device nodes. My main goal would be to write a kernel module that I can load, to control an LED in user space but I know, that's a long way to go. Smile As you can see, there's going to be some very naive things I'm going to say, so please bear with me... I'd really like to know how this works!

I am fairly new to the subject and by now I was only developing firmware for STM32 devices and some software backend things, but no embedded linux at all. On a microcontroller I would look up on which GPIO pin the LED is connected, then search the programming manual for the registers that configure and controle the pin and write to those register addresses.

Still, I think I know at least SOME things about how the linux kernel works. Correct me if I'm wrong, but I suppose there is a kernel module which is basically executable machine code and does the "writing-to-register-addresses"-part? This module can be "loaded" in order to control a peripheral. The module then uses files (or nodes) to offer some sort of interface to applications in user space, in order to easily control the peripheral. These files are located either in /sys or /dev (I guess?). Is that kind of true so far? I already saw the files that can be used to turn an LED on or off in /sys/platform/leds/leds/.

If the above isn't too far off, I have many follow-up questions, but one after the other.  Smile
It would be really kind if someone would like to take time and provide some inside knowledge and just help me find my way here!
  Reply
#2
(03-09-2020, 03:10 PM)Foxchild Wrote: So, I would like to use the pinephone to learn more about device driver kernel modules in linux and device nodes. My main goal would be to write a kernel module that I can load, to control an LED in user space but I know, that's a long way to go. Smile As you can see, there's going to be some very naive things I'm going to say, so please bear with me... I'd really like to know how this works!

I am fairly new to the subject and by now I was only developing firmware for STM32 devices and some software backend things, but no embedded linux at all. On a microcontroller I would look up on which GPIO pin the LED is connected, then search the programming manual for the registers that configure and controle the pin and write to those register addresses.

Still, I think I know at least SOME things about how the linux kernel works. Correct me if I'm wrong, but I suppose there is a kernel module which is basically executable machine code and does the "writing-to-register-addresses"-part? This module can be "loaded" in order to control a peripheral. The module then uses files (or nodes) to offer some sort of interface to applications in user space, in order to easily control the peripheral. These files are located either in /sys or /dev (I guess?). Is that kind of true so far? I already saw the files that can be used to turn an LED on or off in /sys/platform/leds/leds/.

If the above isn't too far off, I have many follow-up questions, but one after the other.  Smile
It would be really kind if someone would like to take time and provide some inside knowledge and just help me find my way here!

You want to reimplement leds-gpio?

https://www.kernel.org/doc/Documentation...s-gpio.txt

https://elixir.bootlin.com/linux/v5.5.8/...eds-gpio.c

Your overall understanding is correct. the sysfs api lets userspace pass parameters into your kernel driver. There you can then manipulate registers. Register sets of functional blocks on the soc, such as a gpio controller, are typically memory mapped by the soc (memory controller?).
  Reply
#3
That is very good to know, thank you! Smile

Well, yes I'd like to reimplement leds-gpio, I think. I guess a very simple LED driver would be a good learning experience for a beginner.

So, I have a question... When I write to "brightness" in /sys/devices/platform/leds/leds/pinephone:blue:user/ (Ubuntu Touch), then the brightness can be modified. Which, I assume, is a value that is used by the leds-gpio module and written in the corresponding memory mapped register. So, why is there no leds-gpio module present when I execute lsmod?
  Reply
#4
(03-09-2020, 05:16 PM)Foxchild Wrote: That is very good to know, thank you! Smile

Well, yes I'd like to reimplement leds-gpio, I think. I guess a very simple LED driver would be a good learning experience for a beginner.

So, I have a question... When I write to "brightness" in /sys/devices/platform/leds/leds/pinephone:blue:user/ (Ubuntu Touch), then the brightness can be modified. Which, I assume, is a value that is used by the leds-gpio module and written in the corresponding memory mapped register. So, why is there no leds-gpio module present when I execute lsmod?


Maybe the kernel module is built-in? What does


Code:
zgrep -i led /proc/config.gz

say?


Before you ask:

A module has an init() function that registers the driver with the kernel proper. It is executed if the module is built in or when the module is insmod'ed. The driver informs the kernel in this frunction for what peripherals it is in charge of.

If the kernel is aware of a peripheral for this driver then the kernel is calling the driver's probe() function. In this function, the driver would set in your example the sysfs callback functions.

There are discoverable busses (PCI, USB) and the kernel knows the peripherals. For non-discoverable buses, the kernel learns the peripherals from the device tree. See my first link.
  Reply
#5
Code:
# CONFIG_PSI_DEFAULT_DISABLED is not set
CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y
CONFIG_MEMCG_SWAP_ENABLED=y
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
CONFIG_NETFILTER_XT_TARGET_LED=m
CONFIG_BT_LEDS=y
CONFIG_MAC80211_LEDS=y
CONFIG_RFKILL_LEDS=y
# CONFIG_LED_TRIGGER_PHY is not set
CONFIG_RT2X00_LIB_LEDS=y
CONFIG_INPUT_LEDS=y
# CONFIG_KEYBOARD_GPIO_POLLED is not set
CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
# CONFIG_BACKLIGHT_QCOM_WLED is not set
# CONFIG_HID_LED is not set
# CONFIG_USB_LED_TRIG is not set
# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set
# Gadget/Dual-role mode requires USB Gadget support to be enabled
# CONFIG_USB_APPLEDISPLAY is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_CLASS_FLASH is not set
# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
# LED drivers
# CONFIG_LEDS_AN30259A is not set
# CONFIG_LEDS_BCM6328 is not set
# CONFIG_LEDS_BCM6358 is not set
# CONFIG_LEDS_CR0014114 is not set
# CONFIG_LEDS_EL15203000 is not set
# CONFIG_LEDS_LM3530 is not set
# CONFIG_LEDS_LM3532 is not set
# CONFIG_LEDS_LM3642 is not set
# CONFIG_LEDS_LM3692X is not set
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_LP3952 is not set
# CONFIG_LEDS_LP5521 is not set
# CONFIG_LEDS_LP5523 is not set
# CONFIG_LEDS_LP5562 is not set
# CONFIG_LEDS_LP8501 is not set
# CONFIG_LEDS_LP8860 is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_PCA963X is not set
# CONFIG_LEDS_DAC124S085 is not set
CONFIG_LEDS_PWM=y
# CONFIG_LEDS_REGULATOR is not set
# CONFIG_LEDS_BD2802 is not set
# CONFIG_LEDS_LT3593 is not set
# CONFIG_LEDS_TCA6507 is not set
# CONFIG_LEDS_TLC591XX is not set
# CONFIG_LEDS_LM355x is not set
# CONFIG_LEDS_IS31FL319X is not set
# CONFIG_LEDS_IS31FL32XX is not set
# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)
# CONFIG_LEDS_BLINKM is not set
CONFIG_LEDS_SYSCON=y
# CONFIG_LEDS_MLXREG is not set
# CONFIG_LEDS_USER is not set
# CONFIG_LEDS_SPI_BYTE is not set
# CONFIG_LEDS_TI_LMU_COMMON is not set
# LED Triggers
CONFIG_LEDS_TRIGGERS=y
# CONFIG_LEDS_TRIGGER_TIMER is not set
# CONFIG_LEDS_TRIGGER_ONESHOT is not set
CONFIG_LEDS_TRIGGER_DISK=y
# CONFIG_LEDS_TRIGGER_MTD is not set
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
CONFIG_LEDS_TRIGGER_CPU=y
# CONFIG_LEDS_TRIGGER_ACTIVITY is not set
# CONFIG_LEDS_TRIGGER_GPIO is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
# iptables trigger is under Netfilter config (LED target)
# CONFIG_LEDS_TRIGGER_TRANSIENT is not set
# CONFIG_LEDS_TRIGGER_CAMERA is not set
CONFIG_LEDS_TRIGGER_PANIC=y
# CONFIG_LEDS_TRIGGER_NETDEV is not set
# CONFIG_LEDS_TRIGGER_PATTERN is not set
# CONFIG_LEDS_TRIGGER_AUDIO is not set
/proc/config.gz shows quite some LED configs. so those are the modules that are built into the kernel already?
Is it possible to load and unload built-in kernel modules? In other words, would it be possible to write a new LED driver and unload the old one?
  Reply
#6
(03-14-2020, 10:48 AM)Foxchild Wrote: /proc/config.gz shows quite some LED configs. so those are the modules that are built into the kernel already?
Is it possible to load and unload built-in kernel modules? In other words, would it be possible to write a new LED driver and unload the old one?

The leds-gpio.c driver is probably enabled by CONFIG_LEDS_GPIO. You can verify this by checking in https://elixir.bootlin.com/linux/v5.5.8/...vers/leds/ these files
  • Makefile: maps kernel configs to source files in this directory
  • Kconfig: explains the purpose of kernel configs in this directory
=m are loadable modules
=y are built-in modules

You can't easily remove built-in modules. Maybe there are some tricks. Google.

You can write your own led driver. Both, led-gpio and your driver should be able to co-exist. Nobody will trigger the led-gpio driver to access the gpio controller and even if someone does while your driver is accessing the gpio controller, no harm will be done to the hardware. I doubt you can put the controller in an inconsistent state, either.
  Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  PSA: WiFi driver is broken - Unload kernel module to save lots of power Trbl 3 3,997 06-23-2021, 02:28 AM
Last Post: Merc
Lightbulb Python3 - GPIO - controlling LED's etc bonce 1 2,160 06-06-2021, 09:43 AM
Last Post: bonce
  Ubports Wifi Module not Returning Networks acohl 4 4,414 04-21-2021, 03:27 AM
Last Post: NinjaDino29
  Mainline kernel repo hns 5 7,294 02-15-2020, 08:47 AM
Last Post: hns

Forum Jump:


Users browsing this thread: 1 Guest(s)