I'm trying to understand the udev operators so I can create rules for my device, but there seems to be a discrepancy between a couple online sources about the operator that prevents later changes to keys. Which udev operator, if any, will prevent later changes to keys?
There seems to be a discrepancy between the following two sources about the udev operators that prevent later changes to keys.
http://www.reactivated.net/writing_udev_rules.html states that +: ensures that no later rule can have any effect, but man udev states that := will Assign a value to a key finally; disallow any later changes.. man udev also states that "+=" will Add the value to a key that holds a list of entries.. So, which udev operator, if any, will prevent later changes to keys?
I tested this question by creating /etc/udev/rules.d/80-test.rules for my USB flash drive. The rule had the following key-value lines...
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added.sh"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added_2.sh"
The executable file device_added.sh contains ...
`echo "USB device removed at $(date)" >>/tmp/scripts.log`
...and the executable file device_added_2.sh contains ...
`echo "USB device removed at $(date)" >>/tmp/scripts_2.log`
I registered the changes to udev: $ sudo udevadm control --reload
and then I plugged in the USB flash drive. Then I checked if /tmp/scripts.log and /tmp/scripts_2.log were created and had the appropriate strings, which they did. So, it seems that += does NOT prevent later changes to keys.
Then I tested to know if := prevents later changes to keys by subbing := for += in the first key pair of my rule...
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN:="/bin/device_added.sh"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added_2.sh"
Then I registered the changes with udev again, unplugged my USB drive, plugged it in, then checked the test log files for updates. I expected scripts_2.log to NOT be updated. However, it was! So, it seems that := also does NOT prevent later changes to keys.
So, can the += and/or := operator(s) prevent later changes to keys some way? Is there another operator I should be using to prevent later changes?
It seems unlikely that both man udev and http://www.reactivated.net/writing_udev_rules.html would be wrong about this, so I'm probably misunderstanding something about this.
I expected := to prevent scripts_2.log from being updated.
UPDATE - 2019-05-12:
I found this stackexchange post asking a very similar question, but the two answers provided there do not answer the question in this post. One answer suggests the use of GOTO, which is a workaround that I understand, and the other answer suggests the use of :=, which, like the previously mentioned sources, seems false.
UPDATE - 2019-05-19:
I just realized that the following statement, in http://www.reactivated.net/writing_udev_rules.html...
Additional options
Another assignment which can prove useful is the OPTIONS list. A few options are available:
all_partitions - create all possible partitions for a block device, rather than only those that were initially detected
ignore_device - ignore the event completely
last_rule - ensure that no later rules have any effect
For example, the rule below sets the group ownership on my hard disk node, and ensures that no later rule can have any effect:
KERNEL=="sda", GROUP="disk", OPTIONS+="last_rule"
...uses += to add the last_rule assignment, which seems it is supposed to have the same effect as :=. So, I edited my rule again to...
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN:="/bin/device_added.sh"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", OPTIONS+="last_rule"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added_2.sh"
Then I registered the changes with udev again, unplugged my USB drive, plugged it in, then checked the test log files for updates. I expected scripts_2.log to NOT be updated, but it was. So, it seems that OPTIONS +="last_rule" also does NOT prevent later changes to keys.
It appears that the documentation for := is incomplete; it does what is described, but across rule files. I repeated your experiment like so:
In 50-udevoptest.rules:
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN:="/bin/device_added.sh"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/bin/device_added_2.sh"
In another rules file from upstream named 73-seat-late.rules, there is this rule
TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess"
Now I test the rules with udevadm test /sys/... for a device which both rulesets apply, which gets us:
run: '/bin/device_added.sh'
run: '/bin/device_added_2.sh'
run: 'uaccess'
Unload module index
Unloaded link configuration context.
Then I rename the experiment like so mv 50-udevoptest.rules 99-udevoptest.rules, and repeat udevadm test /sys/..., which gets us:
run: '/bin/device_added.sh'
run: '/bin/device_added_2.sh'
Unload module index
Unloaded link configuration context.
(because rule filenames with higher lexical rank receive priority - another ambiguity in the manuals)
Related
I am running ubuntu 18.04, kernel 4.19.94-ti-r36, on a a beaglebone black. I am connected to ssh, and am trying to adjust the boot configuration of the GPIO pins. After boot, I am able to change and query individual GPIO configurations with the "config-pin" command, which is useful for experimentation. But I would like to change all the default GPIO configuration on boot, which this tool does not appear to do.
I found this tutorial on using a device overlay to achieve this here:
http://derekmolloy.ie/gpios-on-the-beaglebone-black-using-device-tree-overlays/
but I am missing the "bone_capemgr.8" directory. I googled this issue and was directed to this page, which says that device tree overlays are now deprecated, and to use u-boot overlays instead:
https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays.2C_which_got_loaded
I read through the article, and googled around, but I haven't found anything on how to actually use a u-boot overlay to change the configuration of the GPIO pins on boot.
Does anyone know how to do this, or know where I might find a good resource to this effect?
Thanks!
Edit: here are the steps I think I need to take, based on De Funct's answer:
install bb.org-overlays found here, https://github.com/beagleboard/bb.org-overlays, with:
sudo apt install bb-cape-overlays
create a .dts file with the correct configuration
compile .dts-->.dtbo file:
dtc -O dtb -o out_file.dtbo -b 0 -# in_file.dts (or something similar?)
adjust this line in /boot/uEnv.txt file to reference compiled dts
###Overide capes with eeprom
#uboot_overlay_addr0=/lib/firmware/.dtbo
something to do with boot images (?)
Questions:
what does searching "in the kernel" mean? how would I do this?
for the actual .dts file, I looked around and found this as a starting point:
https://github.com/derekmolloy/boneDeviceTree/blob/master/overlay/DM-GPIO-Test.dts My plan is to modify/extend lines 29-33 to change the boot configuration of all relevant pins. The second hex number is the pin mode I'm trying to change; that makes sense. The first hex number looks like it somehow corresponds to pin number, but I'm not sure how? for example, 0x078-->P9.12,0x184-->P9.24, etc.
when/where does making an image come into play? what about making two different partitions? I didn't follow that part
to use the uboot-overlays, which is a given for most concepts with GPIO pins on the BBB, one would have to install bb.org-overlays which are found here, https://github.com/beagleboard/bb.org-overlays, and to understand Device-Tree Specifications.
https://github.com/beagleboard/BeagleBoard-DeviceTrees will help you, too.
The Device Tree specification can be found here: https://www.devicetree.org/
In the kernel, you can search the docs. and kernel for specific, already-made device tree ideas and files.
Also, it is as simple as creating your dts file, compiling it, and putting it in the correct space on the BeagleBone Black in /boot/uEnv.txt.
For instance, if I had a specific .dtbo that I compiled from my .dts file(s), I would simply put it in the /boot/uEnv.txt file under this heading...
###Overide capes with eeprom
#uboot_overlay_addr0=/lib/firmware/<file0>.dtbo
http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays should explain the ideas I am listing.
Oh! Also, when creating your image, one would have to create the two partitions, one for booting and the other for the actual OS/filesystem.
Once this is completed, one would have to install the file uEnv.txt in the /boot dir. by simply making the file in a text editor, saving it, and placing it in the system before compilation via make menuconfig or whatever you are using to install the boot partition and OS partition.
If you need exact placements of the files in the kernel to search under for the .dts, .dtb, and .dtbo files, ask away. I have had complications with this before and lacking understanding, I have been a drift. Luckily, there is a long list of ideas but one needs to make them accessible in the correct order.
Also: https://www.digikey.com/eewiki/display/linuxonarm/BeagleBone+Black are some ideas on how to start the image factory of making things available for the BeagleBone Black.
Edit: here are the steps I think I need to take, based on De Funct's answer:
install bb.org-overlays found here, https://github.com/beagleboard/bb.org-overlays, with:
git clone https://github.com/beagleboard/bb.org-overlays
create a .dts file with the correct configuration
Your configuration of the .dts file works too...(supposedly as I have not seen it).
compile .dts-->.dtbo file:
dtc -O dtb -o out_file.dtbo -b 0 -# in_file.dts (or something similar?)
Not this idea. Although, compiling using the device-tree-compiler is an option, I say use their build script w/ their Makefile.
So, try ./install.sh
adjust this line in /boot/uEnv.txt file to reference compiled dts
###Overide capes with eeprom
uboot_overlay_addr0=/lib/firmware/your_newly_added_file.dtbo
...
Also and excuse me if this does not work, you can try with the BeagleBoard-DeviceTrees link I provided.
In that one, you would simply place the correct file, your .dts file, in the /src/arm/ directory, and go back to the BeagleBoard-DeviceTrees/ dir. to perform the make command.
It will perform all the necessary .dts to .dtb to .dtbo file operations.
This is the /boot/uEnv.txt file I have currently...
#Docs: http://elinux.org/Beagleboard:U-boot_partitioning_layout_2.0
uname_r=4.19.94-ti-r59
#uuid=
#dtb=
###U-Boot Overlays###
###Documentation: http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays
###Master Enable
enable_uboot_overlays=1
###
###Overide capes with eeprom
uboot_overlay_addr0=/lib/firmware/BB-UART2-00A0.dtbo
#uboot_overlay_addr1=/lib/firmware/<file1>.dtbo
#uboot_overlay_addr2=/lib/firmware/<file2>.dtbo
#uboot_overlay_addr3=/lib/firmware/<file3>.dtbo
###
###Additional custom capes
#uboot_overlay_addr4=/lib/firmware/<file4>.dtbo
#uboot_overlay_addr5=/lib/firmware/<file5>.dtbo
#uboot_overlay_addr6=/lib/firmware/<file6>.dtbo
#uboot_overlay_addr7=/lib/firmware/<file7>.dtbo
###
###Custom Cape
#dtb_overlay=/lib/firmware/<file8>.dtbo
###
###Disable auto loading of virtual capes (emmc/video/wireless/adc)
#disable_uboot_overlay_emmc=1
#disable_uboot_overlay_video=1
#disable_uboot_overlay_audio=1
#disable_uboot_overlay_wireless=1
#disable_uboot_overlay_adc=1
###
###PRUSS OPTIONS
###pru_rproc (4.14.x-ti kernel)
#uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-14-TI-00A0.dtbo
###pru_rproc (4.19.x-ti kernel)
uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-19-TI-00A0.dtbo
###pru_uio (4.14.x-ti, 4.19.x-ti & mainline/bone kernel)
#uboot_overlay_pru=/lib/firmware/AM335X-PRU-UIO-00A0.dtbo
###
See where the file states #dtb=? That is section where the .dtb needs to be located and uncommented by removing the hash symbol.
Also, under that particular section of the file, there are u_boot-overlay sections. You can now add your .dtbo files in those particular slots.
I am building some kind of kiosk system and I bought this USB DIY keyboard for it: https://www.amazon.com/gp/product/B07QPXQQ7L
This allows me to have a lot of buttons and they behave like keyboard keys.
I'm writing a program (Perl) that will take the input from that keyboard and do things based on that.
The problem is that I need to have the rest of the system (both X and the TTYs) ignore that keyboard so that it won't type random things in the terminal or in the window manager. In other words, the system should disregard it but the device itself must still be available in /dev/input/...
I don't need a real keyboard to control the machine because I connect via VNC and SSH.
Bonus points if you know how to read from a /dev/input/... keyboard and end up with letters typed just like with STDIN in a terminal.
Thanks!
I found the solution here where someone wanted the exact same thing in the case of a barcode reader:
https://serverfault.com/questions/385260/bind-usb-keyboard-exclusively-to-specific-application/976557#976557
SUBSYSTEM=="input", ACTION=="add", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="yyyy", RUN+="/bin/sh -c 'echo remove > /sys$env{DEVPATH}/uevent'"
ACTION=="add", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="yyyy", SYMLINK+="diykeyboard"
And then replace xxxx and yyyy by the Vendor and Product ID as found in lsusb. So in my case 1c4f and 0002:
Bus 001 Device 003: ID 1c4f:0002 SiGma Micro Keyboard TRACER Gamma Ivory
The udevadm control --reload thing didn't do it for me, I had to reboot.
Then in theory the data typed on the keyboard should be available at /dev/diykeyboard (the SYMLINK variable).
Now in my case unfortunately there are multiple events that match this vendor+product, and to match the right one I needed to add DEVPATH=="*:1.0/*", KERNEL=="event*" in the second line where it creates the SYMLINK. And then surprise it did not create the link in /dev so I had to do something dirty, create a link myself with ln:
SUBSYSTEM=="input", ACTION=="add", ATTRS{idVendor}=="1c4f", ATTRS{idProduct}=="0002", RUN+="/bin/sh -c 'echo remove > /sys$env{DEVPATH}/uevent'"
SUBSYSTEM=="input", ACTION=="add", ATTRS{idVendor}=="1c4f", ATTRS{idProduct}=="0002", DEVPATH=="*:1.0/*", KERNEL=="event*", RUN+="/bin/sh -c 'ln -sf /dev/input/$kernel /diykeyboard'"
(don't create the link in /tmp since udev happens before the mounting of /tmp at boot)
From there I can read from /diykeyboard (which usually points to /dev/input/event0) either with evtest which shows the keys typed, or directly with my program and then decoding the scancodes.
I wrote a simple udev rule to mount my compact flash card reader to a writeable device node. The rule was working earlier, but seems to have stopped for some reason, I was editing the file before, but now it just contains:
KERNEL=="/dev/sd*", ATTRS{model}=="Compact Flash ", SYMLINK+="compactflash-%k", MODE=="0666"
The file is called 90-cf-rule.rules and is located in /etc/udev/rules.d. If someone could point out what's wrong I'd be really grateful.
It looks like udevd is still running, and I run udevadm trigger after editing the rules file. I've tried plugging and unplugging the device. I'm also certain that the model matches as I copied and pasted from udevadm info and have had this rule working!
The correct udev filter is:
KERNEL=="sd*", ATTRS{model}=="Compact Flash ", SYMLINK+="compactflash-%k", MODE=="0666"
ie. The /dev/ is not required in front of the KERNEL argument. I must have put this in while editing the file earlier.
I have a bluetooth remote that is paired with my linux box, when active, this remote is visible at /dev/input/event13.
I have a small C program that open this device and read directly from it, which works fine.
Now, my problem is that this remote goes to sleep after a few minutes of inactivity and /dev/input/event13 disappears. It reappears as soon as I press a key on my remote.
I put the output of udevadm here: https://gist.github.com/9fff2f0d7edef1050060.
I use the following code (small ruby ext I wrote), to read from the device: https://gist.github.com/b403d538eb6a8627e2bd.
I thought of writing an udev rule that would start my program when my remote is added and stop it when it is removed. I read the udev documentation, but I couldn't figure it out how to do it. I'm open for suggestion.
After some digging and a lot of frustration I did the following:
I put into /etc/udev/rules.d/99-rmote.rules
KERNEL=="event*", SUBSYSTEM=="input", ACTION=="add|remove", ATTRS{name}=="TiVo Keyboard Remote", RUN+="/home/kuon/handleConnect.rb"
And in handleConnect.rb I check the ACTION environment variable and I start/stop my daemon accordingly. Quite simple in the end and it works well.
This is a dupe from SuperUser.com . Folks over there weren't smart enough or willing to help me out; maybe it's more a programmer question than an administrator one:
I have an app that reads input from 4 (four) mice that are plugged in via USB in addition to the built-in touchpad. This is no problem for Ubuntu 9.10: hald notices the new devices and udev's them brand new entries called /dev/input/mouse4 ... mouse7.
My app runs as a normal user app. The files in /dev belong to root and aren't readable to anyone else.
I don't have a problem doing chmod a+r mouse? once, but the devices come and go with every reboot and every time the dang rodents are plugged in or out.
Can someone please tell me a script or something to manipulate so my chmod happens automagically?
This information is easily discoverable, I just had to look at /etc/udev/rules.d/91-permissions.rules on a Debian configuration. :-)
Some interesting examples pasted from there:
# default permissions for block devices
SUBSYSTEM=="block", GROUP="disk"
Looks like there's this "GROUP" thing to determine the group owner...
And, you can chmod stuff apparently:
KERNEL=="pty*", MODE="0666", GROUP="tty"
Note the MODE part...
I'm sure RTFM-ing for the udev config file format will give you even more information. :-)