Friday 17 February 2017

Linux Kernel Module



For  LDD Project Click on this Link
https://github.com/0xsachin/LDD/


Loadable Kernel Module using C

- kernel module are considered as object files which contains code which Extends the feature of running kernel.
- kernel module are generally used to Support new hardware , to support new file system to add new system call.
- Advantages of kernel module is that It gets loaded memory of kernel whenever required and it gets removed from memory when its used gets completed.
- To load and Unload kernel modules their is no need to reboot our kernel.
- The Concept of kernel module is used in almost every Linux Distro. Including MAC OS.
- To write the kernel module we have to use Basic C programming concept and some commands.
- Types of kernel Module-  1. Device Driver
                                               2. File system Driver
                                               3. Network Driver
                                               4. TTY (teli Type Terminals)

- Advantages of kernel Module-

1. Easy to Insert and Remove from memory.
2. We can Insert it without rebooting the kernel.
3 We can easily Remove it from memory when its used gets completed.

- Disadvantages of kernel Module-

1. Due to loading and unloading of kernel module their is fragmentation in kernel memory.


- Technology Details about Kernel module-  

1. The source code of kernel module is written in file having extension  .c
2. Kernel module gets compiled by writing the command into make file.
3. After successful compilation of kernel module its kernel object file (.ko) is created.
4. After creating .ko file we can insert it into the running kernel.

- Example of Kernel Module-  

//  Module1.c

#include<linux/module.h>     // This header file is required by all kernel modules
#include<linux/kernel.h>      // This header file is required for KERN_INFO

// This function gets called automattically when module gets loaded by insmod

int init_module( void )
{
       printk(KERN_INFO "module loaded" );
       return 0;
}


// This function gets called automatically when module gets removed from memory by rmmod

void cleanup_module( void )
{
       printk(KERN_INFO "Module removed" );
}

// All the information which is printed by printk function is available in /var/log/syslog file.

- After writing the above code kernel module we have to write the make file which is used to compile   the kernel module program.
- Make file is consider as file which contains the command which are executed by make Utility.

// Make File

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


- The above file should be created in a same directory where the program of kernel module is placed.
- Above make file contains one command which is used to compile the kernel module.
- Above command travels the path from linux file system and execute the make file which is written     by kernel.
- After Writing Make file we have to execute make file.
   open terminal and go to directory where make file and module is placed.

- if make file successfully executed then module1.ko file gets created
- module1.ko is an considers as kernel object which gets inserted into running kernel.

- Insert the kernel module into kernel-

For insertion insmod command is used.

     $sudo insmod module1.ko

after this command we are enter in password of super user.

- if we want check whether loaded kernel module in to the kernel we have to use lsmod command.
                   $lsmod
- if our kernel module is inserted successfully inside that list we get name as module1.
- Inside the kernel module we write the printk( ) which is responsible to write the data into kernel        log file 
- kernel log file is present at path    "/var/log/syslog".
- we can open system log file using below command
       $ cat /var/log/syslog

-if we want to remove kernel module then we have to use the command rmmod.
       $ sudo rmmod module1

- to check wheather our module is removed from kernel or not we have to again call the command       lsmod

-modinfo command is used to display the information about the module.
        $ modinfo -0 module1.ko

-Description about the kernel module-

1. For the kernel module we required 2 major files who's contents are used inside kernel module as
     a. module.h          b. kernel.h

2. Every kernel module should contains 2 predefined functions which gets called implicitly automatically when module gets loaded into memory and modules gets removed from memory.

3. init_module( ) is a function which gets called when we call insmod command invoked.
    generally this function should contains the code which is required to allocate resources of kernel  module.

4.cleanup_module( ) is a function which gets called when rmmod command gets invoked.

5. inside the above programe their is a printk( ) function which is required to write the data into kernel log file.



/////////////////////////////////   More Examples of Kernel Module ///////////////////////////////////////////

module 2:   rename the init_module( ) and  cleanup_moduke( )

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>    // This header file is required macroes

static int __init fun(void)    //here fun is a entry point function which is called by insmod
{
printk(KERN_INFO " Inserting module\n");
return 0;
}

// This function gets called automatically when module gets removed from memory by rmmod

static void __exit gun(void)   //here gun( ) which gets called when rmmod command invoked
{
printk(KERN_INFO "Removing module 2\n");
}

module_init(fun);    // Register our init function
module_exit(gun);   // Register our cleanup function

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

module 3:   Register  driver Author ,description,  Licence

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
// Macro for name of author
#define DRIVER_AUTHOR "Sachin_Gaikwad"

