Archive for January, 2010

LKM - Block Device Drivers

Posted in How To's by Shafkat Shahzad, M.Sc - Senior Technical Content Manager on January 13th, 2010

Welcome to the tutorial guide. The guide will provide a user with advise and guidance about blocked device drivers.
floppy: floppy disk driver
This is the device driver for floppy disks. A user will need this in order to access a floppy disk in any way.nn. This LKM is documented in the file README.fd in the linux/drivers/block directory of the Linux source tree. For detailed up to date information refer directly to this file. Please note that if a user boots from a floppy disk or with a root filesystem on a floppy disk, then he/she must have the floppy disk driver bound into the base kernel, because the system will need it before it has a chance to insert the LKM.
For example:

modprobe floppy ‘floppy=”daring two_fdc 0,thinkpad 0×8,fifo_depth”‘

Please note that there is only one LKM parameter: floppy, but it contains many subparameters. The reason for this unusual parameter format is to be consistent with the way a user would specify the same things in the kernel boot parameters if the driver were bound into the base kernel.

The value of floppy is a sequence of blank-delimited words. Each of those words is one of the following sequences of comma-delimited words:
asus_pci
Sets the bit mask of allowed drives to allow only units 0 and 1. Obsolete, as this is the default setting anyways
daring
Tells the floppy driver that a user has a well behaved floppy controller. This allows more efficient and smoother operation, but may fail on certain controllers. This may speed up certain operations.
0,daring
Tells the floppy driver that the floppy controller should be used with caution.
one_fdc
Tells the floppy driver that the user has only floppy controller (default).
address,two_fdc
Tells the floppy driver that a user has two floppy controllers. The second floppy controller is assumed to be at address. This option is not needed if the second controller is at address 0×370, and if the user uses the cmos option
two_fdc
Like above, but with default address
thinkpad
Tells the floppy driver that a user has an IBM Thinkpad model notebook computer. Thinkpads use an inverted convention for the disk change line.
0,thinkpad
Tells the floppy driver that a user doesn’t have a Thinkpad.
nodma
Tells the floppy driver not to use DMA for data transfers. This is needed on HP Omnibooks, which don’t have a workable DMA channel for the floppy driver. This option is also useful if a user frequently gets “Unable to allocate DMA memory” messages. Indeed, DMA memory needs to be continuous in physical memory, and is thus harder to find, whereas non-DMA buffers may be allocated in virtual memory. A user will also need at least a 486 to use nodma. If a user uses nodma mode, it is recommended that a user also sets the FIFO threshold to 10 or lower, in order to limit the number of data transfer interrupts.

If a user has a FIFO-able FDC, the floppy driver automatically falls back on non DMA mode if it can’t find any DMA-able memory. If a user wants to avoid this, explicitly specify “yesdma”.
omnibook
Same as nodma.
yesdma
Tells the floppy driver that a workable DMA channel is available (the default).
nofifo
Disables the FIFO entirely. This is needed if a user gets “Bus master arbitration error” messages from a users Ethernet card (or from other devices) while accessing the floppy.
fifo
Enables the FIFO (default)
threshold,fifo_depth
Sets the FIFO threshold. This is mostly relevant in DMA mode. If this is higher, the floppy driver tolerates more interrupt latency, but it triggers more interrupts (i.e. it imposes more load on the rest of the system). If this is lower, the interrupt latency should be lower too (faster processor). The benefit of a lower threshold is fewer interrupts.
To tune the fifo threshold, switch on over/underrun messages using ‘floppycontrol –messages’. Then access a floppy disk. If a user gets a huge amount of “Over/Underrun - retrying” messages, then the fifo threshold is too low. A user can try with a higher value, until he/she only get an occasional Over/Underrun.
The value must be between 0 and 0xf, inclusive.
As a user inserts and removes the LKM to try different values, remember to redo the ‘floppycontrol –messages’ every time he/she inserts the LKM. A user shouldn’t normally have to tune the fifo, because the default (0xa) is reasonable.
drive,type,cmos
Sets the CMOS type of drive to type. This is mandatory if a user has more than two floppy drives or if he/she uses BIOS non-standard CMOS types. The CMOS types are:
0

Use the value of the physical CMOS
1
5 1/4 DD
2
5 1/4 HD
3
3 1/2 DD
4
3 1/2 HD
5
3 1/2 ED
6
3 1/2 ED
16
unknown or not installed

unexpected_interrupts
Print a warning message when an unexpected interrupt is received. (default behavior)
no_unexpected_interrupts
Don’t print a message when an unexpected interrupt is received. This is needed on IBM L40SX laptops in certain video modes. (There seems to be an interaction between video and floppy. The unexpected interrupts only affect performance, and can safely be ignored.)
L40SX
Same as no_unexpected_interrupts.
broken_dcl
Don’t use the disk change line, but assume that the disk was changed whenever the device node is reopened. Needed on some boxes where the disk change line is broken or unsupported. This should be regarded as a stopgap measure, indeed it makes floppy operation less efficient due to unneeded cache flushings, and slightly more unreliable. A user can verify his/her cable, connection and jumper settings if a user have any DCL problems. However, some older drives, and also some laptops are known not to have a DCL.
debug
Print debugging messages
messages
Print informational messages for some operations (disk change notifications, warnings about over and underruns, and about autodetection)
silent_dcl_clear
Uses a less noisy way to clear the disk change line (which doesn’t involve seeks). Implied by daring.
nr,irq
Tells the driver to expect interrupts on IRQ nr instead of the conventional IRQ 6.
nr,dma
Tells the driver to use DMA channel nr instead of the conventional DMA channel 2.
slow
Use PS/2 stepping rate: PS/2 floppies have much slower step rates than regular floppies. It’s been recommended that take about 1/4 of the default speed in some more extreme cases.
mask,allowed_drive_mask
Sets the bitmask of allowed drives to mask. By default, only units 0 and 1 of each floppy controller are allowed. This is done because certain non-standard hardware (ASUS PCI motherboards) mess up the keyboard when accessing units 2 or 3. This option is somewhat obsoleted by the ‘cmos’ option.
all_drives
Sets the bitmask of allowed drives to all drives. Use this if a user have more than two drives connected to a floppy controller.

If you followed advise and guidance as provided in this tutorial guide then you would have learnt about blocked device drivers.

Bookmark Us
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • MisterWong
  • Netvouz
  • Reddit
  • Slashdot
  • Spurl
  • StumbleUpon
  • Technorati
  • Wists

LKM - differences between versions of Linux

Posted in How To's by Shafkat Shahzad, M.Sc - Senior Technical Content Manager on January 9th, 2010

Welcome to the tutorial guide. The guide will provide a user with advise and guidance about different versions of Linux.

There are a variety of Linux versions that exist in and unlike a proprietary software product where one company carefully controls the name and creates a small number of well defined releases, variations of Linux are developed by lots of different independent people and all of them are called Linux.

The most basic Linux releases are controlled by Linus Torvalds and distributed by kernel.org as the main Linux releases. They are the only releases that can properly by called “Linux 2.4,” “Linux 2.6.6,” etc.

People start with Linux 2.4 and Linux 2.6.6 releases and make modifications. People often sloppily refer to a Linux based on Linux 2.6.6 as Linux 2.6.6 itself. But to be correct, a user has to add something — usually a hyphen and a suffix. Red Hat versions of Linux use a plain number for that suffix, e.g. Linux 2.6.6-12.

Linux 2.4 and Linux 2.6
The biggest change to LKMs between Linux 2.4 and Linux 2.6 is an internal one: LKMs get loaded much differently. Most people won’t see any difference except that the suffix on a file containing an LKM has changed, because they use high level tools to manage the LKMs and the interface to those tools hasn’t changed.

