教育目的で、Debian Wheezy にシステム コールを実装したいと考えています。linux-image-3.2.0--rt-amd64 パッケージに含まれるカーネルに実装したいと考えています。これが私が試したことの概要です:
カーネル ソースを取得するには:
apt-get source linux-image-3.2.0-4-rt-amd64
そこから、実行したディレクトリから次のファイル/ディレクトリを取得します。
linux_3.2.41.orig.tar.xz
linux_3.2.41-2+deb7u2.dsc
linux_3.2.41-2+deb7u2.debian.tar.xz
としても:
linux_3.2.41
カーネルのソースコードが含まれています。
次に、システム コールを追加するために必要な変更を行うために、基本的にこのページに従いました: debian/ubuntu でシステム コールを作成する方法
以下は、私が行った変更を反映するために修正された、そこにある指示の要約版です。
+ファイル 1: linux-xxx/vpart_syscalls/vpart_syscalls.c
#include <linux/linkage.h>
#include <linux/kernel.h>
asmlinkage long insert_partition(char*dest, const char* src)
{
printk("<--- the syscall has been called!");
return 0;
}
ファイル 2: linux-xxx/vpart_syscalls/Makefile。上で作成したのと同じ test ディレクトリ内に Makefile を作成し、次の行を入れます。
obj-y := vpart_syscalls.o
ファイル 3: linux-xxx/arch/x86/kernel/syscall_table_32.S. ここで、システム コールをシステム コール テーブルに追加する必要があります。次の行をファイルに追加します。
.long insert_partition
ファイル 4: linux-xxx/arch/x86/include/asm/unistd_32.h
このファイルでは、すべてのシステム コールの名前が一意の番号に関連付けられます。最後のシステム コール番号のペアの後に、行を追加します。
#define __NR_insert_partition 349
次に、NR_syscalls の値を置き換え、システム コールの総数を (既存の数を 1 ずつ増やした数) に置き換えます。つまり、この場合、NR_syscalls は 338 である必要があり、新しい値は 339 です。
#define NR_syscalls 350
- ファイル 5: linux-xxx/include/linux/syscalls.h
関数のプロトタイプをファイルに追加します。
asmlinkage long insert_partition(int lenTicks, int vpid);
ファイルの #endif 行の直前。
- ファイル 6: ソース ディレクトリのルートにある Makefile。
Makefile を開き、core-y が定義されている行を見つけ、ディレクトリ test をその行の最後に追加します。
core-y += kernel/ mm/ fs/ test/ vpart_syscalls/
次に、ここで説明されている方法とは異なる方法でカーネルを構築しました。
make localmodconfig
make menuconfig (making no changes)
make-kpkg clean
fakeroot make-kpkg --initrd --append-to-version=+tm kernel_image kernel_headers
cd ..
dpkg -i linux-image-3.8.*
dpkg -i linux-headers-3.8.*
インストールされたカーネルは正常に起動します。システムコールをテストするために、次の C プログラムを作成しました。
#include <stdio.h>
#include <linux/unistd.h>
#include <sys/syscall.h>
int main(){
printk("Calling the new syscall!\n");
int ret = 100;
ret = syscall(349, 1, 2);
printf("call return value: %i\n", ret);
return 0;
}
このプログラムをコンパイルして実行すると、戻り値 -1 が返されます。dmesg を使用してメッセージを確認しましたが、printk が呼び出された形跡はありません。
誰かが私の問題がどこにあるかを知っていれば、本当に嬉しいです! 私はカーネルの変更や構築に関してはあまり経験がありませんが、それについて多くのことを学びました。Robert Loves の本 - Linux カーネル開発と Web 上のいくつかのガイドを読みました。