2013-11-26 86 views
1

這是一個類,但我們很難過。我們目前正在爲使用USBCore的Logitech相機編寫USB驅動程序。發生了什麼是我們加載模塊,然後當我們連接USB攝像頭,內核崩潰,並給我們一個內核跟蹤(下面)。經過一些調試後,我們確信它在探測函數中的usb_register_dev上崩潰,但我們無法弄清楚原因。我們希望有人會有任何有用的建議,或將我們帶到正確的道路上。我們不是要求答案,只是指導。usb_register_dev崩潰的Linux內核

我們已經看過所有我們的變量initalizers,並基於我們的筆記和頭骨的例子,它看起來很好。以下是重要功能和呼叫跟蹤的代碼截圖。

內核(自校,但基於3.2.34):

Linux ETSELE 3.2.34etsele #1 SMP PREEMPT Tue Jan 22 18:22:05 EST 2013 i686 i686 i386 GNU/Linux 

初始化:

static int __init 
usb_cam_init(void) { 
    int result = 0; 

    if ((result = usb_register(&cam_driver))) 
    printk("usb_register failed. Error number %d", result); 
    return result; 
} 

探頭:

static int 
usb_cam_probe(struct usb_interface * intf, const struct usb_device_id * devid) { 
    int retval = 0; 
    struct usb_host_interface *interface; 
    struct usb_endpoint_descriptor *endpoint; 
    struct usb_device *dev = interface_to_usbdev(intf); 
    struct usb_cam *usbdev = NULL; 
    int n, m, altSetNum, activeInterface = -1; 

    printk("kmalloc\n"); 
    usbdev = kmalloc(sizeof(struct usb_ele_cam), GFP_KERNEL); /////////////// 
    printk("usb_get_dev\n"); 
    usbdev->usb_dev = usb_get_dev(dev); 

    usbdev->class = (struct usb_class_driver *) kmalloc(sizeof(struct usb_class_driver), GFP_KERNEL); 

    usbdev->class->name = "cam"; 
    usbdev->class->fops = &cam_fops; 
    usbdev->class->minor_base = 0; 
// usbdev->class->mode = O_RDWR; 

    printk("for\n"); 
    for (n = 0; n < intf->num_altsetting; n++) { 
    interface = &intf->altsetting[n]; 
    altSetNum = interface->desc.bAlternateSetting; 
    for (m = 0; m < interface->desc.bNumEndpoints; m++) { 
     endpoint = &interface->endpoint[m].desc; 
     if (!usbdev->bulk_in_endpointAddr && (endpoint->bEndpointAddress & USB_DIR_IN) 
      && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) { 
     usbdev->bulk_in_size = endpoint->wMaxPacketSize; 
     usbdev->bulk_in_endpointAddr = endpoint->bEndpointAddress; 
     usbdev->bulk_in_buffer = kmalloc(usbdev->bulk_in_size, GFP_KERNEL); 
     activeInterface = altSetNum; 
     break; 
     } 
    } 
    if (activeInterface != -1) 
     break; 
    } 
    printk("usb_set_intfdata\n"); 
    usb_set_intfdata(intf, usbdev); 
    printk("usb_register_dev\n"); 
    usb_register_dev(intf, usbdev->class); 
    //printk("Not able to get a minor for this device"); 
    printk("usb_set_interface\n"); 
    usb_set_interface(dev, interface->desc.bInterfaceNumber, activeInterface); 

    return retval; 
} 

結構和全局變量:

struct usb_cam { 
    struct usb_device *usb_dev; 
    struct usb_interface *usb_inf; 
    struct usb_class_driver *class; 
    struct semaphore sem; 
    unsigned char *bulk_in_buffer; 
    size_t bulk_in_size; 
    __u8 bulk_in_endpointAddr; 
    __u8 bulk_out_endpointAddr; 
    int errors; 
    int open_count; 
    struct kref kref; 
}; 
從kern.log

日誌:

