dr a sahu dept of comp sc & engg. iit guwahati. kernel module writing/registering to /proc fs...

34
Introduction to LDD (Reading CMOS Clock & Type of DD) Dr A Sahu Dept of Comp Sc & Engg. IIT Guwahati

Upload: abigale-lamper

Post on 16-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Introduction to LDD(Reading CMOS Clock & Type of DD)

Dr A SahuDept of Comp Sc & Engg.

IIT Guwahati

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

Overall Architecture (cont.)

• Operation Modes– polling– interrupt– DMA

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

• Export Interface• Data Flow in read/write

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

Thanks