2012-03-10 51 views
3

我首先在尋找調試技巧。如果有人能夠指出需要更改的一行代碼或者需要設置一個外設配置位來解決問題,那就太棒了。但那不是我所希望的;我正在尋找更多關於如何去調試它。如何調試ARM Linux內核(msleep())鎖定?

使用谷歌搜索「msleep hang linux kernel site:stackoverflow.com」得到13個答案,但沒有一點是關鍵的,所以我認爲我很安全。

我重建了嵌入式TI AM1808 ARM處理器(Sitara/DaVinci?)的ARM Linux內核。我看到所有的啓動日誌都出現在從串口出來的login:提示符上,但嘗試登錄時沒有得到任何響應,甚至沒有回覆我輸入的內容。

經過大量調試後,我到達了內核,並在第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上是那些獲得設定在上述的永久測試循環的開始的標誌狀態示出了當它掛起時間表()不再稱爲:

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

下的.config唯一的選擇/ '設備驅動程序' 是: 塊設備 支持I2C SPI支持

內核和內存盤是loade d使用uboot/TFTP。 我不相信它會嘗試使用以太網。因爲所有這些發生在'/ sbin/init'之前,所以很少發生。

更多詳細信息: 我有一個非常相似的主板與相同的CPU。我可以運行相同的uImage和相同的ramdisk,並且在那裏可以正常工作。我可以登錄並執行通常的操作。

我已經運行內存測試(總共64 MB,限制內核爲32M,測試其他32M;它是一個單芯片DDR2),並沒有發現問題。 一個電路板使用UART0,另一個使用UART2,但引導日誌從兩者中出來,所以它不應該成爲問題。

任何調試技巧,非常感謝。 我沒有合適的JTAG,所以我不能使用它。

+0

它可能是調度程序依賴於某些硬件計時器?這可能是壞的?或使用不同的io地址? – 2012-03-10 21:27:45

+0

據我所知,一切都應該在芯片上(我猜它的值得雙重檢查),所以他們應該看到除了串口之外的完全相同的環境(所有3個應該是活動的,只要選擇哪一個是活動的。)我想我會尋找時間滴答IRQ並在那裏添加一個printk(如果我能找到它:) – user1261470 2012-03-11 05:32:56

回答

0

如果msleep沒有返回或沒有到達schedule,那麼爲了調試我們可以按照調用堆棧。

msleep調用schedule_timeout_uninterruptible(timeout)這就要求schedule_timeout(timeout)這在默認情況下退出而不調用schedule如果傳遞給它的jiffies超時是< 0,所以這是一兩件事來檢查。

如果timeout爲正,則setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);呼籲schedule之前調用,然後__mod_timer(&timer, expire, false, TIMER_NOT_PINNED);

如果我們沒有達到schedule那麼setup_timer_on_stack__mod_timer必須發生一些事情。

setup_timer_on_stack的呼叫追蹤是如果啓動CONFIG_DEBUG_OBJECTS_TIMERSsetup_timer_on_stacksetup_timer_on_stack_key調用它調用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);然後進行很多其他函數調用。

我會建議通過把一個的printk或兩個schedule_timeout可能是setup_timer_on_stack通話或通話__mod_timer兩側的兩側開始。

+0

這對我來說咀嚼是一噸。謝謝,並會回報。 – user1261470 2012-03-11 06:33:13

+0

在「schedule();」周圍添加「之前」和「之後」: http://lxr.linux.no/linux+v2.6.37/kernel/timer.c#L1477 printk退出日程安排();: http://lxr.linux.no/linux+v2.6.37/kernel/sched.c#L4073 http://lxr.linux.no/linux+v2.6.37/kernel /sched.c#L4152 – user1261470 2012-03-11 07:36:57

+0

在兩個電路板上看到「之前」。 在壞板上看到schedule()進入/退出對兩次,在良好的板上看到trice。 還看到: http://lxr.linux.no/linux+v2.6.37/kernel/sched.c#L4133 上下文切換,從下我們 所以我猜時間表翻轉堆棧()返回到某些地方,只有第三次它回到我的msleep電話。所以我想問題是爲什麼調用msleep()的任務還沒有準備好再次調度,或者CPU已經崩潰(我認爲至少會有一個恐慌信息)。 – user1261470 2012-03-11 07:38:47

0

此問題已解決。

隨着自由使用prink,確定schedule()確實切換到另一個任務,即空閒任務。在這種情況下,作爲嵌入式Linux,我從原先的代碼庫中複製了一個空閒任務。這個空閒的任務似乎不適合我的主板,並鎖定了CPU,從而導致了崩潰。註釋掉調用閒置任務解決該問題

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

作品。

+0

我也遇到同樣的問題,我的董事會掛在msleep電話上,但我沒有得到你的修復....你有沒有在schedule_timeout下注釋schedule()? – 2016-03-23 23:00:33

+0

正如我所說,我評論了空閒任務的調用。 Linux瀏覽器有一個新的URL:http://lxr.free-electrons.com/source/arch/arm/mach-davinci/cpuidle.c?v=2.6.37#L93,我註釋到的是: 'cpu_do_idle();' – 2016-04-05 16:51:59