ดีไวซ์ไดรเวอร์ จาก 2.4 ถึง 2.6 : ตอนที่ 2 คอมไฟล์โมดุล
ดีไวซ์ไดรเวอร์ ตอนที่ 1 "Hello World\n" ถ้าอ่านแล้ว เรามาเริ่มกันเลยดีกว่า
การคอมไพล์โมดุลสำหรับ Linux Kernel ใน 2.4 นั้นเราอาจจะใช้คอมมานด์ง่ายๆแบบนี้:
$ gcc -D__KERNEL__ -c module.c -o module.oหรือบางคนอาจจะเขียน Makefile เป็นแบบนี้:
module.o: module.c gcc -D__KERNEL__ -c module.c -o module.oแต่ทั่วๆไปที่เห็นจะเป็นแบบนี้:
KERNELDIR = /usr/src/linux CFLAGS = -D__KERNEL__ -DMODULE -I$(KERNELDIR)/include -O all: module.o
ในโลกของความเป็นจริง makefiles จะวุ่นวายกว่านี้เยอะ ลองเข้าไปดูใน kernel source ดูก็ได้ เรียกกันไปเรียกกันมา พันกันยุ่งเหยิงไปหมด แต่เรากำลังพูดกันถึงเฉพาะ makefile สำหรับคอมไพล์โมดุลซึ่งมีการทำงานจริงๆแค่ขั้นเดียว (สำหรับ c code ไฟล์เดียว)
ถ้าทำงานกับ kernel 2.6 ถึงไม่ชอบเขียน makefile ก็ต้องถึงเวลาต้องชอบแล้วล่ะ (ไม่งั้นก็ถึงเวลาต้องทน) เราไม่สามารถเรียก gcc ขึ้นมาคอมไพล์โต้งๆ step เดียวง่ายๆสั้นๆได้เหมือนเมื่อก่อน แล้วถ้าจะคอมไพล์โมดุลเนี่ย เราต้องมี kernel source tree ที่ผ่านการ configured มาแล้ว จะด้วย oldconfig, menuconfig, xconfig หรืออะไรก็แล้วแต่ แต่ต้องทำให้เห็น ส่วนตัวผมใช้ source tree สำหรับ running system นั่นแหละ แล้วใน source tree เนี่ย ยังมี makefiles ชุดนึงที่อธิบายกระบวนการคอมไพล์โมดุล ซึ่งก็แน่นอน เราต้องการมันเช่นกัน เหตุผลสั้นๆที่เราต้องการ(และต้องทำ)อะไรต่อมิอะไรให้วุ่นวายปวดหัวก็เพราะ:
(สามข้อนี้ถ้าอ่านแล้วงง แนะนำให้ไปอ่านภาษาอังกฤษดีกว่า แปลยากจริงๆ แปลอังกฤษเป็นไทย แล้วต้องแปลไทยเป็นไทยอีกรอบ)
สรุปว่ายังไงเราก็ต้องเขียน makefile เพื่อใช้ในการคอมไพล์โมดุล ในเอกสารนี้จะอธิบายสั้นๆ ถ้าชอบแบบยาวๆแนะนำให้ไปตามต่อที่ 2.5.59+ kernel makefile documentation เลย
ตัวอย่างแรก เป็น makefile สำหรับคอมไพล์โมดุลอย่างง่ายที่สุด ใช้สำหรับโมดุลที่มาจาก c source file ไฟล์เดียว
obj-m := module.o
ชื่อ module.o ก็แทนด้วยชื่อไฟล์ของเรานะครับ เช่น xyz.o makefile บรรทัดเดียวนี้จะคอมไพล์ xyz.c ออกมาเป็น xyz.o แล้วเอาไปลิงก์กับ vermagic.o ออกมาเป็น xyz.ko จำไว้นะครับ .ko ไม่ใช่ .o เหมือนเมื่อก่อนแล้ว ไฟล์ .ko นี้แหละที่เราจะเอาไป insmod ยัดเข้าไปใน running kernel ของเรา ถ้าเราคอมไพล์ตรงๆให้ได้ object file .o ออกมาแบบเมื่อก่อน ไฟล์นั้นจะโหลดเข้าไปในเคอร์เนลไม่ได้ (ตอนแรกเราก็มึนๆเหมือนกัน)
แล้วถ้าโมดุล xyz ของเราสร้างจากหลายๆไฟล์เช่นจาก x.c, y.c และ z.c ล่ะ? ถ้าเป็นอย่างนั้นเราต้องการอย่างน้อย ๒ บรรทัดนะครับ หน้าตาของ makefile ก็จะออกมาเป็นแบบนี้
obj-m := xyz.o xyz-objs := x.o y.o z.o
ถ้าไม่มีปัญหาอะไรตอนคอมไพล์(หรือตอนลิงก์) เราจะได้ xyz.ko ซึ่งสร้างมาจากน้ำปลาเอ๊ยซอสโค้ด 3 ไฟล์ดังที่กล่าว
โอเค ตอนนี้เรามี makefile ตัวอย่างง่ายๆแล้ว เราจะสั่งรัน makefile ได้ยังไงน๊อ? นี่เลยครับ รันคำสั่งข้างล่างเลย อ่อ อย่าลืมแก้ path ให้ถูกต้องก่อนนะครับ
make -C /path/to/source SUBDIRS=$PWD modules
คำสั่งนี้จะบอกว่า นี่นาย make อ่าน Makefile จาก /path/to/source นะ แล้ววิ่งกลับมาที่อยู่ปัจจุบันของเรา อ่าน Makefile ของเรา แล้วคอมไพล์มันซะ
แต่แหม จะให้พิมพ์คำสั่ง make ยาวเหยียดอย่างนี้คงไม่ไหว เราเอาพวกอากิวเมนต์ยาวๆยัดเข้าไปใน makefile ดีกว่า เราจะได้ makefile สำหรับสร้างโมดุลสำหรับ running kernel ออกมาหน้าตาแบบนี้
ifneq ($(KERNELRELEASE),) obj-m := xyz.o else KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules endif
แต่สำหรับเรา เราทำงานกับ embedded systems เป็นหลัก เครื่องที่ใช้ทำงานกับเครื่องปลายทาง (target machine) มักเป็นคนละเครื่องกัน makefile ที่เราเริ่มเขียนและใช้มาจนถึงปัจจุบันมีหน้าตาแบบนี้ อ่อ ใน top makefile ของ source tree จะไปเลือกใช้ cross-compiler ที่ถูกต้องเอง กรณีของเราขะใช้ arm-linux-gcc
KDIR := /usr/src/linux-2.6.8.1-altair PWD := $(shell pwd) obj-m := ich.o liebe.o cell.o liebe-objs := u.o me.o default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean: rm *.o *.ko *.mod.c
ไม่จำเป็นว่า source tree ต้องอยู่ใน /usrc/src นะครับ ที่ผมไว้ที่นั่นเพราะผมไว้ตรงนั้นมานานแล้ว แล้วก็ติดที่จะพิมพ์ /usr/src ไปแล้วด้วย
ตอนนี้เพื่อนๆคงเขียนและคอมไพล์โมดุลสำหรับ Linux Kernel 2.6.x กันได้แล้ว หวังว่าเพื่อนๆคงสนุกกับเคอร์เนลเวอร์ชั่นใหม่กันนะครับ ถ้าอยากรู้อะไรเกี่ยวกับ Linux Kernel 2.6.x อีกก็เรียกร้องกันมานะครับ จะจัดหาไว้ให้ สวัสดีครับ..
บอมบ์
ปล. เนื้อหาส่วนใหญ่อ้างอิงจาก compiling external modules ใน ชุด ในชุด Porting device drivers to the 2.6 kernel โดย Jonathan Corbet
1 Comments:
ไม่มีคนอ่านเลย
แต่เราไม่สน เอาไว้ทำเป็น mini-Doc ลิงก์ไว้ข้างๆดีกว่า
By bomm, at Thursday, October 21, 2004 1:01:00 AM
Post a Comment
<< Home