0

私はLinuxプロジェクトに取り組んでいます。ユーザー空間プログラムからカーネルに整数値のリストを渡す必要があります。このためのシステムコールを実装しました。ユーザー空間プログラムには、次のコードがありました。の値はnum_values、コマンド ライン引数から取得されます。

int* ptr=NULL;
    ptr = (int*) malloc(sizeof(int)*num_values);

    for(loop_index=0;loop_index<num_values;loop_index++)
    {
        *(ptr+loop_index)=atoi(argv[optind+loop_index]);
    }

次に、システムコールを呼び出しました。

        ret = set_wcet_val(ptr,&num_values);

カーネルでの syscall ' set_wcet_val' の実装は次のとおりです。

asmlinkage long sys_set_wcet_val(int* wcet_val, int* num_values)
{
    int retval=0, retval2=0, index, loop_index;
    int *wcet_ptr=NULL;
    retval2 = get_user(index,(int*)num_values);
    wcet_ptr = kmalloc(((sizeof(int))*index), GFP_ATOMIC);
    if(!wcet_ptr)
            printk("kmalloc:Error in allocating space..\n");
    if (copy_from_user(wcet_ptr, wcet_val, sizeof(wcet_ptr)))
    {
            printk("Syscall-wcet_val failed to copy data..\n");
    }
    for(loop_index=0;loop_index<index;loop_index++)
            printk("wcet_ptr value is %d\n",*(wcet_ptr+loop_index));
    kfree(wcet_ptr);
    return retval;

}

値 ' num_values' は ' ' に正しくコピーされましたindex。問題は、チェックしたときに最初の 2 つのデータのみが印刷されることdmesgです。が 3の場合、num_values3 番目のデータのランダムな正の値を取得しています。が 4の場合、num_values3 番目のデータはランダムな正の値、4 番目のデータは負の値です。> 4 の場合num_values、3 番目のデータの値はすべてゼロです。いずれの場合も、最初の 2 つの値のみが正しくコピーされます。この奇妙な動作の理由は何ですか?

4

1 に答える 1

0

少なくとも呼び出しを修正します (エントリcopy_from_user全体をコピーするため):index

asmlinkage long sys_set_wcet_val(int* wcet_val, int* num_values)
{
    int retval=0, retval2=0, index, loop_index;
    int *wcet_ptr=NULL;
    retval2 = get_user(index,(int*)num_values);
    wcet_ptr = kmalloc(((sizeof(int))*index), GFP_ATOMIC);
    if(!wcet_ptr)
            printk("kmalloc:Error in allocating space..\n");
    if (copy_from_user(wcet_ptr, wcet_val, (sizeof(int))*index))
    {
            printk("Syscall-wcet_val failed to copy data..\n");
    }
    for(loop_index=0;loop_index<index;loop_index++)
            printk("wcet_ptr value is %d\n",*(wcet_ptr+loop_index));
    kfree(wcet_ptr);
    return retval;
}

それへのポインターではなく、直接渡す方が良いでしょうnum_values(何らかの方法で変更する必要がない限り):

asmlinkage long sys_set_wcet_val(int* wcet_val, int num_values)
{
    int retval=0, loop_index;
    int *wcet_ptr=NULL;
    wcet_ptr = kmalloc(((sizeof(int))*num_values), GFP_ATOMIC);
    if(!wcet_ptr)
            printk("kmalloc:Error in allocating space..\n");
    if (copy_from_user(wcet_ptr, wcet_val, (sizeof(int))*num_values))
    {
            printk("Syscall-wcet_val failed to copy data..\n");
    }
    for(loop_index=0;loop_index<num_values;loop_index++)
            printk("wcet_ptr value is %d\n",*(wcet_ptr+loop_index));
    kfree(wcet_ptr);
    return retval;
}

として呼び出しますret = set_wcet_val(ptr, num_values);

しかし、あなたができる最善の方法は、syscall を取り除き、代わりに kobject を使用することだと思います。kobject_create_and_add、、sysfs_create_groupを探しstruct attribute_groupます。

于 2014-07-04T16:06:00.797 に答える