热门关键字:  ubuntu  分区  Fedora  linux系统进程  函数

当前位置 :| 主页>Linux教程>内核研究>

Liunx用户和内核空间之间的通信实现

来源: 作者: 时间:2007-05-20 Tag: 点击:

其中调用到函数的说明:

★ fget()函数,它是用来获取操作文件的指针,在这篇文档里,我是使用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是否对应一个打开的文件,如果是就获取该文件,调用函数get_file()将f_count加1。

具体看一下fcheck函数的执行,参考代码:

include/linux/file.h
static inline struct file * fcheck(unsigned int fd)
{
struct file * file = NULL;
struct files_struct *files = current->files;

if (fd < files->max_fds) /*max_fds是最多打开的文件数*/
file = files->fd[fd]; /*其中files_struct结构中定义的file是进程文件描述符表*/
return file;
}

★ filp->f_op->ioctl()函数,调用设备对应的ioctl函数,对于使用socket创建文件描述符,它应该调用sock_ioctl()函数,具体流程图如下:

每一个设备都可以定义自己的ioctl命令字,命令编号的范围是 SIOCDEVPRIVATE到SIOCDEVPRIVATE + 15。针对ipv6隧道,它定一个四个命令字,分别是SIOCGETTUNNEL,SIOCADDTUNNEL,SIOCCHGTUNNEL, SIOCDELTUNNEL。用户空间通过ioctl系统调用,最终调用到内核中定义的函数ip6ip6_tnl_ioctl。

sock_ioctl()函数调用中有关的内核函数:
sock_ioctl
inet6_ioctl
dev_ioctl
dev_ifsioc

■ sock_ioctl()

功能::直接调用一个协议特定的函数,如:当socket family是PF_INET6,调用函数inet6_ioctl。

■ inet6_ioctl()

功能:v6对应socket的ioctl内核函数,根据不同的case情况,作相应的处理。

case SIOCADDRT:
case SIOCDELRT: 
return(ipv6_route_ioctl(cmd,(void *)arg));/*对路由表的ioctl操作,
调用内核函ipv6_route_ioctl进行增加或是删除*/

当ioctl命令字不满足上述各种case情况时:

default:
if ((cmd >= SIOCDEVPRIVATE) &&
(cmd <= (SIOCDEVPRIVATE + 15)))
return(dev_ioctl(cmd,(void *) arg));

 

该设备自己定义了一些ioctl命令字范围在SIOCDEVPRIVATE到SIOCDEVPRIVATE + 15之间),调用函数dev_ioctl实现对该设备指定的ioctl命令的操作。

■ dev_ioctl()

功能:用来处理所有设备接口的ioctl请求,只是一个包装器, 实际的动作将由dev_ifsioc()来实现。dev_ioctl做的只是检查这个调用是否具有了正当的权限。

■ dev_ifsioc()

功能:真正处理所有设备接口的ioctl请求。

具体操作说明:函数首先要做的一些事情包括得到与ifr.ifr_name相匹配的设备的结构,但这是在实现特定的接口命令之后。这些特定的接口命令被放置到一个巨大的switch语句之中。其中SIOCDEVPRIVATE命令和其他的在0x89F0到0x89FF之间的代码将出现在switch语句中的一个分支——default语句中,代码最后还增加了对无线网络的支持。内核执行时会检查表示设备的结构变量中,是否已经定义了一个与设备相关的ioctl句柄(handler)。这里的句柄是一个函数指针,它在表示设备的结构变量中 do_ioctl部分。如果已经设置了这个句柄,那么内核将会执行它。如ipv6隧道设备体,在初始化时,就作了说明:dev->do_ioctl = ip6ip6_tnl_ioctl,其中函数ip6ip6_tnl_ioctl就是该设备对应的ioctl句柄,由于隧道设备是自己定义的ioctl命令字,因而执行应在default语句中,进而调用到自己定义的ioctl处理函数ip6ip6_tnl_ioctl。




相关文章:
精通initramfs构建step by step
Linux利用kexec迅速切换内核
进程上下文VS中断上下文
内核通知链 学习笔记
linux spi子系统驱动分析
menuconfig 配置选项
《Linux操作系统内核实习》之练习一
udev详解
什么叫微内核,宏内核?
Linux 信号signal处理机制
开发简单的 Linux2.6 内核模块
删除内核的perl脚本
Linux2.6内核usb gadget驱动移植
GCC hacks in the Linux kernel
iomem
kernel学习的想法
让自己的驱动支持udev
linux内核编译步骤
内核的等待队列
Linux内核wait_queue深入分析
升级和删除内核
SD卡驱动分析2
Linux Kernel VDSO本地权限提升漏洞
内核中的TCP的追踪分析-15-TCP(IPV4)的客户端与
linux 2.6内核可加载模块的编译
内核模块HelloWorld
在环回接口上发送一个数据报
ARP初始化
1分钟编译FreeBSD内核
linux设备模型之uart驱动架构分析