2017-07-24 60 views
6

我在擺弄系統調用。我添加了兩個新的並驗證他們使用呼叫syscall在執行系統調用時,您如何將系統調用號碼公開給userland?

我想將系統調用號碼放在頭文件中,以便用戶空間不必明確地知道系統調用號碼。

arch/x86/syscalls/syscall_64.tbl我:

317  64  krun_read_msrs     sys_krun_read_msrs 
318  64  krun_reset_msrs     sys_krun_reset_msrs 

有些grepping暗示的kbuild已經自動生成宏爲新的系統調用:

$ ag __NR_krun * 
arch/x86/include/generated/uapi/asm/unistd_64.h 
321:#define __NR_krun_read_msrs 317 
322:#define __NR_krun_reset_msrs 318 

的文件名顯示,我不需要手動添加條目,但這與Linux Kernel文檔不得不說的相反:

Some architectures (e.g. x86) have their own architecture-specific syscall tables, but several other architectures share a generic syscall table. Add your new system call to the generic list by adding an entry to the list in include/uapi/asm-generic/unistd.h: 

#define __NR_xyzzy 292 
__SYSCALL(__NR_xyzzy, sys_xyzzy) 

那麼,我的系統調用是x86_64特定的,因爲他們讀取和寫入僅在英特爾芯片中找到的MSR。所以在此之後,我開始研究是否可以找到我的amd64系統的arch-specific header。

你會期望它在arch/x86_64之下,但是在那裏根本沒有包含。所以我認爲x86_64繼承自x86。既然如此,具體拱頭應該是:

arch/x86/include/uapi/asm/unistd.h 

如果打開了,它只是一個小包裝派遣基礎上拱:

# ifdef __i386__                 
# include <asm/unistd_32.h>              
# elif defined(__ILP32__)              
# include <asm/unistd_x32.h>             
# else                   
# include <asm/unistd_64.h>              
# endif 

所以這大概是設計來接up /usr/include/x86_64-linux-gnu/asm/unistd.h,但這還不包括我的新系統調用號碼。

我希望headers_install目標安裝新的標題(也許),但可惜它沒有。

我很困惑。我應該手動添加我的新系統調用到文件嗎?如果是這樣的文件?如果不是,我如何將自動生成的__NR_*宏暴露給標準位置的用戶空間?

謝謝

+2

如果您在庫中實現包裝函數以調用系統調用,則不一定需要。畢竟,這是C庫在POSIXy系統上所做的大部分工作。您可以讓庫頭文件公開系統調用號(適用於當前體系結構)。要爲所有Linux用戶提供新的系統調用,您需要將補丁上傳到Linux內核(通過LKML)以及GNU C庫或特定的發行版,以便將更改添加到他們的系統頭文件中。 –

+0

是的,這不是真的可行,因爲系統調用不適合一般用途。 –

+0

什麼(不可行),將系統調用封裝到函數中? (如果你的意思是把它推到上游,我同意)。但你真的應該考慮把系統調用包裝到函數中去;即使像頭文件中的靜態內聯函數一樣,根據拱和字大小(使用預處理器宏)選擇適當的系統調用號。提供* extra *頭文件以及修改後的內核(或內核修改)要比在標準頭文件中包含額外的項目容易得多。 –

回答

1

那麼,我有一個部分的答案。部分原因是因爲它是Debian特有的。

如果您在內核源代碼中使用make deb-pkg目標,則會在父目錄中創建.deb包。如果你安裝了這些,那麼你的頭文件會被安裝到系統中。

這樣做了上述我的內核後:

$ grep krun /usr/include 
/usr/include/asm/unistd_64.h:#define __NR_krun_read_msrs 317 
/usr/include/asm/unistd_64.h:#define __NR_krun_reset_msrs 318 
2

內核構建過程分配實際的系統調用號是內核構建過程的一部分...所以你沒有得到實際的最終數字,但僅限於已經構建的內核。構建你的內核,你會在構建的頭文件中看到實際的分配。恐怕你已經試圖在一個乾淨的內核源代碼中搜索它們,這就是你找不到合適的包含文件的原因。

在另一側,hidding實際系統呼叫號碼是很常見的,它是由一些包裝例程,其包括上述的內核頭完成的,並使用#define d符號來表示的呼叫號碼,以使__SYSCAL(...)實際呼叫。這通常甚至是必要的,因爲每個系統調用通常具有不同的接口。您使用的所有正常系統調用都在stdlib中包含了它們的包裝器,但不包含新包裝器。這裏有兩種方法:修補標準C庫以包含(並在/usr/include的某處爲函數原型編寫標準頭文件)在所有程序中包含包裝文件mySysCall.o(此名稱在您方便時)在你要使用新的系統調用的地方。