ubuntu下使用qemu模擬ARM(六)------驅動程序

驅動程序分爲在ubuntu上運行和在ARM開發板上運行兩種,我們分別來進行測試

1.源碼

empty#include 
#include 


static int hello_init(void)
{
printk(KERN_EMERG "Enter Hello abc World!\n");
return 0;
}

static void hello_exit(void)
{
printk(KERN_EMERG "Exit hello world!\n");

}

module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("RFIDUNION");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("A simple driver");
MODULE_ALIAS("a simple test module");
	empty


2.電腦上的Makefile

ifneq ($(KERNELRELEASE),)
module-objs := helloworld.o
obj-m   := helloworld.o
else
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)
modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
 
clean:
	rm -rf *.o *~core.depend.*.cmd *.ko *.mod.c.tmp versions
 

KERNELRELEASE 內核頂層目錄Makefile的一個變量。
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
內核源碼樹目錄。
 
該Makefile 共讀取兩次,在輸入Makefile時,$(KERNELDIR) 第一次讀取KERNELRELEASE並沒有被定義,然後就開始讀取內核源碼的目錄,開始定義KERNELRELEASE,然後到當前模塊的目錄裏面,M=$(PWD) 進入該Makefile時KERNELRELEAS已經被定義了,讀取要編譯的模塊,然後再返回到modules
編譯完成,產生.KO文件



3.ARM開發板上的Makefile

ifneq ($(KERNELRELEASE),)
 
obj-m := helloworld.o
 
else
KDIR := /qemu_arm/linux-kernel/linux-3.16.39/
all:
	make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
clean:
	rm -f *.ko *.o *.mod.o *.mod.c *.symvers
 
endif

KDIR := /qemu_arm/linux-kernel/linux-3.16.39/
KDIR 指定開發板內核所在目錄。
CROSS_COMPILE=arm-none-linux-gnueabi- 指定編譯器

4.Makefile注意事項

Makefile的拼寫不能出錯,不是makefile,Makefile用要用Tab鍵

常見的錯誤:

提示:missing separator 在這一行要用Tab鍵開頭


5.在電腦上測試驅動

將源碼和Makefile兩個文件放在同一個目錄中,然後用make命令編譯(注意此處的Makefile是用第步中的Makefile)

book@book-virtual-machine:/qemu_arm/driver$ make
make -C /lib/modules/4.8.0-34-generic/build M=/qemu_arm/driver modules
make[1]: Entering directory '/usr/src/linux-headers-4.8.0-34-generic'
  CC [M]  /qemu_arm/driver/helloworld.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /qemu_arm/driver/helloworld.mod.o
  LD [M]  /qemu_arm/driver/helloworld.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.8.0-34-generic'
book@book-virtual-machine:/qemu_arm/driver$ 

編譯完成後用file命令查看下是否是在PC機上運行的模塊,不要和ARM開發板上運行的搞混了。

book@book-virtual-machine:/qemu_arm/driver$ file helloworld.ko 
helloworld.ko: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), BuildID[sha1]=53c0e5e95e8d1c4683f92a7da49c23a5c4d205a8, not stripped
book@book-virtual-machine:/qemu_arm/driver$ 
看到80386即是在電腦上使用。


加載模塊

卸載模塊

注意在控制檯中無法開到printk打印的信息,原因不知。

可以用下面的命令來查看

dmesg | tail -8

6.在Qemu上模擬ARM開發板測試

將源碼和Makefile兩個文件放在同一個目錄中,然後用make命令編譯(注意此處的Makefile是用第步中的Makefile)

book@book-virtual-machine:/qemu_arm/driver$ make
make -C /qemu_arm/linux-kernel/linux-3.16.39/ M=/qemu_arm/driver modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
make[1]: Entering directory '/qemu_arm/linux-kernel/linux-3.16.39'
  CC [M]  /qemu_arm/driver/helloworld.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /qemu_arm/driver/helloworld.mod.o
  LD [M]  /qemu_arm/driver/helloworld.ko
make[1]: Leaving directory '/qemu_arm/linux-kernel/linux-3.16.39'
book@book-virtual-machine:/qemu_arm/driver$ 

編譯完成後用file命令查看下是否是在ARM開發板上運行的模塊,不要和PC機上運行的搞混了。


book@book-virtual-machine:/qemu_arm/driver$ file helloworld.ko 
helloworld.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=a8f903d9a908203d02cbdac6b23a9d258c21e783, not stripped
book@book-virtual-machine:/qemu_arm/driver$ 



看到ARM即是用在開發板上的。

將編譯好的helloworld.ko文件拷到根文件系統中,然後用Qemu模擬運行,

qemu-system-arm -M vexpress-a9 -m 512M -kernel /qemu_arm/linux-kernel/linux-3.16.39/arch/arm/boot/zImage -nographic -append "root=/dev/mmcblk0  console=ttyAMA0" -sd /qemu_arm/root_system/a9rootfs.ext3
啓動完成後在加載模塊顯示如下:


/ # insmod helloworld.ko 
Enter Hello  World!
/ # 


參考文章:
http://blog.chinaunix.net/uid-24219701-id-3035689.html   簡單的驅動makefile解析 





發佈了21 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章