今天还是继续我们内核错误调试,今天是制作一个寄存器编辑器,可以自由的读写某些我们需要调试的寄存器.
一.首先完成一个可自动创建设备节点的字符设备驱动程序
这儿我们前面都写过了N遍,此处不再赘述,直接附上代码:
1 /******************************
2 内核调试之自制寄存器读写工具(驱动)
3 *****************************/
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19
20
21 static int major;
22
23 //auto to create device node
24 static struct class *class;
25 static struct class_device *kernel_class_dev;
26
27
28 static int kernel1_rw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
29 {
30
31 return 0;
32 }
33
34 //定义字符设备结构体
35 static struct file_operations kernel_rw_ops = {
36 .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
37 .ioctl = kernel1_rw_ioctl,
38 };
39
40 static int kernel_rw_init(void)
41 {
42 printk('
43 major = register_chrdev(0, 'kernel_rw', &kernel_rw_ops);
44 class = class_create(THIS_MODULE,'kernel_rw');
45 kernel_class_dev = device_create(class,NULL,MKDEV(major,0),NULL,'kernel_rw'); /*/dev/kernel_rw*/
46
47
48 return 0;
49 }
50
51 static void kernel_rw_exit(void)
52 {
53 printk('
54 device_unregister((void *)kernel_class_dev);
55 class_destroy((struct class *)class);
56 unregister_chrdev(major,'kernel_rw');
57 }
58
59 module_init(kernel_rw_init);
60 module_exit(kernel_rw_exit);
61 MODULE_LICENSE('GPL');
62 MODULE_AUTHOR('Lover雪儿');
二.在ioctl中增加寄存器的读写功能
定义ioctl的command命令.
1 #define KERNEL_RW_R8 0
2 #define KERNEL_RW_R16 1
3 #define KERNEL_RW_R32 6
4
5 #define KERNEL_RW_W8 3
6 #define KERNEL_RW_W16 4
7 #define KERNEL_RW_W32 5
实现ioctl函数.
1 static int kernel1_rw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
2 {
3 volatile unsigned char *p8;
4 volatile unsigned short *p16;
5 volatile unsigned int *p32;
6 unsigned long val;
7 unsigned long addr;
8
9 unsigned int buf[2];
10
11
12 copy_from_user(buf, (const void __user *)arg, 8);
13 addr = buf[0];
14 val = buf[1];
15 printk('
16 p8 = (volatile unsigned char *)ioremap(addr, 4);
17 p16 = p8;
18 p32 = p8;
19
20 switch (cmd)
21 {
22 case KERNEL_RW_R8:
23 {
24 val = *p8;
25 copy_to_user((void __user *)(arg+4), &val, 4);
26 printk('
27 break;
28 }
29
30 case KERNEL_RW_R16:
31 {
32 val = *p16;
33 copy_to_user((void __user *)(arg+4), &val, 4);
34 printk('
35 break;
36 }
37
38 case KERNEL_RW_R32:
39 {
40 val = *p32;
41 copy_to_user((void __user *)(arg+4), &val, 4);
42 printk('
43 break;
44 }
45
46 case KERNEL_RW_W8:
47 {
48 *p8 = val;
49 printk('
50 break;
51 }
52
53 case KERNEL_RW_W16:
54 {
55 *p16 = val;
56 printk('
57 break;
58 }
59
60 case KERNEL_RW_W32:
61 {
62 *p32 = val;
63 printk('
64 break;
65 }
66 default:
67 printk('
68 break;
69 }
70
71 iounmap(p8);
72 return 0;
73 }
附上驱动程序kernel_rw.c
1 /******************************
2 内核调试之自制寄存器读写工具(驱动)
3 *****************************/
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19
20 #define KERNEL_RW_R8 0
21 #define KERNEL_RW_R16 1
22 #define KERNEL_RW_R32 6
23
24 #define KERNEL_RW_W8 3
25 #define KERNEL_RW_W16 4
26 #define KERNEL_RW_W32 5
27
28 static int major;
29
30 //auto to create device node
31 static struct class *class;
32 static struct class_device *kernel_class_dev;
33
34
35 static int kernel1_rw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
36 {
37 volatile unsigned char *p8;
38 volatile unsigned short *p16;
39 volatile unsigned int *p32;
40 unsigned long val;
41 unsigned long addr;
42
43 unsigned int buf[2];
44
45
46 copy_from_user(buf, (const void __user *)arg, 8);
47 addr = buf[0];
48 val = buf[1];
49 printk('
50 p8 = (volatile unsigned char *)ioremap(addr, 4);
51 p16 = p8;
52 p32 = p8;
53
54 switch (cmd)
55 {
56 case KERNEL_RW_R8:
57 {
58 val = *p8;
59 copy_to_user((void __user *)(arg+4), &val, 4);
60 printk('
61 break;
62 }
63
64 case KERNEL_RW_R16:
65 {
66 val = *p16;
67 copy_to_user((void __user *)(arg+4), &val, 4);
68 printk('
69 break;
70 }
71
72 case KERNEL_RW_R32:
73 {
74 val = *p32;
75 copy_to_user((void __user *)(arg+4), &val, 4);
76 printk('
77 break;
78 }
79
80 case KERNEL_RW_W8:
81 {
82 *p8 = val;
83 printk('
84 break;
85 }
86
87 case KERNEL_RW_W16:
88 {
89 *p16 = val;
90 printk('
91 break;
92 }
93
94 case KERNEL_RW_W32:
95 {
96 *p32 = val;
97 printk('
98 break;
99 }
100 default:
101 printk('
102 break;
103 }
104
105 iounmap(p8);
106 return 0;