close

1.先到exercise底下的 chardev_register資料夾




2. chardev.c程式





  1 #include <linux/version.h>
  2 #include <linux/kernel.h>  
 
    // need for kernel alert
  3 #include <linux/module.h>
  4 #include <linux/init.h>        
   // need for __init and __exit
  5 #include <asm/uaccess.h>    
  // for ssize_t
  6 #include <linux/fs.h>          
  // for struct file_operations
  7 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
  8 #include <linux/cdev.h>
  9 static dev_t devno=0;
 10 static struct cdev mycdev;
 11 #endif
 12
 13 static int major=230;
 14
 15 int dev_open (struct inode *inode, struct file *fs) {
 16   printk("dev_open\n");
 17
 18   return 0;
 19 }
 20
 21 int dev_release (struct inode *inode, struct file *fs) {
 22   printk("dev_release\n");
 23
 24   return 0;
 25 }
 26
 27 ssize_t dev_read (struct file *fs, char __user *buffer, size_t size, loff_t *lo) {
 28   printk("dev_read\n");
 29
 30   return 0;
 31 }
 32
 33 ssize_t dev_write (struct file *fs, const char __user *buffer, size_t size, loff_t *lo) {
 34   printk("dev_write\n");
 35
 36   return -1;
 37 }
 38 // To do: declare the file operation structure
 39 static struct file_operations fops = {
 40     .read = dev_read,
 41     .write = dev_write,
 42     .open = dev_open,
 43     .release = dev_release
 44 };
 45
 46 static int __init hello_2_init(void)
 47 {
 48   // To do: register the character device driver
 49     major=register_chrdev(0,"aaa",&fops);
 50     //register_chrdev(0,"aaa",&fops);
 51     if(major<0)
 52     {
 53         printk("<1>register_chrdev() fail,major:%d\n",major);
 54         return -1;//判斷是否註冊成功
 55     }
 56
 57     return 0;
 58 }
 59
 60 static void __exit hello_2_exit(void)
 61 {
 62 // To do: unregister the character device driver
 63     unregister_chrdev(major,"aaa");
 64 }
 65
 66 module_init(hello_2_init);
 67 module_exit(hello_2_exit);
 68     unregister_chrdev(major,"aaa");
 69 }
 70
 71 module_init(hello_2_init);
 72 module_exit(hello_2_exit);
 73
 74 MODULE_LICENSE("GPL");
 75 MODULE_AUTHOR("Jared");
 76 MODULE_DESCRIPTION("Register Character Driver!");
 77 MODULE_SUPPORTED_DEVICE("none");





3. make 


#make -C /lib/modules/2.6.32/build M=`pwd` modules

#insmod ./chardev.ko





#cat /proc/devices

顯示註冊結果


可以看到 252 aaa




4. Create a character device file for our driver

#mknod /dev/kkk  -->kkk是自己取的名字



5.移除

#rm /dev/kkk





6.
#echo 7 >/proc/sys/kernel/printk
把可以顯示的權限調高






Question

1.如何知道driver 註冊有沒有成功?
ans:(i)cat /proc/devices(ii)register_chardev() return value

2.如何移除 /dev/xxx?
ans:rm /dev/xxx

3.為何 cat/dev/xxx會得到以下結果?
dev_open()
dev_read()
dev_release()
ans:因為作業系統開一個file會先 open一個fileread fileclose


4.為何 echo "xxx" > /dev/xxx 會得到operation not permit的結果?
ans:write error,return error -1; include/asm-generic/errnobase.h

5.為何再次insmod chardev.ko會註冊到major number 251?
ans:解除註冊  unregister_chardev()


6.mknod 所建的device filemajor不對,cat /dev/xxx
會是什麼狀況?
ans:可以建立 /dev/xxx,但不能移除
會找不到那個device,或執行到別的driver去了



7.若要註冊固定的major number(230),要如何寫?
ans:  major=register_chardev(major,"aaa",&fops);

最好再另外宣告一個變數接收值 

8.fops中的.read=dev_write, cat /dev/xxx會如何?
ans:

回傳-1=>operation not permitted




另一種新的Register Char Device


#include <linux/version.h>
#include <linux/kernel.h>    
// need for kernel alert
#include <linux/module.h>
#include <linux/init.h>        
// need for __init and __exit
#include <asm/uaccess.h>    
// for ssize_t
#include <linux/fs.h>         
 // for struct file_operations
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
#include <linux/cdev.h>
static dev_t devno=0;
static struct cdev mycdev;
#endif

static int major=230;

int dev_open (struct inode *inode, struct file *fs)
{
  printk("dev_open\n");  
  return 0;
}

int dev_release (struct inode *inode, struct file *fs)
{
  printk("dev_release\n");  
  return 0;
}

ssize_t dev_read (struct file *fs, char __user *buffer, size_t size, loff_t *lo) 
{
  printk("dev_read\n");
  return 0;
}

ssize_t dev_write (struct file *fs, const char __user *buffer, size_t size, loff_t *lo)
{
  printk("dev_write\n");
  return -2;
}
// To do: declare the file operation structure
static struct file_operations fops = 
{
    .read = dev_read,
    .write = dev_write,
    .open = dev_open,
    .release = dev_release
};

static int __init hello_2_init(void) 
  int retval=0;
  // To do: register the character device driver
#if 0
    retval = register_chrdev(major, "aaa", &fops);
    if(retval < 0) {
        printk("<1>reister_chrdev() fail, major:%d\n", retval);
        return -1;
    }
#else
    register_chrdev_region(MKDEV(major,0), 1, "char_reg");
    cdev_init(&mycdev, &fops);
    mycdev.owner=THIS_MODULE;
    cdev_add(&mycdev, MKDEV(major,0), 1);
    
#endif
 
    return 0;
}

static void __exit hello_2_exit(void) 
// To do: unregister the character device driver
#if 0
    unregister_chrdev(major, "aaa");
#else
    cdev_del(&mycdev);
    unregister_chrdev_region(MKDEV(major, 0), 1);
#endif
}

module_init(hello_2_init);
module_exit(hello_2_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("jiunnder2000@yahoo.com.tw");
MODULE_DESCRIPTION("Register Character Driver!");
MODULE_SUPPORTED_DEVICE("none");









arrow
arrow
    文章標籤
    Linux device drive
    全站熱搜

    布拉怡 發表在 痞客邦 留言(0) 人氣()