`
cloudtech
  • 浏览: 4619560 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

linux系统调用简要分析

 
阅读更多

最近又看linux的0.11版本内核,看main.c函数的时候,发现在一个函数调用fork()。竟找不到它的定义,仔细一看,原来都是宏搞的鬼。
在main.c里有这样一句:
static inline _syscall0(int,fork)
查找它的定义,在unistd.h里找到:
#define __NR_setup 0 /* used only by init, to get system going */
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
//略过N行.....

#define _syscall0(type,name) /
type name(void) /
{ /
long __res; /
__asm__ volatile ("int $0x80" /
: "=a" (__res) /
: "0" (__NR_##name)); /
if (__res >= 0) /
return (type) __res; /
errno = -__res; /
return -1; /
}

现在分析一下,unistd.h应该就是定义了unix操作系统的标准。所以__NR_setup、__NR_exit、__NR_fork等宏应该就是一些标准。而在宏_syscall0里的__NR_##name也就是将“__NR_”和“name”连结起来。
对于“static inline _syscall0(int,fork)”进行面预处理后就会变成:
int fork(void)
{
long __res;
__asm__ volatile ("int $0x80"
: "=a" (__res)
: "0" (2));
if (__res >= 0)
return (type) __res;
errno = -__res;
return -1;
}
这个函数的关键代码就是下面三行:
__asm__ volatile ("int $0x80"
: "=a" (__res)
: "0" (2));
从代码可以看到2就是系统调用的参数,__res就是返回值,而且参数和返回值都存放在eax里。int是中断指令,那一定存在着设置中断门的语句,在sched.c里找到:
set_system_gate(0x80,&system_call);
而在文件system_call.s里,找到它的定义:
system_call:
cmpl $nr_system_calls-1,%eax
ja bad_sys_call
push %ds
push %es
push %fs
pushl %edx
pushl %ecx # push %ebx,%ecx,%edx as parameters
pushl %ebx # to the system call
movl $0x10,%edx # set up ds,es to kernel space
mov %dx,%ds
mov %dx,%es
movl $0x17,%edx # fs points to local data space
mov %dx,%fs
call sys_call_table(,%eax,4)
pushl %eax
movl current,%eax
cmpl $0,state(%eax) # state
jne reschedule
cmpl $0,counter(%eax) # counter
je reschedule

关键这是一句“call sys_call_table(,%eax,4)”,在文件sys.h里可以找到它的定义:
fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,
sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,
sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,
sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,
sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,
sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid,
sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,
sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,
sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,
sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,
sys_setreuid,sys_setregid };
很明显sys_call_table[2]就是sys_fork,而它的定义是这样的:
sys_fork:
call find_empty_process
testl %eax,%eax
js 1f
push %gs
pushl %esi
pushl %edi
pushl %ebp
pushl %eax
call copy_process
addl $20,%esp
1: ret
于是又调用到copy_process,而copy_process则是fork.c里的函数。

总结一下linux系统的主要线路:
首先使用set_system_gate(0x80,&system_call)设置中断门。这样这后使用int指令时就会调用到system_call,在它里面又调用到了sys_call_table,而sys_call_table存放着各个系统调用的指针。
分享到:
评论

相关推荐

    Linux常见系统调用列表介绍

    本文列出了大部分常见的Linux系统调用,并附有简要中文说明。

    Linux系统调用列表

    本文列出了大部分常见的Linux系统调用,并附有简要中文说明。

    LINUX上的C编程

    第一部分简要介绍了Linux系统和C语言;第二部分讲述了Linux系统的C编程环境,详细讲述了Linux下C语言编译器(如GCC)、调试工具(如GDB)和程序自动维护工具的使用方法。第三部分详细介绍Linux的系统调用。最后,是一个...

    开源软件丛书 LINUX上的C编程第二部分

    第一部分简要介绍了Linux系统和C语言;第二部分讲述了Linux系统的C编程环境,详细讲述了Linux下C语言编译器(如GCC)、调试工具(如GDB)和程序自动维护工具的使用方法。第三部分详细介绍Linux的系统调用。最后,是一个...

    LINUX上的C编程 pdf

    第一部分简要介绍了Linux系统和C语言;第二部分讲述了Linux系统的C编程环境,详细讲述了Linux下C语言编译器(如GCC)、调试工具(如GDB)和程序自动维护工具的使用方法。第三部分详细介绍Linux的系统调用。最后,是一个...

    _开源软件丛书 LINUX上的C编程

    第一部分简要介绍了Linux系统和C语言;第二部分讲述了Linux系统的C编程环境,详细讲述了Linux下C语言编译器(如GCC)、调试工具(如GDB)和程序自动维护工具的使用方法。第三部分详细介绍Linux的系统调用。最后,是一个...

    Linux内核工作原理 word版本 强烈推荐

    大多数Linux核心工作在基于Intel处理器的系统上,但非Intel系统的Linux用户也越来越多。它们是Alpha AXP, ARM, MIPS, Sparc与Power PC。 虽然我可以根据上叙任何一种平台来编写本书的内容,但是我的技术知识与背景...

    Linux详细教程和用户接口(GUI)编程技术

    第五部分包括三个附录,附录A是书中使用的示例GnomeHello的源代码,附录B介绍了一些与Gtk+/Gnome编程相关的在线资源,附录C是Gtk+/Gnome对象的简要介绍。本书中的Gtk+构件示例都来自于GTK 1.2.3软件包的示例。如果...

    linux之线程同步的概要介绍与分析

    在Linux操作系统中,线程同步是多线程编程中的一个核心概念,它确保了多个线程在访问共享资源时的正确性与一致性,避免了诸如数据竞争和竞态条件等问题。为了实现这一目标,Linux提供了一系列强大的线程同步机制和...

    基于Davinci技术的智能家庭监控系统的设计与实现

    基于对多种嵌入式操作系统的分析,采用MontaVista Linux作为本 系统的操作系统。本文软件部分的工作为系统基础软件框架设计。本文对PAM 可插拔认证模块、MilliGUI图形用户接口等作了简要的介绍,探讨了软件各个功 能...

    入门学习Linux常用必会60个命令实例详解doc/txt

    要想真正理解Linux系统,就必须从Linux命令学起,通过基础的命令学习可以进一步理解Linux系统。 不同Linux发行版的命令数量不一样,但Linux发行版本最少的命令也有200多个。这里笔者把比较重要和使用频率最多的命令...

    SHU大一ALP第一学期大一期末作业10 网购系统

    详细设计:画出函数调用关系图,分析并描述函数的功能。 调试过程中的问题:记录程序编写和调试过程中遇到的各种问题,以及解决这些问题的途径和方法。 总结:回顾整个综合程序设计的过程,对学习到的设计方法和...

    CS_4500_Project_1

    如何在 Linux 内核中添加新的系统调用。 如何从 Linux 内核获取正在运行的进程/线程的各种信息。 ####项目提交 对于每个项目,创建一个包含以下项目的 gzip 文件,并通过电子邮件提交。 在电子邮件标题中包含“CS...

    Linux高级bash编程

    分析一个系统脚本 14. 命令替换 15. 算术扩展 16. I/O 重定向 16.1. 使用exec 16.2. 代码块的重定向 16.3. 应用 17. Here Documents 17.1. Here Strings 18. 休息时间 Part 4. 高级 19. 正则...

    基于Linux嵌入式网络开发的研究与应用.pdf

    叙述了软/硬件设计实现的方法步骤,重点阐述了通信接口器件或模块的选择与使用、基本配置/数据收(读)发(写)/异常处理等底层驱动软件的开发、通信协议的简化与实现、应用程序的驱动调用或嵌入式操作系统下的通信套接...

    用C实现webservice

    linux操作系统kernel2.4.2,安装gsoap2.6到目录/usr/local/gsoap 二.gSOAP的简要使用例子 下面是一个简单的例子,实现一个加法运算的WebService,具体功能是cli端输入num1和num2,server端返回一个num1和num2相加的...

    彩虹UDA软件狗工具带硬复制工具

    提供了针对 Linux 内核 2.2 和 2.4 版本驱动程序,开发商可以使用 Linux 模块保护运行于 Linux 操作系统上的应用程序。 新增功能: 软件狗开发套件 3.0 版新增功能在软件狗开发套件 V3.0 中,新增了与原并口...

    jack_projects:展示了我的编程技能的程序集以及过去几年中完成的项目。 README文件简要说明了每个文件是什么

    它使用系统调用以及流程创建和操作来实现此目的。 caching_simulator.cpp-此程序模拟具有多个层以及不同缓存策略的硬件级缓存。 lift_kernel_module.c-该程序是Linux内核的内核模块。 它调用自定义系统调用来运行...

    基于C的modbus协议实现

    基于C的modbus协议实现,以及简要的调用接口设计及其实现。实际为一个linux so动态库的封装。

    vivo-sparql-presentation

    Linux 网络服务器在使用 Python 的 Linux 系统上,您可以使用以下命令行: python -m SimpleHTTPServer 8082对于 Python 3: python3 -m http.server 8082然后可以通过以下 URL 调用演示文稿: 技术信息演示软件是 ...

Global site tag (gtag.js) - Google Analytics