Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 3 Module Programming and Device Driver (Homework#1 included) Kyu Ho Park Sept. 15, 2015.

Similar presentations


Presentation on theme: "Lecture 3 Module Programming and Device Driver (Homework#1 included) Kyu Ho Park Sept. 15, 2015."— Presentation transcript:

1 Lecture 3 Module Programming and Device Driver (Homework#1 included) Kyu Ho Park Sept. 15, 2015

2 Why module programming?  ‘modules’: relocatable objects that can be loaded or removed dynamically into or from the kernel.  Most of the system functions such as file systems, device drivers, communication protocol can be implemented by modules in Linux!!!  To add or modify some functions of the Kernel, no need to recompile the whole kernel.

3 Monolithic Kernel and Micro kernel  Monolithic kernel: All functions are provided by a single kernel space ->Linux  Micro kernel: Kernel functions are minimized and the other functions are implemented in user space  Mach, VxWorks, Window NT.

4 A simple module program Ref: The Linux Kernel Module Programming Guide, Peter Jay Salzman et al.

5 Module ‘Makefile’ Line1: module name to be created. Line3: uname –r -> current kernel version, kernel directory for this module. Line4: current module programming directory

6 insmod-dmesg-rmmod #insmod simpleModule.ko #dmesg #rmmod simpleModule.ko #dmesg

7 Module utility  insmod, rmmod  lsmod - program to show the status of modules  depmod - program to generate modules.dep and map files.  modprobe – program to add and remove modules from the kernel

8 Kernel 2.4 and 2.6 2.4_header_file2.6_header_file #include MODULE#include #include <linux/module.h>#include <linux/kernel.h> 2.4_module_functions2.6_module_functions int init_module(void);module_init(xxx_init); void cleanup_module(void);module_exit(xxx_exit);

9 Passing parameters charp == char *

10 Module_param( ) module_param(para_name, para_type, attribute) Para_type: short, ushort, int, uint, long, ulong, charp, bool, invbool, intarray

11 printk( )  Typical usage: printk(KERN_INFO “message\n”);  loglevel  Remark: the execution time of printk( ) is very long!!!

12 Lecture for Homework 1 (Developing Device Driver) CoreLab.

13 Introduction to Device Driver  What is Device Driver?

14 Introduction to Device Driver  What is Device Driver? Software Hardware

15 User Level Hardware Level Kernel Level

16 Device files -File Types in Linux: Regular Files,Directory, Character Device Files,Block Device File,Link,Pipe, Socket -Device Files(Special Files) Characer Devices Block Devices

17 struct file_opertions The operations users can do on Linux file system are defined at the

18 Device Driver Device driver is a program to access devices through functions defined in file_operations.

19 Major and Minor Number Major number  Each device driver is identified by a unique major number. This number is the index into an array that contains the information about the driver (the device_struct) Minor number  This uniquely identifies a particular instance of a device. For example, a system may have multiple IDE hard disks each would have a major number of 3, but a different minor number.

20 ls –al (-,d,c,l,p,s,b) Major Number Minor Number

21 ls -al - (regular file)

22 register_chrdev( ), unregister_chrdev_region( )

23 register_chrdev, unregister_chrdev and register_chrdev_region,alloc_chrdev_region, unregister_chedev_region -The old way to regiater a char device driver: int register_chrdev(unsigned int major, const char *name, struct file_operations *fops); int unregister_chrdev(unsigned int major, const char *name);

24 -int register_chrdev_region(dev_t first, unsigned int count, char *name); /* If the device major number is known */ -int alloc_chrdev_region(dev_t *dev, unsigned int minor, unsigned int count, char *name)l -void unregister_chrdev_region(dev_t first, unsigned int count);

25 cdev /usr/src/linux/include/linux/cdev.h struct cdev { struct kobjects kobj; struct module *owner; struct file_operations *ops; dev_t dev; unsigned int count; };

26 Functions for character devices #include struct cdev *cdev_alloc(void); void cdev_init(struct cdev +p, struct file_operations *fop); int cdev_add(struct cdev *p, dev_t first, unsigned count); void cdev_del(struct cdev *p);

27

28 - To obtain a standalone cdev structure at at runtime; struct cdev *my_cdev= cdev_alloc( ); dummy_cdev->ops - &my_fops; - To embed the cdev structure within a device specific structure; void cdev_init(struct cdev *cdev, struct file_operations *fops); -Finally to inform the kernel; int cdev_add(struct cdev *dev, dev_t first_dev_num,unsigned int count);

29 fops -Initialization of file operations struct file_operations fops = {.open = dummy_open,.release= dummy_close,.read= dummy_read,.write= dummy_write, };

30 dummy_driver.c

31 #dmesg after running an application program

32 Device Driver Internel  Basically, it is usually generated by C code.  In other word, it can be simple as much as ‘hello world’ in C programming.  You can freely imagine your device driver structure.  Even though it is not linked with real HW, it works.  Closely related with kernel. (use of system calls)

33 Device Drivers  Character Device  Bypass Buffer Cache  Serialized Data  User receives Row Data of the device  Ex. Terminal, video card, sound card…  Block Device  Through Buffer Cache  Random Accessible  Ex. HDD, CDROM …  Network Device  Ex. Ethernet

34 How to access the Device Driver  How can we access to the device driver?  Through Device File (special file)  Char device and Block device have this file.  ‘mknod /dev/dummy c 250 0’ – creation of the device file.  Real Usage  fd = open("/ dev/dummy ", O_RDWR);  write(fd,buf,1);  read(fd,buf,1);  close(fd);

35 Implementation of Device Driver  Specification of Dummy Device Driver  No linkage with Real HW.  Using printk, only printout the name of the device driver operation called by a user.  Implementations  Module init and cleanup  4 Operations in Dummy Device Driver  dummy_read : read system call  dummy_write : write system call  dummy_open : open system call  dummy_release : close system call

36 Implementation of Device Driver  How can we implement it?  Initialization (in init_module function)  Mapping a device file with the device driver  Registration of a Char Device : offered by OS  Needs Major Number, Name, and File_operation Structure of the device driver. int register_chrdev( unsigned int major, const * name, struct file_operations * fops); struct file_operations dummy_fops = {.open = dummy_open,// open.read = dummy_read, // read.write = dummy_write, // write.release = dummy_release, // release }; Mapping system calls with the internal functions of the device drivers

37 How can we implement it? dummy_driver.c #include #define DUMMY_MAJOR_NUMBER 250 static struct file_operations dummy_fops= { open: dummy_open, read: dummy_read, write: dummy_write, release: dummy_release, }; char devicename[20]; char value=' '; static struct cdev my_cdev; static int __init dummy_init(void) { dev_t dev=MKDEV(DUMMY_MAJOR_NUMBER,0); printk("Dummy Driver: init module\n"); strcpy(devicename, "Dummy_Driver"); register_chrdev(DUMMY_MAJOR_NUMBER, devicename, &dummy_fops); cdev_init(&my_cdev, &dummy_fops); cdev_add(&my_cdev,dev,128); return 0; } static void __exit dummy_exit(void) { printk("Dummy Driver : Clean Up Module\n"); cdev_del(&my_cdev); unregister_chrdev_region(MKDEV(DUMMY_MAJOR_NUMBER,0),128); }

38 ssize_t dummy_read(struct file *file, char *buffer, size_t length, loff_t *offset) { printk("Dummy Driver : Here is REad Call[%x]\n", value); if (copy_to_user(buffer, &value, sizeof(char))) return -EFAULT; return 0; } ssize_t dummy_write(struct file *file, const char *buffer, size_t length, loff_t *offset) { char vaule; if( copy_from_user(&value, buffer, sizeof(char))) return -EFAULT; printk("Dummy Driver: Here is Write Call [%x]\n", value); return 0; } int dummy_open(struct inode *inode, struct file *file) { printk("Dummy Driver : Open Call\n"); return 0; } int dummy_release(struct inode *inode, struct file *file) { printk("Dummy Driver : Release Call\n"); return 0; } module_init(dummy_init); module_exit(dummy_exit); MODULE_AUTHOR("KHPARK"); MODULE_DESCRIPTION("Dummy_Driver"); MODULE_LICENSE("GPL"); Continued from the previous page

39 How to build? Makefile

40 Module Instructions  mknod /dev/DUMMY_DEVICE c 250 0  insmod dummy_driver.ko  dmesg  rmmod dummy_driver.ko

41 test.c  Test: #include int main(void) { char buf[20]; int fd = open("/dev/DUMMY_DEVICE", O_RDWR); if(fd <= 0) return -1; buf[0] = 0x07; write(fd, buf, 1); read(fd, buf, 1); printf("data from the device : %x\n", buf[0]); close(fd); return 0; } #dmesg //after the execution of test program.

42 Problem1  1. device driver with FIFO queue  FIFO Queue structure In (write) & Creation of Entry in the Queue Out (read) & Deletion of Entry APP1 APP2 Check the written data sequence and the read data sequence are same or not.

43 Problem2  2. make your own ‘flush function’ that makes queue empty. APP1 APP2 APP3 Flush OP Thrash all the entries in the queue

44 Environment & Policies  Environment  Same as the Project1  Policies  Same as the Project1  Due : Sept. 24, 11:59 PM  Submission :  (hard copy) : jhchoi@core.kaist.ac.kr  (soft copy) : jhchoi@core.kaist.ac.kr

45 Appendix  Queue Example

46 Appendix  Queue Example #define QUEUE_SIZE 1024 typedef { int head, tail; int item[QUEUE_SIZE]; } CQ_t; static inline void InitCQ(CQ_t *q) { q->head = q->tail = 0; } static inline int IsFull(CQ_t *q) { return ( (q->head+1)%QUEUE_SIZE == q->tail ); } static inline int IsEmpty(CQ_t *q) { return (q->head == q->tail); } #define QUEUE_SIZE 1024 typedef { int head, tail; int item[QUEUE_SIZE]; } CQ_t; static inline void InitCQ(CQ_t *q) { q->head = q->tail = 0; } static inline int IsFull(CQ_t *q) { return ( (q->head+1)%QUEUE_SIZE == q->tail ); } static inline int IsEmpty(CQ_t *q) { return (q->head == q->tail); } int Queue(CQ_t *q, int value) { if (q==NULL) return -1; if (IsFull(q)) return -2; q->item[q->head] = value; q->head = (q->head + 1)%QUEUE_SIZE; return 0; } int Dequeue(CQ_t *q, int *value) { if (q==NULL || value==NULL) return -1; if (IsEmpty(q)) return -2; *value = q->item[q->tail]; q->tail = (q->tail + 1)%QUEUE_SIZE; return 0; } int Queue(CQ_t *q, int value) { if (q==NULL) return -1; if (IsFull(q)) return -2; q->item[q->head] = value; q->head = (q->head + 1)%QUEUE_SIZE; return 0; } int Dequeue(CQ_t *q, int *value) { if (q==NULL || value==NULL) return -1; if (IsEmpty(q)) return -2; *value = q->item[q->tail]; q->tail = (q->tail + 1)%QUEUE_SIZE; return 0; }

47


Download ppt "Lecture 3 Module Programming and Device Driver (Homework#1 included) Kyu Ho Park Sept. 15, 2015."

Similar presentations


Ads by Google