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