在linux的使用者空間,我們經常會呼叫系統呼叫,下面我們跟蹤一下read系統呼叫,使用的linux核心版本為linux2.6.37。不同的linux版本其中的實現略有不同。
在一些應用中我們可以看到下面的一些定義:
#define real_read(fd, buf, count ) (syscall(sys_read, (fd), (buf), (count)))
其實真正呼叫的還是系統函式syscall(sys_read),也就是sys_read()函式中,在linux2.6.37中的利用幾個巨集定義實現。
linux 系統呼叫(sci,system call inte***ce)的實現機制實際上是乙個多路匯聚以及分解的過程,該匯聚點就是 0x80 中斷這個入口點(x86 系統結構)。也就是說,所有系統呼叫都從使用者空間中匯聚到 0x80 中斷點,同時儲存具體的系統呼叫號。當 0x80 中斷處理程式執行時,將根據系統呼叫號對不同的系統呼叫分別處理(呼叫不同的核心函式處理)。
引起系統呼叫的兩種途徑
(1)int $0×80 , 老式linux核心版本中引起系統呼叫的唯一方式
(2)sysenter彙編指令
在linux核心中使用下面的巨集進行系統呼叫
syscall_define3(read, unsigned int, fd, char __user *, buf, size_t, count)
return ret;
}
其中syscall_define3的巨集定義如下:
#define syscall_define3(name, ...) syscall_definex(3, _##name, __va_args__)
##的意思就是巨集中的字元直接替換,
如果name = read,那麼在巨集中__nr_##name就替換成了__nr_read了。 __nr_##name是系統呼叫號,##指的是兩次巨集展開.即用實際的系統呼叫名字代替"name",然後再把__nr_...展開.如name == ioctl,則為__nr_ioctl。
#ifdef config_ftrace_syscalls
#define syscall_definex(x, sname, ...) \
static const char *types_##sname = ; \
static const char *args_##sname = ; \
syscall_metadata(sname, x); \
__syscall_definex(x, sname, __va_args__)
#else
#define syscall_definex(x, sname, ...) \
__syscall_definex(x, sname, __va_args__)
#endif
不管是否定義config_ftrace_syscalls巨集,最終都會執行下面的這個巨集定義:
__syscall_definex(x, sname, __va_args__)
最終會呼叫下面型別的巨集定義:
asmlinkage long sys##name(__sc_decl##x(__va_args__))
也就是巨集定義中的下面**:
struct file *file;
ssize_t ret = -ebadf;
int fput_needed;
file = fget_light(fd, &fput_needed);
if (file)
return ret;
**解析:
if (file->f_op->read)
ret = file->f_op->read(file, buf, count, pos);
到此,虛擬檔案系統層所做的處理就完成了,控制權交給了 ext2 檔案系統層。
Linux系統呼叫 syscall 原理
linux體系結構 核心空間與使用者空間是程式執行的兩種不同狀態,通過系統呼叫和硬體中斷能夠完成從使用者空間到核心空間的轉移。如下圖所示 linux 體系結構圖 從上圖得知,linux由使用者空間和核心空間 一般情況下,使用者程序是不能訪問核心的。它既不能訪問核心所在的記憶體空間,也不能呼叫核心中的...
Linux系統呼叫 使用syscall
博主的另一篇博文介紹了如何使用int 0x80指令進行linux系統呼叫,這一篇博文介紹一下如何使用另一種方式 syscall指令進行linux系統呼叫,然後會簡要說明二者的不同。通過syscall指令進行linux系統呼叫與通過int 0x80指令進行linux系統呼叫在使用上差別不大,系統呼叫號...
Syscall系統呼叫Linux核心跟蹤
在linux的使用者空間,我們經常會呼叫系統呼叫,下面我們跟蹤一下read系統呼叫,使用的linux核心版本為linux2.6.37。不同的linux版本其中的實現略有不同。在一些應用中我們可以看到下面的一些定義 define real read fd,buf,count syscall sys r...