// Macro for module description
#define DRIVER_DESC   "my device driver demo"

static int __init fun(void)   //Entry function
{
printk(KERN_INFO " loading module\n");
return 0;
}

static void __exit gun(void)    //Exit function
{
printk(KERN_INFO "Removing module\n");
}

module_init(fun);
module_exit(gun);

MODULE_LICENSE("GPL");                            // Register name of licance
MODULE_AUTHOR(DRIVER_AUTHOR);      // Register name of author
MODULE_DESCRIPTION(DRIVER_DESC);   // Provide module description

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

module 4: Accept parameter in kernel module

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>  // This header file is used to get information about the parameters
#include <linux/stat.h>


#define DRIVER_AUTHOR "Sachin_Gaikwad"
#define DRIVER_DESC   " Demo module with arguments"

int myint = 21;

module_param(myint, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(myint, "Integer variable");      // parameter description  

/*
This macro is used to to register information about the input argument
First parameter is name of variable
Second parameter is its type
Third parameter is its permission
*/

static int __init fun(void)
{
printk(KERN_INFO "Integer Value is:  %d\n", myint);
return 0;
}

static void __exit gun(void)
{
printk(KERN_INFO "Removing module\n");
}

module_init(fun);
module_exit(gun);

MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);

// we can insert our module as sudo insmod module.ko myint=10

//////////////////////////////////// Array parameter ///////////////////////////////////////////

module 5: Accept Array parameter in kernel module

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>  // This header file is used to get information about the parameters



#define DRIVER_AUTHOR "Sachin_Gaikwad"
#define DRIVER_DESC   " Demo module with Array arguments"

int myint[3];

module_param_array(myint, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(myint, "Integer array variable");      // parameter description  

static int __init fun(void)
{
printk(KERN_INFO "Integer array Value is:  %d\t%d\t%d\t", myint[0],myint[1],myint[2]);

return 0;
}

static void __exit gun(void)
{
printk(KERN_INFO "Removing module\n");
}

module_init(fun);
module_exit(gun);

MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);

// we can insert our module as sudo insmod module.ko myint=10,20,30
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


Here The Small Project of Linux Kernel Character Device Driver
Just Click on Link

https://github.com/0xsachin/LDD/


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Sunday 8 January 2017

Pointer in C


Improve your programming through a solid Understanding of C pointer.

This topic shows you how to use pointer with array, string, structure, and function.
1.       Pointer is a topic which is use in C, C++, and java internally.
2.       Pointer is variable which hold the address.
3.       By using the programming language technique we can access the contains from that particular address.
4.       Pointer is considered as derived data type.
5.       As pointer is variable which is used to hold the address, and Address is always Integral value due to which size of any pointer is 4 bytes(depend on OS & machine Architecture).       
6.       When we create any Variable in our program ,then memory for that variable allocates in a RAM. Depend on data type of that variable.
7.       The name of variable that is identifier is not stored on RAM, but it is stored on separate data structure named as Symbol Table.
8.       Consider the below example which contains multiple variable.


Pointer declaration:
         Pointer variables, like all other variables, must be declared before , they may be used in C program.
When a pointer variable is declared, the variable name must be preceded by an asterisk (*).
This identifies the fact that the variable is a pointer. The data type that appears in the declaration refers to the object of the pointer. i.e. the data item that is stored in the address represented by the pointer, rather than the pointer itself.

Thus a pointer declaration may be written in general terms as :

Data-type  *pointer_name;

Eg-     1.  int *ptr;
        
                       2. int i;
                        int *ptr = &i;
       //Here ptr is a pointer to integer which stores address of i

          E.g-     3.
float f = 3.14;                  // suppose base add is 500
int no = 12;                       // suppose base add is 600
char ch = ‘m’;                   // suppose base add is 700
             
int *p = &no;                    // suppose base add is 100
float *r = &f;                    // suppose base add is 200
char *q = &ch;                 // suppose base add is 300
Symbol table :
    The information about data which get stored in RAM is available in Symbol Table as:

Name        value     Address(base Address)            from       to          Another name                size

 f              3.14                500                                                                                         4
no            12                   600                                                                                         4
ch             m                   700                                                                                         1
 p             600                 100                                                                                         4
 r              500                 200                                                                                         4
 q             700                 300                                                                                         4


Types Of Pointer:

   1.       In real mode operating System (DOS) there are 3 types of pointer as:
a.       Near pointer (0 to 640 kb)
b.      Far pointer (640 to 1024 kb)
c.       Huge pointer (1024 kb -  above)
   2.       This above 3 types of pointer are not applicable in today’s OS because it works in protected mode  (XP, WIN 7,WIN 8)
   3.       According to data type there are Multiple types of Pointer as:
      
 Integer pointer, character pointer, float pointer, double pointer,…… etc.
