2017-02-26 22 views
1

系統調用函數對於一個家庭作業,我要修改Linux內核。問題調用用C

我的工作在虛擬機上,並且我添加了一個系統調用到內核,我把它叫做get_unique_id。下面是get_unique_id.c代碼:

#include <linux/linkage.h> 
#include <asm/uaccess.h> 

asmlinkage long sys_get_unique_id(int * uuid) 
{ 
    // static because we want its state to persist between calls 
    static int uid = 0; 

    ++uid; 

    // assign new uid value to user-provided mem location 
    // returns non-zero if success or -EFAULT otherwise 
    int ret = put_user(uid, uuid); 
    return ret; 
} 

我還添加了此行syscalls.h

asmlinkage long sys_get_unique_id(int * uuid); 

此行syscall_32.tbl:

383 i386 get_unique_id  sys_get_unique_id 

最後這行syscall_64.tbl

548 common get_unique_id  sys_get_unique_id 

重新編譯和重新加載內核之後,我寫了一個小C程序來測試我的系統調用,這裏是用於C測試文件的代碼:

// get_unique_id_test.c 
#include <stdio.h> 
#include <limits.h> 

#include "syscalls_test.h" 

int main(void) 
{ 
    // initialize the ints we want 
    int id1; 
    int id2; 

    // check the id's are unique and that no error occured 
    for (int i = INT_MIN; i < INT_MAX - 1; i += 2) { 
     long ret1 = get_unique_id(&id1); 
     long ret2 = get_unique_id(&id2); 

     if (ret1 != 0) 
      printf("ERROR: get_unique_id returned: %ld\n", ret1); 

     if (ret2 != 0) 
      printf("ERROR: get_unique_id returned: %ld\n", ret2); 

     if (id2 != id1 + 1) 
      printf("ERROR: successive id's did not increment properly: id1 = %d, id2 = %d\n", id1, id2); 
    } 

    return 0; 
} 

而其頭文件:

// syscalls_test.h 
#include <errno.h> 
#include <sys/syscall.h> 
#include <sys/types.h> 
#include <unistd.h> 

#define __NR_get_unique_id 383 

inline long get_unique_id(int * uuid) 
{ 
    return syscall(__NR_get_unique_id, uuid) ? errno : 0; 
} 

不幸的是,在試圖編譯以下命令C測試文件:gcc -std=c99 get_unique_id_test.c -o get_unique_id_test,我得到以下錯誤:

In file included from get_unique_id_test.c:4:0: 
syscalls_test.h: In function ‘get_unique_id’: 
syscalls_test.h:10:5: warning: implicit declaration of function  ‘syscall’ [-Wimplicit-function-declaration] 
    return syscall(__NR_get_unique_id, uuid) ? errno : 0; 
    ^
syscalls_test.h: In function ‘get_unique_id’: 
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration] 
    return syscall(__NR_get_unique_id, uuid) ? errno : 0; 
    ^
/tmp/cc1euZ3r.o: In function `main': 
get_unique_id_test.c:(.text+0x22): undefined reference to `get_unique_id' 
get_unique_id_test.c:(.text+0x34): undefined reference to `get_unique_id' 
collect2: error: ld returned 1 exit status 

看來GCC找不到功能get_unique_id(int * uuid),這是在syscalls_test.h宣佈,與syscall功能,應聲明,我相信,在syscall.h,對不對?

我不明白爲什麼會發生這種情況。有人有想法嗎?

編輯:使用A3F的解決方案(見下文)PLUS在文件的最頂端移動#include "syscalls_test.h",因爲他在評論中說,我的問題就解決了。非常感謝你。

+2

首先在'syscalls_test.h'的頂部添加'#define _GNU_SOURCE' – StoryTeller

+2

FYI'sys_get_unique_id'不是線程安全的;多個線程可以同時調用它並獲得相同的值。你可以用'atomic_t'來解決這個問題。 –

+0

是的,我知道,現在我的系統調用非常簡單,但我目前正試圖使其線程安全。 – Scrashdown

回答

1
  • #define _GNU_SOURCE之前包括unistd.h或任何其它標頭,如syscall(2)不是POSIX。
  • 使用static inline而不是純inline。 Plain inline提供了內聯定義,但編譯器可以自由地忽略它並使用外部定義,而不是您提供的。
+0

謝謝,在我的函數中加入'static'解決了錯誤。有一些我不明白的東西,難道不會讓'get_unique_id'函數在syscalls_test.h'文件之外不可見? – Scrashdown

+0

我接着說:#定義_GNU_SOURCE'像你說的,但是我還是syscall'的'隱函數聲明的警告。但我只有一次,而不是像以前那樣兩次。 – Scrashdown

+0

'#define'作爲第一件事,在包含任何頭文件之前。 'static'在翻譯單元內部產生一個函數,一個文件可以包含多個頭文件,所以翻譯單元可以包含多個文件,並且所有這些文件都可以使用static函數。 – a3f