FalcoGer
Posts: 37
Joined: Mon Jul 09, 2018 6:35 am

Ubuntu no /dev/gpiomem - how to create?

Wed Aug 15, 2018 12:15 pm

The way I understand it is that on raspbian there is a device /dev/gpiomem with 0660 and owner root:gpio, set by an udev rule similar to this:
(I have no clue about udev rules, I copied that from the rpi-gpio-common package)

Code: Select all

SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="dialout", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"
However on my Ubuntu installation there is no such device. /dev/gpiomem simply doesn't exist.
Running programs that use the bcm2835 library ( http://www.airspayce.com/mikem/bcm2835/ ) as root works perfectly fine. Trying to run them as non root gives permission denied.

While I could give elevated permissions to /dev/mem this seems like a way to invite pain and suffering.
I could of course always run my program as root, but that of course is a major security risk, too.

So my prefered way of handling this is to install the gpio device drivers that add the gpiomem device to /dev/
After looking for quite some time, I have found nothing much of interest

particularly I have found this: https://www.theseus.fi/bitstream/handle ... yen_Vu.pdf
which doesn't really help
and this: https://github.com/torvalds/linux/tree/ ... ivers/gpio
which I don't know what to do with.

Oddly enough I have a /dev/gpiochip0 device. I don't know what that is.
I found this: https://fosdem.org/2018/schedule/event/ ... _for_linux. (PDF extention missing)
I don't know if it's a substitute or equal or what. I don't wanna write an entirely new driver to port this over.
also this: https://elixir.bootlin.com/linux/latest ... /sysfs.txt

Any help would be welcome.

On a side note:

Another thing. I tried installing the python3-rpi.gpio package. Trying to import RPi.GPIO results in:
"Can only be imported on a raspberry pi".
I am on a pi, but it doesn't seem to care.
I don't use the python stuff though, so that's not a priority. I just installed the package because I thought it might install the gpiomem device for me.

for anyone interested, I use bcm2835 library with a mono driven dot net project with raspberrypidotnet
https://github.com/cypherkey/RaspberryP ... ryPiDotNet
Last edited by FalcoGer on Thu Aug 16, 2018 2:10 pm, edited 3 times in total.

feelslikeautumn
Posts: 307
Joined: Wed Aug 09, 2017 9:51 pm

Re: Ubuntu no GPIO device

Wed Aug 15, 2018 2:21 pm

Have a look at the raspberrypi-sys-mods package?

If something doesn't work, a good place to look is the Ubuntu flavour maker source code. That often shows the extra packages that are needed.

FalcoGer
Posts: 37
Joined: Mon Jul 09, 2018 6:35 am

Re: Ubuntu no GPIO device

Thu Aug 16, 2018 6:09 am

feelslikeautumn wrote: Have a look at the raspberrypi-sys-mods package?

If something doesn't work, a good place to look is the Ubuntu flavour maker source code. That often shows the extra packages that are needed.
That package doesn't seem to be in the default repository. I did find it here though: https://github.com/RPi-Distro/raspberrypi-sys-mods
Guess I have to compile that myself and hope it does install the kernel module I want.

Edit: I don't see anything I need in there.
Edit2: I found this: https://elinux.org/RPi_GPIO_Code_Samples
The c code looks useful, and I might be able to write my own kernel module to allow users to access just that bit of memory. But I kinda need a resolution quickly.
I was thinking about something like this:
character device, group root:gpio, access crw-rw---- (660)
File read 0x00 for the first 0x20200000 bytes, then for the next 4096 bytes return what's read from /dev/mem, then return 0x00 again.
does that make sense?

FalcoGer
Posts: 37
Joined: Mon Jul 09, 2018 6:35 am

Re: Ubuntu no GPIO device

Thu Aug 16, 2018 12:15 pm

It does not make sense. But I found this kernel module:
https://github.com/raspberrypi/linux/bl ... -gpiomem.c

I compiled it with a custom Makefile:

Code: Select all

obj-m += bcm2835-gpiomem.c

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
I coped the kernel object (.ko) file to /lib/modules/$(shell uname -r)/kernel/drivers/gpio/

loading it with insmod doesn't produce the /dev/gpiomem device of course.
I added the udev rule file in /lib/udev/rules.d/60-rpi.gpio-common.rules

Code: Select all

SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="dialout", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"
I follow this guide: https://askubuntu.com/questions/299676/ ... ed-on-boot
As sudo:

Edit the /etc/modules file and add the name of the module (without the .ko extension) on its own line. On boot he kernel will try to load all the modules named in this file.

Copy the module to a suitable folder in /lib/modules/`uname -r`/kernel/drivers. In my case this was /lib/modules/`uname -r`/kernel/drivers/pci. This will place the module in modprobe's database. I don't know if this can be a link.

Run depmod. This will find all the dependencies of your module.

At this point, I rebooted and then run lsmod | grep module-name to confirm that the module was loaded at boot.

See the man pages for modprobe, lsmod, and depmod for more information.
I then redid the dependency map

Code: Select all

sudo depmod -v
then I load the kernel module at boot time with /etc/modules-load.d/gpiomem.conf

Code: Select all

bcm2835-gpiomem
reboot aaaaaaand:
the module is loaded. (lsmod shows it)
however the device /dev/gpiomem is still not there.

I'm at a complete loss. I'll do a workaround, dumping all pins into a file in /run/ tmpfs every few hundred miliseconds...
any sort of advice would be greatly appreciated

edit: I read up on udev rules here: http://reactivated.net/writing_udev_rules.html
And sure enough it ought to create that device for me. yet it does not.

FalcoGer
Posts: 37
Joined: Mon Jul 09, 2018 6:35 am

Re: Ubuntu no /dev/gpiomem - how to create?

Tue Aug 21, 2018 7:42 am

Getting a bit desperate here. I'm gonna cross compile this kernel:
https://github.com/raspberrypi/linux/tree/rpi-4.18.y

and hope for the best.

Edit:
been fiddling with the cross compiler for a while now. and it doesn't like me

senswet
Posts: 1
Joined: Mon Dec 03, 2018 4:50 pm

Re: Ubuntu no /dev/gpiomem - how to create?

Mon Dec 03, 2018 4:55 pm

Did you solve your problem?
I have the same, the gpiomem module loads, but /dev/gpiomem device is not created.

FalcoGer
Posts: 37
Joined: Mon Jul 09, 2018 6:35 am

Re: Ubuntu no /dev/gpiomem - how to create?

Mon Jan 28, 2019 9:16 am

senswet wrote: Did you solve your problem?
I have the same, the gpiomem module loads, but /dev/gpiomem device is not created.
I eventually ended up using a 64bit compiled version of the raspbian kernel by sakaki ( https://github.com/sakaki-/bcmrpi-kernel ), I load this kernel with the raspberry pi build in boot loader.

I wrote this script to update the kernel from git:

Code: Select all

#!/bin/bash

if [[ $EUID -ne 0  ]]; then
	echo "This script must be run as root"
	exit 1
fi

KERNEL_GIT_USERNAME="sakaki-"
KERNEL_GIT_PROJECTNAME="bcmrpi3-kernel"

KERNEL_GIT_NAME="$KERNEL_GIT_USERNAME"/"$KERNEL_GIT_PROJECTNAME"


# usage:
# get_latest_release git path eg. "sakaki-/bcmrpi-kernel"
get_latest_release()
{
	wget -q --output-document=- "https://api.github.com/repos/$1/releases/latest" |
		grep '"tag_name":' |
		sed -E 's/.*"([^"]+)".*/\1/'
}

# download the archive
echo downloading "$KERNEL_GIT_NAME"
VERSION=$(get_latest_release $KERNEL_GIT_NAME)
echo version "$VERSION"
FILENAME="$KERNEL_GIT_PROJECTNAME"-"$VERSION".tar.xz
echo file "$FILENAME"
# spacer
echo
wget -c https://github.com/"$KERNEL_GIT_NAME"/releases/download/"$VERSION"/"$FILENAME"
echo

# make backup
echo Making backup
cp -vi /boot/kernel8.img /boot/kernel8.img-$(uname -r)
cp -vi /boot/System.map /boot/System.map-$(uname -r)
cp -vi /boot/bcm2710-rpi-3-b-plus.dtb /boot/bcm2710-rpi-3-b-plus.dtb-$(uname -r)
cp -vi /boot/bcm2710-rpi-3-b.dtb /boot/bcm2710-rpi-3-b.dtb-$(uname -r)
cp -vi /boot/bcm2837-rpi-3-b.dtb /boot/bcm2837-rpi-3-b.dtb-$(uname -r)
cp -vi /boot/config /boot/config-$(uname -r)

echo
echo
# check with user
while true; do
	read -p "Archive downloaded. Are you sure you want to extract it to / ? [Y/N]: " -n 1 -r
	echo
	case $REPLY in
		[Yy]* )
			# extract archive
			tar -x -J -v -f "$FILENAME" -C /
			break;;
		[Nn]* )
			exit;;
		* )
			echo "Please answer Y or N";;
	esac
done

echo
echo

# done
echo "All done. Reboot to use new kernel."


Return to “Other”