Before Linux 2.6, a user space program would interpret the ELF object (.o) file and do all the work of linking it to the running kernel, generating a finished binary image. The program would pass that image to the kernel and the kernel would do little more than stick it in memory. In Linux 2.6, the kernel does the linking. A user space program passes the contents of the ELF object file directly to the kernel. For this to work, the ELF object image must contain additional information. In order to identify this particular kind of ELF object file, a user can name the file with suffix “.ko” (”kernel object”) instead of “.o” For example, the serial device driver that in Linux 2.4 lived in the file serial.o in Linux 2.6 lives in the file serial.ko.

So there is a whole new modutils package for use with Linux 2.6. In it, insmod is a trivial program, as compared to the full blown linker of the Linux 2.4 version. Also, the procedure to build an LKM is somewhat harder. In order to make a .ko file, a user can start with a regular .o file. A user can then run the program modpost (which comes with the Linux source code) on it to create a C source file that describes the additional sections the .ko file needs. This can be called as a .mod file because a user can include “.mod” in the file name.

A user can compile the .mod file and link the result with the original .o file to make a .ko file. The .mod object file contains the name that the LKM instance will have when he/she load the LKM. A user can set that name with a -D compile option that sets the KBUILD_MODNAME macro.

This change means some things are decidedly harder — choosing the name for the LKM instance, for example. In Linux 2.4, the name was one of the inputs to the kernel. insmod decided on the name and passed it to the kernel. insmod’s -o option told it explicitly what to use for the LKM instance name. But in 2.6, there is no such parameter on the system call and hence no -o option on insmod. The name is part of the ELF object (.o file) that a user passes to the kernel. The default name is built into the ELF object, but if a user wants to load it with some other name, then he/she must edit the ELF image before passing it to insmod.

If you followed advise and guidance as provided in this tutorial guide then you would have learnt about different versions of Linux.

Bookmark Us
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • MisterWong
  • Netvouz
  • Reddit
  • Slashdot
  • Spurl
  • StumbleUpon
  • Technorati
  • Wists

LKM - module use counts

Posted in How To's by Shafkat Shahzad, M.Sc - Senior Technical Content Manager on January 5th, 2010

Welcome to the tutorial guide. The guide will provide a user with advise and guidance on module use counts.

It is good to understand that a user must not unload a module while it is in use. An example of in use is a device driver for which a device special file is open. As there is an open file descriptor for it, a user should read the device and to execute that read, the kernel would want to call a function that is in the device driver. If a user unloaded that device driver module before the read — the kernel would reuse the memory that used to contain the read subroutine and there’s no telling what instructions the kernel would branch to when it thinks it’s calling the read subroutine.

In the original design, the LKM increments and decrements its use count to tell the module manager whether it is OK to unload it. If it is a filesystem driver, it would increment the use count when someone mounts a filesystem of the type it drives, and decrement it at unmount time.

Your LKM can register a function that the module manager will call whenever it wants to know if it is OK to unload the module. If the function returns a true value, that means the LKM is busy and cannot be unloaded. If it returns a false value, the LKM is idle and can be unloaded. The module manager holds the big kernel lock from before calling the module-busy function until after its cleanup subroutine returns or sleeps, and unless you’ve done something odd, that should mean that your LKM cannot become busy between the time that you report “not busy” and the time you clean up.

If you would like to register the module-busy function, then it can be done by putting its address in the unfortunately named can_unload field in the module descriptor (”struct module”). The name is truly unfortunate because the boolean value it returns is the exact opposite of what can unload means: true if the module manager cannot unload the LKM.

The module manager ensures that it does not attempt to unload the module before its initialization subroutine has returned or sleeps, so you are safe in setting the can_unload field anywhere in the initialisation subroutine except after a sleep.
can_unload is little known and rarely used. Starting with Linux 2.6, it no longer exists.
Whether you use traditional use counts of can_unload, there are cases where you cannot be sure that your module doesn’t get unloaded while it is still in use. If your LKM creates a kernel thread that executes LKM code, it is just about impossible to be absolutely sure that thread is gone before the LKM gets unloaded. There are various other kernel services that a user can give addresses within his/her LKM that won’t properly let a usrer know when they have forgotten them.

