Hacking USB@LINUX (2)

Last year i wrote 'Hacking USB@LINUX (1)' already but hadn't uploaded but anyway will do it soon. From this section, we're going to use KGDB to trace how USB driver and device be registered in linux kernel and how kernel manages the drivers and devices. The kernel version i use is 2.6.37.1.

 

In this section, we are introducing what happens when device is plugged-in after driver module has already been registered.

 

Preparations:

1. Select KGDB options in kernel 2.6.37.1 and re-compile, and then customize your bootloader scripts and re-boot your system.

 

2. Let's take usb-skeleton.c for example. Please copy it out from Linux Kernel archive to your local folder, and modify the device id table like below:

/* table of devices that work with this driver */
static const struct usb_device_id skel_table[] = {
 { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
 { USB_DEVICE(0x0781, 0x5151)}, /** hongao: this is to support Sandisk USB thumb-drive */
 { }     /* Terminating entry */
};

 

and then we create a Makefile like below:

 

obj-m := usb-skeleton.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)

all:
 $(MAKE) -C $(KERNELDIR) M=$(PWD)

clean:
 rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

 

and then make.

After a short while, you're able to see usb-skeleton.ko be created under this folder. Just keep it, will use it soon.

 

3. Let's check the configuration of our usb device to be tested with dmesg. OMG, my KGDB client is base on 2.6.27.5-hongao-4-kgdb which has been added up too much debug information already. NVM, i just list certain useful information for you to refer. And BTW, you may see lots of 'HONGAO' inside my debug information, what does it mean? It's actually my N-A-M-E. Hello everybody, my Chinese name is Lu Hongao, currently a senior software engineer and lives in Singapore City.

 

[  853.479191] [HONGAO] bus_for_each_drv: bus: usb
[  853.479296] - usbfs
[  853.479331] - hub
[  853.479334] - usb
[  853.479337] - usb-storage
[  853.479340] - usbserial
[  853.479343] - usbserial_generic
[  853.479351] - debug
[  853.479353] - ftdi_sio
[  853.479356] - pl2303
[  853.479361] - hiddev
[  853.479365] - usbhid

 

[  853.612299] [HONGAO] bus_for_each_drv: bus: scsi
[  853.612303] - sd
[  853.612310] - sr

 

[  853.616491] [HONGAO] [00212] bus: 'usb': driver_probe_device: matched device 1-1:1.0 with driver usb-storage

[  853.617554] drivers/usb/core/inode.c: creating file '002'
[  853.618388] [HONGAO] driver_probe_device:00208:ret=1
[  853.618395] [HONGAO] [00212] bus: 'usb': driver_probe_device: matched device 1-1 with driver usb

[  853.618947] usb 1-1: New USB device found, idVendor=0781, idProduct=5151
[  853.618978] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  853.619058] usb 1-1: Product: Cruzer Micro
[  853.619086] usb 1-1: Manufacturer: SanDisk Corporation
[  853.619102] usb 1-1: SerialNumber: SNDK5098D511FA307807
[  853.621471] usb-storage: device found at 2
[  853.621503] usb-storage: waiting for device to settle before scanning
[  858.621232] usb-storage: prepare scanning...
[  858.621303] usb-storage: start scanning...

 

[  858.950201] [HONGAO] [203] bus: 'scsi': driver_probe_device: matched device 3:0:0:0 with driver sd
[  858.953248] [HONGAO] really_probe
[  858.953271] [HONGAO] drv[sd] probe:c05bc0f9

[  858.957287] [HONGAO]sd_probe:01883:index=2:dev=sdc
[  858.992831] sd 3:0:0:0: [sdc] 4001760 512-byte hardware sectors (2049 MB)
[  859.034899] sd 3:0:0:0: [sdc] Write Protect is off
[  859.035106] sd 3:0:0:0: [sdc] Mode Sense: 03 00 00 00
[  859.035215] sd 3:0:0:0: [sdc] Assuming drive cache: write through

 

Begin:

So far as you know, when an usb device be plugged-in,  device_add() function will be called to configure the device.

Set a breakpoint at device_add() before an usb thumb-drive be plugged-in and then continue. When KGDB server stop at the breakpoint, we back trace:

 

Breakpoint 1, device_add (dev=0xddfb1064) at drivers/base/core.c:861
861                     goto done;
(gdb) bt
#0  device_add (dev=0xddfb1064) at drivers/base/core.c:861
#1  0xc12c1681 in usb_new_device (udev=0xddfb1000)
    at drivers/usb/core/hub.c:1848
#2  0xc12c2c17 in hub_port_connect_change (portstatus=1281)
    at drivers/usb/core/hub.c:3208
