Showing posts with label repeated. Show all posts
Showing posts with label repeated. Show all posts

Tuesday, March 29, 2011

Use of Module Parameters in Kernel Programming.

Use Cases of Module Parameters:
  • When there is a need to change the irq line of the module then its the best way to pass the irq number as command line argument using module parameter concept.
  • Base address of the register map of a module can be passed at module load time using insmod based on this command line arguments.

Generally the word command line arguments make you strike to argc/argv in C, here coming to Linux kernel modules approach is bit different and even easy to....!! lets go for a walk on this concept.

To allow arguments to be passed to your module, declare the variables that will take the values of the command line arguments as global and then use the module_param() macro, defined in linux/moduleparam.h to set the mechanism up.
Value is assigned to this variable at runtime by a command line arguments that are given like $ insmod mymodule.ko myvariable=5 while inserting/loading the module into kernel.

The variable declarations and macros should be placed at the beginning of the module for clarity.

In this post Loadable Kernel Module i have explained the basic concepts of kernel modules.

The module_param() macro takes 3 arguments: 
  • arg1 : The name of the variable.
  • arg2 : Its type
  • arg3 : Permissions for the corresponding file in sysfs. 
Example Code Snippet :

static int myint =51;
module_param(myint, int, 0);
MODULE_PARM_DESC(myint,"this is the int variable");

Integer types can be signed as usual or unsigned. 

MODULE_PARM_DESC() macro used for giving the description of variable.
Example for all the data types are given below:
static int dint;
module_param(dint, int, 0);
MODULE_PARM_DESC(dint,"this is the dynamic int variable");

static short myshort = 51;
module_param(myshort, short, 0);
MODULE_PARM_DESC(myshort,"this is the short variable");
static long int mylong = 45100;
module_param(mylong, long , 0);
MODULE_PARM_DESC(myshort,"this is the long int variable");

static char *mychar = "Smack Down";
module_param(mychar, charp, 0);
MODULE_PARM_DESC(myshort,"this is the characte string variable");

static int myarr[2] = {51,43};
static int arr_argc = 0;
module_param_array(myarr, int,&arr_argc, 0);
MODULE_PARM_DESC(myarr,"this is the array variable");

Example Code:

Code:
#include <linux/kernel.h> /*needed for priority messages in prink*/
#include <linux/init.h> /*needed for macros*/
#include <linux/module.h> /*needed for all modules*/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vamshi Krishna Gajjela");
MODULE_DESCRIPTION("Test Module Parameters");

static short myshort = 51;
static int myint = 451;
static int dint;
static long int mylong = 45100;
static char *mychar = "Smack Down";
static int myarr[2] = {51,43};
static int arr_argc = 0;
static int hello_world2_data __initdata = 3;

module_param(dint, int, 0);
MODULE_PARM_DESC(dint,"this is the dynamic int variable");

module_param(myshort, short, 0);
MODULE_PARM_DESC(myshort,"this is the short variable");

module_param(myint, int, 0);
MODULE_PARM_DESC(myint,"this is the int variable");


module_param(mylong, long , 0);
MODULE_PARM_DESC(myshort,"this is the long int variable");


module_param(mychar, charp, 0);
MODULE_PARM_DESC(myshort,"this is the characte string variable");


module_param_array(myarr, int,&arr_argc, 0);
MODULE_PARM_DESC(myarr,"this is the array variable");

int __init hello_world2_init(void){
 int i;
 printk(KERN_INFO "Vamshi : Entered2 : data = %d",hello_world2_data);
 printk(KERN_INFO "Value of the the short variable is = %hd",myshort);
 printk(KERN_INFO "Value of the the short variable is = %d",myint);
 printk(KERN_INFO "Value of the the dint variable is = %d",dint);
 printk(KERN_INFO "Value of the the short variable is = %ld",mylong);
 printk(KERN_INFO "Value of the the short variable is = %s",mychar);
 for(i=0;i<sizeof(myarr)/sizeof(int);i++){
  printk(KERN_INFO "arr[%d] = %d\n",i,myarr[i]);
 }
 return 0;
}
void __exit hello_world2_exit(void){
 printk(KERN_INFO "Vamshi : Exited2 ");
}

