服务器设置和教程 · 22 7 月, 2025

Linux驅動開發基礎:基於goldfish內核的實踐指南

1 技術背景

在Linux系統中,內核負責核心資源管理(CPU調度、記憶體管理、裝置控制等),使用者空間透過系統呼叫與內核互動。內核模組是動態擴展機制,允許執行時加載功能,而驅動作為特殊的內核模組,專門管理硬體裝置(如字元裝置、區塊裝置、網路裝置)。本文基於goldfish內核環境,演示驅動開發全流程,適用於各類伺服器環境(包括香港伺服器香港雲端伺服器的測試部署。


2 內核模組開發

2.1 最小模組實現
內核模組需定義初始化/清理函數,並透過module_init/module_exit註冊:

#include <linux/init.h>
#include <linux/module.h>  

static int __init hello_init(void) {  
    printk("hello_kernel: Module loaded\n");  
    return 0;  
}  

static void __exit hello_exit(void) {  
    printk("hello_kernel: Module unloaded\n");  
}  

module_init(hello_init);  
module_exit(hello_exit);  
MODULE_LICENSE("GPL");
  • __init/__exit宏優化記憶體:初始化程式碼執行後自動釋放。

2.2 編譯與加載

  • 編譯進內核

    1. 將程式碼置於drivers/misc/demo/,配置Kconfig

    config HELLO_KERNEL  
        tristate "Hello kernel"  
        default y
    1. 修改drivers/misc/Makefile

    obj-$(CONFIG_HELLO_KERNEL) += demo/
    1. 重新編譯內核:make,生成bzImage

  • 編譯為模組

    1. 設定default m,執行模組編譯:

    make M=drivers/misc/demo modules  # 生成hello_kernel.ko  
    1. 推送到裝置並加載:

    adb push hello_kernel.ko /data/local/tmp/  
    adb shell insmod /data/local/tmp/hello_kernel.ko
    1. 驗證日誌:dmesg | grep hello_kernel


3 驅動開發實踐:字元裝置

3.1 雜項裝置驅動(miscdevice)
利用固定主裝置號(10),簡化字元裝置開發:

#include <linux/miscdevice.h>
#include <linux/fs.h>  

#define DEVICE_NAME "hello_device"  
static char str_buffer[128];  
static size_t str_len;  

// 檔案操作介面  
static struct file_operations hello_fops = {  
    .owner = THIS_MODULE,  
    .open = hello_open,  
    .release = hello_release,  
    .read = hello_read,  
    .write = hello_write,  
};  

// 註冊雜項裝置  
static struct miscdevice hello_misc = {  
    .minor = MISC_DYNAMIC_MINOR,  
    .name = DEVICE_NAME,  
    .fops = &hello_fops,  
};  

// 初始化(加載驅動)  
static int __init hello_init(void) {  
    misc_register(&hello_misc);  // 建立裝置節點/dev/hello_device  
    return 0;  
}

關鍵函數說明

  • copy_from_user(): 使用者空間→內核空間資料傳輸。

  • copy_to_user(): 內核空間→使用者空間資料傳輸。

3.2 測試與驗證

  1. 終端讀寫測試

echo “test” > /dev/hello_device # 觸發write()  
cat /dev/hello_device            # 觸發read()  
  1. 應用層讀寫(Android範例)

fun writeToDevice(data: String) {
    FileOutputStream("/dev/hello_device").use { it.write(data.toByteArray()) }  
}  
fun readFromDevice(): String {  
    return FileInputStream("/dev/hello_device").readBytes().toString()  
}

權限處理

chmod 666 /dev/hello_device # 開放讀寫權限  
setenforce 0                 # 關閉SELinux(測試環境)  

4 部署與場景應用

  • 測試環境

    • 使用Android模擬器加載goldfish內核:

    emulator -avd Pixela10 -kernel arch/x86_64/boot/bzImage
  • 生產環境

  • 技術價值

    • 遵循「一切皆檔案」理念,透過/dev節點統一管理硬體(如序列埠裝置/dev/ttyS0、Binder驅動/dev/binder)。


5 總結

本文透過goldfish內核環境完成:

  1. 內核模組:實現動態加載/卸載的hello_kernel模組。

  2. 字元裝置驅動:開發支援讀寫操作的雜項裝置/dev/hello_device

  3. 跨空間通訊:使用copy_from_user/copy_to_user安全傳輸資料。
    後續可擴展至真實硬體驅動開發,適用於雲端環境(如香港雲端伺服器)的客製化部署。

附:驅動互動時序

使用者空間write() → 系統呼叫 → VFS → hello_write() → copy_from_user()  
使用者空間read()  → 系統呼叫 → VFS → hello_read()  → copy_to_user()