The problem used to be worse than it is now. For example, it used to be that if he/she LKM created a proc filesystem file, he/she couldn’t stop the LKM from getting unloaded while some process was executing your read and write routines for the file. This and other instances of the problem have been fixed by having code outside the LKM understand that the address it’s using might be in an LKM, and therefore increment and decrement the use count as necessary. Where this function is implemented, you often see a structure member named owner which is a handle for the LKM (i.e. a struct module address).

These problems may be fixed in future version of Linux. Please note that some of the problems are so hard to fix that the proper design for Linux is just to make it impossible ever to unload an LKM. Starting with Linux 2.6, the CONFIG_MODULE_UNLOAD kernel build configuration option determines whether module unloading is allowed or not.

If you followed advise and guidance as provided in this tutorial guide then you would have learnt about module counts.

Bookmark Us
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • MisterWong
  • Netvouz
  • Reddit
  • Slashdot
  • Spurl
  • StumbleUpon
  • Technorati
  • Wists

LKM - using the Kernel Build System

Posted in How To's by Shafkat Shahzad, M.Sc - Senior Technical Content Manager on January 5th, 2010

Welcome to the tutorial guide. The tutorial guide will provide a user with advise and guidance on how to use the Kernel Build System.

Please note that Lkmpg contains fine instructions for building or compiling an LKM (except that the __KERNEL__ macro and usually the MODULE macro should be defined in the source code instead of with -D compiler options as Lkmpg suggests).

Research suggests that the right way to build an LKM is to add it to a copy of the complete Linux source tree and build it with the existing Linux make files just like the LKMs that are part of Linux.

The advantage is is that when Linux programmers change the way LKMs interface with the rest of the kernel in a way that affects how a user builds an LKM, he/she covered.
On the other hand, a user can find from a code management point of view that he/she has to keep his/her code and Linux separate, and from a coding point of view, a user needs to understand all the intricacies of how the code gets compiled, especially when it changes.

If you followed advise and guidance as provided in this tutorial guide then you would have learnt about the Kernel build system.

Bookmark Us
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • MisterWong
  • Netvouz
  • Reddit
  • Slashdot
  • Spurl
  • StumbleUpon
  • Technorati
  • Wists

LKM - writing your own loadable Kernel module

Posted in How To's by Shafkat Shahzad, M.Sc - Senior Technical Content Manager on January 5th, 2010

Welcome to the tutorial guide. The guide will provide a user with advise and guidance on how to write a loadable Kernel module.

Let’s have a quick look at how to write loadable Kernels.

simpler hello.c
Lkmpg gives an example of the world’s simplest LKM, hello-1.c. The program requires a user to include -D options on the compile command to work, because it does not define some macros in the source code, where the definitions belong.

A simple LKM, hello.c. is as provided below:
/* hello.c
*
* “Hello, world” - the loadable kernel module version.
*
* Compile this with
*
* gcc -c hello.c -Wall
*/

/* Declare what kind of code we want from the header files */
#define __KERNEL__ /* We’re part of the kernel */
#define MODULE /* Not a permanent part, though. */

/* Standard headers for LKMs */
#include
#include

#include /* console_print() interface */

/* Initialize the LKM */
int init_module()
{
console_print(”Hello, world - this is the kernel speaking\n”);
/* More normal is printk(), but there’s less that can go wrong with
console_print(), so let’s start simple.
*/

/* If we return a non zero value, it means that
* init_module failed and the LKM can’t be loaded
*/
return 0;
}

/* Cleanup - undo whatever init_module did */
void cleanup_module()
{
console_print(”Short is the life of an LKM\n”);
}

This can be compiled with the following command:

$ gcc -c -Wall -nostdinc -I /usr/src/linux/include hello.c

The -I above assumes that a user has the source code from which the base kernel was built in the conventional spot, /usr/src/linux.

If a user loads a kernel that is loaded from a distribution CD, then he/she has to separately load the headers for it. If a user is compiling LKMs, then he/she should compile his/her own kernel, to know exactly what he/she is working with and can be absolutely sure he/she is working with matching header files.

