linux - 如何调试 ARM Linux 内核 (msleep()) 锁定?

标签 linux kernel arm schedule

我首先要寻找调试技巧。如果有人可以指出要更改的一行代码或要设置的一个外围配置位来解决问题,那就太好了。但这不是我所希望的;我正在寻找更多关于如何调试它的信息。

谷歌搜索“msleep hang linux kernel site:stackoverflow.com”得到了 13 个答案,但没有一个是重点,所以我想我可以安全地问了。

我为嵌入式 TI AM1808 ARM 处理器(Sitara/DaVinci?)重建了 ARM Linux 内核。我看到所有引导日志到登录:串行端口提示,但尝试登录没有任何响应,甚至不回应我输入的内容。

经过大量调试后,我到达了内核并在第 828 行和第 830 行之间添加了调试代码(是的,内核版本是 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,该条件以在上述永久测试循环开始时设置的标志为条件,表明 schedule() 在挂起时不再被调用:

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

.config/'Device Drivers' 下的唯一选择是: block 设备 I2C支持 SPI支持

内核及其 ramdisk 使用 uboot/TFTP 加载。 我不相信它会尝试使用以太网。 因为所有这些都发生在 '/sbin/init' 之前,所以应该很少发生。

更多详情: 我有一个非常相似的板子和相同的 CPU。我可以运行相同的 uImage 和相同的 ramdisk,并且在那里工作正常。我可以登录并执行常规操作。

我已经运行了内存测试(总共 64 MB,将内核限制为 32M 并测试其他 32M;它是单芯片 DDR2)并且没有发现问题。 一 block 板使用 UART0,另一 block 板使用 UART2,但是引导日志都来自两者,所以这应该不是问题。

非常感谢任何调试提示。 我没有合适的 JTAG,所以我不能使用它。

最佳答案

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

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

如果 timeout 为正,则调用 setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);,然后调用 __mod_timer(&timer, expire, false, TIMER_NOT_PINNED); 在调用 schedule 之前。

如果我们没有得到 schedule,那么 setup_timer_on_stack__mod_timer 中一定有事情发生。

setup_timer_on_stack 的调用跟踪是 setup_timer_on_stack 调用 setup_timer_on_stack_key 如果 CONFIG_DEBUG_OBJECTS_TIMERS 调用 init_timer_on_stack_key 是外部的 已启用或调用 init_timer_key(timer, name, key); 调用 debug_init 后跟 __init_timer(timer, name, key)

__mod_timer 首先调用 timer_stats_timer_set_start_info(timer); 然后调用大量其他函数。

我建议首先在 schedule_timeout 中放置一个或两个 printk 可能是 setup_timer_on_stack 调用的任一侧或 __mod_timer 调用的任一侧.

关于linux - 如何调试 ARM Linux 内核 (msleep()) 锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9649771/

相关文章:

ARM Cortex-M3 从 RAM 初始状态启动

c - Arm客户端服务器程序开发

linux - 为什么你会在 addr 和 addrlen 设置为 0 的情况下调用 accept()?

linux - 通过 sudo 识别当前用户的最可靠方法

macos - 通过网络设置两机内核调试

arm - neon 实现汇总 SAD(绝对差值之和)时出现总线错误

c++ - 如何捕获父进程中的Term操作信号?

linux - 如何在工作时限制文件大小?

linux - 驱动程序中的 usb_kill_urb、usb_submit_urb、usb_find_interface 显示未知符号

linux - Linux中gdtr的地址