debian下使用dynamic printk分析usb转串口驱动执行流程
看了一篇文章《debug by printing》,文中提到了多种通过printk来调试驱动的方法,其中最有用的就是"Dynamic debugging"。
“Dynamic debugging"的官方文档:http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/dynamic-debug-howto.txt?id=HEAD
"Dyanmic debugging"的功能适用于所有的linux内核,所以也可以用于嵌入式开发板中调试驱动程序。
在使用"Dynamic debugging"前需要在内核中使能Dynamic printk选项(可用于控制代码代码中的pr_debug和dev_dbg的信息是否输出)。
默认官方debian内核中没有使能这个选项,可以参考我的博文《debian下配置dynamic printk以及重新编译内核 》重新编译和配置内核才能使用该功能。
本文用一个usb转串口线(核心芯片是pl2303)的例子来说明如何使用"Dynamic debugging",内核版本是linux-3.2.57。
先插入usb转串口线,得到下面的信息:
[ 8.728526] usbcore: registered new interface driver usbserial
[ 8.728669] USB Serial support registered for generic
[ 8.728720] usbcore: registered new interface driver usbserial_generic
[ 8.728722] usbserial: USB Serial Driver core
[ 8.737942] USB Serial support registered for pl2303
[ 8.737963] pl2303 5-2:1.0: pl2303 converter detected
[ 8.750530] usb 5-2: pl2303 converter now attached to ttyUSB0
[ 8.750565] usbcore: registered new interface driver pl2303
[ 8.750568] pl2303: Prolific PL2303 USB to serial adaptor driver
pl2303驱动中用到了pl2303的驱动,查看pl2303驱动信息:
$ sudo modinfo pl2303
filename: /lib/modules/3.2./kernel/drivers/usb/serial/pl2303.ko
license: GPL
description: Prolific PL2303 USB to serial adaptor driver
alias: usb:v0B8Cp2303d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0B63p6530d*dc*dsc*dp*ic*isc*ip*
alias: usb:v11ADp0001d*dc*dsc*dp*ic*isc*ip*
alias: usb:v054Cp0437d*dc*dsc*dp*ic*isc*ip*
alias: usb:v04B8p0522d*dc*dsc*dp*ic*isc*ip*
alias: usb:v04B8p0521d*dc*dsc*dp*ic*isc*ip*
alias: usb:v03F0p3524d*dc*dsc*dp*ic*isc*ip*
alias: usb:v5372p2303d*dc*dsc*dp*ic*isc*ip*
alias: usb:v05ADp0FBAd*dc*dsc*dp*ic*isc*ip*
alias: usb:v07AAp002Ad*dc*dsc*dp*ic*isc*ip*
alias: usb:v11F6p2001d*dc*dsc*dp*ic*isc*ip*
alias: usb:v058Fp9720d*dc*dsc*dp*ic*isc*ip*
alias: usb:v050Dp0257d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0731p2003d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0E55p110Bd*dc*dsc*dp*ic*isc*ip*
alias: usb:v0413p2101d*dc*dsc*dp*ic*isc*ip*
alias: usb:v079Bp0027d*dc*dsc*dp*ic*isc*ip*
alias: usb:v10B5pAC70d*dc*dsc*dp*ic*isc*ip*
alias: usb:v078Bp1234d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0745p0001d*dc*dsc*dp*ic*isc*ip*
alias: usb:v04A5p4027d*dc*dsc*dp*ic*isc*ip*
alias: usb:v11F5p0005d*dc*dsc*dp*ic*isc*ip*
alias: usb:v11F5p0004d*dc*dsc*dp*ic*isc*ip*
alias: usb:v11F5p0003d*dc*dsc*dp*ic*isc*ip*
alias: usb:v11F5p0001d*dc*dsc*dp*ic*isc*ip*
alias: usb:v04E8p8001d*dc*dsc*dp*ic*isc*ip*
alias: usb:v11F7p02DFd*dc*dsc*dp*ic*isc*ip*
alias: usb:v6189p2068d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0731p0528d*dc*dsc*dp*ic*isc*ip*
alias: usb:v1453p4026d*dc*dsc*dp*ic*isc*ip*
alias: usb:v2478p2008d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0584pB000d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0DF7p0620d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0EBAp2080d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0EBAp1080d*dc*dsc*dp*ic*isc*ip*
alias: usb:v056Ep5004d*dc*dsc*dp*ic*isc*ip*
alias: usb:v056Ep5003d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0547p2008d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0557p2008d*dc*dsc*dp*ic*isc*ip*
alias: usb:v04BBp0A0Ed*dc*dsc*dp*ic*isc*ip*
alias: usb:v04BBp0A03d*dc*dsc*dp*ic*isc*ip*
alias: usb:v067Bp0307d*dc*dsc*dp*ic*isc*ip*
alias: usb:v067Bp331Ad*dc*dsc*dp*ic*isc*ip*
alias: usb:v067Bp0609d*dc*dsc*dp*ic*isc*ip*
alias: usb:v067Bp0612d*dc*dsc*dp*ic*isc*ip*
alias: usb:v067Bp0611d*dc*dsc*dp*ic*isc*ip*
alias: usb:v067BpAAA0d*dc*dsc*dp*ic*isc*ip*
alias: usb:v067BpAAA2d*dc*dsc*dp*ic*isc*ip*
alias: usb:v067Bp1234d*dc*dsc*dp*ic*isc*ip*
alias: usb:v067Bp04BBd*dc*dsc*dp*ic*isc*ip*
alias: usb:v067Bp2303d*dc*dsc*dp*ic*isc*ip*
depends: usbserial,usbcore
intree: Y
vermagic: 3.2. SMP mod_unload modversions
parm: debug:Debug enabled or not (bool)
可以看到pl2303又依赖于usbserial和usbcore.
下载linux内核源码(可以参考我的博文《debian下配置dynamic printk以及重新编译内核》),解压缩后进入该文件夹。
$ grep 'pl2303' drivers/usb/serial/Makefile
obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
$ grep 'usbserial' drivers/usb/serial/Makefile
obj-$(CONFIG_USB_SERIAL) += usbserial.o
usbserial-y := usb-serial.o generic.o bus.o
usbserial-$(CONFIG_USB_SERIAL_CONSOLE) += console.o
usbserial-$(CONFIG_USB_EZUSB) += ezusb.o
$ grep 'usbcore' drivers/usb/core/Makefile
usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
usbcore-y += devio.o notify.o generic.o quirks.o devices.o
usbcore-$(CONFIG_PCI) += hcd-pci.o
usbcore-$(CONFIG_USB_DEVICEFS) += inode.o
obj-$(CONFIG_USB) += usbcore.o
从搜索结果可以看出:
pl2303驱动由drivers/usb/serial/pl2303.c文件来生成的。
usbserial驱动是由drivers/usb/serial下的usb-serial.c generic.c bus.c这三个文件来生成的。
usbcore是由drivers/usb/core/下面的usb.c hub.c hcd.c urb.c message.c driver.c config.c file.c buffer.c sysfs.c endpoint.c
devio.c notify.c generic.c quirks.c devices.c hcd-pci.c inode.c这些文件生成的。
切换到root用户:
su
挂载debugfs:
# mount -t debugfs none /sys/kernel/debug/
对上面提到的所有文件使能"Dynamic debugging":
root@debian:~# echo 'file drivers/usb/serial/pl2303.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/serial/usb-serial.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/serial/generic.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/serial/bus.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/usb.c +p' > /sys/kernel/debug/dynamic_debug/control^C
root@debian:~# echo 'file drivers/usb/core/hub.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/hcd.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/urb.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/message.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/driver.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/config.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/file.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/buffer.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/sysfs.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/endpoint.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/device.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/notify.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/generic.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/quirks.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/devices.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/hci-pci.c +p' > /sys/kernel/debug/dynamic_debug/control
root@debian:~# echo 'file drivers/usb/core/inode.c +p' > /sys/kernel/debug/dynamic_debug/control
先拔掉usb转串口线,然后删除pl2303驱动(因为之前已经插入过usb转串口,pl2303已经加载):
sudo rmmod pl2303
再插入usb转串口线,在另一个控制台下执行命令:
$ dmesg | tail -n
[ 3405.314567] hub -:1.0: state ports chg evt
[ 3405.314587] hub -:1.0: port , status , change , Mb/s
[ 3405.472015] hub -:1.0: debounce: port : total 125ms stable 100ms status 0x501
[ 3405.528178] hub -:1.0: port not reset yet, waiting 50ms
[ 3405.528197] usb usb5: usb wakeup-resume
[ 3405.528203] usb usb5: usb auto-resume
[ 3405.568011] hub -:1.0: hub_resume
[ 3405.568027] hub -:1.0: port : status change
[ 3405.584034] hub -:1.0: state ports chg evt
[ 3405.672026] hub -:1.0: state ports chg evt
[ 3405.672041] hub -:1.0: port , status , change , Mb/s
[ 3405.784018] usb -: new full-speed USB device number using uhci_hcd
[ 3405.936037] usb -: default language 0x0409
[ 3405.946039] usb -: udev , busnum , minor =
[ 3405.946044] usb -: New USB device found, idVendor=067b, idProduct=
[ 3405.946049] usb -: New USB device strings: Mfr=, Product=, SerialNumber=
[ 3405.946053] usb -: Product: USB-Serial Controller
[ 3405.946057] usb -: Manufacturer: Prolific Technology Inc.
[ 3405.946151] bus: 'usb': add device -
[ 3405.946228] usb -: usb_probe_device
[ 3405.946234] usb -: configuration # chosen from choice
[ 3405.949040] usb -: adding -:1.0 (config #, interface )
[ 3405.949061] bus: 'usb': add device -:1.0
[ 3405.949110] usbserial_generic -:1.0: usb_probe_interface
[ 3405.949115] usbserial_generic -:1.0: usb_probe_interface - got id
[ 3406.014058] bus: 'usb-serial': add driver pl2303
[ 3406.014092] USB Serial support registered for pl2303
[ 3406.014096] bus: 'usb': add driver pl2303
[ 3406.027529] pl2303 -:1.0: usb_probe_interface
[ 3406.027533] pl2303 -:1.0: usb_probe_interface - got id
[ 3406.027539] pl2303 -:1.0: pl2303 converter detected
[ 3406.039051] bus: 'usb-serial': add device ttyUSB0
[ 3406.039201] usb -: pl2303 converter now attached to ttyUSB0
[ 3406.039221] usbcore: registered new interface driver pl2303
[ 3406.039223] pl2303: Prolific PL2303 USB to serial adaptor driver
明显多了很多调试信息,更便于跟踪实际代码的执行情况。
下面分析插入usb转串口线时的执行情况.
考虑“[ 3405.314567] hub 1-0:1.0: state 7 ports 8 chg 0000 evt ”这一行输出信息。
我们只考虑driver/usb下执行的代码,所以只在该文件夹下搜索源代码。
$ grep -rnHi 'chg.*evt' drivers/usb/
drivers/usb/core/hub.c:: dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n",
这一行代码位于hub_events函数,该函数被hub_thread调用:
static int hub_thread(void *__unused)
{
/* khubd needs to be freezable to avoid intefering with USB-PERSIST
* port handover. Otherwise it might see that a full-speed device
* was gone before the EHCI controller had handed its port over to
* the companion full-speed controller.
*/
set_freezable(); do {
hub_events();
wait_event_freezable(khubd_wait,
!list_empty(&hub_event_list) ||
kthread_should_stop());
} while (!kthread_should_stop() || !list_empty(&hub_event_list)); pr_debug("%s: khubd exiting\n", usbcore_name);
return ;
}
hub_thread是在usb_hub_init中创建的一个内核线程khubd的执行函数,这个内核线程开机后就会一直处于运行状态。
考虑“[ 3405.314587] hub 1-0:1.0: port 8, status 0501, change 0001, 480 Mb/s”这一行输出信息:
$ grep -rnHi 'port.*status.*change.*\\n' drivers/usb/
drivers/usb/core/hub.c:: "port %d: status %04x change %04x\n",
drivers/usb/core/hub.c:: "port %d, status %04x, change %04x, %s\n",
drivers/usb/gadget/dummy_hcd.c:: dev_dbg(dummy_dev(dum_hcd), "port status 0x%08x has changes\n",
drivers/usb/host/xhci-ring.c:: xhci_dbg(xhci, "Port Status Change Event for port %d\n", port_id);
可以看出只有第两行输出信息可能和当前的输出有关系,此行代码位于hub_port_connect_change函数,
而hub_port_connect_change被hub_events函数调用。
考虑下一行输出“[ 3405.472015] hub 1-0:1.0: debounce: port 8: total 125ms stable 100ms status 0x501”。
$ grep -rnHi 'debounce:' drivers/usb/
drivers/usb/core/hub.c:: "debounce: port %d: total %dms stable %dms status 0x%x\n",
该行输出信息位于hub_port_debounce函数,hub_port_debounce函数又被hub_port_connect_change所调用。
考虑下一行输出“[ 3405.528178] hub 1-0:1.0: port 8 not reset yet, waiting 50ms”。
$ grep -rnHi 'reset yet,' drivers/usb/
drivers/usb/core/hub.c:: "port %d not %sreset yet, waiting %dms\n",
这行代码位于hub_port_wait_reset函数,hub_port_wait_reset又被hub_port_reset函数调用,hub_port_reset又被hub_port_init调用,
hub_port_init又被hub_port_connect_change函数调用。
下一行输出“[ 3405.528197] usb usb5: usb wakeup-resume”。
$ grep -rnHi '%sresume' drivers/usb/core
drivers/usb/core/hcd.c:: dev_dbg(&rhdev->dev, "usb %sresume\n",
drivers/usb/core/hub.c:: dev_dbg(&udev->dev, "usb %sresume\n",
drivers/usb/core/hub.c:: dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
查看代码后得知,与之匹配的是hub.c中2737行代码,位于usb_remote_wakeup中.
usb_remote_wakeup在好几个地方被调用,不清楚是哪个函数调用引起的。
下一行输出信息是:[ 3405.528203] usb usb5: usb auto-resume
根据上面的查新结果,很可能是被usb_port_resume或者hcd_bus_resume函数调用,而这两个函数都是被generic_resume函数所调用。
下一行输出信息:[ 3405.568011] hub 5-0:1.0: hub_resume
没有用grep搜索到有用信息,但是很可能是执行hub_resume函数输出的,查看hub_resume定义:
static int hub_resume(struct usb_interface *intf)
{
struct usb_hub *hub = usb_get_intfdata(intf); dev_dbg(&intf->dev, "%s\n", __func__);
hub_activate(hub, HUB_RESUME);
return ;
}
果然代码中有__func__,就是hub_resume。hub_resume没有被直接调用,它在hub_driver.resume=hub_resume中被定义。
下一行输出信息是:[ 3405.568027] hub 5-0:1.0: port 2: status 0101 change
$ grep -rnHi 'port.*status.*change.*\\n' drivers/usb/
drivers/usb/core/hub.c:: "port %d: status %04x change %04x\n",
drivers/usb/core/hub.c:: "port %d, status %04x, change %04x, %s\n",
drivers/usb/gadget/dummy_hcd.c:: dev_dbg(dummy_dev(dum_hcd), "port status 0x%08x has changes\n",
drivers/usb/host/xhci-ring.c:: xhci_dbg(xhci, "Port Status Change Event for port %d\n", port_id);
第一行搜索到的信息格式和输出信息相匹配。此行代码位于hub_activate中。而上一行中hub_resume恰好调用了hub_activate函数。
接下来三行输出信息:
[ 3405.584034] hub -:1.0: state ports chg evt
[ 3405.672026] hub -:1.0: state ports chg evt
[ 3405.672041] hub -:1.0: port , status , change , Mb/s
这三行信息和最前面的两行输出信息类似,不再重复分析了。 但是这里又重新从hub_event的开头部分开始执行程序。
下一行输出信息:[ 3405.784018] usb 5-2: new full-speed USB device number 4 using uhci_hcd
$ grep -rnHi 'USB device number' drivers/usb/
drivers/usb/core/hub.c:: "%s %s USB device number %d using %s\n",
drivers/usb/core/hub.c:: "%s SuperSpeed USB device number %d using %s\n",
第一行搜索到内容与输出信息完全匹配,该代码位于hub_port_init中。hub_port_init又被hub_port_connect_change调用。
下一行输出信息:[ 3405.936037] usb 5-2: default language 0x0409
$ grep -rnHi 'default language' drivers/usb/
drivers/usb/core/message.c:: dev_dbg(&dev->dev, "default language 0x%04x\n",
该行代码位于usb_get_langid中,usb_get_langid又被usb_string函数调用。调用usb_string的函数不好分析,留待以后再看。
下一行输出信息:[ 3405.946039] usb 5-2: udev 4, busnum 5, minor =
$ grep -rnHi 'udev.*busnum.*minor' drivers/usb/
drivers/usb/core/hub.c:: dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n",
该代码位于usb_new_device中,而usb_new_device又被usb_port_connect_change函数所调用。
而查看该行代码前,执行了usb_enumerate_device函数。该函数调用了usb_cache_string,而usb_cache_string又调用了usb_string.
所以上一行的输出信息就是在调用usb_enumerate_device时产生的。
接下来四行信息:
[ 3405.946044] usb -: New USB device found, idVendor=067b, idProduct=
[ 3405.946049] usb -: New USB device strings: Mfr=, Product=, SerialNumber=
[ 3405.946053] usb -: Product: USB-Serial Controller
[ 3405.946057] usb -: Manufacturer: Prolific Technology Inc.
之前在我的博文《linux下无线鼠标驱动执行流程》中已经找到了执行这几行代码的函数,其名称是announce_device,该函数也被usb_new_device调用。
下一行输出信息:[ 3405.946151] bus: 'usb': add device 5-
这行输出信息在函数bus_add_device(drivers/base/bus.c)被执行。这是因为我在配置"dynamic debugging"时执行了下面的命令:
echo 'file bus.c +p' > /sys/kernel/debug/dynamic_debug/control
后来看没有只是打开了drivers/base/bus.c,而不是打开drivers/usb/core/bus.c的"dynamic debugging"功能,所以才添加了路径名称来保证唯一性。
但是以前打开的drivers/base/bus.c中的"dynamic debugging"功能并没有关闭,所以这里有相关的信息显示。
bus_add_device在device_add函数中被调用,device_add又被usb_new_device调用。
下一行输出信息:[ 3405.946228] usb 5-2: usb_probe_device
猜想是执行usb_probe_device时显示的信息,查看usb_probe_device函数代码发现果然有下面一行代码:
dev_dbg(dev, "%s\n", __func__);
usb_probe_device可能是在device_add调用bus_probe_device时调用的(过程比较复杂,不再详述)。
下一行输出信息:[ 3405.946234] usb 5-2: configuration #1 chosen from 1 choice
$ grep -rnHi 'chosen from' drivers/usb/
drivers/usb/core/generic.c:: "configuration #%d chosen from %d choice%s\n",
drivers/usb/core/generic.c:: "no configuration chosen from %d choice%s\n",
只有第一行搜索信息与实际输出信息格式相匹配。
该行代码位于usb_choose_configuration函数中,usb_choose_configuration函数又被generic_probe函数调用。
代码中显示usb_generic_driver和usb_serial_generic_driver这两个驱动都使用了generic_probe函数执行probe功能。
此处应该使用的是usb_generic_driver的generic_probe函数。
下一行输出信息:[ 3405.949040] usb 5-2: adding 5-2:1.0 (config #1, interface 0)
$ grep -rnHi 'adding.*config.*interface' drivers/usb/
drivers/usb/core/message.c:: "adding %s (config #%d, interface %d)\n",
该代码位于usb_set_configuration中,usb_set_configuration函数被generic_probe函数所调用。
下一行输出信息:[ 3405.949061] bus: 'usb': add device 5-2:1.0
跟前面其中一行的情况相同,执行bus_add_device时调用了这个函数,bus_add_device又被device_add函数所调用。
下一行输出信息:[ 3405.949110] usbserial_generic 5-2:1.0: usb_probe_interface
$ grep -rnHi 'usbserial_generic' drivers/usb/
drivers/usb/serial/generic.c:: .name = "usbserial_generic",
看起来很像是执行usb_probe_interface时给出的输出信息,查看函数源码,果然有下一行代码:
dev_dbg(dev, "%s\n", __func__);
下一行输出信息:[ 3405.949115] usbserial_generic 5-2:1.0: usb_probe_interface - got id
在查看usb_probe_interface函数源码时看到有类似于"got id"之类的输出,所以是在usb_probe_interface中被调用。
下一行输出信息:[ 3406.014058] bus: 'usb-serial': add driver pl2303
$ grep -rnHi 'add driver' drivers/base
drivers/base/bus.c:: pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
看输出信息中第一个冒号前是usb,再拿前面的例子作对比,可以知道应该是在drivers/base下执行代码产生类似的输出。
该代码位于bus_add_driver中,bus_add_driver又被driver_register函数所调用。
下一行输出信息:[ 3406.014092] USB Serial support registered for pl2303
$ grep -rnHi 'registered for' drivers/usb
drivers/usb/serial/usb-serial.c:: printk(KERN_INFO "USB Serial support registered for %s\n",
drivers/usb/gadget/s3c-hsotg.c:: * registered for each available).
搜索到的第一行信息与输出信息格式一致。
该代码位于usb_serial_register中,usb_serial_register又被pl2303_init所调用。
下一行输出信息:[ 3406.039051] bus: 'usb-serial': add device ttyUSB0
跟前面一些输出信息类似,也是被bus_add_device调用,bus_add_device又被device_add调用。
下一行输出信息:[ 3406.039201] usb 5-2: pl2303 converter now attached to ttyUSB0
$ grep -rnHi 'attached to ttyUSB' drivers/usb
drivers/usb/serial/bus.c:: "%s converter now attached to ttyUSB%d\n",
此代码位于usb_serial_device_probe中。代码中还有这样的赋值:usb_serial_bus_type.probe=usb_serial_device_probe
下一行信息输出:[ 3406.039221] usbcore: registered new interface driver pl2303
$ grep -rnHi 'registered new interface' drivers/usb
drivers/usb/core/driver.c:: pr_info("%s: registered new interface driver %s\n",
该代码位于usb_register_driver函数中。
文件include/linux/usb.h中有下面的定义:
#define usb_register(driver) \
usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
所以有可能是调用usb_register时输出了这行信息。 pl2303_init也调用了usb_register。
最后一行输出信息:[ 3406.039223] pl2303: Prolific PL2303 USB to serial adaptor driver
这行输出信息对应pl2303_init中的下列代码:
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
从上面的分析可以看出,执行程序时会运行drivers/base下的一些代码。
拔掉usb转串口线,然后使能drivers/base下所有文件的"dynamic debugging"功能。
从帮助文件中查到下面的命令:
echo 'file drivers/base/* +p' > /sys/kernel/debug/dynamic_debug/control
但是执行后却没有作用,貌似还只能一个一个文件的使能"dynamic debugging"。
另外,使能命令中的+p可以修改成+flmpt,这样会显示出了模块名称和函数名称、行号、线程信息等。
后注:
上面提到使用drivers/base/下的文件,关联文件:
$ head -n drivers/base/Makefile
# Makefile for the Linux device tree obj-y := core.o sys.o bus.o dd.o syscore.o \
driver.o class.o platform.o \
cpu.o firmware.o init.o map.o devres.o \
attribute_container.o transport_class.o \
topology.o
周末在我自己电脑上又想执行上面的配置,但是一个一个的输入命令太麻烦了,我写了一个小脚本,内容如下:
#!/bin/sh DYNAMIC_CONTROL=/sys/kernel/debug/dynamic_debug/control
echo 'file drivers/usb/serial/usb-serial.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/serial/genemic.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/serial/bus.c +flmpt' > $DYNAMIC_CONTROL echo 'file drivers/usb/core/usb.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/hub.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/hcd.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/urb.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/message.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/driver.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/config.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/file.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/buffer.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/sysfs.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/endpoint.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/device.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/notify.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/generic.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/quirks.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/devices.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/hci-pci.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/usb/core/inode.c +flmpt' > $DYNAMIC_CONTROL echo 'file drivers/base/core.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/sys.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/bus.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/dd.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/syscore.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/driver.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/class.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/platform.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/cpu.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/firmware.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/init.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/map.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/devres.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/attribute_container.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/transport_class.c +flmpt' > $DYNAMIC_CONTROL
echo 'file drivers/base/topology.c +flmpt' > $DYNAMIC_CONTROL
挂载debugfs,执行这个脚本,然后插入和移除usb转串口得到下面的信息:
[24923.523302] [] usbcore:usb_remote_wakeup:: usb usb1: usb wakeup-resume
[24923.523314] [] usbcore:hcd_bus_resume:: usb usb1: usb auto-resume
[24923.536972] [] usbcore:hub_resume:: hub -:1.0: hub_resume
[24923.536995] [] usbcore:hub_activate:: hub -:1.0: port : status change
[24923.537013] [] usbcore:hub_activate:: hub -:1.0: port : status change
[24923.640857] [] usbcore:hub_events:: hub -:1.0: state ports chg evt
[24923.640884] [] usbcore:hub_port_connect_change:: hub -:1.0: port , status , change , Mb/s
[24923.752690] usb -: new full-speed USB device number using xhci_hcd
[24923.769191] [] usbcore:usb_get_langid:: usb -: default language 0x0409
[24923.769490] [] usbcore:usb_new_device:: usb -: udev , busnum , minor =
[24923.769498] usb -: New USB device found, idVendor=067b, idProduct=
[24923.769502] usb -: New USB device strings: Mfr=, Product=, SerialNumber=
[24923.769507] usb -: Product: USB-Serial Controller D
[24923.769510] usb -: Manufacturer: Prolific Technology Inc.
[24923.769520] [] core:device_add:: device: '1-1': device_add
[24923.769685] [] bus:bus_add_device:: bus: 'usb': add device -
[24923.769761] [] dd:driver_probe_device:: bus: 'usb': driver_probe_device: matched device - with driver usb
[24923.769772] [] dd:really_probe:: bus: 'usb': really_probe: probing driver usb with device -
[24923.769793] [] usbcore:usb_probe_device:: usb -: usb_probe_device
[24923.769805] [] usbcore:usb_choose_configuration:: usb -: configuration # chosen from choice
[24923.769984] [] usbcore:usb_set_configuration:: usb -: adding -:1.0 (config #, interface )
[24923.769993] [] core:device_add:: device: '1-1:1.0': device_add
[24923.770019] [] bus:bus_add_device:: bus: 'usb': add device -:1.0
[24923.770082] [] dd:driver_probe_device:: bus: 'usb': driver_probe_device: matched device -:1.0 with driver usbserial_generic
[24923.770096] [] dd:really_probe:: bus: 'usb': really_probe: probing driver usbserial_generic with device -:1.0
[24923.770119] [] usbcore:usb_probe_interface:: usbserial_generic -:1.0: usb_probe_interface
[24923.770130] [] usbcore:usb_probe_interface:: usbserial_generic -:1.0: usb_probe_interface - got id
[24923.770157] [] dd:really_probe:: usbserial_generic: probe of -:1.0 rejects match -
[24923.770181] [] core:device_add:: device: 'ep_81': device_add
[24923.770228] [] core:device_add:: device: 'ep_02': device_add
[24923.770258] [] core:device_add:: device: 'ep_83': device_add
[24923.770299] [] dd:driver_bound:: driver: '1-1': driver_bound: bound to device 'usb'
[24923.770306] [] dd:really_probe:: bus: 'usb': really_probe: bound device - to driver usb
[24923.770317] [] core:device_add:: device: 'ep_00': device_add
[24923.796744] [] bus:bus_add_driver:: bus: 'usb-serial': add driver pl2303
[24923.796779] USB Serial support registered for pl2303
[24923.796787] [] bus:bus_add_driver:: bus: 'usb': add driver pl2303
[24923.796814] [] dd:driver_probe_device:: bus: 'usb': driver_probe_device: matched device -:1.0 with driver pl2303
[24923.796820] [] dd:really_probe:: bus: 'usb': really_probe: probing driver pl2303 with device -:1.0
[24923.796831] [] usbcore:usb_probe_interface:: pl2303 -:1.0: usb_probe_interface
[24923.796837] [] usbcore:usb_probe_interface:: pl2303 -:1.0: usb_probe_interface - got id
[24923.796845] pl2303 -:1.0: pl2303 converter detected
[24923.797497] [] core:device_add:: device: 'ttyUSB0': device_add
[24923.797518] [] bus:bus_add_device:: bus: 'usb-serial': add device ttyUSB0
[24923.797573] [] dd:driver_probe_device:: bus: 'usb-serial': driver_probe_device: matched device ttyUSB0 with driver pl2303
[24923.797582] [] dd:really_probe:: bus: 'usb-serial': really_probe: probing driver pl2303 with device ttyUSB0
[24923.797601] [] core:device_add:: device: 'ttyUSB0': device_add
[24923.797753] usb -: pl2303 converter now attached to ttyUSB0
[24923.797760] [] dd:driver_bound:: driver: 'ttyUSB0': driver_bound: bound to device 'pl2303'
[24923.797768] [] dd:really_probe:: bus: 'usb-serial': really_probe: bound device ttyUSB0 to driver pl2303
[24923.797778] [] dd:driver_bound:: driver: '1-1:1.0': driver_bound: bound to device 'pl2303'
[24923.797786] [] dd:really_probe:: bus: 'usb': really_probe: bound device -:1.0 to driver pl2303
[24923.797816] usbcore: registered new interface driver pl2303
[24923.797820] pl2303: Prolific PL2303 USB to serial adaptor driver
[24933.777560] [] usbcore:hub_events:: hub -:1.0: state ports chg evt
[24933.777599] [] usbcore:hub_port_connect_change:: hub -:1.0: port , status , change , Mb/s
[24933.777608] usb -: USB disconnect, device number
[24933.777615] [] usbcore:usb_disconnect:: usb -: unregistering device
[24933.777622] [] usbcore:usb_disable_device:: usb -: unregistering interface -:1.0
[24933.777631] [] core:device_unregister:: device: 'ep_81': device_unregister
[24933.777696] [] core:device_unregister:: device: 'ep_02': device_unregister
[24933.777723] [] core:device_unregister:: device: 'ep_83': device_unregister
[24933.777771] [] bus:bus_remove_device:: bus: 'usb': remove device -:1.0
[24933.777803] [] bus:bus_remove_device:: bus: 'usb-serial': remove device ttyUSB0
[24933.777829] [] core:device_unregister:: device: 'ttyUSB0': device_unregister
[24933.778102] [] core:device_create_release:: device: 'ttyUSB0': device_create_release
[24933.778108] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0
[24933.778127] pl2303 -:1.0: device disconnected
[24933.778158] [] usbcore:usb_disable_device:: usb -: usb_disable_device nuking all URBs
[24933.778244] [] core:device_unregister:: device: 'ep_00': device_unregister
[24933.778359] [] bus:bus_remove_device:: bus: 'usb': remove device -
[24933.905540] [] usbcore:hub_port_debounce:: hub -:1.0: debounce: port : total 100ms stable 100ms status 0x100
[24935.902567] [] usbcore:hub_suspend:: hub -:1.0: hub_suspend
[24935.902585] [] usbcore:hcd_bus_suspend:: usb usb1: bus auto-suspend, wakeup
从这个输出信息来看就比较清楚了,哪个模块的那个函数的某一行执行的什么功能,不需要搜索代码就可以看的一清二楚。
代码执行流程和usb网卡的执行过程很类似,可以参看《debian下使用dynamic printk分析usb网卡驱动》有更详细的介绍。
还可以将脚本中所有+flmpt替换成-flmpt号,就能去除上面所有文件中的动态调试信息。
debian下使用dynamic printk分析usb转串口驱动执行流程的更多相关文章
- debian下使用dynamic printk分析usb网卡驱动
在<debian下使用dynamic printk分析usb转串口驱动执行流程>中使用了usb转串口,当前例子使用usb网卡分析驱动(dm9601芯片). 仍然需要使能dynamic pr ...
- debian下配置dynamic printk以及重新编译内核
在以前的一篇博文<编译debian内核>已经提过了重新编译内核的方法,但是整个过程花费时间较长,并且生成deb包. 这里我采用稍微简单一些的方法,因为我并没有对内核或者驱动代码做任何修改, ...
- linux下usb转串口驱动分析【转】
转自:http://blog.csdn.net/txxm520/article/details/8934706 首先说一下linux的风格,个人理解 1. linux大小结构体其实是面向对象的方法,( ...
- Linux 串口、usb转串口驱动分析(2-2) 【转】
转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26807463&id=4186852 Linux 串口.usb转 ...
- Linux 串口、usb转串口驱动分析(2-1) 【转】
转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26807463&id=4186851 Linux 串口.usb转 ...
- linux驱动基础系列--Linux 串口、usb转串口驱动分析
前言 主要是想对Linux 串口.usb转串口驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如字符设备驱动.平台驱动等也不进行详细说明原理.如果有任何错误地方,请指出, ...
- usb转串口驱动时会出现“文件的哈希值不在指定的目录”这样的提示
一般在安装一些usb转串口驱动时会出现“文件的哈希值不在指定的目录”这样的提示,那么怎么解决呢?知道的别喷我哦,我只是再普及一下,嘿嘿1.鼠标移到右下角,点击“设置”,再点击“更改电脑设置”2.点击最 ...
- TI 开发板安装USB转串口驱动
使用TI开发板的时候,USB转串口驱动没有,显示,无法识别设备.搜了好久才搜到相关驱动. 做个记录. 链接: https://pan.baidu.com/s/1ZT5zzVcU727jrYacKVoT ...
- STM32 USB转串口驱动安装不成功出现黄色感叹号解决方法!
相信很多人在做USB转串口时出现过串口驱动安装不成功,出现黄色感叹号问题, 出现这种问题一般是驱动安装不成功造成的. 这里我就这个问题总结几个简单的方法. 方法1: 插上USB,利用驱动人生安装驱动. ...
随机推荐
- git undo last commit
$ git commit -m "Something terribly misguided" (1) $ git reset --soft HEAD~ (2) << e ...
- ubuntu 中wget (下载)命令用法
Linux wget是一个下载文件的工具,它用在命令行下. 对于Linux用户是必不可少的工具,尤其对于网络管理员,经常要下载一些软件或从远程服务器恢复备份到本地服务器 1.使用wget下载单个文件 ...
- Android APK反编译就这么简单 具体解释
在学习Android开发的过程你.你往往会去借鉴别人的应用是怎么开发的,那些美丽的动画和精致的布局可能会让你爱不释手,作为一个开发人员.你可能会非常想知道这些效果界面是怎么去实现的,这时,你便能够对改 ...
- 怎么用ChemDraw Pro绘制不定域共轭环
ChemDraw Pro 14作为一款非常受欢迎的化学绘图软件,不论是化学分子结构.轨道,还是符号.箭头等图形都可以用它轻松的绘制出来,而且在其工具栏中,集成了10种环工具,可以对不同种类.不同尺寸的 ...
- 用javascript复制富文本
由于项目需求,希望能够用javascript复制富文本格式的数据,例如全选一个网页Ctrl+C, Ctrl+V到一个word文档中,数据还是原来的格式,显示出来的样子也都和原来一样.现在希望使用jav ...
- Xamarin.Forms学习之位图(二)
上篇文章分享了如何加载网络图片和PCL中的图片,所以今天继续分享关于如何加载平台的内嵌图片,在这之前说一下上篇文章开头的一个问题:为什么不能加载UWP项目,这是因为我升级了UWP的SDK,而Xamar ...
- <2013 08 12> Andrew:C语言的一点心得
C语言的特点在于,这是少见的中级语言(介于机器汇编和高级语言之间),因此它极其紧密地与特定机器架构.编译器.操作系统.库等基本概念相连.在底层,人们可以少量的甚至不使用汇编,但是不能不使用C.它以一种 ...
- python系列十:python3函数
#!/usr/bin/python #-*-coding:gbk-*- '''函数的简单规则: 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 (). 任何传入参数和自变量必 ...
- BigDecimal使用整理
BigDecimal使用整理 一. BigDecimal简介 计算机计算中无论是float还是double都是浮点数,由于计算机是二进制的,导致在在浮点数计算时会出现精度丢失,因此引入BigD ...
- sql server监控图解