Skip to content

Commit

Permalink
Merge pull request IntelRealSense#12 from YoshuaNava/feature/uvc_patc…
Browse files Browse the repository at this point in the history
…h_lowlatency

Added bash script for low latency kernel UVC patch
  • Loading branch information
YoshuaNava authored Mar 5, 2019
2 parents f1a1879 + 53aa27c commit 677ed1a
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 7 deletions.
62 changes: 62 additions & 0 deletions doc/leggedrobotics/additional_instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Additional instructions
## Build
For building the package, run:

catkin build librealsense2

## Patching of UVC kernel module
Running RealSense Depth Cameras on Linux requires patching and inserting modified kernel drivers, specially when it comes to devices with the latest firmware versions (> v5.09.02).

Furthermore, applying the kernel is essential to have access to the following features:
* More accurate timestamping.
* Enabling hardware synchronization.
* Fetching frame metadata.
* Improved depth frame alignment.
* Fetching motion module data (applicable to IMU-enabled devices, such as the T265).

In order to patch the Linux UVC kernel module, the steps outlined below must be followed in order:
1. Navigate to *librealsense* root directory to run the following scripts.<br />
Unplug any connected Intel RealSense camera.<br />

2. Install the core packages required to build *librealsense* binaries and the affected kernel modules:
`sudo apt-get install git libssl-dev libusb-1.0-0-dev pkg-config libgtk-3-dev` <br /><br />
Distribution-specific packages: <br />

* Ubuntu 18:<br />
`sudo apt-get install libglfw3-dev libgl1-mesa-dev libglu1-mesa-dev` <br /><br />

3. Install Intel Realsense udev rules:<br />
`sudo cp config/99-realsense-libusb.rules /etc/udev/rules.d/` <br />
`sudo udevadm control --reload-rules && udevadm trigger`
<br />

4. Build and apply patched kernel modules: <br />
The librealsense package ships with scripts that will download, patch and build the Linux UVC kernel module. After the build process is finished, these scripts will attempt to insert the patched module instead of the active one into the kernel. If failed the original uvc modules will be restored.

* **Ubuntu 18 with LTS kernel**

`./scripts/patch-realsense-ubuntu-lts.sh`<br />

* **Ubuntu 18 with Low Latency kernel**

`./scripts/patch-realsense-ubuntu-lowlatency.sh`<br />

### FAQ / Troubleshooting
#### I get the following error message: 'Unsupported kernel version xx-xx . The patches are maintained for Ubuntu XX.XX LTS with kernel y.yy only'
Currently, the kernel patch has only been released for a few versions of the Linux kernel. We recommend that users stick to one of the supported kernels to retain full compatibility with the UVC kernel patch.

