淺談 linux kernel module

kernel module

又稱 Loadable Kernel Module(LKM)

  • linux 採用 monolithic (單核心)架構,即 OS 大部分的功能都在 kernel 中實現,例如 process management, memory management 或 process scheduler 等等,這些功能都在 kernel space 下運行。與之相反的則是 microkernel (微核心)架構,僅將 OS 最基本的功能實作在 kernel 內部,其他大部份功能都則在 user space 下運作, microkernel 的設計的優點在於其可移植性與擴展性。

  • 可以在 run time 時候,再增加或移除 module 到 linux kernel 上。
    • 若是不採用這種做法,就必須在 build kernel 時就將 code 編入,但有這麼多的 driver,會使得 kernel 過大,而且只要一個 driver 需要修改,就必須 rebuild 整個 kernel。
  • kernel module 屬於 kernel space,不是 user space。

  • user space and kernel space have their own unique memory address space. 這個做法讓 user space 可以對不同的硬體都能夠有一致的觀點
  • user space 必須透過 system call 才能夠存取到 kernel services。
  • 由於電腦週邊存在各式各樣的設備,這些設備擁有不同的實現原理與電氣特性,linux 為了要能夠抽象的去描述他們,就先劃分出三種不同的分類來方便開發者實做驅動框架跟 API

    1. character device
    2. bulk device
    3. network device

    與這些 device 對應的 driver 都屬於 linux kernel module 。

kernel module 並不是一般 application

  • do not execute sequentially: 一般在撰寫程式時,會有一個 main () 作為程式的入口點,但 kernel module 並沒有這樣的形式。 kernel module 存在 init 和 exit function ,會在載入和移除 module 時自動執行,
  • no automatic cleanup: 任何在 module 內分配的 resource ,在 module 移除時都必須要主動移除,否則直到 reboot 前,這些 resource 都是 unavailable.
  • no printf function: printf() 屬於 user space 的 library, kernel space 是無法去使用的。kernel space 提供 printfk() 這個函式,有著一樣的功能。
  • can be interrupted: kernel module 可以同時被不同 program/process 使用,所以必須思考當 module 收到 interrupt 後是否能夠維持一致且預期的行為。 can be used by several different programs/processes at the same time. So you have to carefully construct it so that they have a consistent and valid behavior when they are interrupted.
  • have a higher level of execution privilege: 一般來說, kernel module 相較 user space program 會被分配到比較多的 CPU cycles ,必須注意 module 是否會影響到整體系統效能。typically, more CPU cycles are allocated to kernel modules than user space programs. So you have to carefully that your module does not adversely affect the overall performance of your system.
  • do not support floating-point: 浮點數運算應該留在 user space 執行。 kernel code that uses traps to transition from integer to float-point mode for user space program. However, it is very difficult to perform these traps in kernel space. The best is that left it to your user space code.
  • 避免使用在 kernel 內使用 global variable ,否則這些變數將會被整個 kernel 分享,你應該使用 static 來限制變數的 scope 。

Reference

  1. Writing a Linux Kernel Module — Part 1: Introduction
  2. 奔跑吧 Linux內核 入門篇

Updated on 2021-02-05 21:58:47 星期五