The -nostdinc option isn’t strictly necessary, but is the right thing to do. It will keep a user out of trouble and also remind a user that the services of the standard C library, which he/she has melded in the mind with C itself, are not available to kernel code. -nostdinc says not to include “standard” directories in the include file search path. This means, most notably, /usr/include.

The -c option says a user just want to create an object (.o) file, as opposed to gcc’s default which is to create the object file, then link it with a few other standard object files to create something suitable for exec’ing in a user process, but as a user will not be exec’ing this module but rather adding it to the kernel, that link phase would be entirely inappropriate.
-Wall is obviously not necessary, but this program should not generate any warnings. If it does, a usr need to fix something. –Wall makes the compiler warn a user about lots of kinds of questionable code

If you followed advise and guidance as provided in this tutorial guide then you would have learnt about loading a loadable kernel module.

Bookmark Us
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • MisterWong
  • Netvouz
  • Reddit
  • Slashdot
  • Spurl
  • StumbleUpon
  • Technorati
  • Wists

LKM - memory allocation for loading

Posted in How To's by Shafkat Shahzad, M.Sc - Senior Technical Content Manager on January 2nd, 2010

Welcome to the tutorial guide. The guide will provide a user with guidance and instructions on memory allocation.

Please note that the memory where an LKM resides is a little different from that where the base kernel resides. The base kernel is always loaded into one big contiguous area of real memory, whose real addresses are equal to is virtual addresses. That’s possible because the base kernel is the first thing ever to get loaded, it has a wide open empty space in which to load.

By the time a user loads an LKM, real memory is all fragmented and a user can’t simply add the LKM to the end of the base kernel. But the LKM needs to be in contiguous virtual memory, so Linux uses vmalloc to allocate a contiguous area of virtual memory (in the kernel address space), which is probably not contiguous in real memory. But the memory is still not pageable. The LKM gets loaded into real page frames from the start, and stays in those real page frames until it gets unloaded.

Some CPUs can take advantage of the properties of the base kernel to effect faster access to base kernel memory. For example, on one machine, the entire base kernel is covered by one page table entry and consequently one entry in the translation lookaside buffer (TLB). Naturally, that TLB entry is virtually always present. For LKMs on this machine, there is a page table entry for each memory page into which the LKM is loaded. Much more often, the entry for a page is not in the TLB when the CPU goes to access it, which means a slower access.

Please note that PowerPC Linux does something with its address translation so that transferring between accessing base kernel memory to accessing LKM memory is costly. I don’t know anything solid about that.

The base kernel contains a large expanse of reusable memory the kmalloc pool. In some versions of Linux, the module loader tries first to get contiguous memory from that pool into which to load an LKM and only if a large enough space was not available, go to the vmalloc space. Andi Kleen submitted code to do that in Linux 2.5 in October 2002. He claims the difference is in the several per cent range.

If you followed advise and guidance as provided in this tutorial guide then you would have learnt about the memory for loading.

Bookmark Us
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • MisterWong
  • Netvouz
  • Reddit
  • Slashdot
  • Spurl
  • StumbleUpon
  • Technorati
  • Wists

LKM - ksymtab and .kstrtab

Posted in How To's by Shafkat Shahzad, M.Sc - Senior Technical Content Manager on January 2nd, 2010

Welcome to the tutorial guide. The guide will provide guidance and instructions on Ksymtab and .kstrtab.

Please note that there are two sections that an LKM object file is named are __ksymtab and .kstrtab. They list symbols in the LKM that should be accessible to other parts of the kernel. A symbol is just a text name for an address in the LKM. LKM A’s object file can refer to an address in LKM B by name (say, getBinfo”). When you insert LKM A, after having inserted LKM B, insmod can insert into LKM A the actual address within LKM B where the data/subroutine named getBinfo is loaded.

