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

发布者:CrystalClear最新更新时间:2024-08-13 来源: cnblogs关键字:调试分析  自制工具 手机看文章 扫描二维码
随时随地手机看文章

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


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


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

[1] [2] [3]
关键字:调试分析  自制工具 引用地址:调试分析之 自制工具<寄存器编辑器>

上一篇:调试分析之 修改内核来定位系统僵死问题
下一篇:调试分析之 根据内核报错信息栈信息分析错误

推荐阅读最新更新时间:2026-02-16 09:55

国人自制工具IOS4.3上线仅四天即可越狱
    四天前,苹果的IOS4.3升级上线,内置的个人热点和网页加速功能已经吸引了一大批同学来升级自己手中的"i"设备,不过依然有很多同学没有升级,大多是因为IOS4.3还没有越狱工具。 不过今天小编发现,已经有国内的手机玩家根据之前国外网友越狱IOS4.21的漏洞代码,自己修改制作出了IOS4.3的越狱工具。虽然现在还是不完美的越狱,但是至少可以表明IOS4.3也不是那么的牢不可破,越狱的希望还是很近的。 转播到腾讯微博 ▲图为IOS4.3越狱软件 有兴趣的IOS4.3越狱的同学,如果你手中的设备是iPhone4或者iPad(暂时还不支持iPod Touch),可以在互联网上自行搜索下载该软件,
[手机便携]
调试分析之 根据内核报错信息PC指针分析错误
大家写驱动的时候不知道有没有发现,当我们驱动写错了,发生内核奔溃时,会打印一大堆的报错信息, 如果再返回我们的程序中一行一行代码的检查,既耗费时间,并且有些逻辑上的错误,我们是很难看的出来的, 那我们能不能再这一大堆的报错信息中发现问题的所在呢? 此处我们来模拟一个错误,还是沿用上一篇文章中的驱动代码err_led.c的驱动程序中的代码修改错误,当然大家用其他的驱动代码做测试也可以. 1 40 static int key_open(struct inode *inode, struct file *file) 2 41 { 3 42 printk( 0 function open!nn ); 4 43
[单片机]
<font color='red'>调试</font><font color='red'>分析</font>之 根据内核报错信息PC指针<font color='red'>分析</font>错误
调试分析之 根据内核报错信息栈信息分析错误
错误驱动源文件: 加载错误驱动程序 1 root@EasyARM-iMX257 /mnt/nfs/module/37_debug_err_led# echo 1 /dev/errdule/37_debug_err_led# echo 1 /dev/err_led_dev 2 le kernel paging request at virtual address 43fac060 3 pgd = c3b8c000 4 *pgd=00000000 5 Internal error: Oops: 5 PREEMPT 6 Modules linked in: err_led gpio 7 C
[单片机]
基于STM32驱动CC1101的程序分析 浅谈CC1101调试
首先明确:CC1101是通过SPI与MCU进行通信的。根据从TI官方上获得CC1101驱动,直接先移植SPI部分,STM32F103提供了SPI1和SPI2两条SPI总线,可自行选择,对于SPI的移植,直接参考STM32开发板上关于通过SPI操作Flash示例代码,对于SPI的配置与TI提供的驱动代码里的SPI配置保持一致。SPI移植完成之后,接上CC1101射频模块,测试SPI是否能正常通信,主要通过向CC1101任意可读可写寄存器写一个任意值,然后再读出该寄存器里的值,通过串口打印出该值,通过以上操作判断SPI是否正常通信,SPI移植是否成功。当然,这里使用到了串口,所以需要同时将串口的代码实现,同样参考串口实例。 其次,
[单片机]
车载多设备的调试/分析解决方案
本文将介绍在需要协同操作的 多设备环境 中 软件开发 课题的解决方案。 架构的演变与车载软件 近年来,汽车行业正在经历重大变革。在这个变革中,趋势和需求也发生了巨大变化,互联、自动驾驶、驾驶辅助、电动化等功能需求逐年增加。随着功能的增加,搭载的 ECU 也在不断增加,为了适应日益复杂的系统,汽车的电气/电子架构(E/E架构)也在不断发展。 为了控制这些系统,需要构成 ECU 的多个设备之间进行协调操作。 车载 软件开发 中的课题 面向需要多个设备协同操作的 多设备环境 进行 软件开发 面临以下课题: 1. 难以判断哪个设备的软件出了问题 在多个设备上各类软件协同运行的系统中,一个出现问题的软件可能会
[汽车电子]
车载多设备的<font color='red'>调试</font>/<font color='red'>分析</font>解决方案
联盛德 HLK-W801(一):串口下载复位和使用其他串口工具调试的问题分析和解决方法
开发环境 系统:win10 开发板:联盛德 HLK-W801开发板 程序下载方式:基于串口的Upgrade_Tools_V1.4.8下载工具 发现问题 usb连接电脑,用官方提供的Upgrade_Tools_V1.4.8下载工具,当打开点击打开串口的时候,芯片会复位。 当我想用MobaXterm等其他串口工具调试芯片的时候,发现根本无法使用,只要打开串口,w801就会停止工作。 问题出现的原因 通过查看电路图发现一个非常有意思的问题,如图: 没错,串口芯片ch340N的RTS引脚竟然和w801的reset引脚接在一起。 普及一下知识:我们平时使用串口一般只是用 TX、RX、GND这三根线,所以有很多人认为串口就三根线
[单片机]
联盛德 HLK-W801(一):串口下载复位和使用其他串口<font color='red'>工具</font><font color='red'>调试</font>的问题<font color='red'>分析</font>和解决方法
示波器频域分析如何应用于电源调试
电源噪声是电磁干扰的一种,其传导噪声的频谱大致为10kHz~30MHz,最高可达150MHz。电源噪声,特别是瞬态噪声干扰,其上升速度快、持续时间短、电压振幅度高、随机性强,对微机和数字电路易产生严重干扰。 示波器频域分析在电源调试的应用 本文谈到这么多年来最受关注的电源噪声测量问题,有最实用的经验总结,有实测案例佐证,有仿真分析相结合。 在电源噪声的分析过程中,比较经典的方法是使用示波器观察电源噪声波形并测量其幅值,据此判断电源噪声的来源。但是随着数字器件的电压逐步降低、电流逐步升高,电源设计难度增大,需要使用更加有效的测试手段来评估电源噪声。本文是使用频域方法分析电源噪声的一个案例,在观察时域波形无法定位故障时,通过F
[测试测量]
示波器频域<font color='red'>分析</font>如何应用于电源<font color='red'>调试</font>?
巧用Bertscope进行芯片/系统的接收端容限测试和调试分析
在用户进行系统或者芯片测试的时候,一般主要验证几个方面的性能和可靠性,包括系统发送端的信号质量,链路的损耗/串扰,接收端的容限。如下图1,一个链路系统的基本架构。通常在发送端会使用FFE来补偿链路的损耗,接收端会采用DFE/FFE等方法来进行均衡,一些比较高速率的标准如PCIE 4.0/5.0,SAS4等还会采用FEC来进行纠错,当然接收端还需要CDR来从串行信号里面进行时钟恢复得到同步时钟来对信号进行采样。 图1: 高速串行链路的基本架构 对于系统/芯片的接收端测试,会有几个方面的挑战,第一是loopback (环回)模式的Training,第二是link(链路)traini
[嵌入式]
巧用Bertscope进行芯片/系统的接收端容限测试和<font color='red'>调试</font><font color='red'>分析</font>
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved