実験オペレーティングシステム価値付加価値のシステムコールと読み書きするために、スレッドを閉じます

実験オペレーティングシステム価値付加価値のシステムコールと読み書きするために、スレッドを閉じます

オペレーティングシステム:Ubuntuの

カーネルのバージョン:kernel5.5.5

Aの全体的なアイデア

コンピュータのユーザーモードとカーネルモードは二つの状態に分割され、上部空間はユーザーモードアプリケーションが下との直接接触から制限されています。ハードウェアのカーネルモードの直接制御、ユーザーモード用の操作環境を提供します。2コントロールチューブとの間の訪問があり、直接アクセスすることはできません。あなたがユーザーモードからカーネルモードに入った場合は、システムコールを必要とします。システムコールインタフェース機能は、ユーザーモードとカーネルモードのシリーズです。

独自のシステムコールを追加し、次の3つのステップを必要としています。

まず、システムコールを追加するためのシステムコールテーブル

第二に、申告システムコールサービス・ルーチンのプロトタイプ

第三に、システムコールを達成するために

再起動をコンパイルし、カーネルのコード補完を変更した後、あなたはあなた自身のシステムが関数を呼び出す呼び出すことができます。

あなたは値の値を変更することができ、あなたがプロセスを強制終了することができ、入ってくるPIDを、そしてプロセスの値PRIO値を読むことができます:コール機能の機能が実装されています。

2つの具体的な実装

私のカーネルのバージョンは5.5.5ですので、USR / SRC /カーネルのルートディレクトリのlinux-5.5.5、ディレクトリ操作を入力してください

まず、システムコールを追加するためのシステムコールテーブル

システムコールテーブルが./arch/x86/entry/syscalls/syscall64.tblです

テーブルの末尾にシステムコール番号を追加します。

ネームサービスルーチンのエントリー空いコール番号のx32 / x64の/共通のシステムコール

550 common mysetprocess __x64_sys_mysetprocess

II。

サービスルーチンのプロトタイプ宣言./include/linux/syscalls.h

asmlinkage int sys_mysetprocess(pid_t pid, int flag, int nicevalue,void __user * prio, void __user * nice);

5つのパラメータ:

PID:PID演算スレッド

フラグ:オペレーションコード、値0は、変更された値の値は、プロセスは2を殺す読み取ります

nicevalue:値の値を変更するには

PRIO、素敵:copy_to_userコール()関数は、カーネルモードPRIOを読み取るために、素敵なユーザーに配信しました

第三に、システムコールを達成するために

	在./kernel/sys.c中实现系统调用函数
```
SYSCALL_DEFINE5(mysetprocess,pid_t,pid, int, flag, int, nicevalue,void __user *, prio, void __user *, nice){
if(find_get_pid(pid)==NULL){
	printk("input pid error.");
	return EFAULT;
}
struct pid * kpid;
struct task_struct * task;
kpid = find_get_pid(pid);
task = pid_task(kpid,PIDTYPE_PID);
int cur_nice;
int cur_prio;
cur_nice=task_nice(task);
cur_prio=task_prio(task);
if(flag==1){
	//set process's nice
	set_user_nice(task,nicevalue);
	cur_nice=task_nice(task);
	cur_prio=task_prio(task);
	printk("the nice value is changed!\n");
	printk("current nice is %d and piro is %d.\n",cur_nice,cur_prio);
}else if(flag==0){
	//get process's nice
	printk("current nice is %d and piro is %d.\n",cur_nice,cur_prio);
}else if(flag==2){
	//safely kill process by pid
	kill_pid(kpid,SIGTERM,1);
	printk("process is killed safely.\n");
	return 0;
}else{
	printk("operate failed.\n");
	return EFAULT;
}
copy_to_user(prio,&cur_prio,sizeof(cur_prio));
copy_to_user(nice,&cur_nice,sizeof(cur_nice));
return 0;
}

この関数は、単純な命令を使用しています

find_get_pid(pid_t NR)

取得したプロセスID NR処理記述子構造体のPID

pid_task(構造体には、列挙型pid_type * PIDをPID)

PIDTYPE_PIDは、プロセス番号を示し、プロセスに従い、

プロセスの記述によると、タスクの記述を返さ

task_nice(定数構造体task_struct * P)、素敵な范围-20-19

復帰処理ナイス値

task_prio(定数構造体task_struct * P)

復帰処理PRIO値

set_user_nice(構造体task_struct * P、長い素敵な)

プロセスのnice値

kill_pid(構造体のpid *のpid、int型SIG、int型PRIV)

SIGプログラムが終了SIGTERM信号に設定されている、SIGTERMは、通常、プログラムが終了し、ブロックし、処理することができます。

1 PRIVセット、SEND_SIG_PRIV送信信号、

プロセス記述子、信号の終わりを送り、プロセスを強制終了

(unsigned long型のn、からのconst void *型に無効__user *)copy_to_user

ユーザ空間にカーネル空間からコンテンツをコピーします

nがコピースペースを表し

第四には、カーネルをコンパイル

カーネル時間がかかる(シングルコア、2つの時間)は、(少なくとも30G空間レディ)大きなスペースを占有するコンパイル、患者であります

linux-5.5.5ディレクトリの下に

メークmenuconfigをした後、出口のセーブを選択

-j4(推奨マルチコアのコンパイルを、約2倍の高速で、仮想マシンはより多くのパラメータがより監査できる割り当てられている)を作ります

メイクmodules_install

make installを

コンパイルが成功するかどうかを判断するために、現在のカーネルバージョンは、una​​me -rを表示するために使用します

(コンパイル済みのフットプリントを清掃する前に必須の使用、)ビルドファイルクリーンアップクリーン作ります

再起動

コンパイラは問題がある場合は、非常に詳細に説明し、この記事https://www.govzzp.cn/?p=198を参照することをお勧めします

第五に、テスト・システムコール

書き込みCプログラム、成功を追加するかどうかをテストシステムコール

#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>

int main(){
    int pid,flag,nicevalue,prio,nice;
    char control;
 
    printf("请输入pid:\n");
    scanf("%d",&pid);
    printf("读入:0,修改:1, 杀死: 2 \n");
    scanf("%d",&flag);
    if(flag!=0&&flag!=1&&flag!=2){
        printf("输入错误");
        return 1;
    }

    if(flag==0){
        int res = syscall(550,pid ,flag,0,&prio,&nice);
        if(res!=0){
            printf("进程不存在!\n");
            return 1;
        }
        printf("进程的nice值为%d,prio值为%d\n",nice,prio);
    }else if(flag==1){
        printf("请输入要修改的nice值:\n");
        scanf("%d",&nicevalue);
        int res = syscall(550,pid,flag,nicevalue,&prio,&nice);
        if(res!=0){
            printf("进程不存在!\n");
            return 1;
        }
        printf("修改成功!\n");
        printf("进程的nice值为%d,prio值为%d\n",nice,prio);
    }else if(flag==2){
	int res = syscall(550,pid,flag,0,&prio,&nice);
	if(res!=0){
            printf("进程不存在!\n");
            return 1;
        }
	
	printf("杀死进程成功.\n");
    }
 
 return 0;

}

テストの実行:
ここに画像を挿入説明
dmesgのログで
ここに画像を挿入説明

成功!

元の記事を公開 ウォンの賞賛0 ビュー2

おすすめ

転載: blog.csdn.net/getafox/article/details/104977858