Let’s have a look at Ksymoops Symbols
insmod adds a bunch of exported symbols to the LKM as it loads it. These symbols are all intended to help ksymoops do its job. ksymoops is a program that interprets and oops display. And “oops” display is stuff that the Linux kernel displays when it detects an internal kernel error. This information contains a bunch of addresses in the kernel, in hexadecimal.

ksymoops looks at the hexadecimal addresses, looks them up in the kernel symbol table and translates the addresses in the oops message to symbolic addresses, which you might be able to look up in an assembler listing. The oops message contains the address of the instruction that choked.

Ksymoops must be able to get the loadpoints and lengths of the various sections of the LKM from the kernel symbol table. In Linux 2.4, insmod knows those addresses, so it just creates symbols for them and includes them in the symbols it loads with the LKM.
In particular, those symbols are named (and you can see this for yourself by looking at /proc/ksyms):
__insmod_name_Ssectionname_Llength
name is the LKM name (as you would see in /proc/modules.
sectionname is the section name, e.g. .text (don’t forget the leading period).
length is the length of the section, in decimal.

The value of the symbol is, of course, the address of the section.
Insmod also adds a pretty useful symbol that tells from what file the LKM was loaded. That symbol’s name is __insmod_name_Ofilespec_Mmtime_Vversion
name is the LKM name, as above.
filespec is the file specification that was used to identify the file containing the LKM when it was loaded. Note There are multiple file specifications that might have been used to refer to the same file. For example, ../dir1/mylkm.o and /lib/dir1/mylkm.o.
mtime is the modification time of that file, in the standard Unix representation (seconds since 1969), in hexadecimal.
version tells the kernel version level for which the LKM was built (same as in the .modinfo section). It is the value of the macro LINUX_VERSION_CODE in Linux’s linux/version.h file. For example, 132101.
The value of this symbol is meaningless.
In Linux 2.6, it works differently.

Please note that insmod adds another symbol, similar to the ksymoops symbols. This one tells where the persistent data lives in the LKM, which rmmod needs to know in order to save the persistent data.
__insmod_name_Plength

There is another kind of symbol that relates to an LKM: kallsyms symbols. These are not exported symbols; they do not show up in proc/ksyms. They refer to addresses in the kernel that are nobody’s business except the module they are in, and are not meant to be referenced by anything except a debugger. Kdb, the kernel debugger that comes with the Linux kernel, is one user of kallsyms symbols.

The kallsyms facility works for both the base kernel and LKMs. For the base kernel, you select it when you build the base kernel, with the CONFIG_KALLSYMS configuration option. When you do that, the kernel contains a kallsyms symbol for all the symbols in the base kernel object files. If you the symbol __start___kallsyms in /proc/ksyms then the base kernel is participating in the kallsyms facility.

For an LKM, at load time it can be decided that whether it will contain kallsyms symbols.
Each loaded LKM that is participating in kallsyms has its own kallsyms symbol table. When the base kernel is participating in the kallsyms facility, the individual LKM kallysms symbol tables are linked into a master symbol table so that a debugger can look up a symbol anywhere in the kernel. When the base kernel is not participating in kallsyms, a debugger must look explicitly at a particular LKM to find symbols for that LKM. Kdb, for one, cannot do this. If a user wants to debug, use CONFIG_KALLSYMS.

Please note that the __kallsyms section has nothing to do with LKMs. That’s a section in the base kernel object module. The base kernel doesn’t have the luxury of something as high-level as sophisticated as insmod to load it, so it needs that extra object file section to facilitate its participation in kallsyms.
Similarly, the program kallsyms has nothing to do with LKMs. It is what creates the __kallsyms section.
There is another kind of debugging symbol — the kind that gcc creates with its -g option. These are unrelated to the kallsyms facility. They do not get loaded into kernel memory. Kdb does not use them.

If you followed advise and guidance as provided in this tutorial guide then you would have learnt about Ksymtab and .kstrtab.

Bookmark Us
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • MisterWong
  • Netvouz
  • Reddit
  • Slashdot
  • Spurl
  • StumbleUpon
  • Technorati
  • Wists

Next entries »