Ubuntu 16.04 (linux-4.9.90)にXenomaiを入れるまで

## Outline

UbuntuのLinux kernelにXenomaiパッチ[^Xenomai]を適用するまで．さらにOROCOSとROSを入れる設定に．
Preemptはkernelサポートのsoft lantencyを使います．

## Xenomaiの動作要件のチェック

2018/07/11 現在のXenomai[^Xenomai]最新版はv3.0.7[^Xeno_latest]，I-pipeの最新版[^I-pipe_latest]はx86版でLinux kernel 4.9.90に対応．
そこで現行で動かしているLinuxに一度4.9.90を入れて，パッケージの動作要件を似せておくとともに，boot sequenceだけでも以上がないか確認しておきましょう．

## Linuxカーネルの変更

dpkgを使ってlinux kernel 4.9.90をboot configに登録．
※できればアップデートが望ましいです (Ubuntu serverの16.04.4はlinux-4.4系)

``` sh
wget -P ./tmp http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.90/linux-headers-4.9.90-040990_4.9.90-040990.201803250830_all.deb
wget -P ./tmp http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.90/linux-headers-4.9.90-040990-generic_4.9.90-040990.201803250830_amd64.deb
wget -P ./tmp http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.9.90/linux-image-4.9.90-040990-generic_4.9.90-040990.201803250830_amd64.deb

sudo dpkg -i ./tmp/linux-headers-4.9.90-*.deb ./tmp/linux-image-4.9.90-*.deb
# sudo update-grub && sudo update-initramfs 4.9.90-040990-generic
sudo reboot
```

## Xenomaiパッチの適用とコンパイル