The official list of kernels supported can be found [here](https://github.com/IntelRealSense/librealsense/blob/master/doc/distribution_linux.md#using-pre-build-packages).

If you explicitly need to use an unsupported kernel version, we recommend to follow the steps outlined in the Intel wiki for experimental [LibUVC-backend installation](https://github.com/IntelRealSense/librealsense/blob/master/doc/libuvc_installation.md)

#### When the script tries to mount the patched kernel module I get a message saying 'Permission denied'
Check that you have installed the udev rules, as indicated in step 3.

#### After the kernel build is finished I get a message saying 'Failed to unload module videobuf2_core'.
`Videobuf2_core` is a kernel module that depends on `uvcvideo`. In some systems removing the `uvcvideo` module can fail if another dependent module is already inserted into the kernel. In order to solve this, we recommend to run the kernel patching script again after executing the following commands:

```
sudo modprobe -r videobuf2_core
sudo modprobe -r videodev
sudo modprobe -r uvcvideo
```
11 changes: 4 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
# NOTE: This is a fork from the official repository

**The following changes have been done:**
**The following changes have been applied on top of Intel's main development branch:**

* Caktinized librealsense2
* Catkinized librealsense2.
* Added a bash script for patching the UVC module of Ubuntu low latency kernels.

Build with

catkin build librealsense2

No additional changes to the kernel seem to be necessary (to be confirmed).
For guidelines on how to build and use this package, check [additional instructions](doc/leggedrobotics/additional_instructions.md).

-----------------

Expand Down
151 changes: 151 additions & 0 deletions scripts/patch-realsense-ubuntu-lowlatency.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/bin/bash

#Break execution on any error received
set -e

#Locally suppress stderr to avoid raising not relevant messages
exec 3>&2
exec 2> /dev/null
con_dev=$(ls /dev/video* | wc -l)
exec 2>&3

if [ $con_dev -ne 0 ];
then
echo -e "\e[32m"
read -p "Remove all RealSense cameras attached. Hit any key when ready"
echo -e "\e[0m"
fi

#Include usability functions
source ./scripts/patch-utils.sh

# Get the required tools and headers to build the kernel
sudo apt-get install linux-headers-lowlatency build-essential git
#Packages to build the patched modules
require_package libusb-1.0-0-dev
require_package libssl-dev

retpoline_retrofit=0

LINUX_BRANCH=$(uname -r)


# Construct branch name from distribution codename {xenial,bionic,..} and kernel version
ubuntu_codename=`. /etc/os-release; echo ${UBUNTU_CODENAME/*, /}`
if [ -z "${ubuntu_codename}" ];
then
# Trusty Tahr shall use xenial code base
ubuntu_codename="xenial"
retpoline_retrofit=1
fi
kernel_branch=$(choose_kernel_branch ${LINUX_BRANCH} ${ubuntu_codename})
kernel_name="ubuntu-${ubuntu_codename}-$kernel_branch"
echo -e "\e[32mCreate patches workspace in \e[93m${kernel_name} \e[32mfolder\n\e[0m"

#Distribution-specific packages
if [ ${ubuntu_codename} == "bionic" ];
then
require_package libelf-dev
require_package elfutils
fi


# Get the linux kernel and change into source tree
[ ! -d ${kernel_name} ] && git clone -b $kernel_branch git://kernel.ubuntu.com/ubuntu/ubuntu-${ubuntu_codename}.git --depth 1 ./${kernel_name}
cd ${kernel_name}

# Verify that there are no trailing changes., warn the user to make corrective action if needed
if [ $(git status | grep 'modified:' | wc -l) -ne 0 ];
then
echo -e "\e[36mThe kernel has modified files:\e[0m"
git status | grep 'modified:'
echo -e "\e[36mProceeding will reset all local kernel changes. Press 'n' within 10 seconds to abort the operation"
set +e
read -n 1 -t 10 -r -p "Do you want to proceed? [Y/n]" response
set -e
response=${response,,} # tolower
if [[ $response =~ ^(n|N)$ ]];
then
echo -e "\e[41mScript has been aborted on user requiest. Please resolve the modified files are rerun\e[0m"
exit 1
else
echo -e "\e[0m"
echo -e "\e[32mUpdate the folder content with the latest from mainline branch\e[0m"
git fetch origin $kernel_branch --depth 1
printf "Resetting local changes in %s folder\n " ${kernel_name}
git reset --hard $kernel_branch
fi
fi

#Check if we need to apply patches or get reload stock drivers (Developers' option)
[ "$#" -ne 0 -a "$1" == "reset" ] && reset_driver=1 || reset_driver=0

if [ $reset_driver -eq 1 ];
then
echo -e "\e[43mUser requested to rebuild and reinstall ubuntu-${ubuntu_codename} stock drivers\e[0m"
else
# Patching kernel for RealSense devices
echo -e "\e[32mApplying realsense-uvc patch\e[0m"
patch -p1 < ../scripts/realsense-camera-formats_ubuntu-${ubuntu_codename}-${kernel_branch}.patch
echo -e "\e[32mApplying realsense-metadata patch\e[0m"
patch -p1 < ../scripts/realsense-metadata-ubuntu-${ubuntu_codename}-${kernel_branch}.patch
echo -e "\e[32mApplying realsense-hid patch\e[0m"
patch -p1 < ../scripts/realsense-hid-ubuntu-${ubuntu_codename}-${kernel_branch}.patch
echo -e "\e[32mApplying realsense-powerlinefrequency-fix patch\e[0m"
patch -p1 < ../scripts/realsense-powerlinefrequency-control-fix.patch
# Applying 3rd-party patch that affects USB2 behavior
# See reference https://patchwork.kernel.org/patch/9907707/
echo -e "\e[32mRetrofit uvc bug fix enabled with 4.18+\e[0m"
patch -p1 < ../scripts/v1-media-uvcvideo-mark-buffer-error-where-overflow.patch
fi

# Copy configuration
sudo cp /usr/src/linux-headers-$(uname -r)/.config .
sudo cp /usr/src/linux-headers-$(uname -r)/Module.symvers .

# Basic build for kernel modules
echo -e "\e[32mPrepare kernel modules configuration\e[0m"
#Retpoline script manual retrieval. based on https://github.com/IntelRealSense/librealsense/issues/1493
#Required since the retpoline patches were introduced into Ubuntu kernels
if [ ! -f scripts/ubuntu-retpoline-extract-one ]; then
pwd
for f in $(find . -name 'retpoline-extract-one'); do cp ${f} scripts/ubuntu-retpoline-extract-one; done;
echo $$$
fi
sudo make silentoldconfig modules_prepare

#Vermagic identity is required
IFS='.' read -a kernel_version <<< "$LINUX_BRANCH"
sudo sed -i "s/\".*\"/\"$LINUX_BRANCH\"/g" ./include/generated/utsrelease.h
sudo sed -i "s/.*/$LINUX_BRANCH/g" ./include/config/kernel.release
#Patch for Trusty Tahr (Ubuntu 14.05) with GCC not retrofitted with the retpoline patch.
[ $retpoline_retrofit -eq 1 ] && sudo sed -i "s/#ifdef RETPOLINE/#if (1)/g" ./include/linux/vermagic.h

# Build the uvc, accel and gyro modules
KBASE=`pwd`
cd drivers/media/usb/uvc
sudo cp $KBASE/Module.symvers .

echo -e "\e[32mCompiling uvc module\e[0m"
sudo make -j -C $KBASE M=$KBASE/drivers/media/usb/uvc/ modules
echo -e "\e[32mCompiling accelerometer and gyro modules\e[0m"
sudo make -j -C $KBASE M=$KBASE/drivers/iio/accel modules
sudo make -j -C $KBASE M=$KBASE/drivers/iio/gyro modules
echo -e "\e[32mCompiling v4l2-core modules\e[0m"
sudo make -j -C $KBASE M=$KBASE/drivers/media/v4l2-core modules

# Copy the patched modules to a sane location
sudo cp $KBASE/drivers/media/usb/uvc/uvcvideo.ko ~/$LINUX_BRANCH-uvcvideo.ko
sudo cp $KBASE/drivers/iio/accel/hid-sensor-accel-3d.ko ~/$LINUX_BRANCH-hid-sensor-accel-3d.ko
sudo cp $KBASE/drivers/iio/gyro/hid-sensor-gyro-3d.ko ~/$LINUX_BRANCH-hid-sensor-gyro-3d.ko
sudo cp $KBASE/drivers/media/v4l2-core/videodev.ko ~/$LINUX_BRANCH-videodev.ko

echo -e "\e[32mPatched kernels modules were created successfully\n\e[0m"

# Load the newly-built modules
try_module_insert videodev ~/$LINUX_BRANCH-videodev.ko /lib/modules/`uname -r`/kernel/drivers/media/v4l2-core/videodev.ko
try_module_insert uvcvideo ~/$LINUX_BRANCH-uvcvideo.ko /lib/modules/`uname -r`/kernel/drivers/media/usb/uvc/uvcvideo.ko
try_module_insert hid_sensor_accel_3d ~/$LINUX_BRANCH-hid-sensor-accel-3d.ko /lib/modules/`uname -r`/kernel/drivers/iio/accel/hid-sensor-accel-3d.ko
try_module_insert hid_sensor_gyro_3d ~/$LINUX_BRANCH-hid-sensor-gyro-3d.ko /lib/modules/`uname -r`/kernel/drivers/iio/gyro/hid-sensor-gyro-3d.ko

echo -e "\e[92m\n\e[1mScript has completed. Please consult the installation guide for further instruction.\n\e[0m"

0 comments on commit 677ed1a

Please sign in to comment.