close
1.先到exercise底下的 chardev_register資料夾
2.寫 chardev.c程式
1 #include <linux/version.h>
2 #include <linux/kernel.h>
// need for kernel alert
// 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
// 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一個file再read file再close
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 file若major不對,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:
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");
文章標籤
全站熱搜