ioctl系统调用流程.doc

上传人:sk****8 文档编号:3520144 上传时间:2019-06-01 格式:DOC 页数:7 大小:39.50KB
下载 相关 举报
ioctl系统调用流程.doc_第1页
第1页 / 共7页
ioctl系统调用流程.doc_第2页
第2页 / 共7页
ioctl系统调用流程.doc_第3页
第3页 / 共7页
ioctl系统调用流程.doc_第4页
第4页 / 共7页
ioctl系统调用流程.doc_第5页
第5页 / 共7页
点击查看更多>>
资源描述

1、ioctl系统调用流程一、系统调用框架 与系统调用相关的数据结构和函数 系统调用函数名以“sys_”开头,后面是该系统调用的名字,由此构成了 sys_name()这样的函数名。在 include/asm/unistd.h中不同的体系结构为每一个系统调用定义了惟一的编号,假设用 name来表示系统调用的名称,那么系统调用号与系统调用响应函数的关系是:以系统调用号_NR_name 作为下标,可找出系统调用表 sys_call_table中对应表项的内容,它也就是该系统调用的响应函数 sys_name的入口地址。 系统调用具体执行流程 当执行一个系统调用时,处理器跳转到地址 0xc00。参考代码:a

2、rch/ppc/kernel/head.S. = 0xc00SystemCall:EXCEPTION_PROLOGstw r3,ORIG_GPR3(r21)li r20,MSR_KERNELrlwimi r20,r23,0,16,16bl transfer_to_handler.long DoSyscall.long ret_from_except有关 DoSyscall,它在文件 arch/ppc/kernel/entry.S 中定义。这个函数最终使用系统调用编号把系统调用表的地址和索引加载,操作系统使用系统调用表把系统调用编号翻译为特定的系统调用。系统调用表名为 sys_call_tabl

3、e,在 arch/ppc/kernel/misc.S 中定义。系统调用表包含有实现每个系统调用的函数的地址。_GLOBAL(sys_call_table).long sys_ni_syscalllong sys_getegid.long sys_acct.long sys_umount.long sys_ni_syscall.long sys_ioctl.long sys_fcntl当 DoSyscall 找到正确的系统调用地址后,它把调用指定的系统调用函数。如要做系统ioctl调用,对应的系统调用号为 54,它把调用函数 sys_ioctl()。下面具体会说明sys_ioctl()的调用过程

4、。当函数调用完毕之后,返回到 DoSyscall(),它把控制权切换给 ret_from_except(在 arch/ppc/kernel/entry.S 中定义)。它会去检查那些在切换回用户空间之前需要完成的任务。如果没有需要做的事情,那么就通过 restore 函数恢复用户进程的状态,并把控制权交还给用户程序。二、ioctl 系统调用的整个流程sys_ioctl()是整个 ioctl系统调用过程中的最顶级函数,它需要对输入的参数进行预处理,检查参数的合法性,然后调用底层的处理函数作更进一步的处理。分析函数 sys_ioctl(),参考代码:fs/ioctl.casmlinkage long

5、 sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)struct file * filp;unsigned int flag;int on, error = -EBADF;filp = fget(fd);if (!filp)goto out;error = 0;TRACE_FILE_SYSTEM(TRACE_EV_FILE_SYSTEM_IOCTL,fd,cmd,NULL);lock_kernel();switch (cmd) case FIOCLEX:set_close_on_exec(fd, 1);break;ca

6、se FIONCLEX:set_close_on_exec(fd, 0);break;case FIONBIO:if (error = get_user(on, (int *)arg) != 0)break;flag = O_NONBLOCK;#ifdef _sparc_if(O_NONBLOCK != O_NDELAY)flag |= O_NDELAY;#endifif (on)filp-f_flags |= flag;elsefilp-f_flags break;case FIOASYNC:if (error = get_user(on, (int *)arg) != 0)break;fl

7、ag = on ? FASYNC : 0;if (flag filp-f_flags) else error = -ENOTTY;if (error != 0)break;if (on)filp-f_flags |= FASYNC;elsefilp-f_flags break;default:if (S_ISREG(filp-f_dentry-d_inode-i_mode)error = file_ioctl(filp, cmd, arg);else if (filp-f_op unlock_kernel();fput(filp);out:return error;其中调用到函数的说明: fg

8、et()函数,它是用来获取操作文件的指针,在这篇文档里,我是使用 socket创建了一个文件描述符,fd = socket(AF_INET6, SOCK_DGRAM, 0);用户态的创建 socket()到内核中传给函数 sys_socket()处理, sys_socket()函数先调用函数 sock_create()创建socket,然后把 socket操作和文件操作关联起来,具体调用函数 sock_map_fd()来实现,成功后把文件描述和文件结构 file都保存在 sock-file中。对于函数 fget()函数,它首先调用 fcheck函数,检查一下文件描述符 fd是否对应一个打开的文

9、件,如果是就获取该文件,调用函数 get_file()把 f_count加 1。具体看一下 fcheck函数的执行,参考代码:include/linux/file.hstatic inline struct file * fcheck(unsigned int fd)struct file * file = NULL;struct files_struct *files = current-files;if (fd max_fds)file = files-fdfd;return file; filp-f_op-ioctl()函数,调用设备对应的 ioctl函数,对于使用 socket创建文件

10、描述符,它应该调用 sock_ioctl()函数,具体流程图如下:每一个设备都可以定义自己的 ioctl命令字,命令编号的范围是 SIOCDEVPRIVATE到SIOCDEVPRIVATE + 15。针对 ipv6隧道,它定一个四个命令字,分别是SIOCGETTUNNEL,SIOCADDTUNNEL,SIOCCHGTUNNEL,SIOCDELTUNNEL。用户空间通过 ioctl系统调用,最终调用到内核中定义的函数 ip6ip6_tnl_ioctl。sock_ioctl()函数调用中有关的内核函数:sock_ioctlinet6_ioctldev_ioctldev_ifsioc sock_io

11、ctl()功能::直接调用一个协议特定的函数,如:当 socket family是 PF_INET6,调用函数inet6_ioctl。 inet6_ioctl()功能:v6 对应 socket的 ioctl内核函数,根据不同的 case情况,作相应的处理。case SIOCADDRT:case SIOCDELRT:return(ipv6_route_ioctl(cmd,(void *)arg);当 ioctl命令字不满足上述各种 case情况时:default:if (cmd = SIOCDEVPRIVATE) &(cmd do_ioctl = ip6ip6_tnl_ioctl,其中函数 ip6ip6_tnl_ioctl就是该设备对应的 ioctl句柄,由于隧道设备是自己定义的 ioctl命令字,因而执行应在 default语句中,进而调用到自己定义的 ioctl处理函数 ip6ip6_tnl_ioctl。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 实用文档资料库 > 策划方案

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。