精华内容
参与话题
问答
  • 系统调用

    千次阅读 2020-04-15 21:38:25
    系统调用是如何实现的呢? 这个系统叫什么名字也在内核里,而且系统函数也在内核里。既然内核里的函数也是函数,也在内存里,为什么上层应用不能直接去调用它呢? 不能,不能跳到内核里,否则就是程序调用了,而...

    操作系统全部笔记目录 见:操作系统笔记整理

    系统调用是如何实现的呢?

    这个系统叫什么名字也在内核里,而且系统函数也在内核里。既然内核里的函数也是函数,也在内存里,为什么上层应用不能直接去调用它呢?

    不能,不能跳到内核里,否则就是程序调用了,而不是内核调用。为什么不能呢?因为操作系统里有很多很重要的东西,一旦能随意访问,会有安全问题,比如密码可能就会泄露。

    不能jmp到内核程序是硬件决定的。操作系统把内存分为两个区域,内核段和用户段,对应两个态:内核态和用户态。处于用户态的程序不能进入内核态。

    DPL描述要访问的目标段的特权级,初始化的时候GDT表中的DPL就是0。

    CPL:当前的特权级,执行用户程序的时候表示,用户态的时候设置为3。

    在mov的时候,只有mov后的特权级大于或等于当前的特权级的时候,才会跳转。

    初始化操作系统的时候,建立gdt表,设置DPL为0。每次跳转的时候都要访问gdt表,所以当在用户态的时候,CPL=3,如果大于操作系统的DPL,则不会跳转到内核。

    那么如何进入内核执行内核程序呢?答案是通过中断。

    比如你调用了Open函数,用户程序产生了中断,操作系统处理中断,然后根据中断的类型去执行相应的调用。

    注意上图中的int 0x80,就会去进行中断,然后调用系统的相关函数。

    注意里面的

    type name(atype a, btype b, ctype c)

    把前面的参数带进来,表示为

    int write(int fd,char*……)

    =a"(__res):" 输出等于a,即把es置给 __res 

    然后后面的 __NR_##name 表示 mov __NR_write, %eax

    然后”b”((long)(a)),a是fd,把fd置给ebx。

    因为很多中断都是int 0x80,要想知道是哪个,就要靠这个系统调用号了。

    执行完以后,把es置给 __res,然后返回 __res ,最后返回write的返回值 int 。

    那么现在看一下int 0x80到底做了些什么:

    void sched_init(void) 就是系统初始化函数。里面要设置gate,即“中断处理门”,就是把上图底下那个表初始化好。

    _set_gate(&idt[n],15,3,addr); 第一个参数找到idt表索引80的位置,idt是一个全局的变量。15传到下面的type,3传到下面的dpl,addr就是system_call,movl %%eax,%1 就是把eax弄到为1的地方,即 “o”(*((char*)(gate_addr))),也就是地址的低四位。

    movl %%edx,%2就是把edx弄到为2的地方,即”o”(*(4+(char*)(gate_addr))),也就是地址的高四位。

    ”a”(0x00080000) 会把0008组装到 段选择符 这里,CS=0x0008,  IP = system_call,回想之前的 jmpi 0,8 ,8是gdt表的值,也就是去gdt表中找到内核代码段,然后偏移是system_call。CS=8,则相当于CS最后两位即CPL就是0,即当前特权级为0,所以执行内核代码。

    等执行完内核代码以后,DPL再重新置为3,我们就可以直接跳回用户态(DPL>=CPL则可以直接跳过去)。

    然后说明一下system_call要做什么事情:

    movl $0x10,%edx mov %dx,%ds mov %dx,%es //内核数据 执行完以后,dx和es都变为 0x10 了,表示是内核的数据段。

    现在的数据段代码段都是内核的,所以真正开始执行内核程序。

    call _sys_call_table(,%eax,4) eax是 __NR_write ,即_sys_call_table+4*%eax就是相应系统调用处理函数入口,这里的4表示每个系统调用占4个字节。

    可以看到sys_write正好是第四个。

    整体流程如下:

    展开全文
  • 这些函数及调用函数的行为统称为系统调用(system call),也就是应用对操作系统(system)的功能进行调用(call)的意思。在前面的程序中用到了time()及printf()等函数,这些函数内部也都使用了系统调用。这里之...

    操作系统的硬件控制功能,通常是通过一些小的函数集合体的形式来提供的。这些函数及调用函数的行为统称为系统调用(system call),也就是应用对操作系统(system)的功能进行调用(call)的意思。在前面的程序中用到了time()及printf()等函数,这些函数内部也都使用了系统调用。这里之所以用“内部”这个词,是因为在Windows操作系统中,提供返回当前日期和时刻,以及在显示器中显示字符串等功能的系统调用的函数名,并不是time()和printf()。系统调用是在time()和printf()函数的内部执行的。大家可能会认为这个方法有些绕,不过这是有原因的。

    C语言等高级编程语言并不依存于特定的操作系统。这是因为人们希望不管是Windows还是Linux,都能使用几乎相同的源代码。因此,高级编程语言的机制就是,使用独自的函数名,然后再在编译时将其转换成相应操作系统的系统调用(也有可能是多个系统调用的组合)。也就是说,用高级编程语言编写的应用在编译后,就转换成了利用系统调用的本地代码(图9-6)。

    图9-6 高级编程语言的函数调用在编译后变成了系统调用

    在高级编程语言中,也存在可以直接调用系统调用的编程语言。不过,利用这种方式做成的应用,移植性并不友好(也俗称为有恶意行为的应用)。例如,直接调用Windows系统调用的应用,在Linux上显然是无法运行的。

    Ps:①移植性指的是同样的程序在不同操作系统下运行时需要花费的时间等,费时越少说明移植性越好。

    展开全文
  • 操作系统作业:给linux系统增加一个系统调用

    万次阅读 多人点赞 2018-06-01 00:43:37
    前不久开了一门《操作系统》,老师上课留下了一个作业——给Linux系统添加一个系统调用。刚开始只能用一脸懵逼来形容,只能硬着头皮做下去。由于刚的新电脑,所以就没敢装双系统。所以我选择了虚拟机,虚拟机刚开始...

     

         前不久开了一门《操作系统》,老师上课留下了一个作业——Linux系统添加一个系统调用。刚开始只能用一脸懵逼来形容,只能硬着头皮做下去。由于刚的新电脑,所以就没敢装双系统。所以我选择了虚拟机,虚拟机刚开始配置的过程不算特别复杂,网上也有很多教程,于是我看着虚拟机也是一脸懵逼,不知道从何下手,百度得知快捷键Ctr+Alt+T或者右键+终端可以打开终端,于是我试了一下,哇好眼熟,这不就是Windows系统里面那个黑框框吗(命令行);好像也是可以下手的,于是就这样一边百度一边做着,错了一次改下,改不动了推倒重新来过。终于最终解决了这个问题!

     

     

        下面部分主要分三个部分:一、系统调用的概念;二、实现系统调用的过程;三、实现过程遇到的问题;四、感受(ps:本人第一次写博客,可能前后内容不太连贯)

    ------------------------------------------------------------------------------------------------------------------------------------------------------ 

    一、系统调用的概念

            Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,系统调用由操作系统核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。二者在使用方式上也有相似之处。Linux系统的核心部分即是Linux内核,是一系列设备的驱动程序。系统调用是Linux内核提供的功能十分强大的一系列的函数。这些函数是在内核中实现的,它们是应用程序和内核交互的接口,系统调用在Linux系统中发挥着巨大的作用,如果没有系统调用,那么应用程序就失去了内核的支持。

     

     二、系统调用的实现

    第一步:获取root权限(即管理员权限)

    在终端输入下列指令:

    sudo su

    注意:获取root权限需要用户输入密码(登陆密码),密码是看不见的,用户只需正确的输入密码即可,回车键结束

    示意图如下:

     

    第二步:准备工作

    1、安装相关编译程序

    sudo  apt-getinstallbuild-essentialkernel-package  libncurses5-dev

    2、获取内核

    (1)从外面将linux-4.16.10.tar拖入到了虚拟机桌面(我用的内核是linux-4.16.10)

        内核的话新版本也是可以的,官网下载或者从别人哪儿拷,指令的话只需要对应的把版本号改一下

    (2)下一步就是将该压缩文件移入到/usr/src/文件夹中

    注意:在.tar后面有一个空格,文件名建议复制不建议手敲。可以直接把我的语句复制过去然后方向键移到需要修改的地方进行修改

    sudo mv /peter/home/桌面/linux-4.16.10.tar/usr/src/

    注:由于我之前都将这些东西配置好了,所以是这个显示,一个细节,可以通过方向键的上下快速切换历史命令

     

    第三步、进入/usr/src解压文件

    cd /usr/src

    sudo tar -xvf /usr/src/linux-4.16.10.tar.bz2

    解压过程如下图所示,如果要确定自己的内核版本,可以在终端输入命令uname -r。解压过程稍长,注意:解压语句可能因为文件地址稍有不同,建议去计算机里面去拷贝路径!

     

    第四步:进入解压出的文件目录

    cd /usr/src/linux-4.16.10/kernel

     

    第五步:安装vim

    sudo apt-get install vim

     

     

    第六步:打开sys.c加入函数

    vim sys.c

     

    注意:在vim, i进入编辑, esc退出编辑状态. G跳到末尾, gg进入开头。 :wq保存退出, :q不保存退出)

     

    在末尾加入函数

    asmlinkage long sys_helloworld(void){

        printk( "helloworld!");

         return 1;

    }

     

    第七步、添加声明

    cd /usr/src/linux-4.16.10/arch/x86/include/asm/

    vim syscalls.h

    (插入asmlinkage long sys_helloworld(void);)

     

     

     

     

    第八步:加一个系统调用的id

    cd/usr/src/linux-4.16.10/arch/x86/entry/syscalls

    vim syscall_64.tbl

    a、进入/usr/src/linux-4.16.10/arch/x86/syscalls目录

    b、打开文件syscall_64.tbl(该文件有一个系统调用列表,最前面的属性是id

    c、在里面添加自己的系统调用号(333  64  helloworld           sys_helloworld

    d、使用esc +:wq命令保存退出

     

     

     

    注意:我在任务管理器发现我的VMware workstation是32位的,但我同学用64位成功了!所以我用的是vim syscall_64.tbl,之前试了vim syscall_32.tbl没能成功。所以要以虚拟机为主!!!

     

     

     

     

    第九步:配置内核

    cd  /usr/src/linux-4.16.10

    编译内核和安装内核.

    依次输入这四条语句

    sudo make mrproper

    sudo make clean

    sudo make menuconfig  并且在make

    nfig时,将那个General setup内的localversion修改成新的名称,比如我这里的myKernel

    sudo make menuconfig出现的问题:

    scripts/Makefile.lib:194: recipe for target 'scripts/kconfig/lexer.lex.c' failed make[1]:
    
    *** [scripts/kconfig/lexer.lex.c] Error 127 Makefile:552: recipe for target 'menuconfig' failed make: 
    
    *** [menuconfig] Error 2

     解决办法:

    sudo apt-get install bison
    sudo apt-get install flex

    安装这两个包完成后再sudo make menuconfig

     

     

    根据自己处理器的最大线程数目来编译.

    sudo make -j4 (我的电脑是44线程),线程越多编译越快!

    此处可能报错:

    make[1]:
    *** [scripts/sign-file] Error 1 
    Makefile:1065: recipe for target 'scripts' failed make: 
    *** [scripts] Error 2

     解决办法:

    第一反应耐心看报错信息,缺什么包补什么包sudo apt-get install XXXX

    下面这个语句可以解决较多的问题。

    sudo apt-get install libssl-dev

     

    编译过程真的超级超级漫长。。。

    注意: 这个时候,终端的窗口最好最大化,否则可能会报错。

     

    第十步:安装内核

    编译后安装内核到系统中.

    sudo makemodules_install  

    sudomake install  // 安装内核

    这个地方也需要一定的时间,反正编译三个多小时,不差这一会哈哈哈

     第十一步:重启虚拟机

    将之前的工作保存后直接重启,重启后点击鼠标进入ubuntu并且迅速按住shift,长按!我的虚拟机直接登陆上了,我同学的好像都有一个选择内核过程,有选择的话,只需要选择新核就OK了!

     

    第十二步:验证系统调用是否成功

    a、登陆虚拟机

    b、打开终端

    c、输入下列指令:

    (1)gcc hello.c

    输入下列代码:

     

    (2)./a.out

    输出,见证成果的时候到了!!!

    返回值为1!!!!!

    系统调用成功了!!!!

    终于弄完了,明天篮球场走起哈哈

     

    三、感受

        作为一个linux小白实现上述过程是很痛苦的,但是真的很想去把这件事做好,一步一步,从什么都不知道到好像懂了一点点,再到可以看懂每行代码的含义,到最后做出成果,刚开始做的时候比较浮躁,到了后面就冷静了。看了20多篇博客,解决各种问题;之前做的时候犯的错误多的数不胜数,后面弄的时候一点点规避和解决,功夫不负有心人,虽然为了这个作业花了我整整一周的精力(本人理解能力较差,周围有的大佬花了几天就弄完了),这次的成功相信可以给我后面进一步学好操作系统的信心,也培养了自己的耐心和攻坚精神。相信自己会继续加油的!

        给读者:排版方面,第一次用CSDN亲自写博客(之前都是看各路大牛的博客),格式没有弄得特别人性化,比如代码没能用特定的代码行来进行排版,但感觉应该不影响阅读,下次会继续改进的,希望下次还可以有东西可以写哈哈哈。如果有关于此篇博客的疑问,欢迎来撩!联系方式:QQ 2729707823 备注CSDN(有时候看见一个问题有人解决了但是没看懂,没办法联系博主就很难受!)

     空信最棒!

    更新于2019年5月7日晚。

     

     

     

     

     

     

     

     

    展开全文
  • 什么是系统调用? Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,...

    什么是系统调用?

    Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,系统调用由操作系统核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。

    随Linux核心还提供了一些C语言函数库,这些库对系统调用进行了一些包装和扩展,因为这些库函数与系统调用的关系非常紧密,所以习惯上把这些函数也称为系统调用。

    展开全文
  • 【Linux系统编程】Linux系统调用

    千次阅读 多人点赞 2019-09-22 20:52:34
    用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置定时器等。 ...
  • 系统调用接口

    千次阅读 2018-11-27 09:53:59
    1、系统调用 操作系统作为系统软件,它的任务是为用户的应用程序提供良好的运行环境。因此,由操作系统内核提供一系列内核函数,通过一组称为系统调用的接口提供给用户使用。系统调用的作用是把应用程序的请求传递...
  • 系统调用poll机制分析(非常透彻)

    万次阅读 2020-03-25 20:37:52
    rt-thread其实很多代码都是参考Linux的架构,或者运用的是Linux的设计思想,poll系统调用是经常使用到的系统调用,本次博客来分析poll在rtt(以下没有特殊说明,就把rt-thread简称为rtt)中的实现方法,如果了解了...
  • 在计算机中,系统调用(英语:system call),又称为系统呼叫,指运行在使用者空间的程序向 操作系统内核请求需要更高权限运行的服务。系统调用提供了用户程序与操作系统之间的接口( 即系统调用是用户程序和内核...
  • 系统调用(操作系统6)

    千次阅读 2020-10-03 16:27:24
    - 系统调用的作用 - 系统调用与库函数的区别 - 系统调用背后的过程
  • linux系统 为其每个系统调用映射了 唯一的一个数字,即系统调用号。一旦这种关系确定,就不可修改。如果一个系统调用被删除,那么他的系统调用号不会被回收。 而系统调用表呢,是根据系统调用号的顺序,将系统调用...
  • 系统调用和函数调用区别

    千次阅读 2017-10-20 10:53:15
    系统调用和函数调用 1. 系统调用 a. 什么是系统调用 系统调用,通俗的讲,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以...
  • 系统调用和函数调用

    千次阅读 2015-11-24 13:42:25
    系统调用和函数调用1. 系统调用a. 什么是系统调用系统调用,通俗的讲,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件...
  • Linux系统调用

    千次阅读 2018-03-19 13:19:45
    1 概述相比Intel支持的快速系统调用指令sysenter/sysexit,AMD对应的是syscall/sysret,不过现在,Intel也兼容这两条指令。 测试环境:Ubuntu 12.04Ubuntu 16.04 642 传统系统调用int 0x80只用于32位系统,64位...
  • 系统调用和函数调用的区别

    万次阅读 2018-06-06 22:51:57
    系统调用 操作系统服务的编程接口 通常由高级语言编写(C或C++) 程序访问通常通过高层次 的API接口(C标准库的库函数)而不是直接进行系统调用 每个系统调用对应一个系统调用编号 系统调用与函数调用的区别 ...
  • 操作系统的系统调用

    千次阅读 2018-10-26 21:21:12
    系统调用:操作系统的接口是连接应用软件与操作系统的中间桥梁。接口在程序设计中表现的形式就是:函数。操作系统提供的函数就被称为系统调用(system call)。这里有个标准POSIX(Portable Operating System ...
  • 系统调用知识框架图2.系统调用和库函数的区别3.系统调用的执行过程 1.系统调用知识框架图 2.系统调用和库函数的区别 3.系统调用的执行过程 参考:《2021王道操作系统考研》 bilibili : ...
  • Linux系统添加系统调用

    千次阅读 2018-05-23 12:37:14
    参考链接:Ubuntu 16.10添加系统调用点击打开链接
  • 系统调用与库函数调用

    千次阅读 2017-01-17 21:15:43
    对上的话则暴露出来一些接口,供上层调用,这些接口就叫做系统调用。shell是包裹在linux内核外层的,一个可通过一系列的linux命令对操作系统发出相关指令的人机交互界面。库函数是在系统调用的基础上
  • 系统调用和库函数调用的区别

    千次阅读 2018-09-04 16:19:24
    一:系统调用和库函数调用的区别: 1:系统调用是最底层的应用,是面向硬件的。而库函数的调用是面向开发的,相当于应用程序的API(即预先定义好的函数)接口; 2:各个操作系统的系统调用是不同的,因此系统调用...
  • 系统调用是什么

    千次阅读 2018-08-09 11:12:17
    系统调用 1.系统调用和普通函数完全不同,系统调用实际上是0x80号中断对应的中断处理程序的子程序。换句话说,在linux系统上,0x80中断是系统调用的统一入口。某个具体的系统调用是这个中断处理程序的子程序,进入...
  • 系统调用与普通过程调用的异同点

    千次阅读 2019-11-24 10:48:33
    系统调用与普通过程调用的异同点系统调用与普通过程调用的异同点 系统调用与普通过程调用的异同点 相同点: 改变指令流程 重复执行和公用 改变指令流程后需要返回原处 不同点: 系统调用是动态调用,而CALL调用方式...

空空如也

1 2 3 4 5 ... 20
收藏数 203,010
精华内容 81,204
关键字:

系统调用