a.       Every pointer respective of its type requires 4 bytes of memory.
b.      If pointer type and pointed data type is different then we can fetch the contains depends on size of pointer type.
c.       It is possible that pointer type and pointed data type is different.




















printf(“%d”, no);                  // output is -  11
printf(“%d”, &no);               // output is -  100
printf(“%d”, **Z);                // output is -  300
printf(“%d”, &Y);                 // output is -  500
printf(“%d”, *****A);          // output is -  100
printf(“%d”, **X);                // output is -  100
printf(“%d”, *****Z);          // output is -  11
printf(“%d”, &Q);                 // output is -  300
printf(“%d”, &P);                  // output is -  200
printf(“%d”, ***Z);               // output is -  200
printf(“%d”, &(**X));           // output is -  200
printf(“%d”, ****Y);             // output is -  11
printf(“%d”, &(*****A));     // output is -  100
printf(“%d”, &(***Z));         // output is -  300

Pointer Arithmatics:

        This topic contains the Arithmetic Operations which are applying on pointer.
There are multiple arithmetic operator which are applying on pointer which is-   + , - , = =, + +, - -, etc.
    1.     Addition:-
a.       Addition of pointer with integer constant:-

Eg-         int a[5] = {10,20,30,40,50};
              int *p = &(a[0]) ;







[ NOTE-  if we Want to add integral constant with our pointer then we have to multiply integral constant with size of pointer type]

b.       Addition of two Pointer:-
         Addition of two pointers is not allowed, because if we add this two pointers then we get such address which may not be the part of our address space. Due to which Addition of two pointers considered as Compile time Error.

     2.     Subtraction :-

a.       Subtracting integral constant from pointer :-

Eg -     int a[5] = { 10, 20 ,30 ,40 ,50};
int *p = &( a[0]);
int *q = &( a[4] );










1.       * ( q – 3 )
Ans:=>  * ( q – 3 (size of (int ) ) )
                                                                        =>  * ( q – 3 ( 4 ) )
                                                                        =>  *( q – 12)
                                                                        => * ( 116 - 12)
                                                                        => *( 104)
                                                                        => 20               ouput is -20


b.       Subtraction of two pointer:-
As consider above Diagram we can subtract two pointer as

              Eg       q – p
              Ans=> ( q – p ) / ( size of (int) )
                                                                 =>  ( q – p) /  4
                                                                 =>  ( 116 – 100) / 4
                                                                 =>  ( 14 )  /  4
                                                                 =>  4
                                                                       
If we want to subtract two pointers then both pointer should be of same type and both pointer should point to same contiguous memory.
At the type of subtraction we have to divide the result by size of pointer type.   

     3.     Multiplication:-
       Multiplication of two pointers and multiplication of pointer with Integral Constant is not allowed.
    4.     Division:-
       Division of two pointer and Division of pointer with Integral Constant is not allowed.

5.     Increment and Decrement:-

Eg ..       double a[4] = { 3.10, 4.10, 5.10, 6.10};
              double *p = &( a[0] );
              double *q = &( a[3] );