#### **パッケージのインストール**
こっから先は，ほとんど,[rtt_lwr](http://rtt-lwr.readthedocs.io/en/latest/rtpc/xenomai3.html)[^rtt_lwr]の内容と同じです．
まずはaptで必要パッケージのインストール．終わったら一度再起動推奨．

``` sh
sudo apt install gcc make -y
sudo apt install git build-essential kernel-package\
 fakeroot libncurses5-dev libssl-dev ccache -y
sudo apt update
sudo apt upgrade -y
sudo reboot
```

#### **Xenomaiのダウンロード**
次に必要となるvanilla kernelとxenomaiおよびI-pipe patchを集める．一旦作業用のディレクトリを作るといいでしょう． 
一応自前でshell scriptを書いてみたので，置いておきます →https://github.com/realteck-ky/Xenomai-Script

``` sh
mkdir workspace && cd workspace
wget https://xenomai.org/downloads/xenomai/stable/xenomai-3.0.7.tar.bz2
tar xvf xenomai-3.0.7.tar.bz2
wget http://www.kernel.org/pub/linux/kernel/v4.x/linux-4.9.90.tar.gz
tar xvf linux-4.9.90.tar.gz
wget https://xenomai.org/downloads/ipipe/v4.x/x86/ipipe-core-4.9.90-x86-6.patch
```

#### **Kernel configurationの設定**
kernelのコンパイル[^Xenobuild]の設定します．
以下，解凍したLinux kernelのディレクトリ下で作業．

``` sh
cd linux-4.9.90
cp -vi /boot/config-`uname -r` .config
../xenomai-3.0.7/scripts/prepare-kernel.sh --arch=x86_64\
 --linux=./ --ipipe=../ipipe-core-4.9.90-x86-6.patch --verbose

make olddefconfig
make menuconfig
```
途中の`make menuconfig`では，kernelのコンパイルパラメータをいじるので，以下のように設定します．


ちなみにここでの想定は，Intel系の64bitCPU．加えて，Preemption Modelをlowlatencyにします[^preempt]．これはカーネル側からも投機的にスケジューラを起動するための設定ですが，効果の程は未検証です．機能の詳細は，少し古いですがNECのPDF[^NEC]に詳しいです．
さらにIntelのPDF[^Intel]や電ドラブログ[^Nyx]を見ながら設定します．

余談ですが，[rtt_lwr](http://rtt-lwr.readthedocs.io/en/latest/rtpc/xenomai3.html)[^rtt_lwr]がOROCOS[^OROCOS]導入を意識しているため，メモリ割り当てやRT-net[^RTnet]サポートが念頭にある設定となってます．
デバイス周りや監視にもリアルタイム性を課していくと重くなるので，基本的に余計な機能を切りましょう[^IOdis]．
終わったらSaveで.configを書き換えてExitします．

* General setup
  - Timers subsystem
      - High Resolution Timer Support (Enable)
* Xenomai/cobalt
  - Sizes and static limits
      - Number of registry slots (set to 4096)
      - Size of system heap (Kb) (set to 4096)
      - Size of private heap (Kb) (set to 256)
      - Size of shared heap (Kb) (set to 256)
      - Maximum number of POSIX timers per process (set to 512)
  - Drivers
      - RTnet
          - RTnet, TCP/IP socket interface (Enable)
          - Drivers
              - New intel(R) PRO/1000 PCIe (Enable)
              - Realtek 8169 (Enable)
              - Loopback (Enable)
          - Add-Ons
              - Real-Time Capturing Support (Enable)
* Power management and ACPI options
  - CPU Frequency scaling
      - CPU Frequency scaling (Disable)
  - ACPI (Advanced Configuration and Power Interface) Support
      - Processor (Disable)
  - CPU Idle
      - CPU idle PM support (Disable)
* Pocessor type and features
  - Processor family
      - Core 2/newer Xeon  //ex. i-series
      - Generic-x86-64 //ex. Celeron  
    // if `cat /proc/cpuinfo | grep family` returns 6, set as Generic otherwise
  - Preemption Model
      - Preemption Kernel (Low-Latency Desktop)
  - Enable maximum number of SMP processors and NUMA nodes (Disable)  
  // Ref : http://xenomai.org/pipermail/xenomai/2017-September/037718.html
  - Maximum number of CPUs (4or8)  
  // set a number of CPU cores as `cat /proc/cpuinfo | grep "model name"`
  - Transparent Hugepage Support (Disable)
  - Allow for memory compaction (Disable)
  - Contiguous Memory Allocation (Disable)
  - Allow for memory compaction
      - Page Migration (Disable)
  - Timer frequency (1000 HZ)
* Kernel hacking
  - Memory Debugging
      - Check for stack overflows (Disable)
* Device Drivers
  - Staging drivers
      - Unisys SPAR driver support
          - Unisys visorbus driver (Disable)

#### **Make**
いよいよkernelコンパイルこと`make`です．コンピュータによりますが，軽く2時間ぐらいかかります．
`CONCURRENCY_LEVEL`はいわゆる`-j`オプションですので，makeを何プロセスに分割するかになります．
ここではいきなりkernelをインストールするのではなく，一度debファイルを生成させます．

``` sh
CONCURRENCY_LEVEL=$(nproc) make-kpkg --rootcmd fakeroot\
 --initrd --arch=amd64 --append-to-version=-xenomai-3.0.7\
 kernel-image kernel-headers
 ```

こうしてできたdebファイルでXenomaiパッチされたkernelをインストールしましょう．

``` sh
cd ../
sudo dpkg -i linux-image-*.deb linux-headers-*.deb
sudo reboot
```

## Xenomai kernelでの設定
まずは，`uname -a`で適用されていることを確認しましょう．
次にuser groupの設定です．

``` sh
sudo addgroup xenomai --gid 1234
sudo addgroup root xenomai
sudo usermod -a -G xenomai $USER
```

xenomaiのディレクトリに移って，moduleをインストールします．

``` sh
cd workspace/xenomai-3.0.7
./configure --with-pic --with-core=cobalt --enable-smp --disable-tls --enable-dlopen-libs --disable-clock-monotonic-raw
make -j`nproc`
sudo make install
```
[rtt_lwr](http://rtt-lwr.readthedocs.io/en/latest/rtpc/xenomai3.html)[^rtt_lwr]には，grubへの設定方法も書いてあります．長くなるので割愛．
最後に環境変数の指定です．

``` sh
echo '
### Xenomai
export XENOMAI_ROOT_DIR=/usr/xenomai
export XENOMAI_PATH=/usr/xenomai
export PATH=$PATH:$XENOMAI_PATH/bin:$XENOMAI_PATH/sbin
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$XENOMAI_PATH/lib/pkgconfig
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$XENOMAI_PATH/lib
export OROCOS_TARGET=xenomai
' >> ~/.xenomai_rc

echo 'source ~/.xenomai_rc' >> ~/.bashrc
source ~/.bashrc
```

お疲れ様でした．`sudo -s`したのちに`xeno-test`でlatencyを確認すると30usぐらいかと思います．
この状態だと`sudo xeno-test`にPATHが通ってないので，sudoでtestコマンドを実行したいときは，/etc/sudoersの`secret_path`をコメントアウトし，`Defaults  env_keep += "PATH"`を追記しましょう．
一助となれば幸いです．良きrealtime lifeを！


#### 引用リンク
[^Xenomai]: Linux kernelのリアルタイム化パッチツール．hard realtimeな動作を提供する．現在，HPがGitlabに移行中． https://xenomai.org/
[^Xenobuild]: https://gitlab.denx.de/Xenomai/xenomai/wikis/Installing_Xenomai_3
[^rtt_lwr]: http://rtt-lwr.readthedocs.io/en/latest/rtpc/xenomai3.html を参考にしました．
[^preempt]: http://szmlb.hatenablog.com/entry/2016/11/24/132322 を参考にしました．
[^NEC]: http://www.nec.co.jp/semi/LWCD2004/pdf/LinuxWorld2004_EL2.pdf
[^Intel]: https://www.intel.cn/content/dam/www/public/us/en/documents/white-papers/multicore-real-time-linux-xenomai-paper.pdf
[^Nyx]: https://ameblo.jp/x-faust/entry-12157268437.html
[^OROCOS]: Open Robot Control Software http://www.orocos.org/
[^RTnet]: RTAI準拠なネットワークプロトコル群 http://www.rtnet.org/links.html
[^IOdis]: ただしPCI周りは個人的にGPUの使用する可能性があるので保留
[^I-pipe_latest]: 2018/07/11現在． https://xenomai.org/downloads/ipipe/v4.x/x86/
[^Xeno_latest]: 2018/07/11現在． https://xenomai.org/downloads/xenomai/stable/latest/