module_init(hello_world2_init);
module_exit(hello_world2_exit);





Note: Copying the code directly into your source.c file will also copies the invisible characters and finally you will left out with stray errors, i recommend you to type the code and that even becomes a practice.

Makefile:
obj-m := hello_world2.o
all:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean


Building module Sequence Steps:



Click to Download Code 





Friday, March 11, 2011

Compilation error: stray ‘\342’ in program

These stray errors are because of non-printing characters present in our source file and I am going to explain this in this post.

There are many characters that print nothing still take space in your document. You use many of these characters every day, but probably don't think of them as characters (as such). The list of non-printing characters that Word uses includes the following:
  • Column breaks
  • Hidden text
  • Newline characters
  • Optional hyphens
  • Page breaks
  • Paragraph marks
  • Section breaks
  • Spaces
  • Tabs
Here I will show you how does these non-printing characters creep into your document, how to view them and how to remove them.

For example: you copy this peace of code below, a simple kernel module and try to compile it with the Makefile and if you really want to prove your self try even to remove those compilation errors...!

Code for test.c:

#include <linux/module.h>  /* Needed by all modules */
#include <linux/kernel.h>/* Needed for KERN_INFO */
#include <linux/init.h> 
#include <linux/version.h>

MODULE_LICENSE(“GPL”)
MODULE_DESCRIPTION(“This is a basic test moudle)
MODULE_AUTHOR(“Vamshi Krishna Gajjela)

int init_module(void)
{
printk(KERN_INFO "My first test module loaded.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO “Test module unloaded\n");
}

Makefile:

obj-m += test.o

all:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

after compilation you will end up with stray errors like this, shown in the below image, and these stray errors are because of non printing characters.




















Viewing Non-Printing characters:

To view the non-printing character use the following command as below :

$ cat --show-nonprinting test.c






















Removing Non-Printing characters:

To remove the non-printing character use the following command as below :

$ cat  'test.c' | tr -dc [\\n,[:print:]]> new_test.c

Now the source code is redirected to the new file "new_test.c" which is free from non-printing characters.

Note: Hey this may even remove the double quotes so go through for any such errors in your new_test.c .

How to Remove Non-Printing characters in Linux ?

There are many characters that print nothing still take space in your document. You use many of these characters every day, but probably don't think of them as characters (as such). The list of non-printing characters that Word uses includes the following:
  • Column breaks
  • Hidden text
  • Newline characters
  • Optional hyphens
  • Page breaks
  • Paragraph marks
  • Section breaks
  • Spaces
  • Tabs
Here I will show you how does these non-printing characters creep into your document, how to view them and how to remove them.

For example: you copy this peace of code below, a simple kernel module and try to compile it with the Makefile and if you really want to prove your self try even to remove those compilation errors...!

Code for test.c:

#include <linux/module.h>  /* Needed by all modules */
#include <linux/kernel.h>/* Needed for KERN_INFO */
#include <linux/init.h> 
#include <linux/version.h>

MODULE_LICENSE(“GPL”)
MODULE_DESCRIPTION(“This is a basic test moudle)
MODULE_AUTHOR(“Vamshi Krishna Gajjela)

int init_module(void)
{
printk(KERN_INFO "My first test module loaded.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO “Test module unloaded\n");
}

Makefile:

obj-m += test.o

all:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

after compilation you will end up with stray errors like this, shown in the below image, and these stray errors are because of non printing characters.




















Viewing Non-Printing characters:

To view the non-printing character use the following command as below :

$ cat --show-nonprinting test.c






















Removing Non-Printing characters:

To remove the non-printing character use the following command as below :

$ cat  'test.c' | tr -dc [\\n,[:print:]]> new_test.c

Now the source code is redirected to the new file "new_test.c" which is free from non-printing characters.

Note: Hey this may even remove the double quotes so go through for any such errors in your new_test.c .

Thursday, March 3, 2011

Loadable Kernel Module

Modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the functionality of the kernel without the need to reboot the system. 
Example: one type of module is the device driver, which allows the kernel to access hardware connected to the system. 
 Without modules, we would have to build monolithic kernels and add new functionality directly into the kernel image. Besides having larger kernels, this has the disadvantage of requiring us to rebuild and reboot the kernel every time we want new functionality.


  • kernel modules are object files that contain kernel code. 
  • They can be loaded and removed from the kernel during run time.
  • They contain unresolved symbols that are linked into the kernel when the module is loaded.
  • kernel modules can only do some of the things that built-in code can do , they do not have access to internal kernel symbols.dep
 Kernel Module Utilities:

lsmod      : lists the modules already loaded into kernel.

rmmod    : Removes or unloads a module one at a time.

insmod    : Insert or load a module.

depmod   : Creates the data base of module dependencies. This is created based         on the information present in /lib/modules/module.dep file.

modprob : Inserts a module and its dependencies based on information from modules.dep file.

modinfo  : List the information about the module like author, version tag, parameters etc. 

Writing a simple kernel module:

Here I am explaining how to write a simple kernel module that doesn't have any functionality. 
Every Kernel modules must have at least two functions:
"start" (initialization) function called init_module()
It is called when the module is loaded using insmod into the kernel.

"end" (cleanup) function called cleanup_module()
It is called just before it is removed using rmmod. 


Kmod is a subsystem that allows the loading and unloading of modules.

Issues to be considered in writing a kernel module:
  • Module code should not invoke user space Libraries or API’s or System calls.
  • Modules are free to use kernel data types and GNU-C extensions for linux kernel.
  • Following path contains the list of header files that can be included in module programs./lib/modules/2.6.32.generic/build/include/linux.
Code for Test.c:

#include <linux/module.h>  /* Needed by all modules */
#include <linux/kernel.h>/* Needed for KERN_INFO */
#include <linux/init.h> 
#include <linux/version.h>

MODULE_LICENSE(“GPL”); 
MODULE_DESCRIPTION(“This is a basic test moudle); 
MODULE_AUTHOR(“Vamshi Krishna Gajjela);

int init_module(void)
{
printk(KERN_INFO "My first test module loaded.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO “Test module unloaded\n");
}

Note: Copying the code directly into your source.c file will also copies the invisible characters and finally you will left out with stray errors, i recommend you to type the code and that even becomes a practice.


module.h : module management subsystem, its an interface file for Kmod functions.
kernel.h   : resolves kernel symbol calls, it provides access to global symbol table.
init.h        : describes the sequence of initialization.
version.h : It binds a module to a particular version of kernel.
printk     : printk is printf for kernel programs, as said earlier modules can’t use stdlib due to user space/ kernel space issues. Most of C library is implemented in kernel. with in printk “KERN_INFO” is a macro found in kernel.h that defines the priority to printk logs. There are 8 such macros as shown below.

0- highest priority 7-lowest priority

KERN_EMERG "<0>" /* system is unusable */
KERN_ALERT "<1>" /* action must be taken immediately */
KERN_CRIT "<2>" /* critical conditions */
KERN_ERR "<3>" /* error conditions */
KERN_WARNING "<4>" /* warning conditions */
KERN_NOTICE "<5>" /* normal but significant condition */
KERN_INFO "<6>" /* informational */
KERN_DEBUG "<7>" /* debug-level messages */

MACROS :
      MODULE_LICENSE() : declares the module's licensing
      MODULE_DESCRIPTION() : to describe what the module does
      MODULE_AUTHOR() : declares the module's author
  • In modules the comments are achieved with macros so that information of module sits along with the code so that debugging becomes easy. i.e., comments are not stripped out.
  • License macro is mandatory even if it is free or proprietary.
  • Modules can comprise of any number of functions and data elements which form module body.
Building a Module:
Kernel source has two types of make files:
  1. src/Makefile called as top/primary Makefile
  2. Each branch in kernel source has a Makefile called as kbuild Makefile.
So to build a module we have to write a Makefile that follows the rules followed by kbuild. To learn more on how to compile modules, see file linux/Documentation/kbuild/modules.txt.

Makefile:
obj-m += test.o

all:
 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

