Lập trình device driver trên linux
Mục tiêu khóa học:
1. Mục đích - Tìm hiểu cơ chế lập trình kernel module trên Linux - Minh họa qui trình viết một device driver đơn giản 2. Tiến hành 2.1. Viết kernel module Xây dựng một module đơn giản theo đúng khuôn dạng Bước 1. Viết mã nguồn (File hello_kernel_module.c) #include #include #include static int hello_init(void) { printk(KERN_ALERT "Khoi tao thanh cong\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Ket thuc thanh cong\n"); } module_init(hello_init); module_exit(hello_exit); Bước 2. Viết Makefile cho kernel module để biên dịch (đặt cùng thư mục file mã nguồn) obj-m += hello_kernel_module.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 Bước 3. Biên dịch bằng lệnh make được file hello_kernel_module.ko Bước 4. Cài đặt module vào hệ thống (sử dụng lệnh insmod) insmod hello_kernel_module .ko Gỡ kernel module dùng lệnh rmmod Bước 5. Kiểm tra quá trình cài đặt xem module đã cài đặt thành công hay chưa (Trên Ubuntu, mở System/Log Viewer xem mục kernel log) 2.2. Viết một device driver đơn giản Bước 1: Xây dựng device driver đơn giản theo cơ chế kernel module - Viết mã nguồn (File hello_driver.c) theo đúng khuôn dạng qui định #include #include #include #include static ssize_t hello_read(struct file *filp, char *buffer, size_t length, loff_t *offset); static int Major; //Cấu trúc để đăng ký các hàm qua driver interface được được qui định theo chuẩn static struct file_operations fops={ .owner=THIS_MODULE, .read=hello_read, }; static int hello_init(void) { //Đăng ký thiết bị kiểu character với major
id hệ thống cung cấp Major=register_chrdev(0,"KTMT-Device",&fops); if(Major<0) { printk(KERN_ALERT "Dang ky that bai\n"); } else{ printk(KERN_ALERT "Dang ky thiet bi thanh cong voi MajorID=%d\n",Major); } return 0; } static void hello_exit(void) { //Giải phóng thiết bị đã đăng ký unregister_chrdev(Major,"KTMT-Device"); printk(KERN_ALERT "Thiet bi da bi ngat khoi he thong\n"); } //Hàm read được cung cấp qua driver interface static ssize_t hello_read(struct file *filp, char *buffer, size_t length, loff_t *offset) { return 100; //Hảm read của driver chỉ đơn giản trả về một giá trị } module_init(hello_init); module_exit(hello_exit); Bước 2. Viết Makefile để biên dịch mã nguồn trên, được file hello_driver.ko obj-m += hello_driver.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 Bước 3: Cài đặt device driver theo cơ chế của Kernel module Lệnh: insmod hello_driver.ko Bước 4: Sử dụng lệnh mknod để tạo ra một device file trong thư mục /dev (giả sử đặt tên device file là KTMT0) mknod /dev/KTMT0 c 250 1 (Tạo ra một device file có tên là KTMT0 cho device driver kiểu character có major id là 250) (Xem major id của kernel module hello_driver dùng lệnh cat /proc/devices) Đến đây, chúng ta có một thiết bị tên KTMT0 với driver đã viết (cung cấp hàm read). Bước tiếp theo sẽ viết một ứng dụng để giao tiếp thiết bị này. Bước 5: Viết chương trình để test giao tiếp với driver (hello_driver) #include #include #include #include #include #include #include #include #include #include int main(int argc, char** argv) { int fd; int result,rt; fd = open(argv[1], 0); rt=read(fd,&result,sizeof(result)); printf("\nKet qua nha ve la %d\n",rt); close(fd); return 0; } - Biên dịch và chạy ứng dụng này, quan sát kết quả do hàm read của driver trả về. |