调试分析之 自制工具<寄存器编辑器>

发布时间:2024-08-13  

今天还是继续我们内核错误调试,今天是制作一个寄存器编辑器,可以自由的读写某些我们需要调试的寄存器.


一.首先完成一个可自动创建设备节点的字符设备驱动程序


这儿我们前面都写过了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

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;

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    用显示测试模式检查连线正确性。显示测试模式不受控制和数据寄存器影响,点亮显示器所有的段,但不改变任何寄存器内容。向寄存器0x07写入0x01启动显示测试模式。测试模式下显示器如果有不亮的段则说明连线有误。向寄存器0x07写入......
    器实现闪烁功能。下面是一个利用MAX6954驱动显示八个字符,“MAXIM-IC”,的实例。设置配置寄存器禁止闪烁功能,这样就可以通过向寄存器0x20至0x27写入数据来分别控制数据位0至7。使用图3中的......
    之前需要配置 USART 的一些参数,例如波特率、数据位数、停止位等。在配置完成后,可以使用 USART_SendData 函数向数据寄存器写入数据。函数原型如下:void USART_SendData......
    ;    //SCLK上升沿,MCU向DS1302写入数据         DS1302_SCLK = 0;    //一个完整的脉冲     }          for(i=0;i<8;i......
    -layer drivers.pdf手册。建议将该手册作为参考书,有需要时再查阅,不要通读,以后该文件简称为UM1884.pdf文件。RM, Reference Manual ,参考手册。说明芯片内部寄存器如何......
    是为什么要读取32位的原因。 2.3、写入 写入之前必须擦除,这里和NorFlash操作是相同的 复位后,Flash控制器寄存器(FLASH_CR)不允许写入的,去保护Flash闪存因为电气原因出现的以外操作,以下......
    只是为了说明区别,):选择 None (没有触发源):只在向 DAC 数据寄存器 DHR 写入数据之后,DAC 转化模块自动转换一次。选择 software trigger (软件触发): 向软件触发寄存器 SWTRIGR......
    在编号1 端通过“位设置/ 清除寄存器”或“输出数据寄存器写入数据后 该数据位将通过编号2的输出控制电路传送到编号4 的I/O端口。 如果CPU 写入的是逻辑“1 ”,则编号3 的N-MOS管将......
    使用多个DS1267数字电位器和8051微处理器产生3线信号;DS1267为双通道数字电位器,具有串行“移位寄存器”型接口。移位寄存器有一个输入引脚,用于移入数据,还有一个输出引脚,在写入时将数据移出移位寄存器......
    工作模式1-输入浮空模式 1)外部通过IO口输入电平,外部电平通过上下拉部分(浮空模式下都关闭,既无上拉也无下拉电阻)2)传输到施密特触发器(此时施密特触发器为打开状态)3)继续传输到输入数据寄存器......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>