5 製品別サポート 5 DT10&DT-Storage 5 チュートリアル 5 応用編 5 ドライバのカスタム手法のご提案 5 Linuxでオーバーヘッドが削減できるsyscallを使ったドライバ

チュートリアル

Linuxでオーバーヘッドが削減できるsyscallを使ったドライバ

課題

・Linuxシステムで、さらにオーバーヘッドを削減したい。
・テストポイントを挿入しているアプリが、ファイルアクセス権限によって、procファイルへアクセスできないシステムで使いたい。

 

解決方法

syscallを使ったドライバを使用します。
従来のサンプルドライバは、構造体を使ってユーザー領域からカーネル領域へデータを渡していましたが、
その処理が不要になる分、オーバーヘッド削減が可能となります。
また、従来の方法では、procフォルダの権限を変えるか、アプリ起動時にroot権限での起動が必要でしたが、
syscallの方法ではアクセス権限に関係なく使用できるようになります。

 

効果

弊社で提供する従来のサンプルドライバを(Procファイルシステム)ご使用いただいた場合よりも、
オーバーヘッドを削減することができます。

例) CPU : Samsung Exynos5422 Board : Odroid-XU3
従来のサンプルドライバ : 約 3.2us
syscallを使ったドライバ  : 約 1.7us

 

ドライバのカスタム方法

syscallを使用する形でDT10を環境に組み込む際の作業手順と使い方を説明します。
接続方式は、ファイル書き出しです。

Linuxディストリビューションやバージョンなどによって、若干異なるケースがございます。
また、archフォルダ以下についてはターゲットのCPUにてフォルダが分かれますので、
使用しているCPUに合わせて組み込むようにご注意ください。
ここではx86系を例として説明します。

1. サンプルドライバのダウンロード
対応OS 接続方式 言語 イベントID出力方式 ダウンロード 備考
Linux ファイル書き出し
(18Byte)
C/C++ カーネル情報出力
ポイント挿入
ダウンロード DT10Ver11.00以降のサンプルドライバ
Linux ファイル書き出し
(18Byte)
C/C++ カーネル情報出力
ポイント挿入
ダウンロード DT10Ver10.51以前のサンプルドライバ
2. syscallフォルダの構成

使用する定義を下記のように変更します。

syscall
  ├app               … dt10appを作製
  │├ProcFileOutput.c        … dt10app の実体
  │└Makefile
  │
  ├kernel…Kernel向け
  ││階層は[Linux]相当
  │├arch
  ││└x86
  ││  ├include
  ││  │ └asm
  ││  │    ├unistd_32.h       … syscall番号の登録(32bit)
  ││  │    └unistd_64.h       … syscall番号の登録(64bit)
  ││  │
  ││  └kernel
  ││    └syscall_table_32.S     … syscallTabel登録(32bit)
  ││
  │├include
  ││ ├asm-x86
  ││ │  └asm-offsets.h      … syscall最大値の設定(64bit)
  ││ │
  ││ └linux
  ││    └syscalls.h         … syscallの宣言一覧(共通)
  │└drivers
  │  └misc
  │    └dt_datawriting_drv.c     … DT10カーネルモジュール
  │                   MakefileはmiscのMakefileに追加
  │
  └userspace
     └dt10_tpdrv.c          … ユーザーランド向けドライバ

appフォルダ、及び userspaceフォルダ以下のファイルは、ユーザーランド層に対応しています。
kernelフォルダ以下のファイルは、カーネル層に対応しています。

kernelフォルダについては、Linuxのフォルダ構成に従った階層になっていますので、
構成を変更せずに、そのままの位置で設置します。

3. DT10用システムコールの登録

DT10の処理をシステムコールで処理できるように、カーネル側に設定します。
なお、32bit環境と64bit環境によって、操作するファイルが異なりますのでご注意ください。

■32bit環境の場合

(1) linux/arch/x86/include/asm/unistd_32.h の変更

システムコールのdefineにDT10のシステムコールを追加します。

dcm_p4_1

unistd_32.h の最後に以下の2つを追加します。

#define __NR_dt10_write  337
#define __NR_dt10_writev  338

“NR_syscalls”がシステムコールの最大値になりますので追加分を更新します。

#define NR_syscalls 340			

(2) linux/arch/x86/kerne/syscall_table_32.S の変更

dcm_p4_2

以下の設定を最後に追加します。

.long sys_dt10_write		
.long sys_dt10_writev	

(3) linux/include/linux/syscalls.hの変更

dcm_p4_3

syscall.h の最終行に以下の2つの宣言を追加します。

asmlinkage long sys_dt10_write(unsigned int addr, unsigned int dat);
asmlinkage long sys_dt10_writev
(unsigned int addr, unsigned int dat, void __user *p, unsigned int size);				

■64bit環境の場合

(1) linux/arch/x86/include/asm/unistd_64.h の変更

システムコールのdefineにDT10のシステムコールを追加します。

dcm_p4_4

(2) __NR_syscall_max の変更

システムコールの最大値を修正します。
Linuxのバージョンによって差異がありますので、以下のような形で検索し、
“__NR_syscall_max”の値を手順(1)で変更した値に修正します。

find ~/ linux -type f -name  "*.h" | xargs grep "__NR_syscall_max" 
grep -r "__NR_syscall_max"						

以下に、参考例を記載します。
linux/include/asm-x86/asm-offsets.hへ移動

dcm_p4_5

上記の赤枠の箇所のように修正してください。

その他、別のLinuxバージョンでは、下記のように、別ファイルにて定義されており
unistd.hの変更のみで対応されている場合もあります。

linux/arch/x86/kernel/asm_offsets_64.c

dcm_p4_6

(3) linux/include/linux/syscalls.hの変更

dcm_p4_7

syscall.h の最終行に以下の2つの宣言を追加します。

asmlinkage long sys_dt10_write(unsigned int addr, unsigned int dat);
asmlinkage long sys_dt10_writev
(unsigned int addr, unsigned int dat, void __user *p, unsigned int size);
4. dt_datawriting_drv.c の登録

linux/drivers/misc直下にdt_datawriting_drv.cを登録します。
サンプルコードの修正は特に必要ありません。

dcm_p4_8

miscのMakefileに dt_datawriting_drv.c を登録します。

dcm_p4_9

5. userspace/dt10_tpdrv.c の登録

DT10のテストポイントを挿入したアプリのMakefileにdt10_tpdrv.cを追加します。
「3. DT10用システムコールの登録」で変更した際のunistd_32/64.hの値に変更してください。

dcm_p4_10

6. app から dt10appの設定

サンプルドライバ内のMakefileからMakeを実行する事で、dt10app が作成されます。
ソースファイルの実体は、同ファイル内のProcFileOutput.cとなっています。

Makeする前に、以下の点を修正してください。
proc上に保存されているログデータの保存先を指定します。

#define CONVERT_FILE を変更します。

dcm_p4_11

変更が完了したら、Makeコマンドを実行しdt10appを生成します。

7. 動作確認

Procを操作する為、dt10app は root権限で操作する必要があります。
こちらは操作の例です。Convertdata.DATが生成されることを確認してください。

dcm_p4_12

dcm_p4_13