操作系统如何知道要调用哪个设备驱动程序?

时间:2018-02-04 05:59:54

标签: linux linux-kernel operating-system linux-device-driver

我一直openwrite/read来自文件/设备文件,并且一直在阅读操作系统,但从未理解设备驱动程序如何不可避免地被调用的流程

例如,我们执行writestdout fd=1 当我执行write时,我知道操作系统会调用此特定设备文件的设备驱动程序已经打开,但我不了解的是我们如何访问设备驱动程序本身。

  1. 首先创建设备文件(即stdout)需要什么?安装?内核模块加载?

  2. (后续[1])因此,如果我有一个外围设备,例如单个LED灯连接到我的计算机,并且已经安装了正确的LED设备驱动程序并且创建了设备文件在/dev/singleled中,当我open/dev/singleled时会发生什么?

  3. (具体)

    • 当我致电write时,操作系统如何知道要为此设备文件调用哪个设备驱动程序?
    • 当我们在此设备文件上执行open时,我们是否在文件描述符中存储信息?

    我真的想了解这个设置是如何创建的 提前感谢大家

2 个答案:

答案 0 :(得分:2)

在简短的概述术语中,设备节点由主要和次要编号标识,您可以使用ls -l之类的命令查看这些编号,并且需要将其传递给{{1}之类的命令1}}如果从用户空间创建它们。

在内核方面,驱动程序可以为这些数字的范围注册自己。

然后问题减少到管理适度大小的关联数据表并使用它来查找注册用于处理用户空间调用的相应驱动程序和方法。

您还提到了LED,但这些LED通常作为mknod节点处理,即sysfs这是一个独特的接口,通过匹配名称而不是主要/次要数字来运作。

您可能会发现实际查看一些设备(包括/sys/class/LED/xxx/dev中的节点以及相关的内核代码会很有帮助。编写用于解释概念的示例/教程驱动程序可能是最清晰的。

答案 1 :(得分:0)

嵌入式系统(我工作的地方)领域,OS内核通过读取设备树知道要调用哪个设备驱动程序。阅读here,了解我所说的内容。

但是,更准确地说,在启动时读取设备树(即描述操作系统将运行的硬件的文件)。因此,读取它的操作系统将实例化正确的驱动程序。在设备树的compatible字段中,必须与驱动程序的关键字匹配的确切关键字

例如,假设您有一个包含此节点的设备树:

  ps7_axi_interconnect_0: axi@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
ranges ;
gic: interrupt-controller@f8f01000 {
  #interrupt-cells = < 3 >;
  compatible = "arm,cortex-a9-gic";
  interrupt-controller ;
  reg = < 0xf8f01000 0x1000  >,< 0xf8f00100 0x100  >;
} ;
pl310: pl310-controller@f8f02000 {
  arm,data-latency = < 3 2 2 >;
  arm,tag-latency = < 2 2 2 >;
  cache-level = < 2 >;
  cache-unified ;
  compatible = "arm,pl310-cache";
  interrupts = < 0 34 4 >;
  reg = < 0xf8f02000 0x1000 >;
} ;

  [ ... more items ... ]

xillybus_0: xillybus@50000000 {
  compatible = "xlnx,xillybus-1.00.a";
  reg = < 0x50000000 0x1000 >;
  interrupts = < 0 59 1 >;
  interrupt-parent = <&gic>;
  xlnx,max-burst-len = <0x10>;
  xlnx,native-data-width = <0x20>;
  xlnx,slv-awidth = <0x20>;
  xlnx,slv-dwidth = <0x20>;
  xlnx,use-wstrb = <0x1>;
} ;

};

请注意字段compatible。 现在,将使用此节点的驱动程序必须具有以下内容:

static struct of_device_id xillybus_of_match[] __devinitdata = {
  { .compatible = "xlnx,xillybus-1.00.a", },
  {}
};

MODULE_DEVICE_TABLE(of, xillybus_of_match);
/********something else*******/
static struct platform_driver xillybus_platform_driver = {
  .probe = xilly_drv_probe,
  .remove = xilly_drv_remove,
  .driver = {
    .name = "xillybus",
    .owner = THIS_MODULE,
    .of_match_table = xillybus_of_match,
  },
};

要更好地了解正在发生的事情,请参阅this简单教程。我希望这可以提供帮助。

关于LED示例

在此git repository folder中,您可以找到一个设备驱动程序模块,该模块可以读取设备树的compatible字段,并且可以设置为打开它。在同一文件夹中,有源C文件来测试驱动程序打开和关闭它。您可以通过C代码了解调用openclose时发生的情况等等。