dr a sahu dept of comp sc & engg. iit guwahati. kernel module writing/registering to /proc fs...
TRANSCRIPT
Outline• 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
Advance Peripheral interfacing• Kernel and Device driver• Device Driver Types• CMOS• Reading CMOS Clock and printing at /proc
Linux Kernel Modules
application
standard“runtime”libraries
callret
user space kernel space
Operating Systemkernel
syscall
sysret
module
Linux allows us to write our own installable kernel modulesand add them to a running system
callret
Kernel module written in C#include <linux/module.h> // 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);
Creating our own ‘/proc’ files
• 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
The ‘get_info()’ callback
• 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
The ‘sprintf()’ function
• 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, <arguments> );
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:
Register/unregister
• 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
Reading CMOS Clock entry#include <linux/module.h> // for init_module()#include <linux/proc_fs.h> // for
create_proc_info_entry()#include <asm/io.h> // 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" };
Ten clock/calendar bytesCurrent 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..59
Range is 0..59
Range is 0..59
Range is 0..23 or 1..12
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
Reading CMOS Clock entryint 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-numberreturn len;
}
Reading CMOS Clock entry: get_infoint 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 entriesfor (i = 0; i < 10; i++) {
outb( i, 0x70 ); cmos[i] = inb( 0x71 ); }………………….. Here’s “C” code to read the N-th location:{
int datum; // storage for a CMOS data-valueoutb( N, 0x70 ); // select cell number N for accessdatum = inb( 0x71 ); // input value from selected location
}
Reading CMOS Clock entrystatic int __init my_init( void ){ printk( "<1>\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( "<1>Removing \'%s\' module\n",
modname );}module_init( my_init );module_exit( my_exit );MODULE_LICENSE("GPL");
Device Driver• 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
Overall Architecture• VFS (Virtual File System)• Driver Types– Basic:• Character (ADC, Line printer)• Block (SCSI DISK)• Network
– Special• Stream• Terminal
Overall Architecture (cont.)
System Call Interface
VFS
File System
Buffer Cache
BlockDevice Driver
CharacterDevice Driver
NetworkDevice Driver
NetworkProtocol
Socket
Hardware
Loadable Module Entry Points
• 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().
Character Driver
• Device Properties– can’t be randomly accessed– can’t be buffered– usually are slow devices
• Export Interface– file_operations
• Data Flow in read/write
Character Device Drivers• 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.
Character Driver FunctionsFunction MeaningsLseek to change the current read/write position in a fileRead to retrieve data from the deviceWrite Sends data to the devicReaddir NULL for device files; reading dirs & only useful to FS. Poll back end of two system calls, poll and select, used to inquire a
device is readable or writable or in some special stateIoctl to issue device-specific commandsMmap to request a mapping of device mem to a process's address spaceOpen first operation performed on the device fileFlush ..Lock ..Release ..Fsync ..Fasync ..
Block Driver • 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
Block Driver
• 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
Block Driver (cont.)Processes
Read/Write System Call
Buffer Cache
Invoke Request Function
Check buffer upto date
Done
CallScheduler
Character and Block Driver Entry Points• 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.
Character and Block Driver Entry Points• 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.
STREAMS Drivers
• 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
Auto configuration Entry Points
• 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
Network Driver (cont.)
User Application
Berkley Socket API
INET Socket
TCP UDP
IP ARP ICMP
Network Device Driver
Network Device
Transmit Data: Xmit
Receive DataInt. Handler
Support Functions
• 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()
Lab Excersize
• 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