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
PATH=$PATH:$HOME/bin
so that it looks like this:
PATH=$PATH:.:$HOME/bin
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
Pseudo-files
• 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)