Nov 26 11:25:15 ETSELE kernel: [ 123.845972] usbcore: deregistering interface driver uvcvideo 
Nov 26 11:25:32 ETSELE kernel: [ 140.234188] kmalloc 
Nov 26 11:25:32 ETSELE kernel: [ 140.234192] usb_get_dev 
Nov 26 11:25:32 ETSELE kernel: [ 140.234194] for 
Nov 26 11:25:32 ETSELE kernel: [ 140.234196] usb_set_intfdata 
Nov 26 11:25:32 ETSELE kernel: [ 140.234198] usb_register_dev 
Nov 26 11:25:32 ETSELE kernel: [ 140.234450] BUG: unable to handle kernel paging request at 6d742e65 
Nov 26 11:25:32 ETSELE kernel: [ 140.234506] IP: [<6d742e65>] 0x6d742e64 
Nov 26 11:25:32 ETSELE kernel: [ 140.234539] *pdpt = 000000002bf84001 *pde = 0000000000000000 
Nov 26 11:25:32 ETSELE kernel: [ 140.234585] Oops: 0010 [#1] PREEMPT SMP 
Nov 26 11:25:32 ETSELE kernel: [ 140.234619] Modules linked in: usb_cam(O+) snd_usb_audio snd_usbmidi_lib videodev vtsspp(O) sep3_10(O) pax(O) autofs4 apwr3_1(O) bnep rfcomm bluetooth parport_pc ppdev tpm_infineon binfmt_misc snd_hda_codec_realtek nfsd nfs snd_hda_intel lockd snd_hda_codec fscache auth_rpcgss snd_hwdep nfs_acl snd_pcm sunrpc snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq snd_timer snd_seq_device hp_wmi sparse_keymap snd dm_multipath psmouse serio_raw tpm_tis mac_hid soundcore snd_page_alloc mei(C) lp parport dm_raid45 xor dm_mirror dm_region_hash dm_log btrfs zlib_deflate libcrc32c usbhid hid e1000e i915 drm_kms_helper drm i2c_algo_bit video wmi zram(C) [last unloaded: uvcvideo] 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] Pid: 3153, comm: insmod Tainted: G   C O 3.2.34etsele #1 Hewlett-Packard HP Compaq 6000 Pro MT PC/3048h 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] EIP: 0060:[<6d742e65>] EFLAGS: 00210206 CPU: 0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] EIP is at 0x6d742e65 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] EAX: ea9b8800 EBX: ea9b8800 ECX: 6d742e65 EDX: eb18dc90 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] ESI: eb18dc90 EDI: eb18dc90 EBP: eb18dc30 ESP: eb18dc24 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] Process insmod (pid: 3153, ti=eb18c000 task=eb30d400 task.ti=eb18c000) 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] Stack: 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] c144a1fd ea9b8800 eb18dc4c eb18dc44 c13b05df ea9b8800 00000000 ea9b8808 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] eb18dca0 c13b6be1 00000000 eb3bc0d0 eb18dc94 c11c5560 00000000 00000000 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] 0000000a eb3bffff 00000001 14e7232a eb18dcd5 ffffffff eb18dc80 f7022208 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] Call Trace: 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c144a1fd>] ? usb_devnode+0x2d/0x40 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b05df>] device_get_devnode+0x5f/0xd0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b6be1>] devtmpfs_create_node+0x41/0x100 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c11c5560>] ? sysfs_do_create_link+0xb0/0x1e0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13aff3f>] device_add+0x1ff/0x620 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b9ae0>] ? device_pm_init+0x60/0x80 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b0377>] device_register+0x17/0x20 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b0431>] device_create_vargs+0xb1/0xe0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b048d>] device_create+0x2d/0x30 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c144a093>] usb_register_dev+0x133/0x270 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c15e8afd>] ? _raw_spin_unlock_irqrestore+0x5d/0x80 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<f98d81dc>] ele784_probe+0x17c/0x1bc [usb_cam] 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c14482ae>] usb_probe_interface+0xce/0x210 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b2815>] ? driver_sysfs_add+0x75/0xa0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b2a0f>] driver_probe_device+0x8f/0x2e0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c15e7392>] ? mutex_lock_nested+0x42/0x50 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b2cf9>] __driver_attach+0x99/0xa0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b2c60>] ? driver_probe_device+0x2e0/0x2e0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b1979>] bus_for_each_dev+0x49/0x70 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b2661>] driver_attach+0x21/0x30 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b2c60>] ? driver_probe_device+0x2e0/0x2e0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b22b7>] bus_add_driver+0x1c7/0x2e0 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c13b31d6>] driver_register+0x66/0x110 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c12e5912>] ? __raw_spin_lock_init+0x32/0x60 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c1447229>] usb_register_driver+0x79/0x140 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<f90bc01b>] ele784_init+0x1b/0x1000 [usb_cam] 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c103b3ef>] ? set_memory_nx+0x5f/0x70 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c1003035>] do_one_initcall+0x35/0x170 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<f90bc000>] ? 0xf90bbfff 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c10a3aeb>] sys_init_module+0x2db/0x1d60 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] [<c15ef79f>] sysenter_do_call+0x12/0x38 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] Code: Bad EIP value. 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] EIP: [<6d742e65>] 0x6d742e65 SS:ESP 0068:eb18dc24 
Nov 26 11:25:32 ETSELE kernel: [ 140.235146] CR2: 000000006d742e65 
Nov 26 11:25:32 ETSELE kernel: [ 140.361304] ---[ end trace 3f64a15c3c778575 ]--- 

回答

1

usb_class_driver結構必須正確初始化。

你可以使用kzalloc代替kmalloc,但具有多類多臺攝像機將是錯誤的,所以你應該使相機類的靜態變量(如在使用usb_register_dev其他驅動程序)。