分享

linux

 astrotycoon 2013-08-31
 在2.6.20的内核下编译LDD3的setlevel.c时会报错,安装VMWare Workstation 5.5.3版本的时候也会报错,提示是一样的:_syscallN那行出错。仔细看了一下2.6.20的unistd.h,发现已经没有_syscallN的声明了。对于上述两个错误的地方,直接注释掉那一行就可以了。

记得以前看过的资料,系统调用从用户空间切换到内核空间可以依靠两种方法进行:
  1. 包含<unistd.h>并声明需要的_syscallN,_syscallN负责进行int $0x80。
  2. C库的INLINE_SYSCALL帮助完成int $0x80。
现在看来,内核中已经取消了_syscallN,那么是完全依靠C库触发陷阱门,完成运行空间的切换了。这其实是一个非常大的改变。即使是依靠C库,触发的方式也不再仅仅是INLINE_SYSCALL这一种,而是在不同的条件编译时会有不同的解决方案。

FC6的glibc版本是2.5,通过察看glibc编译过程中生成的sysd-syscalls文件及其指向的各个系统调用的源文件,可以看到,系统调用基本上是通过三种方式完成的:
  1. PESUDO:绝大多数(80%+)系统调用是通过这种方式完成的。仔细分析glibc-2.5和linux-2.6.20的源码,可以看出这种系统调用从用户空间发起直到内核空间响应的全过程如附图所示。要注意的是,浅蓝色部分只有在从源码编译glibc的过程中才能看到。
  2. INTERNAL_SYSCALL:一部分系统调用通过这个类似于原来的INLINE_CALL的宏完成从用户空间向内核空间的切换,大致过程与PESUDO基本上差不多。
  3. 还有极少数的系统调用是通过其他系统调用的结果在运行库中计算出来的,例如ftime就调用了gettimeofday,然后在运行库中格式化了返回的字符串,根本没有进行ftime的系统调用。
现在遗留的问题是:如果修改内核增加了自定义的系统调用,怎样能够从用户空间调用它呢。修改glibc?仿佛太麻烦了。一种可行的方法是:自己定义类似于_syscallN的宏,待试验。。。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多