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