调试杂记

来源:互联网 发布: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);