3

This post has a nice solution for using GPIO (and I2C) without root-privileges. This is useful if you're running an (web) app in a virtual environment as some ve-user, so as to shield off your whole Pi from that ve-user. But let's not digress.

The solution is basically that your ve-user must be member of gpio, and that root:gpio (not root:root) owns /dev/gpio.

pi@RPi2a ~ $ ls -l /dev/gpiomem  
crw------- 1 root root 245, 0 Jan  1  1970 /dev/gpiomem   # BEFORE  
pi@RPi2a ~ $ sudo chown root.gpio /dev/gpiomem && sudo chmod g+rw /dev/gpiomem  
pi@RPi2a ~ $ ls -l /dev/gpiomem  
crw-rw---- 1 root gpio 245, 0 Jan  1  1970 /dev/gpiomem   # AFTER  

The thing is: after a reboot, it's all back to the BEFORE situation. So how do you make it stick? Googling some, I found it's ruled by /etc/udev/rules.d/99-com.rules.
I guess (correctly?) root executes this at boot time. In it, there is:

PROGRAM="/bin/sh -c 'chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio; chown -R root:gpio /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio'"  
SUBSYSTEM=="input", GROUP="input", MODE="0660"  
SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660"  
SUBSYSTEM=="spidev", GROUP="spi", MODE="0660"  

So I inserted this into the first line, just before the closing '":

; chown root.gpio /dev/gpiomem && chmod g+rw /dev/gpiomem  

But that didn't work, nor did this variation: chown root:gpio /dev/gpiomem && chmod 660 /dev/gpiomem). So I've added that line to root's crontab (sudo crontab -e) like this:

@reboot chown root.gpio /dev/gpiomem && chmod g+rw /dev/gpiomem  

This works, but it looks to me like fighting the symptom rather than the cause. So I tried to find what resets the ownership on /dev/gpiomem:

sudo grep -rnw /etc/ -e "/dev/gpio"  

to no avail. Grepping the entire disk (/ instead of /etc/udev) breaks with grep: memory exhausted. It's a 256 MB Pi. I'm using, and want to stick to, Adafruit's Wheezy.

So the question is: what, where, how & why manipulates /dev/gpiomem?

Aurora0001
  • 6,357
  • 3
  • 25
  • 39
RolfBly
  • 609
  • 1
  • 9
  • 24

1 Answers1

1

what, where, how & why manipulates /dev/gpiomem?

Anything that has the correct permissions, so without the udev adjustment, any privileged process.

The adjustment is made by udevd, an init service daemon.

So I tried two add this to the first line

Beware those .rules files are not shell scripts. However, you can change this:

PROGRAM="/bin/sh -c 'chown -R root:gpio ....`

To the path to a shell script:

PROGRAM="/etc/udev/local_scripts/do_what_I_want.sh"

Which will make things a little tidier. I just made that path up (there is no /etc/udev/local_scripts directory); you can put it anywhere, but you must include an appropriate shebang and set $PATH in the script:

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin

However, the reason this will not work:

chown root.gpio /dev/gpiomem && chmod g+rw /dev/gpiomem

Is because when the PROGRAM= entry is run, the device node does not exist yet (see here, and also scroll up to see the previous section). But, as per that, what's indicated by RUN is executed after the device node is created (also note "PROGRAM is used for running programs which produce device names (and they shouldn't do anything other than that)"). So you could instead try:

RUN+="/bin/sh -c 'chown root.gpio /dev/gpiomem && chmod g+rw /dev/gpiomem'"

Or, as just explained, put whatever you want to do in a script and execute it via the same parameter.

goldilocks
  • 60,325
  • 17
  • 117
  • 234