Linuxカーネル追加システムコール

4282 ワード

1、目的:
既存のシステムにパラメータを渡さないシステム呼び出しを追加します.このシステム呼び出しの機能は、システム内のすべてのプロセスを遍歴することである.実験の主な内容:
  • システム呼び出しの名前を追加
  • 標準Cライブラリによる包装
  • システムコール番号
  • を追加
  • システム呼び出しテーブルに対応するテーブル項目
  • を追加する
  • sys_mysyscallの実装
  • ユーザ状態試験プログラム
  • を作成する.
    2、手順:
    a)依存ライブラリのインストール:
    sudo apt-get install libncurses5-dev //    ncurses ,   
    

    b)カーネルソースコードをダウンロードする(バージョン3.6.8を例とする):
    linux-3.6.8.tar.bz 2ファイルは、/homeディレクトリに置けばいいです.
    c)カーネルソースコードを解凍する:
    #su //    ,      root  。  sudo  
    #mv linux-3.6.8.tar.bz2 ~ //            。
    # cd ~	//     
    # tar jxvf linux-3.6.8.tar.bz2 //     ,          linux.3.6.8   
    # cd linux-3.6.8

    d)カーネルのシステム呼び出しライブラリ関数を修正する:
    Ubuntu12.04(変更なし):
    /usr/include/asm-generic/unistd.h

    Kernel 3.6.8で変更するには、次の手順に従います.
    include/asm-generic/unistd.h

    入力後、次のように変更されます.
    ここで223番システム呼び出しはsyscall_tableでは使用されていないので、呼び出しに変更できます.
    /* mm/fadvise.c */
    /*
    #define __NR3264_fadvise64 223
    __SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
    */
    #define __NR_rksyscall 223
    __SYSCALL(__NR_rksyscall, sys_rksyscall)
    

    システム呼び出し番号を追加すると、この番号に基づいてインデックスとしてsyscallを探すことができます.tableの対応するテーブル・アイテム.
    次のステップは
    e)システム呼び出しテーブルに対応するテーブル項目を追加または修正する
    上記の手順で解凍したカーネルソースパッケージで、関連する関数を変更します.
    次のディレクトリに進みます.
    arch/x86/kernel/syscall_table_32.S
    
    番号223に対応するコードセグメントを変更します.
    # 222 is unused
    # 223 is used now
    223 i386 mysyscall sys_rksyscall
    224 i386 gettid sys_gettid
    225 i386 readahead sys_readahead

    これまでシステムはsys_を正しく見つけて呼び出すことができた.mysyscall.あとは一つだけ
    sys_ですrksyscallの実装.
    f)sys_rksyscallの実装:kernel/sysにこの小さなプログラムを追加します.cの中.ここではkernelディレクトリの下に他の
    自分のファイルを追加するのは簡単で、Makefileを修正する必要がなく、不要な麻を省くためです.
    うるさい.
    rksyscallシステム呼び出しは、システム内のすべてのプロセスを遍歴し、各プロセスのプロセス名(name)、進を印刷する.
    スレッド識別子(pid)、プロセスのステータス、および親プロセスの名前.
    asmlinkage int sys_mysyscall(void)
    {
    	//            
    	struct task_struct *p;
        	printk("********************************************
    "); printk("------------the output of rkcall------------
    "); printk("********************************************

    "); printk("%-20s %-6s %-6s %-20s
    ","Name","pid","state","ParentName"); for(p = &init_task; (p = next_task(p)) != &init_task;) printk("%-20s %-6d %-6d %-20s
    ",p->comm , p->pid, p->state, p->parent->comm); return 0; }

    g)カーネルを再コンパイルする:
    cp /boot/config- .config //      
    cp /boot/config-`uname -r` .config //          
    

    h)プロファイルの生成
    make menuconfig //     .config  
    

    次のステップは、念のためです.
      3.6.8        
    “ERROR:”__modver_version_show” [drivers/staging/rts5319/rts5319.ko] underfined”。
      make menuconfig      :
    	Device drivers ---
    		Staging drivers--
    			Realtek RTS5139 USB card reader support
       [M]    [ ](3.6.8       ,     N),       

    i)カーネルコンパイルプロセス
    sudo make   sudo make -j2(-j2        )(    1-2    )
    # sudo make modules_install
    # sudo make install
             # gedit /boot/grub/grub.cfg
        
    sudo reboot
    //           
    
              
    uname -r
    3.6.8

    j)ユーザ状態プログラムの作成
    新しく追加されたシステム呼び出しをテストするには、rksyscallシステム呼び出しを呼び出すユーザ状態テストプログラム(test.c)を作成する必要があります.
    rksyscallシステム呼び出しでprintk関数が出力する情報は/var/log/messagesファイルにあります.
    ユーザ状態テストプログラムが/var/log/messageファイルから各プロセスのプロセス名、プロセス識別子、プロセスの状態を読み出す
    (例:運転、割り込み可能な待機......)親プロセスの名前を分析し、画面に出力します.
    /var/log/messageファイルの内容はshellの下でdmesgコマンドで表示することもできます.
    Linux 2.6.25以降のカーネル、マクロ_Syscall 0()から_Syscall 6()は/usr/include/asm/unistdで定義されません.hでは、
    したがってsyscall()関数を使用してシステム呼び出しを実現する必要がある.
    ユーザ状態テストプログラムは以下の方法で実現できる.
    #include 
    #include 
    //           
    //#define __NR_ mysyscall 223
    //    
    int main()
    {
    	syscall(__NR_mysyscall);	/*  syscall(223) */
    	//                    ;
    	//   /var/log/message        。
    }
    //    
    gcc -o test test.c
    ./test
    dmesg	//      

    最終出力結果:
    プロセス名、プロセスpid、プロセスステータス、親プロセスに従って分類されていることがわかります.