LINUX驅動註冊過程失敗處理不當引起的惡果

LINUX驅動註冊過程失敗處理不當引起的惡果

LINUX設備驅動有標準的結構,註冊的時候對比device和driver的名字,如果相等就調用probe函數將資源註冊進去,但是如果註冊失敗,在probe中途退出的時候要注意,如果直接退出,但是原來註冊了部分資源,如果不設置錯誤原因的參數返回,默認是成功返回這樣,錯誤的驅動就會被其他資源使用,但是由於沒有完成註冊好,缺少資源。或者由於註冊失敗在中途退出雖然將原來的資源釋放掉了,但是probe沒有設置錯誤原因,結果被認爲註冊成功。這樣別的地方調用驅動就會出問題。會空指針引起死機。

        另一方面,如果某個設備壞了,或者沒有裝上某個設備,執行probe探測函數的時候,如果代碼結構不好,開始先執行部分申請了資源代碼,然後做設備探測,如果探測不到設備就退出註冊驅動過程,但是退出的過程沒有釋放前面申請的資源,結果就會引起副作用,比如待機電流大,待機死機。

       比如,編寫camera驅動,如果流程不對,在probe的時候先申請camera控制器的時鐘,把控制器的時鐘打開了,但是由於camera有問題,導致後面的初始化出錯,就退出註冊,但是沒有按照註冊的反方向將資源釋放,沒有將控制器時鐘資源釋放,沒有關閉camera的控制器時鐘。由於註冊不成功,沒有將suspend和resume註冊進去驅動鏈表,睡眠的時候不會執行suspend函數,不會關閉camera控制器的時鐘,導致時鐘的投票關閉不通過,19M的時鐘不會關閉,系統能夠睡眠,但是睡眠電流就有接近17ma的電流(正常睡眠電流是2ma)。另外正常工作的電流也比原來大。這種情況可以no_console_suspend添加到命令行,用示波器看看19M時鐘在系統睡眠狀態是否存在。在睡眠模塊將時鐘樹打印出來,看那個時鐘打開。

     如果註冊某個設備,已經將設備節點註冊到了鏈表,但是中途出錯,退出的時候又沒有將節點釋放,結果suspend函數指針是空的,睡眠的時候調用到這個設備的suspend函數就會由於空指針引起死機。

       正常的流程是註冊過程失敗的時候,要按照申請資源的反方向將原來申請的資源釋放掉,否則會出現孤兒資源,包括內存泄漏,打開了設備的電源沒有關閉導致電流過大,打開了控制器時鐘沒有關閉導致電流過大,孤兒資源導致空指針引起panic等等的問題。雖然這裏就幾行文字,但這是多年的經驗。也是比較難查的問題。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章