若您覺得文章寫得不錯,請點選文章上的廣告,來支持小編,謝謝。
所使用的作業系統為Ubuntu 14.04 Desktop
所使用的作業系統為Ubuntu 14.04 Desktop
安裝所需要的函式庫(library)
sudo apt-get install build-essential linux-headers-$(uname -r)
用Editor輸入以下內容,檔名為helloKernel.c
/* * helloKernel.c */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> static int __init helloKernel_init(void) { printk(KERN_INFO "Hello kernel.\n"); return 0; } static void __exit helloKernel_exit(void) { printk(KERN_INFO "Goodbye kernel.\n"); } module_init(helloKernel_init); module_exit(helloKernel_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Holan Liao"); MODULE_DESCRIPTION("Kernel Module Sample"); MODULE_VERSION("1.0");
Makefile內容如下:
obj-m += helloKernel.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
記得將這兩個檔案(helloKernel.c、Makefile)放置同一個資料夾底下:
接著下make:
產生*.ko檔
下完以下指令就可看到有訊息輸出到Kernel log裡了。
sudo insmod helloKernel.ko
sudo rmmod helloKernel
demsg | tail
可看到有訊息輸出到Kernel log裡了。
Char Device Driver
/* * helloCharDev.c */ #include <linux/init.h> #include <linux/module.h> #include <linux/device.h> #include <linux/kernel.h> #include <linux/fs.h> #include <asm/uaccess.h> #define DEVICE_NAME "helloCharDev" #define CLASS_NAME "holan" static int majorNum; static char msg[256] = {0}; static short msgLen; static int numberOpens = 0; static struct class* helloCharClass = NULL; static struct device* helloCharDev = NULL; static int drvDev_open(struct inode *, struct file *); static int drvDev_release(struct inode *, struct file *); static ssize_t drvDev_read(struct file *, char *, size_t, loff_t *); static ssize_t drvDev_write(struct file *, const char *, size_t, loff_t *); static struct file_operations fops = { .open = drvDev_open, .read = drvDev_read, .write = drvDev_write, .release = drvDev_release, }; static int __init hellCharDev_init(void){ printk(KERN_INFO "helloCharDev: Initializing the helloCharDev.\n"); majorNum = register_chrdev(0, DEVICE_NAME, &fops); if (majorNum<0){ printk(KERN_ALERT "helloCharDev couldn't register a major number\n"); return majorNum; } printk(KERN_INFO "helloCharDev: registered correctly with major number %d\n", majorNum); helloCharClass = class_create(THIS_MODULE, CLASS_NAME); if (IS_ERR(helloCharClass)){ unregister_chrdev(majorNum, DEVICE_NAME); printk(KERN_ALERT "couldn't register\n"); return PTR_ERR(helloCharClass); } printk(KERN_INFO "helloCharDev: registered correctly\n"); helloCharDev = device_create(helloCharClass, NULL, MKDEV(majorNum, 0), NULL, DEVICE_NAME); if (IS_ERR(helloCharDev)){ class_destroy(helloCharClass); unregister_chrdev(majorNum, DEVICE_NAME); printk(KERN_ALERT "couldn't create the device\n"); return PTR_ERR(helloCharDev); } printk(KERN_INFO "helloCharDev: created correctly\n"); return 0; } static void __exit hellCharDev_exit(void){ device_destroy(helloCharClass, MKDEV(majorNum, 0)); class_unregister(helloCharClass); class_destroy(helloCharClass); unregister_chrdev(majorNum, DEVICE_NAME); printk(KERN_INFO "helloCharDev: Goodbye!\n"); } static int drvDev_open(struct inode *inodep, struct file *filep){ numberOpens++; printk(KERN_INFO "helloCharDev: Device has been opened %d time(s)\n", numberOpens); return 0; } static ssize_t drvDev_read(struct file *filep, char *buffer, size_t len, loff_t *offset){ int error_count = 0; error_count = copy_to_user(buffer, msg, msgLen); if (error_count==0){ printk(KERN_INFO "helloCharDev: Sent %d characters to the user\n", msgLen); return (msgLen=0); } else { printk(KERN_INFO "helloCharDev: couldn't send %d characters to the user\n", error_count); return -EFAULT; } } static ssize_t drvDev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){ sprintf(msg, "%s(%d letters)", buffer, len); msgLen = strlen(msg); printk(KERN_INFO "helloCharDev: Received %d characters from the user\n", len); return len; } static int drvDev_release(struct inode *inodep, struct file *filep){ printk(KERN_INFO "helloCharDev: Device successfully closed\n"); return 0; } module_init(hellCharDev_init); module_exit(hellCharDev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Holan Liao"); MODULE_DESCRIPTION("Char driver sample"); MODULE_VERSION("1.0");
helloCharDev的測試程式:
/* * helloCharDevTest.c : Test program for helloCharDev */ #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<fcntl.h> #include<string.h> #define BUF_LEN 256 static char recv[BUF_LEN]; int main(){ int ret, fd; char msgToSend[BUF_LEN]; printf("Device testing...\n"); fd = open("/dev/helloCharDev", O_RDWR); if (fd < 0){ perror("Couldn't open the device..."); return errno; } printf("Please input a string:\n"); scanf("%[^\n]%*c", msgToSend); printf("Sending msg:[%s]...\n", msgToSend); ret = write(fd, msgToSend, strlen(msgToSend)); if (ret < 0){ perror("Couldn't send msg."); return errno; } printf("Press ENTER to read back...\n"); getchar(); printf("Reading...\n"); ret = read(fd, recv, BUF_LEN); if (ret < 0){ perror("Couldn't read the msg."); return errno; } printf("The msg is: [%s]\n", recv); printf("Bye.\n"); return 0; }
Makefile:
obj-m += helloCharDev.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules $(CC) helloCharDevTest.c -o charDrvTest clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
沒有留言:
張貼留言