Linux内核为用户态程序提供的主要功能接口。通过系统调用,用户态进程能够临时切换到内核态,访问系统资源
由于系统有限的资源可能被多个不同的应用程序同时访问,如果不加以保护,那么各个应用程序难免会产生冲突。所以一种解决方法是,不让应用程序直接访问系统的资源,所以增加了一层中间接口,那就是系统调用。
1、应用程序调用open时,进程会调用C库中open的实现
2、C库中open的实现会将open的系统调用号保存在寄存器中(eax)中
3、通过汇编指令 int 0x80 触发软中断
4、程序跳到了系统调用处理程序的入口:system_call()
5、system_call()检查系统调用号(存放在eax中),告诉内核进程请求那种服务
6、查看系统调用表(system_call_table)找到系统调用服务例程
7、执行相应的函数,执行完毕后原路返回
1、添加系统调用的内核实现
在 kernel/arch/arm/kernel/sys_arm.c 文件中添加新系统调用的内核实现sys_add
已有的系统调用内核实现:
asmlinkage int sys_fork(struct pt_regs *regs)
{
#ifdef CONFIG_MMU
return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
#else
return(-EINVAL);
#endif
}
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
int __user *parent_tidptr, int tls_val,
int __user *child_tidptr, struct pt_regs *regs)
{
if (!newsp)
newsp = regs->ARM_sp;
return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
}
asmlinkage int sys_vfork(struct pt_regs *regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
}
添加新的系统调用内核实现:
void sys_add(int x, int y)
{
return ((x)+(y));
}
2、按格式要求添加新的的系统调用号
在 kernel/arch/arm/include/asm/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)
#define __NR_open (__NR_SYSCALL_BASE+ 5)
#define __NR_close (__NR_SYSCALL_BASE+ 6)
/* 7 was sys_waitpid */
#define __NR_creat (__NR_SYSCALL_BASE+ 8)
#define __NR_link (__NR_SYSCALL_BASE+ 9)
#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
#define __NR_execve (__NR_SYSCALL_BASE+ 11)
#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
#define __NR_time (__NR_SYSCALL_BASE+ 13)
#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
......
#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372)
#define __NR_syncfs (__NR_SYSCALL_BASE+373)
#define __NR_sendmmsg (__NR_SYSCALL_BASE+374)
#define __NR_setns (__NR_SYSCALL_BASE+375)
#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
按格式要求添加新的的系统调用号:
#define __NR_add (__NR_SYSCALL_BASE+378)
3、更新系统调用表
在 kernel/arch/arm/kernel/calls.S 系统调用表中添加新的一项
已有的系统调用表:
/* 0 */ CALL(sys_restart_syscall)
CALL(sys_exit)
CALL(sys_fork_wrapper)
CALL(sys_read)
CALL(sys_write)
/* 5 */ CALL(sys_open)
CALL(sys_close)
CALL(sys_ni_syscall) /* was sys_waitpid */
CALL(sys_creat)
CALL(sys_link)
......
/* 375 */CALL(sys_setns)
CALL(sys_process_vm_readv)
CALL(sys_process_vm_writev)
添加新的一项:
CALL(sys_add)
4、重新编译内核,内核中就会有新的系统调用