โมดูลเคอร์เนลอาจไม่ได้เป็นไดรเวอร์อุปกรณ์เลย
"โปรแกรมควบคุมเคอร์เนล" ไม่ใช่คำที่กำหนดไว้อย่างชัดเจน แต่ลองมาดูกัน
นี่คือเคอร์เนลโมดูลที่ไม่ได้ขับฮาร์ดแวร์ใด ๆ และดังนั้นจึงไม่สามารถพิจารณาได้อย่างสมเหตุสมผล "ไดรเวอร์อุปกรณ์":
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int myinit(void)
{
printk(KERN_INFO "hello init\n");
return 0;
}
static void myexit(void)
{
printk(KERN_INFO "hello exit\n");
}
module_init(myinit)
module_exit(myexit)
หลังจากสร้างแล้วคุณสามารถใช้กับ:
insmod hello.ko
และก็พิมพ์ไปhello init
dmesg
อย่างไรก็ตามมีโมดูลเคอร์เนลที่ไม่ใช่ไดรเวอร์อุปกรณ์ แต่มีประโยชน์จริงเช่นโมดูลที่เปิดเผยข้อมูลการดีบักเคอร์เนล / ประสิทธิภาพ
ไดรเวอร์อุปกรณ์มักจะเป็นโมดูลเคอร์เนล
ตัวอย่างของสิ่งที่เป็น "ไดรเวอร์อุปกรณ์" นั้นค่อนข้างยากในการสร้างเนื่องจากต้องใช้ฮาร์ดแวร์ในการขับเคลื่อนและคำอธิบายฮาร์ดแวร์มักจะซับซ้อน
อย่างไรก็ตามการใช้ QEMU หรืออีมูเลเตอร์อื่น ๆ เราสามารถสร้างแบบจำลองซอฟต์แวร์ของฮาร์ดแวร์จริงหรือแบบง่ายซึ่งเป็นวิธีที่ดีในการเรียนรู้วิธีพูดคุยกับฮาร์ดแวร์ นี่คือตัวอย่างง่ายๆของไดร์เวอร์อุปกรณ์ PCI ขั้นต่ำ: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c
จากนั้นเราจะเห็นว่าใน x86 การพูดคุยกับฮาร์ดแวร์นั้นลงไปที่:
การดำเนินการเหล่านั้นไม่สามารถทำได้โดยทั่วไปจาก userland ดังที่อธิบายไว้ที่: พื้นที่ผู้ใช้กับพื้นที่เคอร์เนลแตกต่างกันอย่างไร มี แต่ข้อยกเว้นบางประการ: https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space
เคอร์เนลเสนอ APIs ระดับสูงกว่าเพื่อให้การโต้ตอบกับฮาร์ดแวร์ง่ายและสะดวกยิ่งขึ้น:
request_irq
เพื่อจัดการขัดจังหวะ
ioreadX
และการแมปหน่วยความจำ IO
- อินเตอร์เฟสระดับสูงขึ้นสำหรับโปรโตคอลยอดนิยมเช่น PCI และ USB