如何做正常的文件和设备驱动程序打开作品(how does open works for normal

2019-07-18 16:04发布

目前,我正在学习的Linux设备驱动程序。 而被困在如何打开设备文件的工作?

我得到了什么直到现在......考虑打开正常文件的简单代码..

#incldue<stdio.h>
int main() {
   FILE fp;
   char buffer[20];
   fp = fopen(/home/yoggi/foo.txt, "r");
   fread(buffer, 5, 1, fp);
}

在上述程序中,则fopen()中,c-库函数,是一个包装功能的系统调用打开(),它实习生呼叫SYS_OPEN()或FILE_OPEN()在VFS层功能。 作为Linux支持数量的文件系统,虚拟文件​​系统,则控制转移到实际的文件系统处理程序,以该文件的开口。

1) How does virtual file system(VFS) get to know on which file system the 
   underline file resides?
2) How does it then calls the file_open or open function of that particular
   filesystem to open file.

在设备驱动程序的情况下,类似的事情发生。 假设一个简单的设备驱动程序。

#include <linux/module.h>
// othher includes... 
static dev_t first; // Global variable for the first device number 
static struct cdev c_dev; // Global variable for the character device structure
static struct class *cl; // Global variable for the device class
static int my_open(struct inode *i, struct file *f)
{
   printk(KERN_INFO "Driver: open()\n");
   return 0;
} 
static ssize_t my_read(struct file *f, char __user *buf, size_t len, loff_t *off)
{
   printk(KERN_INFO "Driver: read()\n");
   return 0;
}
struct file_operations pugs_fops =
{
 .owner = THIS_MODULE,
 .open = my_open,
 .read = my_read,
};

static int __init ofcd_init(void) /* Constructor */
{
  printk(KERN_INFO "Namaskar: ofcd registered");
  if (alloc_chrdev_region(&first, 0, 1, "Shweta") < 0)
  {
    return -1;
  }
  if ((cl = class_create(THIS_MODULE, "chardrv")) == NULL)
  {
     unregister_chrdev_region(first, 1);
     return -1;
 }
 if (device_create(cl, NULL, first, NULL, "mynull") == NULL)
 {
    class_destroy(cl);
    unregister_chrdev_region(first, 1);
    return -1;
 }
   cdev_init(&c_dev, &pugs_fops);
 if (cdev_add(&c_dev, first, 1) == -1)
 {
   device_destroy(cl, first);
   class_destroy(cl);
   unregister_chrdev_region(first, 1);
   return -1;
 }
  return 0;
}

static void __exit ofcd_exit(void) /* Destructor */
{
 cdev_del(&c_dev);
 device_destroy(cl, first);
 class_destroy(cl);
 unregister_chrdev_region(first, 1);
 printk(KERN_INFO "Alvida: ofcd unregistered");
} 
module_init(ofcd_init);
module_exit(ofcd_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anil Kumar Pugalia <email_at_sarika-pugs_dot_com>");
MODULE_DESCRIPTION("Our First Character Driver");

首先,我们分配的设备主要和次要号码。 注册设备文件的范围和链接的设备文件操作设备驱动程序的功能。

一些术语,我没有得到的是..

1) What does actually cdev_add() do? in terms of registering a device to the 
   kernel.
2) Registering a device to the kernel means?
3) How does a open(/dev/mynull, O_RONLY); called on a device file actually calls 
   the open function of driver which is mapped while initializing the device 
   by calling routine cdev_init(&c_dev, &pugs_fops); ?

Answer 1:

1)如何虚拟文件系统(VFS)了解哪个文件系统中的下划线文件所在?

你必须指定你想通过其路径名(或当前工作目录)打开文件。
因此,通过向后遍历这个目录路径,第一匹配(最深路径),以一个安装点会提供安装的文件系统,文件系统和设备的类型。

每个文件系统提供了当其被安装和被保存在所述安装表此信息。
您可以查看使用这个(当前状态)信息mount命令。

2)如何做它然后调用特殊的文件系统打开文件的FILE_OPEN或打开功能。

一旦文件系统是已知的, ops结构为FS被检索,并且open()入口点可以被调用。

1)什么是真正cdev_add()呢? 在注册装置到内核的条款。

驱动的注册(例如cdev_init()为一个字符设备)安装驱动程序的ops结构其中列出的驾驶员能够执行功能的入口点。
cdev_add()通知驾驶员可以控制字符设备类型的特定实例内核。 该设备实例分配,在设备名称相关联的次要号码/dev陈述在驾驶者信息。
注意,除了炭其他该设备类型(例如网络或平台(总线)设备)属于不同的子系统,并使用不同的登记手续。

2)注册的设备到内核手段?

访问该设备现在已启用。

3)如何做了开放(的/ dev / mynull,O_RONLY); 称为在设备文件实际调用而通过调用例程cdev_init初始化设备被映射驱动器的开功能(c_dev,&pugs_fops); ?

驾驶员init()例程应在加载驱动程序时,只能被调用一次。 此例程应探测设备的所有实例的存在和操作状态。 应该获取如中断线,DMA通道及I / O端口和/或存储器空间的资源。 该驱动程序注册其ops内核结构。 该驱动程序注册与核设备的每个实例。

open()在用户空间中调用C库处理。 所述/dev设备名称被翻译成该设备的主设备号(其识别哪个设备子系统或类,例如TTY音频 ,具有处理请求)和辅号码(其识别要使用的设备驱动器和该装置的实例被访问)。 该处理器被切换到管理员模式下,以使内核驱动程序的open()例程可以调用,其从驾驶者的检索ops结构。 欲了解更多关于有点ops结构看这对方的回答 。



文章来源: how does open works for normal file and device drivers