2012-03-21 17 views
0

嗨我正在爲我的字符驅動程序寫一個write()方法,我想知道爲什麼當我將數據從用戶複製到我的內核緩衝區時,我的緩衝區包含隨機亂碼。貝婁是我正在使用的方法。如何從內核緩衝區打印字符串?我是否正確使用copy_from_user()?

ssize_t dev_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp){// This function looks good 
    struct my_char_structure *my_dev = filp->private_data; 
    char *offset; // This points to my buffer 
    size_t np, left_to_print = count; // These are the bytes left to write 


//my_dev->set.write is a double pointer to a sentence where 
//set.write = array[sentence number][character in sentence] 
//set.write if set.write points to non-allocated memory, the sentence number is NULL 
//My device only holds 100 sentences in all 

    if(my_dev->set.write == NULL){// Write is a double pointer that points 
     printk(KERN_ALERT "Device has no more room"); 
     return -ENOMEM; // Look up 
    } 


//you can ignore the commented out stuff but I want to check to see if I'm referencing 
//a sentence that has been filled out. other wise the sentence is null and may be 
//written to. I will add this to my code later for traversing sentences. 
    /*if(*(my_dev->set.write) != NULL){ 
     my_dev->set.write ++; 
     dev_write(filp,buff,count,offp); 
     exit 0; 

    }*/ 

    if (down_interruptible(&my_dev->sem)) 
     return -ERESTARTSYS; 

// Here I'm referencing a memory segment that acts as a pointer to a sentence which 
//I write to. *(my_dev->set.write) is a pointer to a char buff which I will place chars 
// which is essentially my string 

    *(my_dev->set.write) = kmalloc(count,GFP_KERNEL); 
    offset = *(my_dev->set.write); // my offset points to that buffer as well 

//A sentence can only be the size of count, which is passed by the user 
//thats why I allocate count bytes for memory. 


     if((np = copy_from_user(offset,buff,left_to_print)) < 0) 
      goto erro_out; 

     left_to_print -= (count-np); 
     offset += (count-np); 
     offp += (count-np); 

//For debbuging purposes I have printk(). My offset points to my buffer, however 
//prints jibberish. In user space I insert \0 at the end of the string. 

      printk(KERN_ALERT " 4 :: write && left is ... %ld. The string %s", left_to_print, offset); // %s prints jibberish 

    return left_to_print; // change to count 

    erro_out:// if there was an error I free the sentence so that it may be written to. 

     kfree(*(my_dev->set.write)); 
     printk(KERN_ALERT "Print error %ld",np); 
     return -EFAULT; // look this up 
} 

如果我的方法有點囉嗦,我的方法總結如下所示。這應該是第一次寫入設備。

ssize_t dev_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp){// This function looks good 
    struct my_char_structure *my_dev = filp->private_data; 
    static char *offset; 

    if (down_interruptible(&my_dev->sem)) 
     return -ERESTARTSYS; 

    *(my_dev->set.write) = kmalloc(count,GFP_KERNEL); 
    offset = *(my_dev->set.write); 

     if(copy_from_user(offset,buff,left_to_print) < 0) 
      goto erro_out; 

// This is my question, why does %s print jibberish 

      printk(KERN_ALERT " 4 :: write && left is ... %ld. The string %s", left_to_print, offset); 

    return 0; // change to count 

    erro_out: 
     kfree(*(my_dev->set.write)); 
     printk(KERN_ALERT "Print error %ld",np); 
     return -EFAULT; // look this up  
} 

我使用echo「my sentence」>/dev/my_dev寫入我的設備。我不在乎echo是否有效。我只是想讓printk()顯示「我的句子」,這意味着copy_from正在工作。另外我已經嘗試使用echo「my sentence \ 0」>/dev/my_dev來堅持在字符串末尾插入空字符的規則。

感謝您的任何幫助。

回答

3

copy_from_user的第一個參數需要一個目標地址。通過傳遞它像這樣的偏移量:

if((np = copy_from_user(offset,buff,left_to_print)) < 0) 

你給它寫錯了地址。你應該通過你的緩衝區,如:

if((np = copy_from_user(_my_buffer_ + offset,buff,left_to_print)) < 0) 

確保您分配足夠的空間,所以你可以添加offset的地址和注意,我假設你的緩衝區是sizeof計算結果爲1的數據類型。

+0

感謝您花時間看這個。最初我設置了offset = start_of_buffer。我認爲它的誤導性在於我的抵消不是我的抵消,而是我的起始地址。我只是爲了測試的目的,但我會解決這個問題,因爲你是對的,它不在我原來的代碼。 – 2012-03-21 23:24:57

+0

好吧,如果你做''memset(offset,0,count)'',會不會顯示垃圾? – Fred 2012-03-22 07:44:14