调试杂记
来源:互联网 发布:sql 修改数据库sysdate 编辑:程序博客网 时间:2024/05/16 03:07
今天运行一段音频驱动代码:
snd_pcm_uframes_t ls1a_pcm_pointer(struct snd_pcm_substream *substream){struct snd_pcm_runtime *runtime = substream->runtime;struct ls1a_runtime_data *prtd = runtime->private_data;snd_pcm_uframes_t x;if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {write_reg((volatile u32*)(CONFREG_BASE + 0x1160), prtd->dma_position_desc_phys|0x5);while(read_reg(CONFREG_BASE + 0x1160)&4);} else {write_reg((volatile u32*)(CONFREG_BASE + 0x1160), prtd->dma_position_desc_phys|0x6); while(read_reg((volatile u32*)((CONFREG_BASE + 0x1160)&4)));}x = bytes_to_frames(runtime, prtd->dma_position_desc->saddr - runtime->dma_addr);if (x == runtime->buffer_size)x = 0;return x;}
运行的时候 出现内核崩溃提示:
Unable to handle kernel paging request at virtual address 00000000,
刚看到这个错误还以为是某个指针为空然后导致这种错误。
根据如下提示可以反汇编精确到某一行
Call Trace: [<80503594>] ls1a_pcm_pointer+0xe0/0xf4
由于对mips指令集不是很熟悉就直接加入printk打印定位到出问题的一句:
while(read_reg((volatile u32*)((CONFREG_BASE + 0x1160)&4)));
怎么想也不会想到是在这里!!
再看看read_reg 的实现:
static inline u32 read_reg(volatile u32 * reg){return (*reg);}
注意到传递过来的reg 数值为0.
再仔细看上面一句 原来是括号加错了
read_reg( (volatile u32*) ((CONFREG_BASE + 0x1160)&4) )
传递的地址要跟4相与,当然就是0 了!
正确的写法应该是:
while(read_reg((volatile u32*)(CONFREG_BASE + 0x1160)) &4);
- 调试杂记
- wordpress 调试杂记
- Java 远程调试设置杂记
- XCode的一些调试 杂记
- 在unity中的调试杂记
- 编写、调试linux常用命令杂记
- Qcom音频调试杂记-DRC
- 杂记
- 杂记
- 杂记
- 杂记
- 杂记
- 杂记
- 杂记
- 杂记
- 杂记
- 杂记
- 杂记
- 不可重复读和幻读的有什么区别,感觉非常类似阿
- ADB 常用命令整理
- hadoop集群配置实例
- 安卓反编译揭秘(爱加密系列教程二)
- Hibernate进行一对多操作
- 调试杂记
- Linux环境进程间通信: 共享内存
- 安卓反编译揭秘(爱加密系列教程三)
- UIButton学习笔记
- ShareSdk(IOS)使用心得
- Java数据结构--------堆栈和队列
- linux shell中的条件判断语句
- 行政能力测试中折叠题型总结
- Table Hints (Transact-SQL)