มาลองสร้าง Kernel Module สำหรับ Embedded Linux กัน

Embedded Linux คือ?

บนระบบฝังตัว (Embedded System) นั้นมีส่วนประกอบใหญ่ๆ อยู่ 2 ส่วน คือ ฮาร์ดแวร์และซอฟต์แวร์ โดยในส่วนของซอฟต์แวร์นั้นก็จะมีระบบปฏิบัติการ (Operating System: OS) ที่เหมือนเป็นตัวกลางระหว่างฮาร์ดแวร์และผู้ใช้งาน โดยระบบปฏิบัติการนั้นจะแตกต่างกันไปตามความสามารถของฮาร์ดแวร์นั่นเอง

Embedded Linux เป็นระบบปฏิบัติการแบบหนึ่งที่นิยมใช้ใน Embedded System ที่ออกแบบมาเพื่อทำงานบนอุปกรณ์ฮาร์ดแวร์ที่มีข้อจำกัดในเรื่องของทรัพยากร ทำให้ส่วนการทำงานบางส่วนภายใน Embedded Linux จะหายไปเมื่อเทียบกับ Linux OS ที่ใช้งานบนคอมพิวเตอร์หรือที่ระบบที่มีส่วนการประมวลผลขนาดใหญ่ เช่น C library เป็นต้น  ทำให้เมื่อต้องการสร้างโปรแกรมหรือ Kernel Module นั้นก็ต้องทำการคอมไพล์แบบ cross-compile เช่นเดียวกับระบบปฏิบัติการอื่นๆ ที่ใช้ใน Embedded System

Components of an Embedded Linux System 
https://www.windriver.com/solutions/learning/embedded-linux

Kernel Module คืออะไร

Loadable Kernel Module หรือมักจะถูกเรียกสั้นๆ ว่า Kernel Module หรือบางทีก็ถูกเรียกว่า Module เฉยๆ ทำหน้าที่เหมือนเป็น driver ที่สามารถควบคุมการทำงานส่วนต่างๆ ทั้งในส่วนของฮาร์ดแวร์ รวมถึง file system ที่อยู่ในระบบปฏิบัติการได้ โดย Kernel Module สามารถจำแนกประเภทตามการทำงานได้ออกเป็น 3 ชนิดย่อยๆ ได้แก่

  1. device drivers ทำหน้าที่เหมือนเป็นตัวกลางระหว่าง User space (ซึ่งอยู่ใน Application ในรูปด้านบน) และส่วนของ Hardware Layer 
  2. file system drivers ทำหน้าที่จัดการไฟล์ต่างๆ ที่อยู่ในระบบปฏิบัติการ Linux
  3. system calls

ข้อดีที่เป็นจุดเด่นของ Loadable Kernel Module เลยก็คือ เราสามารถติดตั้ง หรือนำ Kernel Module ออกไปจากระบบได้โดยอย่างอิสระ โดยไม่จำเป็นต้องไปสร้าง Kernel ตัวใหม่

การทำงานของ Kernel Module คร่าวๆ
ตัว Kernel Module ที่เรา compile ออกมาเสร็จแล้ว พร้อมที่จะติดตั้งลงใน Kernel นั้นจะมีนามสกุล .ko ดังรูป

เมื่อเราต้องการติดตั้ง Kernel Module เราสามารถใช้ command insmod

เช็ค Kernel Module ที่ติดตั้งไปแล้วได้จาก command lsmod

และเมื่อถ้าต้องการลบ Kernel Module ออกเราสามารถใช้ command rmmod

การสร้าง Kernel Module สำหรับ Embedded Linux

อย่างที่ได้เกริ่นไปข้างต้น เนื่องจากบนบอร์ดเป้าหมายของเรามีข้อจำกัดในด้านของทรัพยากรที่ไม่เหมือนกับบน PC ทำให้ต้องทำการ Cross Compile ตัว Kernel Module บน Host เสียก่อน

การเตรียม Environment สำหรับ Host: เตรียม Linux Kernel source

Linux Kernel source สำหรับบอร์ดเป้าหมาย (Target Board) โดยในครั้งนี้ บอร์ดเป้าหมายของเราใช้เป็นบอร์ดที่มี SoC FPGA อยู่ และจะใช้ Linux version 4.19 บนบอร์ดเป้าหมาย โดยสามารถค้นหา Linux Kernel Source สำหรับ SoC FPGA Version ต่างๆ ได้ที่ https://github.com/altera-opensource/linux-socfpga

โดยหน้าตาภายใน Kernel Source จะมีโครงสร้างตามในรูป

การเตรียม Source Code สำหรับ compile Kernel Module

Function init_module
สำหรับ function init_module นั้น จะถูกเรียกใช้เมื่อมีการติดตั้ง Module (ใช้ insmod command) ตามตัวอย่างด้านล่าง ซึ่งจะเห็นว่า เมื่อติดตั้ง Module นั้นมีข้อความ “Hello world.” ออกมา นั่นเอง

Function cleanup_module
สำหรับ function cleanup_module นั้น จะถูกเรียกใช้เมื่อถอนการติดตั้ง Module (ใช้ rmmod command) ตามตัวอย่างด้านล่าง ซึ่งจะเห็นว่า เมื่อนำ Module ออกจะมีข้อความ “Goodbye world.” ออกมา

วิธีการ Compile Kernel Module แบบ Cross-Compile

  1. เตรียม Source Code ตามหัวข้อ การเตรียม Source Code สำหรับ compile Kernel Module
  2. เตรียม Makefile สำหรับเนื้อหาใน Makefile นั้นจะเป็นการเพิ่ม Object ของ Kernel Source Code เข้าไปสำหรับ compile Kernel Module
  1. Command สำหรับ compile Kernel Module: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C </linux/path> M=$PWD modules

เมื่อ Compile เสร็จแล้ว จะมีไฟล์สำหรับติดตั้ง Kernel Module (.ko) ออกมา ดังรูป

วิธีการติดตั้ง Kernel Module

การส่งไฟล์ไปยังบอร์ดเป้าหมายมีอยู่หลายวิธีด้วยกัน แต่ในวันนี้จะนำเสนอวิธีที่ง่ายที่สุดและเหมาะสำหรับบอร์ดเป้าหมายที่สามารถเชื่อมต่อ Internet ได้ (สามารถทำได้ทั้งผ่าน Ethernet LAN Cable หรือ WiFi) นั่นก็คือ scp command ค่ะ

scp เป็น command สำหรับคัดลอกไฟล์จากอีกเครื่องหนึ่งไปยังอีกเครื่องหนึ่งที่อยู่ภายในเครือข่ายเดียวกัน โดยวิธีใช้มีดังนี้

  1. เช็ค ip address ของเครื่องเป้าหมายที่เราจะทำการส่งไฟล์โดยใช้  ifconfig command
  1. ทดลองส่ง ping command จากเครื่อง host (เครื่องที่คอมไพล์ Kernel Module) ไปยังเครื่องเป้าหมายว่าอยู่ในเครือข่ายเดียวกันจริงหรือไม่
  1. เมื่อเช็คเรียบร้อยแล้วจึงทำการส่งไฟล์ผ่าน scp command
  1. เมื่อเช็คบนบอร์ดเป้าหมายจะเห็นว่า Kernel Module ส่งมาที่บอร์ดเรียบร้อยแล้ว
  1. ลองติดตั้ง Kernel Module โดยใช้ insmod