Linux Driver是什么(driver,linux,开发技术)

时间:2024-05-10 10:55:17 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

Linux Driver即Linux 驱动,linux 系统设计将设备驱动纳入了文件系统,任何一个Linux驱动都需要有一个设备文件,否则应用程序将无法与驱动程序交互。

Linux Driver是什么

设备分类

  • 字符设备

  • 块设备

  • 网络设备

驱动在kernel中的位置

linux 系统设计将设备驱动纳入了文件系统, Linux Driver是什么

更为具体的分层调用结构如下所示: Linux Driver是什么

Linux Device Model

usb 设备的驱动设备模型:

Linux Driver是什么

设备文件的节点记录的信息:

  • 文件类型

  • 主设备号

  • 次设备号 主设备号和类型决定了驱动的类型及其界面,而次设备号则说明是同类设备中的第几个设备。

devfs 文件系统

在linux 2.4 引入,主要优点:

  • 可以通过程序在设备初始化时在/dev目录下创建设备文件,卸载设备时将它 删除。

  • 设备驱动程序可以指定设备名、所有者和权限位,用户空间程序仍可以修改 所有者和权限位。

  • 不再需要为设备驱动程序分配主设备号以及处理次设备号,在程序中可以直 接给 register_chrdev()传递 0 主设备号以动态获得可用的主设备号,并在 devfs_register()中指定次设备号。

udev 设备文件系统

linux 2.6开始抛弃了devfs,引入了udev 文件系统,基于以下几点:

  • devfs所做的工作被确信可以在用户态来完成。

  • 一些bug相当长的时间内未被修复。

  • devfs的维护者和作者停止了对代码的维护工作。

udev 与devfs的区别在于:

devfs 在设备打开时自动加载驱动程序 udev在发现设备时自动加载驱动程序

sysfs 文件系统

udev工作在用户态,利用设备加入或移除时内核所发送的热插拔事件来进行工作,同时hotplug事件,设备的详细信息会由内核输出到位于/sys 的sysfs文件系统。

udev 利用sysfs中的信息来创建设备文件节点等工作

sysfs被看成是与proc、devfs和devpty同 类别的文件系统,该文件系统是一个虚拟的文件系统,它可以产生一个包括所有系统 硬件的层级视图,与提供进程和状态信息的 proc 文件系统十分类似

tree/sys/dev/├──block│├──7:0->../../devices/virtual/block/loop0│├──7:1->../../devices/virtual/block/loop1│├──7:2->../../devices/virtual/block/loop2│├──7:3->../../devices/virtual/block/loop3│├──7:4->../../devices/virtual/block/loop4│├──7:5->../../devices/virtual/block/loop5│├──7:6->../../devices/virtual/block/loop6│├──7:7->../../devices/virtual/block/loop7│├──8:0->../../devices/pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0/block/sda│├──8:1->../../devices/pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0/block/sda/sda1│├──8:16->../../devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8.2/1-8.2:1.0/host4/target4:0:0/4:0:0:0/block/sdb│├──8:2->../../devices/pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0/block/sda/sda2│├──8:32->../../devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8.2/1-8.2:1.0/host4/target4:0:0/4:0:0:1/block/sdc│├──8:48->../../devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8.2/1-8.2:1.0/host4/target4:0:0/4:0:0:2/block/sdd│├──8:5->../../devices/pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0/block/sda/sda5│└──8:6->../../devices/pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0/block/sda/sda6└──char├──10:1->../../devices/virtual/misc/psaux├──10:183->../../devices/virtual/misc/hw_random├──10:184->../../devices/virtual/misc/microcode├──10:200->../../devices/virtual/misc/tun├──10:223->../../devices/virtual/misc/uinput├──10:227->../../devices/virtual/misc/mcelog├──10:228->../../devices/virtual/misc/hpet├──10:229->../../devices/virtual/misc/fuse├──10:231->../../devices/virtual/misc/snapshot├──10:232->../../devices/virtual/misc/kvm12345678910111213141516171819202122232425262728293031

/sys 目录下展示了所有系统中的设备层级目录,其关系大致如下 Linux Driver是什么

kobject

linux3.4

