ISAG's Blog --AYBABTU

Monday, September 20, 2004

ดีไวซ์ไดรเวอร์ จาก 2.4 ถึง 2.6 : ตอนที่ 1 "Hello World\n"

จาก Linux Kernel 2.4 ถึง 2.6 มีการเปลี่ยนแปลงหลายอย่าง ทั้ง Kernel, System Calls รวมไปถึง Device Driver และการจัดการต่างๆ เอกสารชุดนี้จะอธิบายวิธีการแปลงดีไวซ์ไดรเวอร์จากเคอร์เนลเก่า (2.4) ไปยังเคอร์เนลใหม่ (2.6) เราจะสันนิษฐานว่าผู้อ่านมีความคุ้นเคยกับการเขียนดีไวซ์ไดรเวอร์อยู่บ้างแล้วระดับนึง..


โปรแกรมแรกของหลายๆคนคงหนีไม่พ้นโปรแกรม Hello World ใครๆก็ใช้โปรแกรมนี้เป็นแบบฝึกหัดแรก เราก็จะถือเก๋เริ่มด้วยโปรแกรม สวัสดีโลก เหมือนชาวโลกเค้าบ้าง จะเขียนกันแบบ kernel loadable module (อีกแบบก็ built-in คงรู้ความแตกต่างกันอยู่แล้ว)
มาดูโค้ดดีไวซ์ไดร์เวอร์สำหรับ kernel 2.4 กันก่อน:

  #define MODULE
  #include <linux/module.h>
  #include <linux/kernel.h>

  int init_module(void)
  {
      printk(KERN_INFO "Hello World\n");
      return 0;
  }

  void cleanup_module(void)
  {
      printk(KERN_INFO "Goodbye cruel world\n");
  }
โมดุลสวัสดีโลกง่ายๆนี้ อาจจะดูธรรมดา แต่จากรุ่นหนึ่งสู่รุ่นหนึ่ง จากยุคของ ๒.๔ ถึง ๒.๖ เราต้องแปลงโฉมโมดุลนี้ซะใหม่ เปลี่ยนกันตั้งแต่บรรทัดแรกเลย
    #define MODULE
ไม่จำเป็นอีกแล้วสำหรับมาโคร MODULE ตัวนี้ เพราะใน ๒.๖ นั้น ใช้ระบบการ build kernel/module แบบใหม่ และมาโครนี้จะถูก define แล้วโดยอัติโนมัติ (เรื่อง ระบบ build kernel จะพูดถึงกันอีกที)

ใน 2.4 เราใช้การประกาศคู่ฟังก์ชั่น init_module/cleanup_module แต่ใน 2.6 จะใช้การประกาศฟังก์ชั่นผ่าน module_init/module_exit ถึงตอนนี้ก็ยังอาจจะใช้คู่เดิมได้อยู่ แต่เราแนะนำให้เปลี่ยนชื่อใหม่แล้วประกาศผ่านฟังก์ชั่นชุดใหม่จะดีกว่า อ่อ เกือบลืม ฟังก์ชั่น module_init กับ module_exit ประกาศอยู่ใน <linux/init.h> ถ้าจะใช้ก็ต้อง include ด้วยเน้อ
เปลี่ยน ๒ สามจุด ตอนนี้หน้าตาของโปรแกรมสวัสดีโลกของเราก็เป็นแบบนี้:

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

    static int hello_init(void)
    {
        printk(KERN_ALERT "Hello World\n");
        return 0;
    }

    static void hello_exit(void)
    {
        printk(KERN_ALERT "Goodbye cruel world\n");
    }

    module_init(hello_init);
    module_exit(hello_exit);

โมดุลของเราตอนนี้ก็พร้อมจะถูก compile แล้ว แต่เอาไว้ว่ากันต่อคราวหน้าดีกว่า.. อ่อ โมดุลสวัสดีโลกของเราตอนนี้ ถ้าถูกโหลดเข้าไปใน Kernel เรานอกจาก "Hello World\n" แล้ว ยังจะได้ message นี้ด้วย

    hello: module license 'unspecified' taints kernel.
ซึ่งจะว่าไปก็ไม่ซีเรียสอะไรมาก แค่บ่นๆว่าทำไมเอาโมดุลไลเซนส์น่าเกลียดมาทำให้ kernel เปรอะเปรื้อน (แปลแล้วน่าเกลียดแฮะ) ถ้าจะไม่ให้มีเมสเซสนี้ก็แค่ประกาศ
    MODULE_LICENSE("Dual BSD/GPL");
เรื่อง module license ก็ไม่ใช่เรื่องใหม่อะไร มีมานานแล้วแต่บางครั้งก็หลงลืมไม่ได้ใส่กัน มาตอนนี้แนะนำให้ใส่กันได้แล้ว และการประกาศไลเซนส์แบบนี้ยังจะช่วยให้เราสามารถเข้าไปเรียกใช้งาน GPL-only symbols ได้ด้วย (มีอะไรบ้างอย่าถาม แปลมา)



ปล. เนื้อหาและความรู้จาก

0 Comments:

Post a Comment

<< Home