xHCI驱动学习(0) 模块启动
2015-06-24 16:20
232 查看
最近在学习Linux内核中USB相关内容的实现,读完了fudan_abc大神师兄的《USB那些事儿之我是USB Core》,感觉荡气回肠,因为大神不仅教给我们代码的奥义,也教给我们读代码的奥义。于是接下来尝试用学到的“鱼”和“渔”,从USB Core“启下”,自己学习xHCI驱动的代码。
xHCI是USB 3.x的host controller规范,首先进入drivers/usb/host目录浏览一下,其实从文件名就可以知道,跟xHCI关系最密切的必然是xhci.c。保险起见还是看一下KConfig:
主要配置项叫做USB_XHCI_HCD,另外还有USB_XHCI_PCI和USB_XHCI_PLATFORM。再看Makefile,直接搜索XHCI有关的内容:
果然,CONFIG_USB_XHCI_HCD需要xhci.o,另外还有一堆xhci-xxx.o。先打开xhci.c,这个文件有5033行(Linux 4.1)。直接搜索module_init找到模块入口,发现是定义在文件末尾的xhci_hcd_init函数:
xhci_hcd_init和xhci_hcd_fini这两个函数有点坑爹,居然什么实质性的事情都没有做!看来要对另外两个模块下手。
USB_XHCI_PCI,顾名思义,是xHCI驱动和PCI总线驱动之间的“接口”(内核开发者称这种“接口”为glue,有没有感觉黏黏的:D)。USB控制器大多是PCI设备,若控制器连接到PCI总线上,那么自然是先由PCI驱动发现该设备,识别之后才能交给xHCI驱动处理。所以实际上,作为glue的xhci-pci模块代码要早于xhci-hcd模块代码开始工作,因此关键的初始化过程放在前者中也就不奇怪了。
从Makefile中知道(不看也知道),CONFIG_USB_XHCI_PCI需要xhci-pci.o,因此打开xhci-pci.c搜索module_init:
子曰:好戏开始了。
xHCI是USB 3.x的host controller规范,首先进入drivers/usb/host目录浏览一下,其实从文件名就可以知道,跟xHCI关系最密切的必然是xhci.c。保险起见还是看一下KConfig:
config USB_XHCI_HCD tristate "xHCI HCD (USB 3.0) support" ---help--- The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0 "SuperSpeed" host controller hardware. To compile this driver as a module, choose M here: the module will be called xhci-hcd. if USB_XHCI_HCD config USB_XHCI_PCI tristate depends on PCI default y config USB_XHCI_PLATFORM tristate config USB_XHCI_MVEBU tristate "xHCI support for Marvell Armada 375/38x" select USB_XHCI_PLATFORM depends on ARCH_MVEBU || COMPILE_TEST ---help--- Say 'Y' to enable the support for the xHCI host controller found in Marvell Armada 375/38x ARM SOCs. config USB_XHCI_RCAR tristate "xHCI support for Renesas R-Car SoCs" select USB_XHCI_PLATFORM depends on ARCH_SHMOBILE || COMPILE_TEST ---help--- Say 'Y' to enable the support for the xHCI host controller found in Renesas R-Car ARM SoCs. endif # USB_XHCI_HCD
主要配置项叫做USB_XHCI_HCD,另外还有USB_XHCI_PCI和USB_XHCI_PLATFORM。再看Makefile,直接搜索XHCI有关的内容:
xhci-hcd-y := xhci.o xhci-mem.o xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o xhci-hcd-y += xhci-trace.o xhci-plat-hcd-y := xhci-plat.o ifneq ($(CONFIG_USB_XHCI_MVEBU), ) xhci-plat-hcd-y += xhci-mvebu.o endif ifneq ($(CONFIG_USB_XHCI_RCAR), ) xhci-plat-hcd-y += xhci-rcar.o endif obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o
果然,CONFIG_USB_XHCI_HCD需要xhci.o,另外还有一堆xhci-xxx.o。先打开xhci.c,这个文件有5033行(Linux 4.1)。直接搜索module_init找到模块入口,发现是定义在文件末尾的xhci_hcd_init函数:
static int __init xhci_hcd_init(void) { /* * Check the compiler generated sizes of structures that must be laid * out in specific ways for hardware access. */ BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8); BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8); /* xhci_device_control has eight fields, and also * embeds one xhci_slot_ctx and 31 xhci_ep_ctx */ BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8); BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); return 0; } /* * If an init function is provided, an exit function must also be provided * to allow module unload. */ static void __exit xhci_hcd_fini(void) { } module_init(xhci_hcd_init); module_exit(xhci_hcd_fini);
xhci_hcd_init和xhci_hcd_fini这两个函数有点坑爹,居然什么实质性的事情都没有做!看来要对另外两个模块下手。
USB_XHCI_PCI,顾名思义,是xHCI驱动和PCI总线驱动之间的“接口”(内核开发者称这种“接口”为glue,有没有感觉黏黏的:D)。USB控制器大多是PCI设备,若控制器连接到PCI总线上,那么自然是先由PCI驱动发现该设备,识别之后才能交给xHCI驱动处理。所以实际上,作为glue的xhci-pci模块代码要早于xhci-hcd模块代码开始工作,因此关键的初始化过程放在前者中也就不奇怪了。
从Makefile中知道(不看也知道),CONFIG_USB_XHCI_PCI需要xhci-pci.o,因此打开xhci-pci.c搜索module_init:
static int __init xhci_pci_init(void) { xhci_init_driver(&xhci_pci_hc_driver, xhci_pci_setup); #ifdef CONFIG_PM xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; xhci_pci_hc_driver.pci_resume = xhci_pci_resume; #endif return pci_register_driver(&xhci_pci_driver); } module_init(xhci_pci_init);
子曰:好戏开始了。
相关文章推荐
- PL/SQL DEV Debug问题
- 【Java设计模式】三种单例模式
- 《Effective C++》学习笔记——条款33
- linuxvi命令的使用
- string字符串的翻转---(子字符串不翻转)问题
- 使用 PHP 的 Phing 项目部署工具
- iOS 上传图片到服务器
- 诸葛新技能Get!速成数据分析师方法
- Win7系统开机后弹出supervisory.exe应用程序错误提示框
- Linux下SD卡启动制作
- leetcode_8_String to Integer (atoi)
- IOS快速开发框架
- log4php实用配置
- 强制退出Mac程序的六种方法
- java作业整理
- 浅析数据挖掘(图)
- IE打开后电脑蓝屏死机
- iOS导航模式综述
- 富爸爸——富人的阴谋
- Ubuntu 自己编译安装wireshark遇到的问题和解决方法