Вы находитесь на странице: 1из 24

How to make a pseudo-file

As a follow-up to our first lab, we


examine the steps needed to
create our own /proc file

The extensibility imperative

A modern OS needs the ability to evolve


It will need to support new devices
It will need to allow bugs to be repaired
It will need to permit performance gains

Otherwise: suffer early obsolescence!

Two Extensibility Mechanisms


Open Source programming
Installable kernel modules

Open Source
Source text for the Linux kernel is on disk
(usual directory-location is /usr/src/linux)
Majority of the sources are written in C
(so portable across CPU architectures)
Some are written in assembly languages
(for nearly twenty different architectures)
Files are grouped into major categories
(kernel, mm, fs, net, ipc, lib, drivers, init)
You could edit and recompile your kernel

Installable kernel modules

Great mechanism for kernel extensibility


Neat tool for studying how kernel works
Kernel can be modified while its running
Unnecessary to recompile and then reboot
But inherently unsafe: programming bugs
in the kernel can cause system crashes!

Some superuser privileges


Since modifying a running kernel is risky,
only authorized system administrators
are normally allowed to install kernel
modules
But our systems are specially configured
to permit you to install or remove modules
This is purely for educational purposes
(so you should use this privilege wisely)

Linux module structure


Two module administration functions are
mandatory components in every module
plus
Appropriate module service functions and
their supporting kernel data-structures are
optional components in particular modules
also
Recent kernels require a Module License!

A minimal module-template
#include <linux/module.h>
int init_module( void )
{
// code here gets called during module installation
}
void cleanup_module( void )
{
// code here gets called during module removal
}
MODULE_LICENSE(GPL);

How to compile a module


You could directly invoke the C-compiler:
$ gcc c O D__KERNEL__ -DMODULE
I/lib/modules/2.4.26/build/include mod.c
OR: you can use the make utility:
$ make mod.o

The printk() function


Kernel modules cannot call any functions
in the C runtime library (e.g., printf())
But similar kernel versions of important
functions are provided (e.g., printk())
Syntax and semantics are slightly different
(e.g., priority and message-destination)
Capabilities may be somewhat restricted
(e.g., printk() cant show floating-point)

Simple module example


#include <linux/module.h>
int init_module( void )
{
printk( <1>Hello, world!\n );
return 0;
// SUCCESS
}
void cleanup_module( void )
{
printk( <1>Goodbye everyone\n );
}
MODULE_LICENSE(GPL);

How to install and remove


root#/sbin/insmodhello.o
root#/sbin/rmmodhello

A non-trivial module-example
Lets see how we can use kernel functions
to create our own /proc file
Easy if we use create_proc_read_entry()
during module-initialization (and then use
remove_proc_entry() during cleanup)
Prototypes in the <linux/proc_fs.h> header
Well show the current value of a volatile
kernel variable, named jiffies

jiffies

unsigned long volatile jiffies;


global kernel variable (used by scheduler)
Initialized to zero when system reboots
Gets incremented when timer interrupts
So it counts clock-ticks since cpu restart
tick-frequency is architecture dependent

Writing the jiffies.c module


We need to declare a name for pseudo-file
static char modname[ ] = jiffies;
We need to define a proc_read function
(see code on the following slide)
We need to register our filename, along
with its read method, in init_module()
We need to unregister our pseudo-file in
cleanup_module()

Our modules read method


static int
my_proc_read( char *buf, char **start,
off_t off, int count, int *eof, void *data )
{
return sprintf( buf, jiffies=%lu\n, jiffies );
}

Our initialization function


int init_module( void )
{
create_proc_read_entry( modname,
0, NULL, my_proc_read, NULL );
return 0;
}

Our cleanup function


void cleanup_module( void )
{
remove_proc_entry( modname, NULL );
}

In-class exercise #1
Use an editor (e.g., vi) to create a source
file in C (named jiffies.c) for your module
Use the make command to compile your
modules source-file into an object-file
Use the insmod command to install your
module object-file into the running kernel
Use the cat command to display jiffies
Then use rmmod to remove your module

Makefile

We need it to automate module compiles


Otherwise we type a VERY long command
To compile jiffies.c type: $ make jiffies.o
Our Makefile defines some implicit rules
make works by doing pattern-matching

Rule syntax

targets:dependencies
commands
...

Pattern Rule example


CC=gcc
INCLUDE=
/lib/modules/2.4.26/build/include
CFLAGS=cO
CFLAGS+=D__KERNEL__DMODULE
#primarypatternrule
%.o:%.c%.h
$(CC)I$(INCLUDE)$CFLAGS$<
#fallbackpatternrule
%.o:%.c
$(CC)I$(INCLUDE)$CFLAGS$<

Makefile is on class website


You can download the Makefile from our
website: http://cs.usfca.edu/~cruse/cs326/
Put the Makefile in your current working
directory (along with your module source)
Then you can compile by typing this short
command: $ make jiffies.o

In-class exercise #2
Use your knowledge of standard C library
functions (e.g., open(), read(), close() ) to
write an application-program (name it
showjifs.cpp) which reads the information
from your proc/jiffies pseudo-file and then
prints it on the screen
Use a program-loop to re-read the pseudo
file multiple times
How rapidly does jiffies value increase?

Вам также может понравиться