如何debuggingARM Linux内核(msleep())locking?

我首先在寻找debugging技巧。 如果有人可以指出一行代码改变或一个外设configuration位来设置解决问题,那将是了不起的。 但这不是我所希望的; 我正在寻找更多的如何去debugging它。

使用谷歌search“msleep挂linux内核网站:stackoverflow.com”产生13个答案,没有一点是关键的,所以我想我可以安全地问。

我为embedded式TI AM1808 ARM处理器(Sitara / DaVinci?)重build了一个ARM Linux内核。 我看到所有的启动日志都从串口出来的login:提示符,但是尝试login没有响应,甚至没有回应我input的内容。

经过大量debugging后,我到达了内核,并在第828行和第830行之间添加了debugging代码(是的,内核版本是2.6.37)。 在调用sbin / init之前的内核模式下,

http://lxr.linux.no/linux+v2.6.37/init/main.c#L815

在830行之前,我添加了一个永久循环的printk,我看到了结果。 我已经让它运行了大约几个小时,数量达到了200万。 采样线:

dbg:init/main.c:1202: 2088430 

所以它已经吐出了6000万字节没有问题。

但是,如果我在循环中添加msleep(1000),它只打印一次,即msleep()不会返回。

详细信息:在调度程序的第4073行添加一个条件printk,该条件在上面描述的永久testing循环的开始处设置的标志上显示,它在挂起时不再被调用:

http://lxr.linux.no/linux+v2.6.37/kernel/sched.c#L4064

.config /'设备驱动程序'下的唯一select是:块设备I2C支持SPI支持

内核和它的虚拟磁盘是使用uboot / TFTP加载的。 我不相信它会尝试使用以太网。 由于所有这些发生在'/ sbin / init'之前,所以很less发生。

更多细节:我有一个非常相似的主板与相同的CPU。 我可以运行相同的uImage和相同的ramdisk,它在那里工作得很好。 我可以login,并做平常的事情。

我已经运行了内存testing(总共64 MB,将内核限制为32M,testing其他32M;这是一个单芯片DDR2),没有发现问题。 一个板子使用UART0,另一个使用UART2,但是启动日志从两者都出来,所以它不应该成为问题。

任何debugging技巧,不胜感激。 我没有合适的JTAG,所以我不能使用它。

如果msleep没有返回或没有进行schedule ,那么为了调试,我们可以按照调用堆栈。

msleep调用schedule_timeout_uninterruptible(timeout) ,它调用schedule_timeout(timeout) ,在默认情况下,如果传递给它的jiffies中的超时值<0,在默认情况下它将不调用schedule,所以这是一件要检查的事情。

如果timeout是正的,那么setup_timer_on_stack(&timer, process_timeout, (unsigned long)current); 被调用,接着是__mod_timer(&timer, expire, false, TIMER_NOT_PINNED); 在打电话之前

如果我们没有按schedule那么setup_timer_on_stack__mod_timer必须有一些事情发生。

setup_timer_on_stack的setup_timer_on_stacksetup_timer_on_stack调用setup_timer_on_stack_key ,如果CONFIG_DEBUG_OBJECTS_TIMERS被启用或调用init_timer_key(timer, name, key); ,调用init_timer_on_stack_key是外部的init_timer_key(timer, name, key); 其中调用__init_timer(timer, name, key)后跟__init_timer(timer, name, key)

__mod_timer先调用timer_stats_timer_set_start_info(timer); 那么很多其他函数调用。

我建议先在schedule_timeout放置一个或多个setup_timer_on_stack或许在setup_timer_on_stack调用的任一端或setup_timer_on_stack调用的任一端。

这个问题已经解决了。

随着prink的自由使用,确定schedule()确实切换到另一个任务,即空闲任务。 在这个例子中,作为一个嵌入式Linux,我从原来的代码库中拷贝了一个空闲的任务。 这个空闲的任务似乎不适合我的主板,并锁定了CPU,从而导致崩溃。 注释掉空闲任务的呼叫

http://lxr.linux.no/linux+v2.6.37/arch/arm/mach-davinci/cpuidle.c#L93

解决这个问题。