From 572a775638f14ddc5fbba03d2b1135e8feeca6c9 Mon Sep 17 00:00:00 2001 From: Tanmay Shah Date: Wed, 18 Mar 2026 20:24:27 -0700 Subject: [PATCH] examples: linux: add rpmsg udev rules and scripts Linux userspace apps can't use rpmsg devices without root access. Introduce udev rules to modify rpmsg device permissions so that userspace apps can use these devices. Also, create symlink to rpmsg device with channel name, src ept and dest ept. Apps can use these symlinks directly without going through sysfs to find out which rpmsg device to use. This makes apps to use rpmsg devices very easy. It is also required to add current user to "rpmsg" group for apps to use rpmsg devices now. This also makes sure rpmsg communication is secure. Signed-off-by: Tanmay Shah --- .../linux/rpmsg_udev_scripts/99-rpmsg.rules | 60 +++++++++ examples/linux/rpmsg_udev_scripts/README.md | 119 ++++++++++++++++++ .../rpmsg_add_ept_symlink.sh | 53 ++++++++ .../rpmsg_create_channel.sh | 43 +++++++ .../rpmsg_remove_ept_symlink.sh | 50 ++++++++ 5 files changed, 325 insertions(+) create mode 100644 examples/linux/rpmsg_udev_scripts/99-rpmsg.rules create mode 100644 examples/linux/rpmsg_udev_scripts/README.md create mode 100644 examples/linux/rpmsg_udev_scripts/rpmsg_add_ept_symlink.sh create mode 100644 examples/linux/rpmsg_udev_scripts/rpmsg_create_channel.sh create mode 100644 examples/linux/rpmsg_udev_scripts/rpmsg_remove_ept_symlink.sh diff --git a/examples/linux/rpmsg_udev_scripts/99-rpmsg.rules b/examples/linux/rpmsg_udev_scripts/99-rpmsg.rules new file mode 100644 index 00000000..a6a1fcea --- /dev/null +++ b/examples/linux/rpmsg_udev_scripts/99-rpmsg.rules @@ -0,0 +1,60 @@ +# Copyright (C) 2026, Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +# Skip rpmsg_ctrl and rpmsg_ns devices by name using GOTO +SUBSYSTEM=="rpmsg", ACTION=="add", \ + KERNEL=="virtio*.rpmsg_ctrl.0.0", GOTO="rpmsg_end" + +SUBSYSTEM=="rpmsg", ACTION=="add", \ + KERNEL=="virtio*.rpmsg_ns.53.53", GOTO="rpmsg_end" + +SUBSYSTEM=="rpmsg", ACTION=="add", \ + KERNEL=="rpmsg_ctrl[0-9]*", GOTO="rpmsg_end" + +SUBSYSTEM=="rpmsg", ACTION=="remove", \ + KERNEL=="rpmsg_ctrl[0-9]*", GOTO="rpmsg_end" + +# rpmsg endpoint creation rule +SUBSYSTEM=="rpmsg", KERNEL=="rpmsg[0-9]*", ACTION=="add", \ + GROUP="rpmsg", MODE="0660", \ + RUN+="/usr/bin/rpmsg_add_ept_symlink.sh %k" GOTO="rpmsg_end" + +# rpmsg endpoint creation rule +SUBSYSTEM=="rpmsg", KERNEL=="rpmsg[0-9]*", ACTION=="remove", \ + RUN+="/usr/bin/rpmsg_remove_ept_symlink.sh %k" GOTO="rpmsg_end" + +# rpmsg channel creation rule +SUBSYSTEM=="rpmsg", ACTION=="add", RUN+="/usr/bin/rpmsg_create_channel.sh %k" + +# ttyRPMSG device permission rule +SUBSYSTEM=="tty", KERNEL=="ttyRPMSG[0-9]*", ACTION=="add", \ + GROUP="rpmsg", MODE="0660" + +LABEL="rpmsg_end" diff --git a/examples/linux/rpmsg_udev_scripts/README.md b/examples/linux/rpmsg_udev_scripts/README.md new file mode 100644 index 00000000..fc6c7a40 --- /dev/null +++ b/examples/linux/rpmsg_udev_scripts/README.md @@ -0,0 +1,119 @@ +# RPMsg udev Scripts + +Udev rules and helper scripts to automatically manage RPMsg endpoint devices. +When an RPMsg channel is created by the remote processor, these scripts handle +device permissions, symlink creation, and endpoint export automatically. + +## Files + +| File | Description | +|------|-------------| +| `99-rpmsg.rules` | udev rules — triggers scripts on RPMsg char device add/remove events | +| `rpmsg_create_channel.sh` | Creates RPMsg endpoint for a new channel using `rpmsg_export_ept` | +| `rpmsg_add_ept_symlink.sh` | Creates user-friendly symlinks and sets device permissions on endpoint add | +| `rpmsg_remove_ept_symlink.sh` | Removes symlinks when endpoint is removed | + +## How It Works + +When the remote processor starts and establishes an RPMsg channel, the kernel +creates devices under `/sys/bus/rpmsg/devices/`. The udev rules trigger the +scripts in the following order: + +``` +Remote processor boots + ↓ +RPMsg channel created → virtio0.rpmsg-openamp-demo-channel.-1.1024 + ↓ udev ACTION==add +rpmsg_create_channel.sh → creates /dev/rpmsg0 via rpmsg_export_ept + ↓ udev ACTION==add (rpmsg0 endpoint) +rpmsg_add_ept_symlink.sh → creates symlinks + ├── /dev/rpmsg-openamp-demo-channel.-1.1024 → /dev/rpmsg0 + └── /dev/rpmsg0.rpmsg-openamp-demo-channel.-1.1024 → above symlink +``` + +On endpoint removal: +``` +udev ACTION==remove (rpmsg0) + ↓ +rpmsg_remove_ept_symlink.sh → removes both symlinks + + +``` +When removing the symlink, we need to find out which rpmsgX device is mapped +to which symlink, and to track that the second symlink was created with name, +rpmsgX.ch_name.ch_src.ch_dst. So, when the device is destroyed, we know which +symlinks to remove. + +## Installation +```bash +# Copy scripts to /usr/bin +sudo cp rpmsg_create_channel.sh /usr/bin/ +sudo cp rpmsg_add_ept_symlink.sh /usr/bin/ +sudo cp rpmsg_remove_ept_symlink.sh /usr/bin/ +sudo chmod +x /usr/bin/rpmsg_*.sh + +# Install udev rule +sudo cp 99-rpmsg.rules /etc/udev/rules.d/99-rpmsg.rules + +# Reload udev rules +sudo udevadm control --reload-rules +sudo udevadm trigger +``` + +## User Group Setup + +The udev rule assigns `/dev/rpmsg*` devices to the `rpmsg` group with +`MODE="0660"` — only members of the `rpmsg` group can read and write the +devices. + +```bash +# Create rpmsg group, or optionally can be created by default during rootfs build +sudo groupadd rpmsg + +# Add user to the group +sudo usermod -aG rpmsg + +# Apply group membership without logout +newgrp rpmsg +``` + +> **Note:** Users must be members of the `rpmsg` group to access `/dev/rpmsg*` +> devices. Changes to group membership require logout/login or `newgrp rpmsg` +> to take effect. + +## Symlink Naming Convention + +| Symlink | Example | Points to | +|---------|---------|-----------| +| `ept_name.src.dst` | `/dev/rpmsg-openamp-demo-channel.-1.1024` | `/dev/rpmsg0` | +| `rpmsg_dev.ept_name.src.dst` | `/dev/rpmsg0.rpmsg-openamp-demo-channel.-1.1024` | above symlink | + +## udev Rule Logic + +``` +SUBSYSTEM=="rpmsg", ACTION=="add" + │ + ├── KERNEL=="virtio*.rpmsg_ctrl.0.0" → SKIP (control device) + ├── KERNEL=="virtio*.rpmsg_ns.53.53" → SKIP (namespace device) + ├── KERNEL=="rpmsg_ctrl[0-9]*" → SKIP (ctrl device) + ├── KERNEL=="rpmsg*[0-9]*" → rpmsg_add_ept_symlink.sh + └── default → rpmsg_create_channel.sh +``` + +## Requirements + +- Linux kernel 6.18 or later (`rpmsg_add_ept_symlink.sh`) +- `rpmsg_export_ept` utility available in `/usr/bin` +- udev running on the target system + +## Debugging + +# Monitor udev events +udevadm monitor --udev --subsystem-match=rpmsg + +# Test rule match without executing +udevadm test /sys/bus/rpmsg/devices/ + +# Check udev logs +journalctl -u systemd-udevd -f +``` diff --git a/examples/linux/rpmsg_udev_scripts/rpmsg_add_ept_symlink.sh b/examples/linux/rpmsg_udev_scripts/rpmsg_add_ept_symlink.sh new file mode 100644 index 00000000..eecc8fd8 --- /dev/null +++ b/examples/linux/rpmsg_udev_scripts/rpmsg_add_ept_symlink.sh @@ -0,0 +1,53 @@ +# Copyright (C) 2026, Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#!/bin/bash + +# valid for kernel 6.18 and later + +rpmsg_dev=$1 + +# find control device for this channel +# e.g. /sys/bus/rpmsg/devices/virtio0.rpmsg_ctrl.0.0/rpmsg/rpmsg_ctrl0/rpmsg0 +rpmsg_dev_dir=$(find -L /sys/bus/rpmsg/devices/ -maxdepth 4 -name $rpmsg_dev 2>/dev/null) + +# Get the ept name, src and dst +ept_name=$(cat $rpmsg_dev_dir/name) # e.g. rpmsg-openamp-demo-channel +ept_src=$(cat $rpmsg_dev_dir/src) # e.g. -1 +ept_dst=$(cat $rpmsg_dev_dir/dst) # e.g. 1024 +ept_symlink_name="$ept_name.$ept_src.$ept_dst" + +# create user mode accessible symlink + +# create symlink for apps to use. /dev/rpmsg-openamp-demo-channel.-1.1024 +ln -s /dev/$rpmsg_dev /dev/$ept_symlink_name + +# map rpmsg device with symlink name by creating another symlink that has actual +# rpmsg device name in it. e.g. /dev/rpmsg0.rpmsg-openamp-demo-channel.-1.1024 +ln -s /dev/$ept_symlink_name /dev/$rpmsg_dev.$ept_symlink_name diff --git a/examples/linux/rpmsg_udev_scripts/rpmsg_create_channel.sh b/examples/linux/rpmsg_udev_scripts/rpmsg_create_channel.sh new file mode 100644 index 00000000..adb66c58 --- /dev/null +++ b/examples/linux/rpmsg_udev_scripts/rpmsg_create_channel.sh @@ -0,0 +1,43 @@ +# Copyright (C) 2026, Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#!/bin/bash + +# e.g. virtio0.rpmsg-openamp-demo-channel.-1.1024 +rpmsg_dev=$1 + +# Split the string based on '. ' and assign to respective variables +# +IFS='. ' read -r virtio_name ch_name ch_src ch_dest <<< "$rpmsg_dev" + +#find control device for this channel e.g. /dev/rpmsg_ctrl0 +rpmsg_ctrl_dev=$(ls /sys/bus/rpmsg/devices/$rpmsg_dev/subsystem/devices/$virtio_name.rpmsg_ctrl.0.0/rpmsg/) + +# create endpoint for this channel e.g. /dev/rpmsg0 +res=$(rpmsg_export_ept /dev/$rpmsg_ctrl_dev $ch_name $ch_src $ch_dest) diff --git a/examples/linux/rpmsg_udev_scripts/rpmsg_remove_ept_symlink.sh b/examples/linux/rpmsg_udev_scripts/rpmsg_remove_ept_symlink.sh new file mode 100644 index 00000000..f17be53f --- /dev/null +++ b/examples/linux/rpmsg_udev_scripts/rpmsg_remove_ept_symlink.sh @@ -0,0 +1,50 @@ +# Copyright (C) 2026, Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#!/bin/bash + +set -e +set +x + +# e.g. "rpmsg0" +rpmsg_dev=$1 + +# This will give format: $rpmsg_dev.$ch_name.$src.$dst +# e.g. /dev/rpmsg0.rpmsg-openamp-demo-channel.-1.1024 +rpmsg_dev_symlink1=$(ls /dev/$rpmsg_dev.* 2>/dev/null) + +# Remove rpmsg device name from the sym link +# e..g rpmsg-openamp-demo-channel.-1.1024 +rpmsg_dev_symlink2="${rpmsg_dev_symlink1#*.}" + +set +e + +# remove both symlinks +unlink $rpmsg_dev_symlink1 +unlink /dev/$rpmsg_dev_symlink2