松下伺服err340(系统调用的实现细节(用户态))

Posted

篇首语:如果终止了学习,人就结束了成长的进步。本文由小常识网(cha138.com)小编为大家整理,主要介绍了松下伺服err340(系统调用的实现细节(用户态))相关的知识,希望对你有一定的参考价值。

松下伺服err340(系统调用的实现细节(用户态))

该文档以一个具体的事例来描述系统调用的细节。本文档的事例在Ubuntu 14.04.4 LTS环境,CPU架构为x86_64,glibc版本为RELEASE = development,VERSION = 2.26.9000。

假如我们写了一个应用程序test.c如下所示:



fork的函数申明在/usr/include/unistd.h头文件中,如下所示:



我们知道gcc会在编译完成test.c后,然后链接libc.so动态库中的fork,所以fork的实现就在glibc代码中,下载glibc源代码,然而glibc中并没有找到fork()的实现。


所以先做一个小实验:编译test.c,然后静态链接libc.a,生成test,然后


反汇编可执行文件test,查看test.s

部分如下内容:



看到main函数实际调用的是__libc_fork。

__libc_fork实现在glibc工程sysdeps/nptl/fork.c路径下,代码略长,此处省略。

但是我们的应用程序调用fork的,是怎么链接到__libc_fork的?在__libc_fork实现下方有如下代码:



__weak_alias实现在glibc工程include/libc-symbols.h路径下,如下:



现在,我们来看看__libc_fork函数,它调用系统功能的代码如下:



可以看出是通过调用ARCH_FROK宏实现调用系统功能的。

该宏在glibc工程sysdeps/unix/sysv/linux/x86_64/arch-fork.h目录下,如下代码所示:



可以看出是通过INLINE_SYSCALL宏调用,传递的参数是clone,该宏在glibc工程sysdeps/unix/sysv/linux/x86_64/sysdep.h头文件定义,与体系结构相关,代码如下:



其中INTERNAL_SYSCALL定义在同文件中,代码如下:



SYS_ify宏定义,代码如下:



__NR_##syscall_name定义在ubuntu系统的/usr/include/x86_64-linux-gnu/asm/unistd_64.h文件中,它是系统调用具体调用系统函数的参数,它是一个编号,比如我们的fork系统调用,它实际通过__NR_clone标号传参,它的定义如下:

#define __NR_clone 56

其中internal_syscall##nr相关的宏在glibc工程sysdeps/unix/sysv/linux/x86_64/sysdep.h定义,如下:

