linux操作系统内核文件,Linux操作系统内核和设备文件对话.docx

62e50291a81fc54b507f33cb80033297.gif Linux操作系统内核和设备文件对话.docx

(27页)

26a7ba4a6fe60917454904e769671aef.gif

本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!

19.9 积分

Linux操作系统内核和设备文件对话 设备文件是用来代表物理设备的。多数物理设备是用来进行输出或输入的,所以必须由某种机制使得内核中的设备驱动从进程中得到输出送给设备。这可以通过打开输出设备文件并且写入做到,就想写入一个普通文件。在下面的例子里,这由device_write实现。   这不是总能奏效的。设想你与一个连向modem的串口(技是你有一个内猫,从CPU看来它也是作为一个串口实现,所以你不需要认为这个设想太困难)。最自然要做的事情就是使用设备文件把内容写到modem上(无论用modem命令还是电话线)或者从modem读信息(同样可以从modem命令回答或者通过电话线)。但是这留下的问题是当你需要和串口本身对话的时候需要怎样做?比如发送数据发送和接收的速率。   回答是Unix使用一个叫做ioctl(input output control的简写)的特殊函数。每个设备都有自己的ioctl命令,这个命令可以是ioctl读的,也可以是写的,也可以是两者都是或都不是。Ioctl函数由三个参数调用:适当设备的描述子,ioctl数,和一个长整型参数,可以赋予一个角色用来传递任何东西。   Ioctl数对设备主码、ioctl类型、编码、和参数的类型进行编码。Ioctl数通常在头文件由一个宏调用(_IO,_IOR,_IOW或_IOWR——决定于类型)。这个头文件必须包含在使用ioctl(所以它们可以产生正确的ioctl's)程序和内核模块(所以它可以理解)中。在下面的例子里,这个头文件是chardev.h,使用它的程序是ioctl.c。   如果你希望在你自己的内核模块中使用ioctl's,最好去接受一分正式的ioctl职位,这样你就可以得到别人的ioctl's,或者他们得到你,你就可以知道哪里出了错误。如果想得到更多的信息,到'documentation/ioctl-number.txt'中查看内核源文件树。    ex chardev.c /* chardev.c * * Create an input/output character device */ /* Copyright (C) 1998-99 by Ori Pomerantz */ /* The necessary header files */ /* Standard in kernel modules */ #include /* Were doing kernel work */ #include /* Specifically, a module */ /* Deal with CONFIG_MODVERSIONS */ #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include #endif /* For character devices */ /* The character device definitions are here */ #include /* A wrapper which does next to nothing at * at present, but may help for compatibility * with future versions of Linux */ #include /* Our own ioctl numbers */ #include "chardev.h" /* In 2.2.3 /usr/include/linux/version.h includes a * macro for this, but 2.0.35 doesnt - so I add it * here if necessary. */ #ifndef KERNEL_VERSION #define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) #include /* for get_user and put_user */ #endif #define SUCCESS 0 /* Device Declarations ******************************** */ /* The name for our device, as it will appear in * /proc/devices */ #define DEVICE_NAME "char_dev" /* The maximum length of the message for the device */ #define BUF_LEN 80 /* Is the device open right now? Used to prevent * concurent access into the same device */ static int Device_Open = 0; /* The message the device will give when asked */ static char Message[BUF_LEN]; /* How far did the process reading the message get? * Useful if the message is larger than the size of the * buffer we get to fill in device_read. */ static char *Message_Ptr; /* This function is called whenever a process attempts * to open the device file */ static int device_open(struct inode *inode, struct file *file) { #ifdef DEBUG printk ("device_open(%p)\n", file); #endif /* We dont want to talk to two processes at the * same time */ if (Device_Open) return -EBUSY; /* If this was a process, we would have had to be * more careful here, because one process might have * checked Device_Ope。省略部分。* number for passing information from a user process * to the kernel module. * * The first arguments, MAJOR_NUM, is the major device * number were using. * * The second argument is the number of the command * (there could be several with different meanings). * * The third argument is the type we want to get from * the process to the kernel. */ /* Get the message of the device driver */ #define IOCTL_GET_MSG _IOR(MAJOR_NUM, 1, char *) /* This IOCTL is used for output, to get the message * of the device driver. However, we still need the * buffer to place the message in to be input, * as it is allocated by the process. */ /* Get the nth byte of the message */ #define IOCTL_GET_NTH_BYTE _IOWR(MAJOR_NUM, 2, int) /* The IOCTL is used for both input and output. It * receives from the user a number, n, and returns * Message[n]. */ /* The name of the device file */ #define DEVICE_FILE_NAME "char_dev" #endif ex ioctl.c /* ioctl.c - the process to use ioctls to control the * kernel module * * Until now we could have used cat for input and * output. But now we need to do ioctls, which require * writing our own process. */ /* Copyright (C) 1998 by Ori Pomerantz */ /* device specifics, such as ioctl numbers and the * major device file. */ #include "chardev.h" #include /* open */ #include /* exit */ #include /* ioctl */ /* Functions for the ioctl calls */ ioctl_set_msg(int file_desc, char *message) { int ret_val; ret_val = ioctl(file_desc, IOCTL_SET_MSG, message); if (ret_val < 0) { printf ("ioctl_set_msg failed:%d\n", ret_val); exit(-1); } } ioctl_get_msg(int file_desc) { int ret_val; char message[100]; /* Warning - this is dangerous because we dont tell * the kernel how far its allowed to write, so it * might overflow the buffer. In a real production * program, we would have used two ioctls - one to tell * the kernel the buffer length and another to give * it the buffer to fill */ ret_val = ioctl(file_desc, IOCTL_GET_MSG, message); if (ret_val < 0) { printf ("ioctl_get_msg failed:%d\n", ret_val); exit(-1); } printf("get_msg message:%s\n", message); } ioctl_get_nth_byte(int file_desc) { int i; char c; printf("get_nth_byte message:"); i = 0; while (c != 0) { c = ioctl(file_desc, IOCTL_GET_NTH_BYTE, i++); if (c < 0) { printf( "ioctl_get_nth_byte failed at the %dth byte:\n", i); exit(-1); } putchar(c); } putchar(\n); } /* Main - Call the ioctl functions */ main() { int file_desc, ret_val; char *msg = "Message passed by ioctl\n"; file_desc = open(DEVICE_FILE_NAME, 0); if (file_desc < 0) { printf ("Cant open device file: %s\n", DEVICE_FILE_NAME); exit(-1); } ioctl_get_nth_byte(file_desc); ioctl_get_msg(file_desc); ioctl_set_msg(file_desc, msg); close(file_desc); } 关 键 词: 文件 linux 操作系统 设备 内核 对话

524d6daf746efaa52c3c71bbfe7ba172.gif  天天文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。

关于本文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值