Linux裝置驅動移植注意事項
- 移植驅動前注意資料型別:
u8、u16、u32、u64、s8、s16、s32、s64只能在核心空間使用
_ _u8、_ _u16、_ _u32用來使用者空間
驅動中最好使用 int8_t、int16_t、int32_t、uint8_t、uint16_t、uint32_t、int64_t、uint64_t 這些 C99 標準確定長度型別
- 結構體對界
預設情況下,編譯器為結構體的每個成員按其自然對界(natural alignment)條件分配空間,各個成員按照它們被宣告的順序在記憶體中順序儲存,第一個成員的地址和整個結構的地址相同。自然對界指按結構體的成員中 sizeof 最大的成員對齊
- Little Endian 與 Big Endian
採用 Little Endian 模式的 CPU 對運算元的存放方式是從低位元組到高位元組,而 Big Endian 模式對運算元的存放方式是從高位元組到低位元組
- 記憶體頁面大小
記憶體頁一般在4-64k大小。不同的 PAGE_SIZE 和 PAGE_SHIFT可以確定申請記憶體大小
當在核心空間中通過 get_free_pages()函式申請記憶體時,公式如下:PAGE_SIZE * 2order
即,PAGE_SIZE和order確定記憶體大小。
- 當出現從無作業系統的驅動移植到linux上。則需要注意以下幾點
一:無作業系統的硬體訪問方法中往往沒有實體地址到虛擬地址的對映過程,因此,在搬到 Linux 系統中的時候,要注意以靜態對映或 ioremap()等方式對映到虛擬地址
二:硬體訪問中往往夾雜著延時,因此,在無作業系統的原始碼中,經常會出現xxx_delay()這樣的 for 迴圈延遲,這些程式碼應該被核心中的 ndelay()或 udelay()替換。如果延遲時間達到數十 ms,應該使用 msleep()或 msleep_interruptible()等函式
三:如果系統中用的 Linux 不支援搶佔排程,while (!(regb &0x1));需要相當長的時間(如數十 ms),這種忙等待會導致其他的程序全部得不到機會執行
四:從良好的程式碼風格角度出發,模組中不需要輸出到核心空間且不需為模組中其他檔案所用的全域性變數及函式最好顯式申明為 static