239 #undef internal_syscall0240 #define internal_syscall0(number, err, dummy...)            \\241 (                                  \\242     unsigned long int resultvar;                    \\243     asm volatile (                          \\244     "syscall\\n\\t"                           \\245     : "=a" (resultvar)                          \\246     : "0" (number)                          \\247     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);            \\248     (long int) resultvar;                       \\249 )250 251 #undef internal_syscall1252 #define internal_syscall1(number, err, arg1)                \\253 (                                  \\254     unsigned long int resultvar;                    \\255     TYPEFY (arg1, __arg1) = ARGIFY (arg1);              \\256     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;           \\257     asm volatile (                          \\258     "syscall\\n\\t"                           \\259     : "=a" (resultvar)                          \\260     : "0" (number), "r" (_a1)                       \\261     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);            \\262     (long int) resultvar;                       \\263 )264 265 #undef internal_syscall2266 #define internal_syscall2(number, err, arg1, arg2)          \\267 (                                  \\268     unsigned long int resultvar;                    \\269     TYPEFY (arg2, __arg2) = ARGIFY (arg2);              \\270     TYPEFY (arg1, __arg1) = ARGIFY (arg1);              \\271     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;           \\272     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;           \\273     asm volatile (                          \\274     "syscall\\n\\t"                           \\275     : "=a" (resultvar)                          \\276     : "0" (number), "r" (_a1), "r" (_a2)                \\277     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);            \\278     (long int) resultvar;                       \\279 )280281 #undef internal_syscall3282 #define internal_syscall3(number, err, arg1, arg2, arg3)        \\283 (                                  \\284     unsigned long int resultvar;                    \\285     TYPEFY (arg3, __arg3) = ARGIFY (arg3);              \\286     TYPEFY (arg2, __arg2) = ARGIFY (arg2);              \\287     TYPEFY (arg1, __arg1) = ARGIFY (arg1);              \\288     register TYPEFY (arg3, _a3) asm ("rdx") = __arg3;           \\289     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;           \\290     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;           \\291     asm volatile (                          \\292     "syscall\\n\\t"                           \\293     : "=a" (resultvar)                          \\294     : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3)         \\295     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);            \\296     (long int) resultvar;                       \\297 )299 #undef internal_syscall4300 #define internal_syscall4(number, err, arg1, arg2, arg3, arg4)      \\301 (                                  \\302     unsigned long int resultvar;                    \\303     TYPEFY (arg4, __arg4) = ARGIFY (arg4);              \\304     TYPEFY (arg3, __arg3) = ARGIFY (arg3);              \\305     TYPEFY (arg2, __arg2) = ARGIFY (arg2);              \\306     TYPEFY (arg1, __arg1) = ARGIFY (arg1);              \\307     register TYPEFY (arg4, _a4) asm ("r10") = __arg4;           \\308     register TYPEFY (arg3, _a3) asm ("rdx") = __arg3;           \\309     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;           \\310     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;           \\311     asm volatile (                          \\312     "syscall\\n\\t"                           \\313     : "=a" (resultvar)                          \\314     : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4)      \\315     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);            \\316     (long int) resultvar;                       \\317 )318 319 #undef internal_syscall5320 #define internal_syscall5(number, err, arg1, arg2, arg3, arg4, arg5)    \\321 (                                  \\322     unsigned long int resultvar;                    \\323     TYPEFY (arg5, __arg5) = ARGIFY (arg5);              \\324     TYPEFY (arg4, __arg4) = ARGIFY (arg4);              \\325     TYPEFY (arg3, __arg3) = ARGIFY (arg3);              \\326     TYPEFY (arg2, __arg2) = ARGIFY (arg2);              \\327     TYPEFY (arg1, __arg1) = ARGIFY (arg1);              \\328     register TYPEFY (arg5, _a5) asm ("r8") = __arg5;            \\329     register TYPEFY (arg4, _a4) asm ("r10") = __arg4;           \\330     register TYPEFY (arg3, _a3) asm ("rdx") = __arg3;           \\331     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;           \\332     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;           \\333     asm volatile (                          \\334     "syscall\\n\\t"                           \\335     : "=a" (resultvar)                          \\336     : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4),     \\337       "r" (_a5)                             \\338     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);            \\339     (long int) resultvar;                       \\340 )341 342 #undef internal_syscall6343 #define internal_syscall6(number, err, arg1, arg2, arg3, arg4, arg5, arg6) \\344 (                                  \\345     unsigned long int resultvar;                    \\346     TYPEFY (arg6, __arg6) = ARGIFY (arg6);              \\347     TYPEFY (arg5, __arg5) = ARGIFY (arg5);              \\348     TYPEFY (arg4, __arg4) = ARGIFY (arg4);              \\349     TYPEFY (arg3, __arg3) = ARGIFY (arg3);              \\350     TYPEFY (arg2, __arg2) = ARGIFY (arg2);              \\351     TYPEFY (arg1, __arg1) = ARGIFY (arg1);              \\352     register TYPEFY (arg6, _a6) asm ("r9") = __arg6;            \\353     register TYPEFY (arg5, _a5) asm ("r8") = __arg5;            \\354     register TYPEFY (arg4, _a4) asm ("r10") = __arg4;           \\355     register TYPEFY (arg3, _a3) asm ("rdx") = __arg3;           \\356     register TYPEFY (arg2, _a2) asm ("rsi") = __arg2;           \\357     register TYPEFY (arg1, _a1) asm ("rdi") = __arg1;           \\358     asm volatile (                          \\359     "syscall\\n\\t"                           \\360     : "=a" (resultvar)                          \\361     : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4),     \\362       "r" (_a5), "r" (_a6)                      \\363     : "memory", REGISTERS_CLOBBERED_BY_SYSCALL);            \\364     (long int) resultvar;                       \\365 )

