原理:(2.6.22.6内核)
应用程序先用适当的值填充寄存器,然后调用一个特殊的指令跳到内核某一个固定的位置,内核根据应用程序所填充的固定值来找到相应的函数执行;
适当的值:
在include/asm-arm/unistd.h中为每个系统调用规定了唯一的编号,称为 系统调用号;
#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
#define __NR_exit (__NR_SYSCALL_BASE+ 1)
#define __NR_fork (__NR_SYSCALL_BASE+ 2)
#define __NR_read (__NR_SYSCALL_BASE+ 3)
#define __NR_write (__NR_SYSCALL_BASE+ 4)
......特殊的指令:
在intel CPU中,这个指令有中断0x80实现;
在ARM中,由SWI(已重命名为SVC指令)。
固定的位置:
在ARM体系中,应用程序跳到固定内核的位置是ENTRY(vecter_swi)<entry-common.S>.
相应的函数:
内核根据应用程序传递来的系统调用号,从系统调用表sys_call_table中找到相应的内核函数。
/* 0 */ CALL(sys_restart_syscall)
CALL(sys_exit)
CALL(sys_fork_wrapper)
CALL(sys_read)
CALL(sys_write)示例:
1、在kernel/sys.c中添加:
asmlinkage int sysMul(int a, int b)
{
int c;
c = a * b;
return c;
}
2、在include/asm-arm/unistd.h中添加:
#define __NR_sysMul (__NR_SYSCALL_BASE+352)
3、在arch/arm/kernel/call.S中添加:
CALL(sysMul)4、重新编译内核
5、编写测试程序
#include <stdio.h>
#include <linux/unistd.h>
int main(void)
{
int result;
result = syscall(352, 4, 2);
printf("result = %d\n", result);
return 1;
}
6、测试
#arm-linux-gcc -Wall -g -o syscall syscall.c
在开发板上:
#./syscall即可得到输出结果;
本文详细介绍了ARM系统中系统调用的工作原理,包括通过特定值和指令触发进入内核的过程,以及如何在用户态和内核态之间传递参数。此外还提供了一个具体的系统调用示例,展示了从定义新的系统调用到用户程序中调用它的全过程。
338

被折叠的 条评论
为什么被折叠?



