Linux内核调用用户空间程序的一般方法分析

9500阅读 0评论2016-07-04 kowems
分类:LINUX

当在内核空间中希望执行用户空间的程序时,我们通常会调用call_usermodehelper函数或者kernel_execve。实际上,call_usermodehelper最终也执行了kernel_execve。但call_usermodehelper所多做的是将该执行请求添加到工作队列中,待处理器执行。

函数实现在/include/linux/kmod.h中,该函数首先调用call_usermodehelper_setup初始化subprocess_info(其中包含工作队列对象)并将__call_usermodehelper作为工作队列的处理函数。然后调用call_usermodehelper_exec将工作队列对象加入到khelper_wq队列中,并等待其执行完成。__call_usermodehelper处理函数中将调用kernel_execve函数以在用户空间执行所要执行的程序。至于kernel_execve的实现,在/arch/x86/kernel/entry_64.S中实现,其将调用sys_execve系统调用。

点击(此处)折叠或打开

  1. ENTRY(kernel_execve)
  2.     CFI_STARTPROC
  3.     FAKE_STACK_FRAME $0
  4.     SAVE_ALL
  5.     movq %rsp,%rcx
  6.     call sys_execve
  7.     movq %rax, RAX(%rsp)
  8.     RESTORE_REST
  9.     testq %rax,%rax
  10.     je int_ret_from_sys_call
  11.     RESTORE_ARGS
  12.     UNFAKE_STACK_FRAME
  13.     ret
  14.     CFI_ENDPROC
  15. END(kernel_execve)


这里有个小技巧:subprocess_info中的第一个字段必须为work_struct结构,因为在工作队列执行__call_usermodehelper时,其可以获取到subprocess_info的全部内容。

分析:这里为什么要使用call_usermodehelper来执行程序呢,个人认为执行用户空间程序时,不需要占用调用者的资源和时间,由工作队列来处理即可。

遗留的问题:所要执行的程序是执行在用户空间,还是内核空间呢?个人认为应该执行在用户空间,原因很简单,当我们在用户态程序中调用该系统调用时,所执行的程序执行在用户空间。所以我推测sys_execve系统调用中,肯定会有将内核栈指针更换为用户栈指针的处理。只是猜测,需要后续找到证据。

上一篇:Centos 7 编译安装 vim7.4
下一篇:Centos7.0中 gcc升级-------使用gcc4.8.5编译gcc4.9.2