Eg      1)  p ++                                                               2)  q - -
Ans=> p = p + 1                                     ans => q = q - 1
                                          =>  p = p + 1 ( size of( double) )            => q = q – 1 (size of (double) 
                                          =>  p =  100 + 1 (8)                                =>  q =  124 - 1 (8)
                                          =>  p = 100 + 8                                       => q = 124 - 8
                                          =>  p = 108                                             => q= 116                  

NULL Pointer :-

1.     NULL pointer is not consider as type of pointer
2.     If we contains uninitialized pointer then that uninitialized pointer may generate run time accident.
3.     To avoid that runtime accident we to initialized the pointer with particular default value.
4.     Consider the below syntax in which our pointer is initialized with value NULL as

Syntax –           int  * p = NULL;

In this syntax NULL is considered as MACRO which is define in almost all header file as   #define  NULL  0
5.     After preprocessing our syntax becomes
                  int *p = 0;
6.     Writing a constant value for the pointer is illogical  due to which compiler convert above syntax as
int *p = (void *) 0;
7.     According this syntax NULL pointer points to 0th address of our RAM.

Void Pointer(Generic Pointer) :-

1.       If we want to store address of integer then we have to create a integer pointer , similarly if we want to create such a variable which is used to hold Address of character then we have to create character pointer.
2.       If we don’t know data type of such variable whose address in to be stored in pointer then we can create void pointer.  
3.       Void pointer is a such pointer which can hold address of any data type.
4.       Eg -           int no = 10 ;
 char ch = ‘a’ ;
 float ff = 3.14 ;
 double d = 6.10 ;
 int *p = &no ;
 char  *cp = &ch ;
 float *fp = &ff ;
 double *dp = &d ;

In above syntax we have 4 different data type and stored the address of every data type, so we have to create the separate pointer By considering pointed data type.

Can we access the content above pointer as-
1.       Printf(“%d”, *p);                      // output is 10
2.       Printf(“%c”, *cp);                      // output is  a
3.       Printf(“%f”, *fp);                      // output is 3.14
4.       Printf(“%ld”, *dp);                      // output is 6.10

Instead of Creating different pointer we create a single pointer which is capable to Hold address of any data type. That is void pointer.

Eg-         void *vp = NULL;
   vp = &no;
               printf(“ %d ”, *( int *) vp);                         // Output is - 10
               vp = &ch;
                                       printf(“ %c ”, *( char *) vp);                      // Output is - a
   vp = &ff;
               printf(“ %f ”, *( float *) vp);                      // Output is – 3.14
   vp = &d;             
               printf(“ %ld ”, *( double *) vp);                // Output is – 6.10

To access the data by using void * we have to use type cast because our void * unable the predict How much byte fetched from pointed data type.
-          If we  type cast with char *  we can fetch 1 byte.
-          If we  type cast with float *  we can fetch 4 byte.


[ NOTE-   We can not perform any arithmetic pointer with void pointer.By using any appropriate type casting we can perform arithmetic opration. We can initialize any other pointer to void pointer.]

Eg -               int no = 11;
                      int *p = &no;
                      void *vp = NULL;
                      vp = p;

but we cannot initialize to void pointer to any specific pointer.
Eg -        p = vp;     // NOT ALLOWED

Function Pointer :-

1.       Function pointer is considered as normal pointer , which required 4 bytes of memory.
2.       Function pointer Holds address of function.  Which is the part of text section.
3.       Like normal pointer we can store address of our function with pointer.
4.       In case of normal pointer we can apply * operator for fetch information, but in case of function pointer is no need to use * operator.
5.       In C / C++ these are 2 things in which name is at internally  contains its base address.
1.       Array                          2.  function
6.       To create function pointer the prototype of function is to be known , whose address is to be stored in function pointer.
7.       Consider the below example which contains 2 pointer whose prototype is same.

Eg          int  add ( int no1, int no2 )          // consider 1000 is address
              {
                             int ans = 0;
                             ans = no1 + no2;
                             return ans;
}
int sub ( int no1, int no2)             //consider 2000 is address
{
              int ans = 0;
              ans = no1 – no2;
              return ans;
}
As we want to create function pointer our technique should be –

                                     int       add       ( int  ,   int ) ;   //normal function

 int       (*fp)      ( int ,   int) ;   // here fp is pointer which hold address of add( )

-          we can read above syntax as fp is pointer which hold address of such function  which accept 2 parameter both are integer. and it returns integer as return value.
-          At this stage we want to store address of function in 

fp = add ;
fp ( 10 , 20) ;      // call to add( )

fp = sub ;
fp ( 20 ,10) ;       // call to sub( )

8.       Applications of function pointer –
-          In System programming function pointer required.
-          If we want to receive address of function from DLL ( Dynamic link library ) then it should require.
-          We can  practically explore this concept in virtual  in C++.
9.    We can create different type of pointer which points to every section of executable file(.exe )
10.       Means our pointer points to text section , data section , stack section.
11.       Below programe explains all the type of pointer as

#include<stdio.h>
void fun ( int no)                                        // text section
{
              Prinf( “inside fun\n”);
}

int  global1 ;                                               // BSS                  data section               
int  global2 = 11 ;                                       //NON BSS         data section
int main()
{
            int i = 21;                                      // stack section
            int *p = (int *)malloc(40);            // heap section

            void (*fp) (int) ;
fp = fun;
int *no = &i;
int *g1 = &global1;
int *g2 = &global2;
return 0;
}          
                
We can diagrammatically represent exe of above programe as –




























Constant with Pointer :-

   1.       Constant pointer is considered as data type qualifier, by using this quality we cannot change data of the variable.
   2.       If our variable is constant variable then value of that variable remains as it is through out of our programe.
     
  










 4.       According to c++ rule constant variable should be at a time of definition otherwise compiler generate error.
Eg                         const int I;         //error in c++ but allowed in c
                                   i = 21;            // error in both C and C++


























-          Above syntax is explains concept of constant with pointer
-          There are 4 different scenario in it & we read the statement as –
-          1.  -  no is s vaiable of type integer which is initialize to 11.
- P is pointer which hold address of integer and currently it hold address of no.
                               2.  -  no is s vaiable of type integer constant which is initialize to 11.
                                    - P is pointer which hold address of integer constant and currently it hold address of no.
                               3.  -  no is s vaiable of type integer which is initialize to 11.
 - P is a constant pointer which hold address of integer and currently it hold address of no.
                               4.   -  no is s vaiable of type integer constant which is initialize to 11.
 - P is constant pointer which hold address of integer constant and currently it hold address of no.

Array of pointer
       An Array of pointer is collection of addresses. The addresses in an Array of pointer could be the Addresses of isolated variable of addresses of an Array element or any other addresses.  The only constraint is all the pointer in an array must be of same type.

Eg     // Array of pointer
         #include<stdio.h>
         int main()
        {
                int  a = 10, b = 20, c = 30 ;
                int *arr[3] ={&a, &b, &c} ;  // arr is array of integer pointer which                                                                       hold address of variable a, b , c

                printf(“The value of variable\n”);
                printf(“%d %d %d\n”,a,b,c);                                 //output 10 20 30
                printf(“%d %d %d\n”,*arr[0],*arr[1],*arr[2] );    //output 10 20 30
                return 0;
         }
Remarks: - arr is array of integer pointer which hold address of variable a, b ,c 
                    -  All the variable are of the same  type.














Working with Pointers and Structures:-

You have seen how a pointer can be defined to point to a basic data type,
 such as an int or a char. But pointers can also be defined to point to structures.

“Working with Structures,” you defined your date structure as follows:
Working with Pointers and Structures
struct date
{
int month;
int day;
int year;
};
Just as you defined variables to be of type struct date,    
               struct date todaysDate;
so can you define a variable to be a pointer to a struct date variable:
      struct date *datePtr;

The variable datePtr, as just defined, then can be used in the expected fashion.
For example, you can set it to point to todaysDate with the assignment statement

datePtr = &todaysDate;

After such an assignment has been made, you then can indirectly access any of the members of the date structure pointed to by datePtr in the following way:
   (*datePtr).day = 21;

This statement has the effect of setting the day of the date structure pointed to by datePtr to 21. The parentheses are required because the structure member operator . has higher precedence than the indirection operator *To test the value of month stored in the date structure pointed to by datePtr, a statement such as- 

if ( (*datePtr).month == 12 )
...
can be used.


Pointers to structures are so often used in C that a special operator exists in the language. The structure pointer operator ->, which is the dash followed by the greater than sign, permits expressions that would otherwise be written as,
(*x).y
to be more clearly expressed as
x->y


So, the previous if statement can be conveniently written as
if ( datePtr->month == 12 )
...
can be used.

Program  Using Pointers to Structures

// Program to illustrate structure pointers
#include <stdio.h>
int main (void)
{
struct date
{
int month;
int day;
int year;
};
struct date today, *datePtr;
datePtr = &today;
datePtr->month = 9;
datePtr->day = 25;
datePtr->year = 2004;
printf ("Today's date is %i/%i/%.2i.\n",
datePtr->month, datePtr->day, datePtr->year % 100);
return 0;
}
Output
Today's date is 9/25/04.

Working with Pointers and Structures

Structures Containing Pointers

Naturally, a pointer also can be a member of a structure. In the structure definition

struct intPtrs
{
int *p1;
int *p2;
};

a structure called intPtrs is defined to contain two integer pointers, the first one called p1 and the second one p2.
You can define a variable of type struct intPtrs in the usual way:

struct intPtrs ptr;

The variable ptr can now be used in the normal fashion, remembering that  ptr itself is not a pointer, but a structure variable that has two pointers as its members.

how the intPtrs structure can be handled in a C program.

Program Using Structures Containing Pointers
// Function to use structures containing pointers
#include <stdio.h>
int main (void)
{
struct intPtrs
{
int *p1;
int *p2;
};
struct intPtrs ptr;
int i1 = 100, i2;
ptr.p1 = &i1;
ptr.p2 = &i2;
*ptr.p2 = -97;

printf ("i1 = %i, *ptr.p1 = %i\n", i1, *ptr.p1);
printf ("i2 = %i, *ptr.p2 = %i\n", i2, *ptr.p2);
return 0;
}
Program Output

i1 = 100, *ptr.p1 = 100
i2 = -97, *ptr.p2 = -97