做嵌入式linux移植,最常見也最鬱悶的問題,就是自己新做的核心映象,還沒有神馬把握,,就要忐忑不安地燒到板子上去測試。這個時候,我寧願它突出一堆oops,甚至panic,心裡覺得舒坦些。可是它要啥都不吐,那就抓瞎了。
這種情況,就是printk緩衝區的資訊準備好了,但是串列埠console初始化失敗或者還沒執行,printk記憶體緩衝區吐不出來造成的。
一般核心開啟會列印linux version 2.6.xx (gcc version 4.2.2) #47 preempt 這樣的linux_banner資訊。
見2.3.34.1,start_kernel 函式
printk( kern_notice "%s"
, linux_banner)
;setup_arch(
& command_line)
;
可以看到,這裡是先printk,再setup_arch的。
我這裡是powerpc的板子,很可能由於dts的配置導致板子不能識別或串列埠配置錯誤等,導致核心連個屁都吐不出來。
而檢查dts的內容,是在setup_arch裡進行的啊。我就不服氣了,憑什麼要因為後面函式的原因,導致我前面的printk出不來。
核心早期輸出工具early_printk不是所有平台都能用。powerpc特有的早期除錯機制,我嘗試了半天也沒成功。
使用ppc_md.progress ,貌似可以實現powrpc下的早期輸出。但是ppc_md.progress的初始化,可是在
void __init chrp_setup_arch(void)
這裡才被初始化的,此時start_kernel 我覺得早就開始執行了。也就是說第乙個printk已經使用過,
ppc_md.progress的初始化才開始。
這裡,我從embedded linux primer上汲取力量,得到一種強大的軟體除錯手段,讓printk的東西吐出來。
前提條件:
1、板子有熱重啟鍵,或者其他熱重啟機制(linux異常重啟,預設時間180秒),或者使用**器重啟。不過既然有**器,那就不用往下看了。
2、執行到了start_kernel 中printk(kern_notice "%s", linux_banner);這一步核心尚未異常。
3、擁有能夠檢視記憶體的bootloader,如 uboot或其前身ppcboot 的md命令。
檢視核心的system.map檔案,__log_buf這個符號的虛擬位址,如我這裡
c032cf48 b __log_buf
將核心虛擬位址轉換成物理記憶體位址很簡單,因為大多數嵌入式平台不會使用984m以上的記憶體,核心虛擬位址僅僅是實體地址的乙個線性偏移而已。
我的物理記憶體基址是0,所以物理記憶體位址很可能是0x0032cf48
boot核心,等待一會,然後熱重啟。其實記憶體上的資訊還熱乎著呢,馬上使用uboot檢視
=> md 32cf48
cmdtp 1ffc9b1c ,flag 0 ,argc 2,argv[0] md ,argv[1] 32cf48
0032cf48: 3c363e55 73696e67 204d5043 38333778 <6>using mpc837x
0032cf58: 20524442 2f574c41 4e206d61 6368696e rdb/wlan machin
0032cf68: 65206465 73637269 7074696f 6e0a3c35 e description.<5
0032cf78: 3e4c696e 75782076 65727369 6f6e2032 >linux version 2
0032cf88: 2e362e33 342e3120 28787940 626e632d .6.34.1 (xy@bnc-
0032cf98: 79687029 20286763 63207665 7273696f yhp) (gcc versio
0032cfa8: 6e20342e 322e3320 28536f75 72636572 n 4.2.3 (sourcer
0032cfb8: 7920472b 2b204c69 74652034 2e322d31 y g++ lite 4.2-1
0032cfc8: 37312929 20233530 2053756e 204f6374 71)) #50 sun oct
0032cfd8: 20313020 32333a35 353a3239 20504454 10 23:55:29 pdt
0032cfe8: 20323031 300a3c37 3e466f75 6e64206c 2010.<7>found l
0032cff8: 65676163 79207365 7269616c 20706f72 egacy serial por
0032d008: 74203020 666f7220 2f696d6d 72406530 t 0 for /immr@e0
0032d018: 30303030 30302f73 65726961 6c403435 000000/serial@45
0032d028: 30300a3c 373e2020 6d656d3d 65303030 00.<7> mem=e000
0032d038: 34353030 2c207461 6464723d 65303030 4500, taddr=e000
雖然條件艱苦了點,總比沒有強啊。怎麼也比點燈除錯爽多了。
此方法非常imba,山窮水盡的時候可以一試。
同樣適用於arm,之前測試過。
當然,最好能有**器。
徹底解決 OBJC CLASS
最近在使用靜態庫時,總是出現這個問題。下面總結一下我得解決方法 1.m檔案沒有匯入 在build phases裡的compile sources 中新增報錯的檔案 2.framework檔案沒有匯入 靜態庫編譯時往往需要一些庫的支援,檢視你是否有沒有匯入的庫檔案 同樣是在build phases裡的...
徹底解決INSTALL FAILED UPDATE
按ctrl c退出系統,利用adb pull data system packages.xml命令將packages.xml放到你pc機本地,然後找到你需要的包名,刪除到的一段資料。例如 儲存packages.xml,然後adb push packages.xml data system將packa...
徹底解決 OBJC CLASS
1.m檔案沒有匯入 在build phases裡的compile sources 中新增報錯的檔案 2.framework檔案沒有匯入 靜態庫編譯時往往需要一些庫的支援,檢視你是否有沒有匯入的庫檔案 同樣是在build phases裡的link binary with libraries中新增 3....