一种Linux内核模块获取usb_bus_type符号地址的方法及
系统
技术领域
本发明涉及符号地址获取技术领域,具体地说是一种Linux内核模块获取usb_bus_type符号地址的方法及系统。
背景技术
在很多时候,usb设备驱动并不包含在内核中,因此内核模块会通过调用usb总线地址的方式进行加载usb设备。
就当下Linux操作系统各个发行版而言,其内核中usb_bus_type符号地址并不一定会允许第三方内核模块直接调用。
在系统内核进行微调重新编译后,如果系统内核发行号未发生变化,那么新的系统内核将会允许基于老的系统内核开发的第三方内核模块加载,但其中部分甚至绝大部分内核参数地址将会发生变化,其中包含pci_bus_type符号地址(pci总线地址)和usb_bus_type符号地址(usb总线地址)。这种现状无疑对于第三方内核模块调用该符号造成了困难。这就是现有技术的问题所在。
发明内容
本发明实施例中提供了一种Linux内核模块获取usb_bus_type符号地址的方法及系统,用于解决由于usb_bus_type符号地址随系统加载内核而变化,造成的第三方无法调用usb_bus_type符号地址的问题。
为了解决上述技术问题,本发明实施例公开了如下技术方案:
本发明第一方面提供了一种Linux内核模块获取usb_bus_type符号地址的方法,具体包括以下方法:
查找内核pci_bus_type符号地址;
遍历pci总线上的子设备,查找usb控制器设备;
对usb控制器设备进行内核结构体转换,获取usb_bus_type符号地址。
结合第一方面,在第一方面第一种可能的实现方式中,所述查找内核pci_bus_type符号地址通过调用内核符号。
结合第一方面,在第一方面第二种可能的实现方式中,遍历pci总线上的子设备的方法包括调用内核函数bus_for_each_dev传入参数pci_bus_type符号地址。
结合第一方面,在第一方面第三种可能的实现方式中,查找usb控制器设备的方法包括判断子设备的参数定义,当子设备配置空间中的class code中的base class为0x0C,sub class为0x03时,为usb控制器设备。
结合第一方面,在第一方面第四种可能的实现方式中,所述对usb控制器设备进行内核结构体转换的方法包括:
调用pci_get_drvdata获取当前usb控制器设备的内核驱动对象uhcd;
把usb控制器设备的内核驱动对象uhcd转换为当前usb总线的根设备结构体udev;
通过usb总线根设备结构体udev获取通用内核设备对象结构体cdev。
结合第一方面,在第一方面第五种可能的实现方式中,所述获取usb_bus_type符号地址的方法包括:
读取通用内核设备对象结构体cdev中的bus成员,所述的bus成员为usb_bus_type符号地址。
本发明第二方面提供了一种Linux内核模块获取usb_bus_type符号地址的系统,包括查询模块,用于查找内核pci_bus_type符号地址和usb控制器设备;和,
内核结构体转换模块,用于将usb控制器设备进行结构体转换,把内核驱动对象转换为通用内核设备对象结构体;和,
usb_bus_type符号地址获取模块,用于根据通用内核设备对象结构体获取usb_bus_type符号地址。
结合第二方面,在第二方面第一种可能的实现方式中,所述usb控制器设备的标志是子设备配置空间中的class code中的base class为0x0C,sub class为0x03。
结合第二方面,在第二方面第二种可能的实现方式中,所述的usb_bus_type符号地址即为通用内核设备对象结构体的bus成员。
本发明第一方面所述的方法能够实现第二方面以及其各个方面的系统,并取得相同的技术效果。
由以上技术方案可见,本发明通过遍历pci总线上的子设备查找usb控制器设备,从而获取usb_bus_type符号地址,使usb_bus_type符号地址不受新的系统内核参数变动的影响。
本发明的bus成员即为usb_bus_type符号地址,不受系统内核中usb_bus_type符号地址未导出或者以内核模块实现的限制。
本发明可嵌入第三方内核模块中,跨平台可移植性和通用性较好。
附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1为一种Linux内核模块获取usb_bus_type符号地址的方法流程示意图;
图2为本发明实施例对usb控制器设备进行内核结构体转换的方法流程示意图;
图3为本发明实施例所应用的一种Linux内核模块获取usb_bus_type符号地址的系统结构示意图。
具体实施方式
为了使本技术领域的人员更好地理解本发明中的技术方案,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本发明保护的范围。
如图1所示,一种Linux内核模块获取usb_bus_type符号地址的方法,具体包括以下方法:
S1、查找内核pci_bus_type符号地址;可以通过调用内核符号查找函数查找,如:kallsyms_lookup_name、find_symbol。
S2、遍历pci总线上的子设备,查找usb控制器设备;通过调用内核函数bus_for_each_dev传入参数pci总线地址可以完成内核中pci总线(pci_bus_type符号)上所有子设备的遍历,通过pci总线上子设备配置空间中的class code可以判断是否是USB控制器设备,当class code中的base class为0x0C,sub class为0x03时,即为usb控制器设备。
S3、对usb控制器设备进行内核结构体转换,获取usb_bus_type符号地址。
如图2所示,对usb控制器设备进行内核结构体转换包括以下方法:
S31、调用pci_get_drvdata获取当前usb控制器设备的内核驱动对象uhcd;调用方法为uhcd=pci_get_drvdata(pdev)。
S32、把usb控制器设备的内核驱动对象uhcd转换为当前usb总线的根设备结构体udev;该步骤可以通过uhcd对象中的成员直接获取。转换方法为udev=uhcd->self.root_hub。
S33、通过usb总线根设备结构体udev获取通用内核设备对象结构体cdev。转换方法为cdev=&(udev->dev)。
S3中获取usb_bus_type符号地址的方法包括:
读取通用内核设备对象结构体cdev中的bus成员,bus成员为usb_bus_type符号地址,获取方法为:usb_bus_type=cdev->bus,获取到的符号可以直接使用。
如图3所示,一种Linux内核模块获取usb_bus_type符号地址的系统,包括查询模块101,用于查找内核pci_bus_type符号地址和usb控制器设备;和,内核结构体转换模块102,用于将usb控制器设备进行结构体转换,把内核驱动对象转换为通用内核设备对象结构体;和,usb_bus_type符号地址获取模块103,用于根据通用内核设备对象结构体获取usb_bus_type符号地址。
usb控制器设备的标志是子设备配置空间中的class code中的base class为0x0C,sub class为0x03。
usb_bus_type符号地址即为通用内核设备对象结构体的bus成员。
以上所述仅是本发明的具体实施方式,使本领域技术人员能够理解或实现本发明。对这些实施例的多种修改对本领域的技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本发明的精神或范围的情况下,在其它实施例中实现。因此,本发明将不会被限制于本文所示的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。