`
leehomjan
  • 浏览: 16804 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

linux系统调用流程浅析

阅读更多

1. 内核部分

1-1. 系统调用函数的定义

系统调用函数的原型定义在内核代码include/linux/syscalls.h中,
除此之外在该头文件中还提供了如下的宏

#define __SC_DECL1(t1, a1)      t1 a1
#define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__)
...
#define __SC_DECL6(t6, a6, ...) t6 a6, __SC_DECL5(__VA_ARGS__)

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

#define SYSCALL_DEFINEx(x, sname, ...)                          \
        __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)

#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
...
#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)

系统调用函数的定义分散在内核的各个模块,内核的各个模块使用上面宏构建系统调用函数。

以socket相关的系统调用函数为例,

socket相关的系统调用函数定义在net/socket.c中,有一个共通的接口,其定义如下:
SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
该函数编译展开后,可以得到如下的函数
asmlinkage long sys_socketcall(int call, unsigned long __user *args)

 

1-2. 系统调用表

每一个系统调用都有自己的编号,以x86架构的系统为例,
系统调用的编号保存在如下的文件中
arch/x86/include/asm/unistd_64.h
arch/x86/include/asm/unistd_32.h
而系统调用表sys_call_table则定义在如下的文件中
arch/x86/kernel/syscall_table_32.S
arch/x86/kernel/syscall_64.c

根据系统调用编号,可以在系统调用表中找到相应的系统调用函数。

 

1-3. 系统调用初始化

在x86架构中,系统调用是通过软件中断0x80来触发的。
linux系统在启动时使用如下的方式注册0x80软件中断的处理函数

start_kernel(void)[init/main.c]

`-- trap_init(void)[arch/x86/kernel/traps.c]

     `-- set_system_trap_gate(SYSCALL_VECTOR, &system_call)[arch/x86/include/asm/desc.h]

system_call函数是由汇编实现的,其实现在如下文件中可以找到

arch/x86/kernel/entry_32.S
arch/x86/kernel/entry_64.S

system_call根据传入的系统调用编号结合系统调用表,找到并执行相应的系统调用处理函数。

 

2. glibc

glibc对系统调用进行了封装,简化了系统调用的使用。以socket相关的系统调用函数为例进行说明。
socket相关的系统调用实际上都是执行内核中的sys_socketcall函数,sys_socketcall会根据传入的参数call决定具体执行哪个处理函数。在内核中call定义在include/linux/net.h中,而在glibc中则提供了一个相同的头文件sysdeps/unix/sysv/linux/socketcall.h

glibc中socket相关的系统调用,共通处理部分定义在如下的文件中
sysdeps/unix/sysv/linux/sh/socket.S
sysdeps/unix/sysv/linux/i386/socket.S

其它socket相关的系统调用函数则定义在sysdeps/unix/sysv/linux目录下

当socket.S未被其它文件引入时socket.S会生成socket函数,而当被其它文件引入时则会生成引入文件对应的函数。
以bind为例,bind.S通过引入socket.S来生成bind函数
sysdeps/unix/sysv/linux/bind.S 

#define	socket	bind
#define	NARGS	3
#define NO_WEAK_ALIAS	1
#include <socket.S>
weak_alias (bind, __bind)

 

在socket.S中系统调用的编号和call会被传递给内核,内核根据系统调用编号和call决定接下来执行哪个具体的处理函数。当系统调用函数实际上不存在时,则实际会调用socket/socket.c中的socket函数

int      
__socket (domain, type, protocol)
     int domain;
     int type; 
     int protocol;
{       
  __set_errno (ENOSYS);
  return -1;
}

此时就会返回错误,并且将errno设置为ENOSYS。

分享到:
评论

相关推荐

    Linux内核bridge浅析.doc

    Linux内核bridge浅析是Linux操作系统中的一种网桥模型,用于连接和桥接多个以太网接口设备。下面是对Linux内核bridge浅析的详细说明: 网桥模型 Linux内核通过一个虚拟的网桥设备来实现桥接的,这个设备可以绑定...

    LINUX设备模型浅析固件篇.pdf

    根据提供的文件信息,本文将深入探讨Linux设备模型中的固件管理机制...综上所述,Linux设备模型中的固件管理机制不仅提高了系统的稳定性,还大大简化了设备驱动的开发工作,对于理解和掌握Linux设备驱动具有重要意义。

    Linux内核配置系统浅析

    Linux内核配置系统是Linux操作系统开发中的核心组成部分,它允许开发者根据特定的需求定制内核,以便在不同的硬件平台上实现最佳性能和功能。随着Linux在嵌入式领域的广泛使用,掌握内核配置系统的知识变得越来越...

    linux 设备模型浅析 设备篇

    # Linux 设备模型浅析 —— 设备篇 ## 前言 为了更好地理解Linux设备模型,我们可以通过结合理论介绍和内核代码的方式来进行学习。这样不仅能让我们更直观地了解概念,还能深入掌握其实现细节。本文将以S3C2410RTC...

    linux下字符设备驱动开发浅析

    ### Linux下字符设备驱动开发浅析 #### 一、字符设备驱动的概念与作用 字符设备驱动在Linux系统中扮演着连接内核与用户空间应用程序的关键角色。它是一种相对简单但功能强大的驱动类型,主要用于处理串行数据传输...

    Linux内核Makefile浅析

    总之,Linux内核的Makefile系统是一个复杂而精细的工程,它使得庞大的内核源码能够根据用户的定制需求,有效地进行编译和构建。理解这个系统对于内核开发和调试至关重要,尤其是在进行内核模块开发或定制内核功能时...

    Linux设备模型浅析之uevent篇.pdf

    ### Linux设备模型浅析之uevent篇 #### 一、引言 在深入探讨`uevent`机制前,我们先回顾一下Linux设备模型的基本概念。Linux设备模型是Linux内核中用于管理硬件设备的一种框架,它提供了一种统一的方式来处理各种...

    浅析Linux内核中的BottomHalf机制.pdf

    ### 浅析Linux内核中的BottomHalf机制 #### 引言与背景 现代计算机系统面临着越来越复杂的中断处理需求。为了确保系统的稳定性和响应性,Linux内核采用了多种机制来优化中断处理过程。其中,BottomHalf(BH)机制...

    Linux环境下基于TCP的Socket编程浅析.pdf

    《Linux环境下基于TCP的Socket编程浅析》 在现代计算机科学中,Socket编程是构建网络应用程序的基础,尤其在Linux操作系统中,它的重要性更是不言而喻。Socket提供了一种标准接口,使得进程间通信(IPC)以及网络...

    浅析firmware完整生存和使用流程.rar

    本文将深入探讨firmware的完整生存和使用流程,重点关注在Linux环境下的开发和应用。 首先,firmware的生存流程包括以下几个关键步骤: 1. **设计与编写**: firmware的开发始于需求分析,根据硬件设备的功能需求...

    浅析linux开发工具adb具体实现

    Linux开发工具ADB(Android Debug Bridge)是Android系统中不可或缺的一部分,它为开发者提供了一种与Android设备进行通信的桥梁。本文将深入剖析ADB的具体实现,包括ADB如何启动、ADB服务器与设备之间的通信流程...

    浅析frmware的加载和init通过netlink处理uevent事件的一般流程

    3. **加载固件**:一旦找到固件文件,驱动程序会调用`request_firmware()`函数向固件加载子系统发送请求,加载固件到内存中。 4. **传递固件**:固件加载子系统会读取文件内容并将其传递给驱动程序,然后驱动程序...

    浅析linux 2.6.30.4内核中uda134x声卡驱动源码

    在Linux内核中,驱动程序是操作系统与硬件设备之间的桥梁,负责初始化、管理和操作特定的硬件设备。在本文中,我们将深入分析Linux 2.6.30.4内核中的uda134x声卡驱动源码,了解声卡驱动的注册与工作流程。 uda134x...

    LINUX系统开发技术详解---基于ARM

    9 2.1.2 ARM处理器体系结构........................................................................................ 10 2.1.3 Linux 与ARM处理器.....3.6.2 Linux 系统调用.........................................

    嵌入式系统学习基础知识浅析

    7. **多进程编程**:理解Linux系统中的进程概念,如何创建和管理进程,编写守护进程,并使用系统调用进行同步和通信,如管道、信号和共享内存。 8. **多线程编程**:线程是提高系统效率的关键。学习多线程编程方法...

    数据治理 安卓app漏洞挖掘浅析及案例 - linux.zip

    在安全上下文中,我们可以利用这一模式来构造安全的API调用,防止命令注入攻击。 SSH(Secure Shell)在工控安全领域扮演着重要角色。虽然SSH主要用于远程登录和命令执行,但在安卓APP中,它可能用于安全地连接到...

    U-BOOT 内存布局及启动过程浅析

    U-BOOT的启动过程对于理解整个系统的启动流程非常重要。以下是U-BOOT启动的主要步骤: 1. **内存初始化**:系统启动时,CPU首先映射FLASH到其内存空间。此时,U-BOOT位于FLASH上,CPU会执行其中的代码。初始化内存...

Global site tag (gtag.js) - Google Analytics