Syscall系統調用Linux核心跟蹤

來源:互聯網
上載者:User
    在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 interface)的實現機制實際上是一個多路匯聚以及分解的過程,該匯聚點就是 0x80 中斷這個進入點(X86 系統結構)。也就是說,所有系統調用都從使用者空間中匯聚到 0x80 中斷點,同時儲存具體的系統調用號。當 0x80 中斷處理常式運行時,將根據系統調用號對不同的系統調用分別處理(調用不同的核心功能處理)。

引起系統調用的兩種途徑

      (1)int $0×80 , 老式linux核心版本中引起系統調用的唯一方式

      (2)sysenter彙編指令

在Linux核心中使用下面的宏進行系統調用

SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
    struct file *file;
    ssize_t ret = -EBADF;
    int fput_needed;

    file = fget_light(fd, &fput_needed);
    if (file) {
        loff_t pos = file_pos_read(file);
        ret = vfs_read(file, buf, count, &pos);
        file_pos_write(file, pos);
        fput_light(file, fput_needed);
    }

    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[] = {            \
        __SC_STR_TDECL##x(__VA_ARGS__)            \
    };                            \
    static const char *args_##sname[] = {            \
        __SC_STR_ADECL##x(__VA_ARGS__)            \
    };                            \
    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__)

#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS

#define SYSCALL_DEFINE(name) static inline long SYSC_##name

#define __SYSCALL_DEFINEx(x, name, ...)                    \
    asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__));        \
    static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__));    \
    asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__))        \
    {                                \
        __SC_TEST##x(__VA_ARGS__);                \
        return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__));    \
    }                                \
    SYSCALL_ALIAS(sys##name, SyS##name);                \
    static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__))

#else /* CONFIG_HAVE_SYSCALL_WRAPPERS */

#define SYSCALL_DEFINE(name) asmlinkage long sys_##name
#define __SYSCALL_DEFINEx(x, name, ...)                    \
    asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))

#endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */

最終會調用下面類型的宏定義:

asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))
也就是我們前面提到的sys_read()系統函數。
asmlinkage通知編譯器僅從棧中提取該函數的參數。所有的系統調用都需要這個限定詞!這和我們上一篇文章quagga中提到的宏定義,有異曲同工之妙。

也就是宏定義中的下面代碼:

struct file *file;
    ssize_t ret = -EBADF;
    int fput_needed;

    file = fget_light(fd, &fput_needed);
    if (file) {
        loff_t pos = file_pos_read(file);
        ret = vfs_read(file, buf, count, &pos);
        file_pos_write(file, pos);
        fput_light(file, fput_needed);
    }

    return ret;

代碼解析:

  • fget_light() :根據 fd 指定的索引,從當前進程描述符中取出相應的 file 對象(見圖3)。
  • 如果沒找到指定的 file 對象,則返回錯誤
  • 如果找到了指定的 file 對象:
  • 調用 file_pos_read() 函數取出此次讀寫檔案的當前位置。
  • 調用 vfs_read() 執行檔案讀取操作,而這個函數最終調用 file->f_op.read() 指向的函數,代碼如下:

if (file->f_op->read)
ret = file->f_op->read(file, buf, count, pos);

  • 調用 file_pos_write() 更新檔案的當前讀寫位置。
  • 調用 fput_light() 更新檔案的引用計數。
  • 最後返回讀取資料的位元組數。

到此,虛擬檔案系統層所做的處理就完成了,控制權交給了 ext2 檔案系統層。

http://blogold.chinaunix.net/u3/104447/showart_2527011.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.