#3  hub_events () at drivers/usb/core/hub.c:3423
#4  hub_thread (__unused=<value optimized out>) at drivers/usb/core/hub.c:3475
#5  0xc1046fcf in kthread (_create=<value optimized out>)
    at kernel/kthread.c:95
#6  0xc1002e76 in kernel_thread_helper () at arch/x86/kernel/entry_32.S:1009

 

for details please check with 'Hacking USB@LINUX (1)'. We continue debugging step by step. The function-call chain is shown below:

 

The first session, to find driver "usb":

device_add

|________________________ 

|                                               |

bus_probe_device    update sysfs and related file system

|

device_attach

|

bus_for_each_drv(dev->bus, NULL, dev, __device_attach)

dev->bus->name="usb"

 

dev->parent->kobj->name="usb1"

dev->parent->bus->name="usb"

dev->parent->type->name="usb_device"

 

dev->parent->parent->kobj->name="0000:02:03.0"

dev->parent->parent->bus->name="pci"

 

dev->parent->parent->parent->kobj->name="0000:00:11.0"

dev->parent->parent->parent->bus->name="pci"

 

dev->parent->parent->parent->parent->kobj->name="pci0000:00"

dev->kobj->name="1-1"

dev->type->name="usb_device"

|

__device_attach

    drv->name=

        "usbfs"  

        "hub"  

        "usb" => BINGO!!! driver has matched already!!!
|

driver_probe_device

|

really_probe

|

drv->probe(usb_probe_device (dev=0xddd06064) at drivers/usb/core/driver.c:224)

|

udriver->probe() ((int (*)(struct usb_device *)) 0xc12cd37f <generic_probe> at drivers/usb/core/generic.c:156)

|

usb_set_configuration

|_________________________________________

|                                                                                 |

Initialize interfaces:

intf->cur_altsetting = alt;                                          /** hongao: for more info please refer to usb spec CH9 */
usb_enable_interface(dev, intf, true);                      usb_control_msg(USB_REQ_SET_CONFIGURATION) 

intf->dev.parent = &dev->dev; /** "1-1" */
intf->dev.driver = NULL;
intf->dev.bus = &usb_bus_type; /** "usb" */ 
intf->dev.type = &usb_if_device_type; /** "usb_interface" */
intf->dev.groups = usb_interface_groups;
intf->dev.dma_mask = dev->dev.dma_mask;

INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
intf->minor = -1;
device_initialize(&intf->dev);
dev_set_name(&intf->dev, "%d-%s:%d.%d", /** "1-1:1.0" */
   dev->bus->busnum, dev->devpath,
   configuration, alt->desc.bInterfaceNumber);

                  

after that it calls: device_add(&intf->dev)

 

Ok, from here, we're entering the second session.

 

The Second Session:                                

Before starting this session, let's check the parameters handed-over by the first session.

(gdb) print dev.parent->kobj->name
$24 = 0xdcd283f8 "1-1"
(gdb) print dev.parent->bus->name
$25 = 0xc15ff612 "usb"
(gdb) print dev.parent->type->name
$26 = 0xc15ece9a "usb_device"
(gdb) print dev->type->name
$27 = 0xc15ee4eb "usb_interface"
(gdb) print dev->kobj.name
$29 = 0xdcd284b8 "1-1:1.0"
As you see, they are perfect match!

 

The misson of the second session is to find driver "skeleton".

device_add

|________________________ 

|                                               |

bus_probe_device    update sysfs and related file system

|

device_attach

|

bus_for_each_drv(dev->bus, NULL, dev, __device_attach)

|

__device_attach

    drv->name=

        "usbfs"  

        "hub"  

        "usb" 

        "usblp" 

        "usb-storage" => it is supposed to match over here, but why not match? The trick

            is, in driver/usb/storage/usb.c ,

            .id_table = usb_storage_usb_ids; so i modified usb_storage_usb_ids to:

            struct usb_device_id usb_storage_usb_ids[] = {
                //# include "unusual_devs.h"
                { }  /* Terminating entry */
            };

            and then usb-storage driver does not have any knowledge about the device attached, so matching failed! 

       "libusual"

       "usbhid"

       "skeleton" => BINGO!!! driver has matched already!!!

|

driver_probe_device

|

really_probe

|

drv->probe(dev) (usb_probe_interface (dev=0xdef9761c) at drivers/usb/core/driver.c:274)

|

driver->probe(intf, id) (skel_probe)

 

Ok, from here, we're able to see skel_probe, which is your DIY probe function, is called. Exciting or not? If not, continue reading the next blog.

 

(To Be Continue)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值