Download presentation
Presentation is loading. Please wait.
Published byAbigale Lamper Modified over 9 years ago
1
Dr A Sahu Dept of Comp Sc & Engg. IIT Guwahati
2
Kernel Module Writing/Registering to /proc FS Payload of kernel module Reading CMOS Data – Real Time CMOS Clock Type of devices and drivers – Character – Block – Network/Stream
3
Kernel and Device driver Device Driver Types CMOS Reading CMOS Clock and printing at /proc
4
application standard “runtime” libraries standard “runtime” libraries call ret user spacekernel space Operating System kernel Operating System kernel syscall sysret module Linux allows us to write our own installable kernel modules and add them to a running system call ret
5
#include // for printk() int init( void ){ printk( "\n Kello, everybody! \n\n" ); return 0; } void exit( void ){ printk( "\n Goodbye now... \n\n" ); } MODULE_LICENSE("GPL"); module_init(init); module_exit(exit); #include // for printk() int init( void ){ printk( "\n Kello, everybody! \n\n" ); return 0; } void exit( void ){ printk( "\n Goodbye now... \n\n" ); } MODULE_LICENSE("GPL"); module_init(init); module_exit(exit);
6
We can write code to implement our own ‘pseudo’ files, located in ‘/proc’ directory We do this by adding a ‘payload’ function to a Linux Kernel Module, and by including calls to special kernel-functions within our module- init and our module-exit routines These special kernel-functions serve to ‘register’, and ‘unregister’, our payload
7
When an application-program (like ‘mycat’) tries to read our pseudo-file, the kernel will call our ‘get_info()’ function, passing it four function arguments -- and will expect it to return an integer value: int get_info( char *buf, char **start, off_t off, int count ); pointer to a kernel buffer current file-pointer offset pointer (optional) to module’ own buffer size of space available in the kernel’s buffer function should return the number of bytes it has written into its buffer
8
The kernel provides a function you module can call to print formatted text into a buffer It resembles a standard C library-function: int sprintf( char *dstn, const char *fmt, ); pointer to destination formatting specification string list of the argument-values to format will return the number of characters that were printed to the destination-buffer int len = sprintf( buf, “count = %d \n”, count ); Example:
9
Your module-initialization function should ‘register’ the module’s ‘get_info()’ function: create_proc_info_entry( modname, 0, NULL, get_info ); Your cleanup should do an ‘unregister’: remove_proc_entry( modname, NULL ); the name for your proc file the file-access attributes (0=default) directory where file will reside (NULL=default) function-pointer to your module’s ‘callback’ routine file’s name directory
10
#include // for init_module() #include // for create_proc_info_entry() #include // for inb(), outb() char modname[] = "cmos"; unsigned char cmos[10]; char *day[] = { "", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" }; char *month[] = { "", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; #include // for init_module() #include // for create_proc_info_entry() #include // for inb(), outb() char modname[] = "cmos"; unsigned char cmos[10]; char *day[] = { "", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" }; char *month[] = { "", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
11
Current seconds Alarm seconds Current minutes Alarm minutes Current hours Alarm hours Day-of-the-Week Date of the Month Current Month Current Year 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 Range is 0..59 Range is 0..23 or 1..12 Range is 1..7 (Sunday=7) Range is 1..31 Range is 1..12 (January=1) Range is 0..99
12
int my_get_info( char *buf, char **start, off_t off, int count ) { ……. // show the current time and date len += sprintf( buf+len, "CMOS Real-Time Clock:\ %02X:%02X:%02X on ", mos[4], cmos[2],cmos[0]); // cur h,m,s len += sprintf( buf+len, " %s, ", day[ cmos[6] ] ); // day-name len += sprintf( buf+len, "%02X", cmos[7] ); // day-number // convert 'cmos[ 8 ]' from BCD-format to integer-format month_index = ((cmos[ 8 ] & 0xF0)>>4)*10 + (cmos[ 8 ] & 0x0F); len += sprintf( buf+len, " %s", month[ month_index ] ); // month-name len += sprintf( buf+len, " 20%02X\n ", cmos[9] ); // year-number return len; } int my_get_info( char *buf, char **start, off_t off, int count ) { ……. // show the current time and date len += sprintf( buf+len, "CMOS Real-Time Clock:\ %02X:%02X:%02X on ", mos[4], cmos[2],cmos[0]); // cur h,m,s len += sprintf( buf+len, " %s, ", day[ cmos[6] ] ); // day-name len += sprintf( buf+len, "%02X", cmos[7] ); // day-number // convert 'cmos[ 8 ]' from BCD-format to integer-format month_index = ((cmos[ 8 ] & 0xF0)>>4)*10 + (cmos[ 8 ] & 0x0F); len += sprintf( buf+len, " %s", month[ month_index ] ); // month-name len += sprintf( buf+len, " 20%02X\n ", cmos[9] ); // year-number return len; }
13
int my_get_info( char *buf, char **start, off_t off, int count ) { int i, len = 0; int month_index; // input and store the first ten CMOS entries for (i = 0; i < 10; i++) { outb( i, 0x70 ); cmos[i] = inb( 0x71 ); } ………………….. int my_get_info( char *buf, char **start, off_t off, int count ) { int i, len = 0; int month_index; // input and store the first ten CMOS entries for (i = 0; i < 10; i++) { outb( i, 0x70 ); cmos[i] = inb( 0x71 ); } ………………….. Here’s “C” code to read the N-th location: { intdatum;// storage for a CMOS data-value outb( N, 0x70 );// select cell number N for access datum = inb( 0x71 );// input value from selected location } Here’s “C” code to read the N-th location: { intdatum;// storage for a CMOS data-value outb( N, 0x70 );// select cell number N for access datum = inb( 0x71 );// input value from selected location }
14
static int __init my_init( void ){ printk( " \nInstalling \'%s\' module\n", modname ); create_proc_read_entry( modname, 0, NULL, my_get_info, NULL ); return 0; //SUCCESS } static void __exit my_exit(void ) { remove_proc_entry( modname, NULL ); printk( " Removing \'%s\' module\n", modname ); } module_init( my_init ); module_exit( my_exit ); MODULE_LICENSE("GPL"); static int __init my_init( void ){ printk( " \nInstalling \'%s\' module\n", modname ); create_proc_read_entry( modname, 0, NULL, my_get_info, NULL ); return 0; //SUCCESS } static void __exit my_exit(void ) { remove_proc_entry( modname, NULL ); printk( " Removing \'%s\' module\n", modname ); } module_init( my_init ); module_exit( my_exit ); MODULE_LICENSE("GPL");
15
A device driver is a kernel module responsible for managing low-level I/O operations for a particular hardware device. Block device drivers manage devices with physically addressable storage media, such as disks. All other devices are considered character devices
16
VFS (Virtual File System) Driver Types – Basic: Character (ADC, Line printer) Block (SCSI DISK) Network – Special Stream Terminal
17
System Call Interface VFS File System Buffer Cache Buffer Cache Block Device Driver Block Device Driver Character Device Driver Character Device Driver Network Device Driver Network Device Driver Network Protocol Network Protocol Socket Hardware
18
Operation Modes – polling – interrupt – DMA
19
All drivers are required to implement the loadable module entry points – init () // (load) – finialise () //unload – info () // Gather information of device Drivers should allocate and initialize any global resources in init() and release their resources in finilise().
20
Device Properties – can’t be randomly accessed – can’t be buffered – usually are slow devices Export Interface – file_operations Data Flow in read/write
21
Character device drivers normally perform I/O in a byte stream. Examples of devices using character drivers include tape drives and serial ports. Character device drivers can also provide additional interfaces not present in block drivers, – I/O control (ioctl) commands – memory mapping – device polling.
22
FunctionMeanings Lseekto change the current read/write position in a file Readto retrieve data from the device WriteSends data to the devic ReaddirNULL for device files; reading dirs & only useful to FS. Pollback end of two system calls, poll and select, used to inquire a device is readable or writable or in some special state Ioctlto issue device-specific commands Mmapto request a mapping of device mem to a process's address space Openfirst operation performed on the device file Flush.. Lock.. Release.. Fsync.. Fasync..
23
Block Devices that support a file system are known as block devices. Drivers written for these devices are known as block device drivers. Block device drivers take a file system request, in the form of a buffer structure, – And issue the I/O operations to the disk to transfer the specified block. The main interface to the file system is the strategy routine
24
Device Properties – can be randomly accessed – accessed in units of blocks – to speed up access, buffer cache is used Export Interface – file_operations – request_fn() Data Flow in read/write
25
Processes Read/Write System Call Buffer Cache Invoke Request Function Check buffer upto date Done Call Scheduler Call Scheduler
26
Drivers for character and block devices export a cb_ops structure which defines the driver entry points for block device access and character device access. Both types of drivers are required to support open and close.
27
Block drivers are required to support strategy, while character drivers can choose to implement whatever mix of – read, write, ioctl, mmap, or devmap – These entry points as appropriate for the type of device. Character drivers can also support a polling interface through – ch_poll – as well as asynchronous I/O through aread and awrite.
28
STREAMS is a separate programming model for writing a character driver. Devices that receive data asynchronously (such as terminal and network devices) are suited to a STREAMS implementation. STREAMS device drivers must provide the loading and autoconfiguration support
29
Drivers are required to implement these Entry points for device autoconfiguration. – Attach – Detach, – Getinfo Drivers might need to implement probe if the driver supports devices that are not self identifying, such as SCSI target devices
30
Export Interface Data Flow in read/write
31
User Application Berkley Socket API INET Socket TCP UDP IP ARP ICMP Network Device Driver Network Device Transmit Data: Xmit Receive Data Int. Handler Receive Data Int. Handler
32
I/O ports reservations – request_region() Memory Allocations – kmalloc(), vmalloc(), get_free_page() Interrupt Handler Registration – request_irq() Data Transfer between User/Kernel – memcpy_fromfs()
33
Download mmake.cpp and cmos.c Course Website, tested on Fedora 12 Compile mmake.cpp using ‘make’ Then compile cmos.c using ‘make’ Install ‘cmos.ko’ (and see printk-message) See $cat /proc/cmos
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.