from a technical point of view the first line is really necessary, the "all" and "clean" targets were added for convenience, and make sure that after "all:" give a tab and write the command as its a convention in writing Makefile.
Now you can compile the module test.c using make command. Here is the list of command I am executing the corresponding output is show in below image highlighted with blue arrow.
Note: You should be the root user or should have requisite permissions to load and unload modules.
$ ls    (to list the files in the current directory)
$ make      ( to build the module, this will generate many files)
$ ls      (to list the files in the current directory)
$ insmod test.ko      ( loading the module)
$ dmesg     ( to see the messages printed by printk)
$ modinfo test.ko      (this display the module information, we have put in macros)
$ rmmod test     ( unloading the module)
$ dmesg      ( to see the messages printed by printk)























Finally you are done...! :-)

Stay tuned for more information....!




Microkernel VS Monolithic Kernel

This post explains the two main kernel architectures of operating systems: the monolithic kernel and the micro kernel. Starting with an introduction about the term ”kernel” itself and its meaning for operating systems as a whole, it continues with a comparison of benefits and disadvantages of both architectures.


Kernel: kernel is the indispensable and therefore most important part of an operating system. Roughly, an operating system itself consists of two parts: the kernel space (privileged mode) and the user space (unprivileged mode). Without that, protection between the processes would be impossible.
There are two different concepts of kernels:
·         monolithic kernel.
·         μ-kernel (microkernel).

Monolithic kernel: The older approach is the monolithic kernel, of which Unix, MS-DOS and the early Mac OS are typical representants of. It runs every basic system service like process and memory management, interrupt handling and I/O communication, file system, etc. in kernel space see Figure 1 (click here for Anatomy of Linux Kernel). It is constructed in a layered fashion, built up from the fundamental process management up to the interfaces to the rest of the operating system (libraries and on top of them the applications). The inclusion of all basic services in kernel space has three big drawbacks.
·         The kernel size increase.
·         Lack of extensibility.
·         The bad maintainability. 


Figure 1: Monolithic Kernel base Operating System.
Bug-fixing or the addition of new features means a recompilation of the whole kernel. This is time and resource consuming because the compilation of a new kernel can take several hours and a lot of memory. Every time someone adds a new feature or fixes a bug, it means recompilation of the whole
 kernel. (click here: “ How to Compile Kernel Source”)

To overcome these limitations of extensibility and maintain-ability, the idea of μ-kernels appeared at the end of the 1980’s. 

Microkernel: The concept (Figure 2) was to reduce the kernel to basic process communication and I/O control, and let the other system services reside in user space in form of normal processes (as so called servers). There is a server for managing memory issues, one server does process management, another one manages drivers, and so on. Because the servers do not run in kernel space anymore, so called ”con-text switches” are needed, to allow user processes to enter privileged mode (and to exit again). That way, the μ-kernel is not a block of system services anymore, but represents just several basic abstractions and primitives to control the communication between the processes and between a process and the underlying hardware. Because communication is not done in a direct way anymore, a message system is introduced, which allows independent communication and favors extensibility.


Figure 2: Micro Kernel base Operating System.

Currently, there are two different generations of μ-kernels. The first generation was a more or less a stripped-down monolithic kernel. Because of performance drawbacks concerning process communication, several system services like device drivers, communication stacks, etc. found their way back into kernel space. This resulted in an even bigger kernel than before, which was slower than its monolithic counterpart. 

            Research in the field of μ-kernels prove, that it is not the best solution to create a hybrid kernel 1 , but a pure micro kernel, which has to be very small in size. So small, that it fits into the processor’s first level cache as a whole. Second generation μ-kernels like the L4 are highly optimized, not just referring to the processor family, but also to the processor itself 2 , which results in a very good I/O performance.

In a simple way we can say like this :

Monolithic Kernel (Macro Kernel): Kernel Image = (Kernel Core+Kernel Services). When system boots up entire services  are loaded and resides in memory.
Example: Windows and Unix.

Micro kernel : Kernel Image = Kernel Core. Services are build in to special modules which can be loaded and unloaded as per need.

We have another type of kernel integration technique called
Modular, this is derived from best of micro and monolithic kernel) In
Modular kernel integration:  Kernel Image = (Kernel core + IPC service modules +Memory  module +Process Management module). All other modules are loadable kernel modules.
Example: Linux kernel