Rapid prototyping of LKMs Configuring our Linux systems for loadable kernel modules

Rapid prototyping of LKMs
Configuring our Linux systems for
the quick creation and use of
loadable kernel modules
Fewer keystrokes?
• If you want to run a program you wrote
that resides in your current directory, you
normally have to type the full pathname:
$ ./myprog
• But you can adjust your logon-settings so
you won’t have to specify the directory:
$ myprog
• You just need to edit your ‘.bash_profile’
Environment variables
• You can view your present ‘environment’
using the ‘set’ command, like this:
$ set | more
• Look for the line that begins with ‘PATH=‘
• This line tells your command-shell (‘bash’)
which directories it should search to find a
program whose name you entered, so you
can add ‘.’ (the current directory) to PATH
The ‘PATH=‘ variable
• Your ‘PATH’ environment-variable gets
initialized each time you login
• Its value is setup by your ‘.bash_profile’
• This hidden file is your ‘home’ directrory
• You can view it using the ‘cat’ command:
• You can also edit it (e.g., with ‘vi’) – but be
very careful if you do so!
Including ‘.’ in your PATH
• If you want your command-shell to search
for programs in your current directory, you
can edit the ‘PATH=‘ line in .bash_profile
• Example: change the line that says
so that it looks like this:
Notice: ‘$HOME/bin’
• You can create a new subdirectoy (named
‘bin’) in your home directory, and use it as
a place to put your often-used programs
(such as tools like ‘newmod’ and ‘mmake’)
• Then, after you execute the ‘.bash_profile’
script, you can run those programs from
any directory, without having to type a full
pathname -- ‘bash’ will now find them!
A word about ‘wizards’
We will be writing lots of modules
We can ‘automate’ the boilerplate
We should write a ‘wizard’ program
It will save us LOTS of time!
Our ‘newmod’ example
• The ‘newmod.cpp’ application creates the
bare minimum of module source-code
• It’s an example of a ‘wizard’ tool – but it’s
not as useful as it could be, since the code
it creates doesn’t really DO anything
• Tonight we learn to use a better ‘wizard’,
one that will prove very useful in studying
the way the new Linux kernel 2.6 works
Types of files
• UNIX systems implement ordinary files for
semi-permanent storage of programs/data
• But UNIX systems also implement several
kinds of ‘special’ files (such as device-files
and symbolic links) which enable users to
employ familiar commands and functions
(e.g., open(), read(), write(), and close())
when working with other kinds of objects
• Among the various types of ‘special’ files
are the so-called ‘pseudo’ files
• Unlike ordinary files which hold information
that is ‘static’, the pseudo-files don’t ‘store’
any information at all – but they ‘produce’
information that is created dynamically at
the moment when they are being read
• Traditionally they’re known as ‘/proc’ files
Text in ‘/proc’ files
• Usually the data produced by reading from
a ‘/proc’ file consists of pure ASCII text (a
few exceptions exist, however)
• This means you can view the contents of a
‘/proc’ file without having to write a special
application program – just use ‘cat’!
• For example:
$ cat /proc/version
More ‘/proc’ examples
$ cat /proc/cpuinfo
$ cat /proc/modules
$ cat /proc/meminfo
$ cat /proc/iomem
$ cat /proc/devices
$ cat /proc/self/maps
[Read the ‘man-page’ for details: $ man proc
Create your own pseudo-files
• You can use our ‘newinfo.cpp’ wizard to
create ‘boilerplate’ code for a module that
will create a new pseudo-file when you
‘install’ the module into a running kernel
• The module’s ‘payload’ is a function that
will get called by the operating system if
an application tries to ‘read’ from that file
• The ‘get_info()’ function has full privileges!
An example: ‘jiffies.c’
• There is a volatile kernel variable (named
‘jiffies’) that keeps track of elapsed time
• It is used by the task-scheduler to decide
when to perform a task-switch
• It increments 100 times/sec (kernel 2.4)
• It’s normally inaccessible to user programs
• But we can create a ‘/proc’ file that will let
us view the ‘jiffies’ value at any moment
Edit the ‘get_info()’ function
Just replace the statement:
len += sprintf( buf+len, “%s\n”, modname );
with this statement:
len += sprintf( buf+len, “ jiffies = %d \n”, jiffies );
Compile and install the module, then type:
$ cat /proc/jiffies
In-class exercise #1
Try creating your own ‘jiffies’ pseudo-file
1) use ‘newinfo’ to build your ‘boilerplate’
2) edit one line in your module’s ‘get_info’
3) compile your module (using ‘mmake’)
4) install your ‘jiffies.ko’ kernel-object
5) use the ‘cat’ command to see jiffies
A more important example
Control Register Cr4
This Pentium register contains a collection of flag-bits which
enable or disable special architectural extensions to the CPU
(as documented in Intel’s Software Developer Manual, vol3)
movl %cr4, %ebx
# privileged instruction
Among the flag-bits in this register are two which affect how
the Pentium translatres virtual memory-address into physical
memory-addresses. We’ll need to know how these are set!
Our ‘cr4.c’ module
• We’ve written a module that will create a
pseudo-file (named ‘/proc/cr4’) that can let
us view the contents of Control Register 4
$ cat /proc/cr4
• You can download our module’s code from
the class website and try it out
• You can learn what all the flag-bits mean
by reading Intel’s Developer Manual online
In-class exercise #2
• Revise the source-code in the ‘cr4.c’ file so
that it will display the meanings of each
flag-bit in register CR4
• For example, your ‘/proc/cr4’ file should
print output that looks like this:
cr4 = 000006D0 PSE=1 PAE=0 VME=0
(but show ALL of the implemented bits)