先前接到一間上市公司的委託,因為他們被客戶盯良率不好,但RMA回來成本不僅大,把Chip umount 下來又會破壞當下的環境,但客戶又不提供bios之類的環境提供偵錯。所以找上我們看有沒有辦法hijack客戶的環境提供command偵錯….
坦白講一開始收到這個提案的時候, 有一點滿腦問號…….。但因為客戶有提供Image檔案,想說好像可以從軟體跟硬體的方式去想辦法解析。
收到板子後開始從板子去研究,然後大量的餵Google 把相關的資料先收集起來。對板子的架構大致上了解後,發現板子的動作應為以下順序
BIOS -> Preloader -> Uboot -> Kernel -> Rootfs
又因為板子上提供SD card slots, 所以想說在不動BIOS時,試試看可不可透過SD卡開機, 發現SD卡上去後BIOS會優先從SD卡上的preloader來讀取。BINGO!
後來決定透過Uboot的環境下去提供command給客戶偵錯,Uboot優點是開源,指令簡單客戶好上手,重點是可以自己新增code來達成自己要的目的。
以下節錄Wikipedia的敘述
Das U-Boot 是一個主要用於嵌入式系統的啟動載入程式,可以支援多種不同的計算機系統結構,包括68k、AVR32、ARM、Blackfin、MicroBlaze、MIPS、Nios、SuperH、PPC、RISC-V與x86。這也是一套在GNU通用公眾授權條款之下發布的自由軟體。
Uboot的source code ( click me )
build 完Uboot後,把原本的image檔案裡面Uboot位置內容改成我們自己build的Uboot後,正常開機就可以load到我們編譯的 command console底下。這樣其實就告段落了…
但其實後面發現的問題才是很頭大,讓我要寫文章記錄這篇….
正當我以為專案到這邊就告段落時,也開機可以正常到我們編譯的Uboot裡後。當我們換另一塊不同型號(Chipset are same)的板子後,就發現事情不是我們想的這麼簡單
一開機後可以正常進到Uboot. 但不到五秒後,會自動重新開機.
但使用客戶提供的image 檔案後,卻不會有這問題。
這問題卡了大概一個禮拜,一直不知道是哪個地方有問題,查了Uboot所有的init flow後,根本沒有設類似的timer去導致。Uboot在Load的過程中也可以正常到cosole mode.
查了一下也沒有發現Uboot.有任何報錯。後來索性把Uboot所有有load的module全部移除掉。這樣還是會重開機啊!! 到底為啥客戶提供的image檔就不會有這問題…
OK, 沈澱一下,只好把問題轉上一層preloader一定在處理什麼事情的時候導致機器會重開機。但因為Preloader 沒有source code可以參考。所以只好從周邊元件著手。
後來透過交叉驗證及種種的跡象,把矛頭指向了Watchdog,懷疑是Preloader 觸發了Watchdog計數器,原本應在Uboot 或kernel起來的時候去Disable/polling watchdog.
但我們自己build的Uboot卻沒有做這些事情所導致的。
但我不知道這塊板子上的Watchdog的model & Address & spec ,客戶也無法提供…
只好又透過網路世界的力量,翻來翻去找到某個份文件對板子的dtsi檔案裡面有寫到wdt的位置
wdt: watchdog@ff1e0000 {
compatible = "snps,dw-wdt";
reg = <0x0 0xff1e0000 0x0 0x100>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
但由於使用的source code 沒有實現wdt的模組,又想說把wdt模組移植近來很浪費專案成本,所以只好直接透過控制register的方式來控制wdt.
透過各總摸索後,大致摸出WDT的控制方法(好險之前有控制wdt的經驗...)
之後將整個控制WDT的方法放在Uboot init的時候,讓Uboot起來的時先去設定watchdog disable後再去執行後端。
mw ff1e0000 ffff 8
把整套source code 在build成 Uboot後,放進原本會重開機的平台上再試一次。
登愣!終於成功穩定的進到Uboot console 裡面了。
以上基本上就告段落了..
至於客戶後來提出要在Uboot讀取檔案及Uboot空間不夠,要怎麼去偷其他的空間先來用,又是另一個故事了…..
搶先發佈留言