浅尝辄止25-Linux系统调用3

在浅尝辄止24-Linux系统调用2以及前面的分析文章中,没有说明__NR_***是什么东西,今天来说一下。

寻找__NR_write

我们在内核代码中grep一下,可以很容易找到以下内容。可以看到,__NR_write只是一个数字,其实就是系统调用号。

include/uapi/asm-generic/unistd.h:#define __NR_write 64
include/uapi/asm-generic/unistd.h:__SYSCALL(__NR_write, sys_write)

uapi即user api,也就是说,下面的头文件是用户可以引用到的。平常情况下,这个用户就是glibc,我们使用系统调用时,用的是glibc另外提供的头文件。在浅尝辄止24-Linux系统调用2中,我用的头文件是#include <linux/unistd.h>,有了它,就能找到__NR_write,我没有仔细验证,linux/unistd.h应该就是linux/include/uapi/linux/unistd.h,然后由#include <asm/unistd.h>再引用到linux/include/uapi/asm-generic/unistd.h的。

调用系统调用

网上有很多讲系统调用的文章,会讲“处理swi中断的就是vector_swi”,我们就直接看这里好了,我认为关键的就是linux/arch/arm/kernel/entry-common.S中下面的内容。

#define CALL(x) .long x

/*=============================================================================
 * SWI handler
 *-----------------------------------------------------------------------------
 */

    .align  5
ENTRY(vector_swi)
    ...
    adr tbl, sys_call_table     @ load syscall table pointer
    ...
    ldrcc   pc, [tbl, scno, lsl #2]     @ call sys_* routine
    ...
ENDPROC(vector_swi)
...
    .type   sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"

adr tbl, sys_call_table是说,tbl就是sys_call_table,看意思就是系统调用表(表中放着系统调用函数的地址)。看注释,跳转到系统调用的指令就是ldrcc pc, [tbl, scno, lsl #2],tbl是表的首地址,scno(system call No)显然是调用号,将调用号左移2位(一个地址4字节),加上调用表首地址,再赋给pc,这样就跳转到对应系统调用的地址了。

谁说scno是系统调用号?调用表的内容在哪里定义的?

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容