可以看出internal_syscall##nr宏的number是每个系统调用内核中的入口函数向量地址,通过汇编syscall指令,实现系统调用,从用户态到核心态。


其他体系架构的系统调用基本是这个流程,但从用户态到核心态的汇编指令各不相同,如下:


本人水平有限,欢迎大家指正批评,欢迎私信联系我。

相关参考

松下a5伺服报err95(松下伺服驱动器报警210怎么解决伺服驱动器210故障码解决方法)

  松下伺服电机代理—日弘忠信今天给大家讲讲松下伺服驱动器报警21.0怎么解决?伺服驱动器21.0故障码解决方法。松下伺服电机驱动器报警err21是编码器通信出错,编码器通讯断线异常保护。编码器和驱动器的通信,在大道一定...

松下伺服驱动器err40(伺服驱动器故障维修实战集锦)

一西门子直流伺服驱动系统故障维修10例例1.进线快速熔断器熔断的故障维修故障现象:一台配套SIEMENS8MC的卧式加工中心,在电网突然断电后开机,系统无法起动。分析与处理过程:经检查,该机床X轴伺服驱动器的进线快速熔...

松下驱动器err44报警(伺服驱动器故障维修实战集锦)

一西门子直流伺服驱动系统故障维修10例例1.进线快速熔断器熔断的故障维修故障现象:一台配套SIEMENS8MC的卧式加工中心,在电网突然断电后开机,系统无法起动。分析与处理过程:经检查,该机床X轴伺服驱动器的进线快速熔...

松下伺服驱动器报警err160(硬盘,硬盘维修知识)

硬盘磁头技术 1、磁头磁头是硬盘中最昂贵的部件,也是硬盘技术中最匾?妥罟键的一环。传统的磁头是读写合一的电磁感应式磁头,但是,硬盘的读、写却是两种截然不同的操作,为此,这种二合一磁头在设计时必须要同时兼顾...

松下伺服驱动器err21(标杆全球|PMBA日本发现之旅,体验商业之美学习精益管理)

仅仅做出满足客户需求的产品远远不够,唯有做出完美到可以“划伤手指”的产品,才能够在竞争中立于不败之地。——稻盛和夫这句出自《活法》一书的名言,高度凝练出稻盛和夫对产品以及竞争的深刻理解,同时也形象地诠...

松下感应器(松下伺服驱动器报警210怎么解决伺服驱动器210故障码解决方法)

  松下伺服电机代理—日弘忠信今天给大家讲讲松下伺服驱动器报警21.0怎么解决?伺服驱动器21.0故障码解决方法。松下伺服电机驱动器报警err21是编码器通信出错,编码器通讯断线异常保护。编码器和驱动器的通信,在大道一定...

松下继电器样本(松下驱动器维修常见报警代码MFDHTA390报警)

松下驱动器报警代码维修总结松下驱动器报警代码维修总结Err14.0过电流保护;Err14.1IPM异常保护原因:在逆变器上流动电流超过规定值。①驱动器故障(电路,IGBT的部品不良等)②电机电缆U,V,W短路。③电机电缆接地。④电机...

松下伺服驱动器报警代码大全(松下伺服电机系统常见的六种故障及解决办法)

...,解决方法也会不一样,下面由日弘忠信小编为你讲解:松下伺服电机松下伺服电机系统的常见故障有以下六种:1.超程当进给运动超过由软件设定的软限位或由限位开关设定的硬限位时,就会发生超程报警,一般

松下A6伺服电机与plc接线图(松下伺服电机系统常见的六种故障及解决办法)

...,解决方法也会不一样,下面由日弘忠信小编为你讲解:松下伺服电机松下伺服电机系统的常见故障有以下六种:1.超程当进给运动超过由软件设定的软限位或由限位开关设定的硬限位时,就会发生超程报警,一般

松下伺服电机刚性参数(数控系统伺服电机控制你知道多少?)

近年来,伺服电机控制技术正朝着交流化、数字化、智能化三个方向发展。作为数控机床的执行机构,伺服系统将电力电子器件、控制、驱动及保护等集为一体,并随着数字脉宽调制技术、特种电机材料技术、微电子技术及现代...