5

教育目的で、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 上のいくつかのガイドを読みました。

4

1 に答える 1