structkobject{constchar*name;structlist_headentry;//usedformounttoksetliststructkobject*parent;structkset*kset;structkobj_type*ktype;//指向对象类型描述附指针structsysfs_dirent*sd;//structkrefkref;//引用计数unsignedintstate_initialized:1;unsignedintstate_in_sysfs:1;unsignedintstate_add_uevent_sent:1;unsignedintstate_remove_uevent_sent:1;unsignedintuevent_suppress:1;};123456789101112131415

其中 sysfs_dirent,

/**sysfs_dirent-thebuildingblockofsysfshierarchy.Eachand*everysysfsnodeisrepresentedbysinglesysfs_dirent.**Aslongass_countreferenceisheld,thesysfs_direntitselfis*accessible.Dereferencings_elemoranyotherouterentity*requiress_activereference.*/structsysfs_dirent{atomic_ts_count;atomic_ts_active;#ifdefCONFIG_DEBUG_LOCK_ALLOCstructlockdep_mapdep_map;#endifstructsysfs_dirent*s_parent;constchar*s_name;structrb_nodes_rb;union{structcompletion*completion;structsysfs_dirent*removed_list;}u;constvoid*s_ns;/*namespacetag*/unsignedints_hash;/*ns+namehash*/union{structsysfs_elem_dirs_dir;structsysfs_elem_symlinks_symlink;structsysfs_elem_attrs_attr;structsysfs_elem_bin_attrs_bin_attr;};unsignedshorts_flags;umode_ts_mode;unsignedints_ino;structsysfs_inode_attrs*s_iattr;};123456789101112131415161718192021222324252627282930313233343536373839

kset

structkset{structlist_headlist;//doublelistheadspinlock_tlist_lock;structkobjectkobj;//嵌入的kobjectconststructkset_uevent_ops*uevent_ops;//事件操作集};123456

其中 kset_uevent_ops 定义了kset的对所包含的kobject 可以执行的操作,包括事件过滤和导出环境变量操作。

structkset_uevent_ops{int(*constfilter)(structkset*kset,structkobject*kobj);//事件过滤constchar*(*constname)(structkset*kset,structkobject*kobj);int(*constuevent)(structkset*kset,structkobject*kobj,structkobj_uevent_env*env);//环境变量导出};1234567

device

device 数据结构用于描述设备相关的信息和设备之间的层次关系,设备与总线与驱动之间的关系。

structdevice{structdevice*parent;structdevice_private*p;structkobjectkobj;constchar*init_name;/*initialnameofthedevice*/conststructdevice_type*type;structmutexmutex;/*mutextosynchronizecallsto*itsdriver.*/structbus_type*bus;/*typeofbusdeviceison*/structdevice_driver*driver;/*whichdriverhasallocatedthisdevice*/void*platform_data;/*Platformspecificdata,devicecoredoesn'ttouchit*/structdev_pm_infopower;structdev_pm_domain*pm_domain;#ifdefCONFIG_NUMAintnuma_node;/*NUMAnodethisdeviceiscloseto*/#endifu64*dma_mask;/*dmamask(ifdma'abledevice)*/u64coherent_dma_mask;/*Likedma_mask,butforalloc_coherentmappingsasnotallhardwaresupports64bitaddressesforconsistentallocationssuchdescriptors.*/structdevice_dma_parameters*dma_parms;structlist_headdma_pools;/*dmapools(ifdma'ble)*/structdma_coherent_mem*dma_mem;/*internalforcoherentmemoverride*/#ifdefCONFIG_CMAstructcma*cma_area;/*contiguousmemoryareafordmaallocations*/#endif/*archspecificadditions*/structdev_archdataarchdata;structdevice_node*of_node;/*associateddevicetreenode*/dev_tdevt;/*dev_t,createsthesysfs"dev"*/u32id;/*deviceinstance*/spinlock_tdevres_lock;structlist_headdevres_head;structklist_nodeknode_class;structclass*class;conststructattribute_group**groups;/*optionalgroups*/void(*release)(structdevice*dev);};12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758

操作device的相关函数:

device_register():/sys/devices下创建相关目录device_unregister():移除相关目录get_device:增加引用计数put_device:减小引用计数1234

device_driver

structdevice_driver{constchar*name;structbus_type*bus;structmodule*owner;constchar*mod_name;/*usedforbuilt-inmodules*/boolsuppress_bind_attrs;/*disablesbind/unbindviasysfs*/conststructof_device_id*of_match_table;int(*probe)(structdevice*dev);int(*remove)(structdevice*dev);void(*shutdown)(structdevice*dev);int(*suspend)(structdevice*dev,pm_message_tstate);int(*resume)(structdevice*dev);conststructattribute_group**groups;conststructdev_pm_ops*pm;structdriver_private*p;};12345678910111213141516171819202122

其中

structbus_type{constchar*name;constchar*dev_name;structdevice*dev_root;structbus_attribute*bus_attrs;structdevice_attribute*dev_attrs;structdriver_attribute*drv_attrs;int(*match)(structdevice*dev,structdevice_driver*drv);int(*uevent)(structdevice*dev,structkobj_uevent_env*env);int(*probe)(structdevice*dev);int(*remove)(structdevice*dev);void(*shutdown)(structdevice*dev);int(*suspend)(structdevice*dev,pm_message_tstate);int(*resume)(structdevice*dev);conststructdev_pm_ops*pm;structiommu_ops*iommu_ops;structsubsys_private*p;};1234567891011121314151617181920212223

Kernel modules

模块安装与卸载

并不是所有的module都是在编译内核时加入的,主要有以下考虑:

  • 所有模块默认编译进内核,将使得内核臃肿

  • 使得内核不易进行扩展

linux提供可动态安装模块的机制,可将模块编译成ko文件,推迟链接的时间:

  • 在需要时通过insmod 完成链接过程,链接系统内核导出符号,完成模块的可插拔功能。

  • 相对应的,移除模块通过rmmod完成

  • 考虑到模块之间可相互依赖,进行调用,因此在载入模块的同时需要检查依赖的模块是否已经载入,modprobe 可以自动加载依赖模块,其根据依赖信息工作:depmod -A 可生成新模块的依赖信息 推荐使用modprobe 进行模块安装与卸载:

modprobemodule[parameter]modprobe-rmodules;如果依赖的模块有被其他模块调用,则不会移除,反之,一并移除12

导出符号表

模块之间可通过到处符号表实现依赖关系 Linux Driver是什么

EXPORT_SYMBOL(function_name) 导出函数符号 EXPORT_SYMBOL_GPL(function_name) 导出给符合GPL 协议的模块使用

The minor number is used by the kernel to determine exactly which device is being referred to. Depending on how your driver is written (as we will see below), you can either get a direct pointer to your device from the kernel, or you can use the minor number yourself as an index into a local array of devices. Either way, the kernel itself knows almost nothing about minor numbers beyond the fact that they refer to devices implemented by your driver.

Module Stack

驱动常见错误debug

  1. invalid format

#insmodhello.koErrorinserting'./hello.ko':-1Invalidmoduleformat12

cat /var/log/messages

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Linux Driver是什么的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:Linux下怎么安装Docker下一篇:

7 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18