linux调试技巧(2):编写寄存器寄存器读取驱动

前一篇文章写了高通平台对于寄存器底层读取的支持,
这篇文章描述下如何在没有此工具的情况下,如何自己编译一个驱动程序读取寄存器值

工具的原理很简单,Linux 应用层无法直接访问内核空间,使用通过上层应用打开驱动,然后往驱动写值,来通过驱动去访问底层硬件

驱动中我们实现ioctl函数,相对于open 和write, ioctl 更具灵活性

static long debugs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{

	int ret;

	switch(cmd){
		case GET_VALUE:
			ret = get_register(arg);   //读取寄存器值
			if (ret < 0 )
				return -1;
			break;

		case SET_VALUE:
			ret = set_register(arg);  // 设置寄存器值
			if (ret < 0 )
				return -1;
			break;

		default:
			printk("Unknown cmd\n");
	}
	return 0;


}

ioctl实现读和写

读函数:

int get_register(unsigned long arg)
{



	int ret ;

	ret = copy_from_user(®iste,(void * )arg , sizeof (registe));  // 拷贝用户空间传入的值
	if(ret)
		return -EFAULT;    //错误判断

	printk( " kernel get addr form user \n");

     // 分配内核地址,讲具体寄存器地址映射到内核空间,此步骤是重点
	LAW_VIR_ADDRESS = ioremap_nocache( registe.addr , 4 ); 

	registe.value = readl(LAW_VIR_ADDRESS);  // readl 函数读取寄存器的值


	printk( "law_get: kernel get register addr=<0x%08x>\n",registe.addr);

	ret = copy_to_user( ( void * )arg ,®iste , sizeof (registe));  // 返回寄存器值到用户空间
	if(ret)
		return -EFAULT;

	printk( "law_set: kernel put  register value to user \n ");
	iounmap(LAW_VIR_ADDRESS);   //及时释放寄存器申请的内核空间地址


	return 0;
}

写寄存器地址函数;

int set_register(unsigned long arg)
{
	int ret;

	ret = copy_from_user(®iste,(void * )arg , sizeof (registe));
	if(ret)
		return -EFAULT;
	printk( "law_set: kernel get  addr form user\n ");

	LAW_VIR_ADDRESS = ioremap_nocache( registe.addr , 4 );  //申请空间

	writel( registe.value ,  LAW_VIR_ADDRESS);  // 往申请的寄存器地址中写入值

	printk( "law_set: kernel set  register value\n");

	ret = copy_to_user( ( void * )arg ,®iste , sizeof (registe));  
	if(ret)
		return -EFAULT;

	printk( "law_set: kernel put register value to user\n");

	iounmap(LAW_VIR_ADDRESS);


	return 0;

}

应用层读写通过如下函数:

ioctl(fd,GET_VALUE,&rw_regs)
ioctl(fd,SET_VALUE,&rw_regs)

核心代码如上,原理很简单,申请寄存器物理地址到内核空间,通过readl 和 writel 内核函数读写即可,不过此驱动还是有点问题,一旦底层的寄存器没有被使能,直接读取会导致内核崩溃,不过简单的读写查询验证可以满足,有兴趣的可以完善下这个驱动

使用效果:
linux调试技巧(2):编写寄存器寄存器读取驱动_第1张图片
linux调试技巧(2):编写寄存器寄存器读取驱动_第2张图片
代码下载链接
后续会持续分享一下安卓系统平台开发的一些知识点,欢迎关注

你可能感兴趣的:(调试)