1 of 34

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

Dr A Sahu

Dept of Comp Sc & Engg.

IIT Guwahati

2 of 34

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

3 of 34

Advance Peripheral interfacing

  • Kernel and Device driver
  • Device Driver Types
  • CMOS
  • Reading CMOS Clock and printing at /proc

4 of 34

Linux Kernel Modules

application

standard

“runtime”

libraries

call

ret

user space

kernel space

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 of 34

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);

6 of 34

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

7 of 34

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

8 of 34

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:

9 of 34

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

10 of 34

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" };

11 of 34

Ten clock/calendar bytes

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..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

12 of 34

Reading CMOS Clock entry

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 of 34

Reading CMOS Clock entry: get_info

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:

{

int datum; // storage for a CMOS data-value

outb( N, 0x70 ); // select cell number N for access

datum = inb( 0x71 ); // input value from selected location

}

14 of 34

Reading CMOS Clock entry

static 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");

15 of 34

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

16 of 34

Overall Architecture

  • VFS (Virtual File System)
  • Driver Types
    • Basic:
      • Character (ADC, Line printer)
      • Block (SCSI DISK)
      • Network
    • Special
      • Stream
      • Terminal

17 of 34

Overall Architecture (cont.)

System Call Interface

VFS

File System

Buffer

Cache

Block

Device Driver

Character

Device Driver

Network

Device Driver

Network

Protocol

Socket

Hardware

18 of 34

Overall Architecture (cont.)

  • Operation Modes
    • polling
    • interrupt
    • DMA

19 of 34

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().

20 of 34

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

21 of 34

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.

22 of 34

Character Driver Functions

Function

Meanings

Lseek

to change the current read/write position in a file

Read

to retrieve data from the device

Write

Sends data to the devic

Readdir

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 state

Ioctl

to issue device-specific commands

Mmap

to request a mapping of device mem to a process's address space

Open

first operation performed on the device file

Flush

..

Lock

..

Release

..

Fsync

..

Fasync

..

23 of 34

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

24 of 34

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

25 of 34

Block Driver (cont.)

Processes

Read/Write System Call

Buffer Cache

Invoke Request Function

Check buffer upto date

Done

Call

Scheduler

26 of 34

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.

27 of 34

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.

28 of 34

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

29 of 34

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

30 of 34

Network Driver

  • Export Interface
  • Data Flow in read/write

31 of 34

Network Driver (cont.)

User Application

Berkley Socket API

INET Socket

TCP

UDP

IP

ARP

ICMP

Network Device Driver

Network Device

Transmit Data: Xmit

Receive Data

Int. Handler

32 of 34

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()

33 of 34

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

34 of 34

Thanks