问:系统调用的原理,一个C函数的系统调用是怎样进入到系统的?

YoziDream 2005-01-07 01:52:30
最近学习操作系统,了解到操作系统很大一部分可以说是由其提供的系统调用组成。

以前学微机原理时只知道Dos下系统调用int 21h等中断进入到系统的代码,这样系统通过中断向用户程序开放了功能调用。

而到了现代这个时代,不管是Linux还是Windows,系统调用好像都是通过一系列的C库函数提供的。依据我对C语言的理解,编写好的程序总要链接成一个可执行文件。最近我又了解到Linux内核编译后,所有提供系统调用功能的函数应该都是链接到一个内核映像文件里,然后由引导器加载然后执行的。然后由引导器加载然后执行的。

那么,通过 C 函数来调用的系统功能,是如何进入到系统的?我的程序显然不是和内核链接在一起的。好像这也不像通常那样的动态链接呀?动态链接又是怎么实现的?

谢谢各位老大!
...全文
261 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
YoziDream 2005-01-09
  • 打赏
  • 举报
回复
这个帖子,我非要点击管理才能看到内容,不太方便,
请到
http://community.csdn.net/Expert/TopicView3.asp?id=3707697吧。

呵呵,这样也好,这个问题有200分了。
zhengda1936 2005-01-07
  • 打赏
  • 举报
回复
这个应该随着c标准库的不同而不同的吧。下面以getuid()在glibc中的实现为例:
在glibc中定义了__getuid(),然后给__getuid()去了一个别名叫getuid()。__getuid()会调用INTERNAL_SYSCALL (getuid32, err, 0)这个宏,这个宏的主要是一段汇编代码:
define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
unsigned int resultvar; \
asm volatile ( \
LOADARGS_##nr \
"movl %1, %%eax\n\t" \
"int $0x80\n\t" \
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
不过这段我也看得不是很懂,大概的意思就是用movl把__NR_getuid32这个值(对于上面的getuid来说)移到eax寄存器中,然后执行int $0x80陷入到系统调用中,再具体的过程就应该要看一下linux的系统调用的实现。
这段代码具体是做了什么还是请哪位大牛说一下
YoziDream 2005-01-07
  • 打赏
  • 举报
回复
呵呵,居然点击管理才能看到帖子!
谢谢回答,我明白一点了。但还是有点问题:

(1)系统调用有很多,是不是在执行int 80h之前,往什么地方放了些参数,才知道具体调用的那个函数?
(2)C 语言里我调用一个函数,只需要这个函数的声明就可以了,编译器又是怎么知道这是一个系统调用的呢?然后生成一个int 80h 的指令?是不是连接器在链接的时候需要什么特别信,就好像调用C 标准库函数时,连接器知道去libc库里面找这个函数的集体实现?
zdhzidy 2005-01-07
  • 打赏
  • 举报
回复
内核模块是和内核代码连接到一起运行的,并且和内核代码有一样的CPU运行级别所以可以不通过系统调用就直接访问内核空间的内容。如果用户空间要访问这部分代码同样要通过系统调用这个门来进行。

用C/C++等语言编程的时候你虽然没有直接用到int 80h来进行系统调用但是你调用的一些函数编译以后也是编程int 80h,只是你直接看不到而已。

动态连接是一个用户空间的概念,不同的系统有自己不同的可执行文件格式,Linux使用的是elf格式的可执行文件,动态连接只是把多个符合格式的文件在需要的时候加载到用户空间内存,然后把那段地址空间映射到需要调用它的进程空间中。这样用到动态库的进程就可以顺利的访问了。


PS:DOS操作系统提供的21h中断其实不是现在意义上的系统调用,而只是一个函数的入口表而已,因为DOS并没有用户空间的概念,它是一个运行的实模式下的系统。
threadpaper 2005-01-07
  • 打赏
  • 举报
回复
用户态的进程通过系统调用进入核心态,就是通过80h中断
zdhzidy 2005-01-07
  • 打赏
  • 举报
回复
先说系统调用的问题。其实任何操作系统的系统调用原理都是一样的(x86体系下)都是通过一个调用门从用户态转入核心态的,不同的系统对这个门的处理可能在细节上不同,但是反映到编程上都是int xx,比如DOS系列的就是21h中断,Linux是80h中断。由于CPU运行在保护模式下,用户空间和系统空间是分离的,系统调用要作的就是给用户空间和系统空间提供一个桥梁可以让用户访问系统空间的内容,要达到这个目的主要是改变当前CPU的运行级别。这样就可以访问系统空间,当从内核返回的时候又把CPU的运行级别改位用户级别。

4,434

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