2014-09-01 3 views
7

पर विफल होने वाले लिनक्स में एक साधारण चार ड्राइवर को डीबग करना मैंने एक साधारण चार ड्राइवर लिखा था और अब इसे कक्षाओं का उपयोग करके udev में स्वचालित रूप से पंजीकृत करना चाहते हैं। मेरे कोड में init फ़ंक्शन होता है जिसे ड्राइवर लोड किया जाता है और probe फ़ंक्शन कहा जाता है जब ड्राइवर अपने डिवाइस लोड कर रहा है (और निश्चित रूप से उनके काउंटर समकक्ष exit और remove)। समस्या: device_create कमांड निष्पादित करते समय एक नया डिवाइस जोड़ा जाने पर मेरा probe फ़ंक्शन विफल हो जाता है। अब मैं सोच रहा हूं कि क्यों:Linux_create()

यह आदेश संभवतः अधिक जानकारी प्राप्त कैसे कर सकता है कि यह आदेश विफल क्यों होता है (इसके अलावा यह विफल रहता है)? कोई भी तर्क गुम है (जैसे fooClass की वैश्विक घोषणा के साथ कोई समस्या है, क्या मुझे इसे probe फ़ंक्शन पर ले जाना चाहिए, जो मेरी आंखों में संवेदना नहीं करता है लेकिन कई उदाहरणों में दिखाया गया है)? या कोई अन्य विदेशी त्रुटि?

मेरे कोड के बाद मैंने अधिकांश रिटर्न सत्यापन (जैसे IS_ERR()) को हटा दिया और पठनीयता के लिए कार्यों को साफ किया। यह दो चर विश्व स्तर पर परिभाषित कर रहे हैं:

static int foo_majNbr; 
static struct class *fooClass; 

init समारोह:

static int __init foo_init(void) 
{ 
    int rv; 
    dev_t devNbr; 

    /* Registering driver */ 
    rv = pci_register_driver(&foo_driver); 
     /* ----> see answer below for correct order <---- */ 

    /* Create device class */ 
    fooClass = class_create(THIS_MODULE, CLASS_NAME); 

    /* Allocate device number, just one device for the moment */ 
    rv = alloc_chrdev_region(&devNbr, 0, 1, DEVICE_NAME); 
    foo_majNbr = MAJOR(devNbr); 

    ... 
} 

और probe समारोह:

static int __devinit foo_probe(struct pci_dev *dev, 
    const struct pci_device_id *devId) 
{ 
    struct foo_dev *foo_dev = 0; 
    int rv = 0; 

    /* Allocate memory in Kernel (for parameters) */ 
    foo_dev = kzalloc(sizeof(*foo_dev), GFP_KERNEL); 
    foo_dev->pci_dev = dev; 
    pci_set_drvdata(dev, foo_dev); 

    foo_dev->devNbr = MKDEV(foo_majNbr, 1); 

    /* Add class to device */ 
    foo_dev->dev = device_create(fooClass, NULL, foo_dev->devNbr, 
     foo_dev, DEVICE_NAME); 
    if (IS_ERR(foo_dev->dev)) { 
     /* ----> INDICATES FAILURE HERE <---- */ 
    } 

    /* Add char device */ 
    cdev_init(&foo_dev->cdev, &foo_fops); 
    rv = cdev_add(&foo_dev->cdev, foo_dev->devNbr, 1); 

    /* Enabling device */ 
    rv = pci_enable_device(dev); 

    ... 
} 

उत्तर

5

आपको कम से कम कारण जानना त्रुटि संख्या मुद्रित करना चाहिए।

pr_err("%s:%d error code %d\n", __func__, __LINE__, PTR_ERR(foo_dev->dev)); 
  • PTR_ERR(): गलत सूचक एक त्रुटि कोड के लिए
  • ERR_PTR() में परिवर्तित: गलत सूचक को एक त्रुटि कोड परिवर्तित
  • IS_ERR(): जांच करें कि क्या एक सूचक अमान्य है और) एक त्रुटि कोड
  • IS_ERR_OR_NULL (युक्त ऊपर की तरह, के साथ साथ यह जाँच करता है, तो सूचक NULL
फ़ाइलमें

हैआप सबसे आम त्रुटियां पा सकते हैं। यदि यह त्रुटि कोड आपकी मदद नहीं करता है, तो आप source code of device_create() पर जा सकते हैं, यह पता लगाने के लिए कि आपकी तरह की त्रुटि उत्पन्न होती है और क्यों समझती है।

शायद इसे कॉल करने से पहले device_create() के तर्क भी प्रिंट करें।

मुझे पता है, यह ऐसा उत्तर नहीं है जो आपको जादुई रूप से समस्या का समाधान करता है :) लेकिन यह आगे बढ़ने और कारण जानने का एक तरीका है।

+0

धन्यवाद, वास्तव में जो मैं खोज रहा था और इससे समस्या को खोजने में मदद मिली :) - मैंने समाधान को नीचे दिए गए एक अलग उत्तर में पोस्ट किया। – lorenzli

2

प्रश्न डीबगिंग के बारे में जानकारी मांगता है जो पिछले उत्तर में अच्छी तरह से समझाया गया है।

dmesg लॉग निम्नलिखित कॉल इतिहास मॉड्यूल लोड करने के बाद प्रस्तुत किया है पर एक नज़र होने:

[ 2646.982482] [foo_init:246] CALL | Function called. 
[ 2646.982499] [foo_probe:121] CALL | Function called. 
[ 2646.982503] [foo_probe:147] ERR -19 | Failed to add device to class. 
[ 2646.982535] [foo_init:279] OK | Driver loaded, Major number: 235. 

पूर्णता के लिए के लिए मैं क्यों device_create() में विफल रहा है के पीछे वास्तविक समस्या का समाधान साझा करना चाहते हैं जैसा कि कोई देख सकता है, init() फ़ंक्शन probe() से पहले अपना दिनचर्या समाप्त नहीं करता है।इसलिए probe() डिवाइस में इसे जोड़ना चाहता है, इसलिए कोई वर्ग मौजूद नहीं है। init() में बुलाए गए आदेशों का क्रम समस्या है: चालक अपना दिनचर्या समाप्त करने से पहले कर्नेल को पहले ही पंजीकृत कर देता है। pci_register_driver() को केवल अंत में ही बुलाया जाना है। यहाँ अद्यतन कोड: सबसे पहले ड्राइवर अपंजीकृत उपकरण का पंजीकरण रद्द करने के लिए और उसके बाद ही नष्ट:

static int __init foo_init(void) 
{ 
    int rv; 
    dev_t devNbr; 

    /* Create device class */ 
    fooClass = class_create(THIS_MODULE, CLASS_NAME); 

    /* Allocate device number, just one device for the moment */ 
    rv = alloc_chrdev_region(&devNbr, 0, 1, DEVICE_NAME); 
    foo_majNbr = MAJOR(devNbr); 

    ... 

    /* Registering driver */ 
    rv = pci_register_driver(&foo_driver); 
     /* ----> has to be called at the very end! <---- */ 
} 

सही क्रम (के रूप में मैं एक और त्रुटि एक के लिए अग्रणी उफ़ साथ सामना किए जाने के बाद पता चला) exit() समारोह के लिए भी मायने रखता है कक्षा। कोड निम्नानुसार है:

static void __exit foo_exit(void) 
{ 
    pci_unregister_driver(&foo_driver); 
    class_destroy(fooClass); 
} 
+0

बेशक, मैंने आपके कोड पर ध्यान नहीं दिया :) – Federico