Download presentation
Presentation is loading. Please wait.
Published byDrusilla Ward Modified over 8 years ago
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);
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; }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.