これは、単純なカーネル システム コールを記述する方法の単なる例です。次の C 関数 system_strcpy() を考えてみましょう。この関数は、単純にある文字列を別の文字列にコピーします: strcpy() が行うことと同様です。
#include<stdio.h>
long system_strcpy(char* dest, const char* src)
{
int i=0;
while(src[i]!=0)
dest[i]=src[i++];
dest[i]=0;
return i;
}
書き込む前に、カーネル ソース tar を取得し、展開して linux-xxx ディレクトリを取得します。
ファイル 1: linux-xxx/test/system_strcpy.c
linux-xxx 内にディレクトリを作成し、名前test
を付けて、このコードをファイルとして保存system_strcpy.c
します。
#include<linux/linkage.h>
#include<linux/kernel.h>
asmlinkage long system_strcpy(char*dest, const char* src)
{
int i=0;
while(src[i]!=0)
dest[i]=src[i++];
dest[i]=0;
return i;
}
ファイル 2: linux-xxx/test/Makefile上で
作成したMakefile
のと同じtest
ディレクトリ内に を作成し、次の行を入れます。
obj-y := system_strcpy.o
ファイル 3: linux-xxx/arch/x86/kernel/syscall_table_32.S
ここで、システム コールをシステム コール テーブルに追加する必要があります。次の行をファイルに追加します。
.long system_strcpy
注: カーネル 3.3 以降のバージョンの場合。
*参照:linux-3.3.xx/arch/x86/syscalls/syscall_64.tbl*
そこに、次の一連の行の最後に追加します。
310 64 process_vm_readv sys_process_vm_readv
311 64 process_vm_writev sys_process_vm_writev
312 64 kcmp sys_kcmp
313 64 システム_strcpy システム_strcpy
3.3 バージョンの形式は次のとおりです。
number
abi
name
entry point
ファイル 4: linux-xxx/arch/x86/include/asm/unistd_32.h
注: このセクションは、3.3 以降のカーネル バージョンでは冗長です。
このファイルでは、すべてのシステム コールの名前が一意の番号に関連付けられます。最後のシステム コール番号のペアの後に、行を追加します。
#define __NR_system_strcpy 338
(337 が、システム コール番号ペアの最後のシステム コールに関連付けられた番号である場合)。
次に、値を置き換えてNR_syscalls
、システム コールの総数を (既存の数を 1 ずつ増やした数) に置き換えます。つまり、この場合はNR_syscalls
338 である必要があり、新しい値は 339 です。
#define NR_syscalls 339
ファイル 5: linux-xxx/include/linux/syscalls.h
関数のプロトタイプをファイルに追加します。
asmlinkage long system_strcpy(char *dest,char *src);
#endif
ファイルの行の直前。
ファイル 6: ソース ディレクトリのルートにある Makefile。
が定義されている行を開いMakefile
て見つけ、その行の最後にcore-y
ディレクトリを追加します。test
core-y += kernel/ mm/ fs/ test/
カーネルをコンパイルします。問題:
make bzImage -j4
次のコマンドを root として (または root 権限で) 実行して、カーネルをインストールします。
make install
システムを再起動します。
最近作成されたシステム コールを使用するには、次のようにします。
syscall(338,dest,src);
(またはsyscall(313,dest,src);
カーネル 3.3+ の場合) 通常のstrcpy
ライブラリ関数の代わりに。
#include "unistd.h"
#include "sys/syscall.h"
int main()
{
char *dest=NULL,*src="Hello";
dest=(char*)malloc(strlen(src)+1);
syscall(338,dest,src);//syscall(313,dest,src); for kernel 3.3+
printf("%s \n %s\n",src,dest);
return 0;
}
の 313 などの数字の代わりに、syscall
直接使用することもできます__NR_system_strcpy
これは一般的な例です。特定のカーネル バージョンで何が機能するかを確認するには、少し実験を行う必要があります。