linux自定义系统调用
2013-12-24 16:45
405 查看
1 Linux3.10.21内核系统调用设置
以前看的内核版本时2.6.11的,里面的系统调用设置一目了然啊!在文件entry.S中直接定义了sys_call_table表,并在这个文件中用各个系统调用函数的地址初始化了这个表。今天看了下3.10.21的内核,想自己添加个系统调用到这个内核里面,没想到看了半天还是在云里雾里中,只知道sys_call_table表的定义在文件/usr/src/linux-3.10/arch/x86/kernel/syscall_32.c中,当具体怎么初始化这个表的还是不知道。找了半天都没找到表sys_call_table初始化的地方,后来回到syscall_32.c文件中才发现在它定义的地方就初始化了,下面看下定义的代码:const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { /* * Smells like a compiler bug -- it doesn't work * when the & below is removed. */ [0 ... __NR_syscall_max] = &sys_ni_syscall, #include <asm/syscalls_32.h> }; |
现在我们来看下shell脚本syscalltdr.sh到底做了什么,这个文件的内容如下:
#!/bin/sh in="$1" out="$2" grep '^[0-9]' "$in" | sort -n | ( while read nr abi name entry compat; do abi=`echo "$abi" | tr '[a-z]' '[A-Z]'` if [ -n "$compat" ]; then echo "__SYSCALL_${abi}($nr, $entry, $compat)" elif [ -n "$entry" ]; then echo "__SYSCALL_${abi}($nr, $entry, $entry)" fi done ) > "$out" |
文件syscall_32.tbl的部分内容:
# # 32-bit system call numbers and entry vectors # # The format is: # <number> <abi> <name> <entry point> <compat entry point> # # The abi is always "i386" for this file. # 0 i386 restart_syscall sys_restart_syscall 1 i386 exit sys_exit 2 i386 fork sys_fork stub32_fork 3 i386 read sys_read 4 i386 write sys_write 5 i386 open sys_open compat_sys_open 6 i386 close sys_close 7 i386 waitpid sys_waitpid sys32_waitpid |
__SYSCALL_I386(0, sys_restart_syscall, sys_restart_syscall) __SYSCALL_I386(1, sys_exit, sys_exit) __SYSCALL_I386(2, sys_fork, stub32_fork) __SYSCALL_I386(3, sys_read, sys_read) __SYSCALL_I386(4, sys_write, sys_write) __SYSCALL_I386(5, sys_open, compat_sys_open) __SYSCALL_I386(6, sys_close, sys_close) __SYSCALL_I386(7, sys_waitpid, sys32_waitpid) __SYSCALL_I386(8, sys_creat, sys_creat) __SYSCALL_I386(9, sys_link, sys_link) __SYSCALL_I386(10, sys_unlink, sys_unlink) __SYSCALL_I386(11, sys_execve, stub32_execve) __SYSCALL_I386(12, sys_chdir, sys_chdir) __SYSCALL_I386(13, sys_time, compat_sys_time) __SYSCALL_I386(14, sys_mknod, sys_mknod) __SYSCALL_I386(15, sys_chmod, sys_chmod) __SYSCALL_I386(16, sys_lchown16, sys_lchown16) __SYSCALL_I386(18, sys_stat, sys_stat) __SYSCALL_I386(19, sys_lseek, compat_sys_lseek) |
#define __SYSCALL_I386(nr, sym, compat) [nr] = sym, |
现在想想,其实原理和以前2.6.11版本时一样的,只是多拐了一个弯。对gcc中居然可以这样初始化数组表示以前没见过啊!深感gcc的强大啊!
然后定义每个系统调用的调用号和上面初始化表sys_call_table原理是一样的,执行shell脚本并提取出syscall_32.tbl的系统调用号存放到另一个文件中。
2 添加自己的系统调用
1、在系统调用向量表里添加自定义的系统调用号,在文件:/usr/src/linux-3.10/arch/x86/syscalls/syscall_32.tbl中加入自定义的系统调用号和函数名。
2、添加函数声明
在文件/usr/src/linux-3.10/arch/x86/include/asm/syscalls.h文件中加入sys_foo函数的声明。
3、添加函数的定义
在文件/usr/src/linux-3.10/kernel/sys.c文件中加入对sys_foo的定义。
4、编译和安装内核
直接敲下面的命令来编译和安装内核:
make -j10 bzImage make install |
3 测试自定义的系统调用
为了测试是否自己定义的系统调用能够正常的使用,写个测试程序是有必要的。代码如下:#include<stdio.h> #define __NR_foo 351 int main(void) { int rs; rs = syscall(__NR_foo); if (!rs) printf("syscall success!\n"); return 0} |
编译运行上面的代码,用dmesg可以看到系统输出的信息:
出现这个画面,说明自定义的系统调用能正常工作了。
相关文章推荐
- centos的引导及启动全过程
- linux实现php定时执行cron任务详解
- Linux操作系统下的多线程编程详细解析----条件变量
- 环境配置篇之linux定时任务
- 配置FreeBSD对Linux软件的兼容模式
- 基于嵌入式Linux与S3C2410平台的图像识别与处理
- Linux命令:scp
- Linux 下常用的 19 条命令
- Linux 自检和 SystemTap
- LINUX 使用管道实现无需落地文件GZIP压缩
- 使用systemtap调试Linux内核
- 有关Cache –(1) linux list之中的Prefetch
- Ubuntu下deb包的安装方法
- linux gdb 查看内存
- Linux学习路线
- centos维护记录
- LXC(Linux containers)快速入门
- Linux Kernel Development有关内存管理
- [转]Linux内核源码分析——list链表结构
- 针对MySQL的Linux性能调优技巧[翻译]