Monday, December 28, 2015

Basic Steps to registering character device driver

1) Create the object of structure named as dev_t which contains two things as major number and minor number.

2) Call function alloc_chardev_region() which is use to create device file by allocating major number and minor number implicitely.

3) If we call this function then there is no need to create device file explicitely.

4) At the time of removing device driver we have to call unregister_chardev_region() function.

5) Compile that driver and insert into kernel using insmod command.

6) We can check the list of devices which are loaded currently by the kernel by opening the file /proc/devices.

7) Major number and minor number gets display in our log file as /var/log/syslog.

--------------------------------------------------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Device Driver Program:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Program Name: driver-1.c
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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

// This header file is required for __init() and __exit() function.
#include<linux/init.h>

// This header file is required for KERN_INFO, KERN_ALERT macros.
#include<linux/kernel.h>

// This header file required for dev_t typedef.
#include<linux/types.h>

// This header file is required for alloc_chrdev_region() and unregister_chrdev_region() function.
#include<linux/fs.h>

// This header file is required for format_dev_t() function.
#include<linux/kdev_t.h>

// structure which contains major number and minor number.
static dev_t mydev;

// Use for debugging
static char buffer[64];

MODULE_AUTHOR("Sunil Bhagwat");
MODULE_LICENSE("GPL");

static __init chardrv_in(void)
{
printk(KERN_INFO "Character driver being loaded.\n");

// It is used to register our device with kernel // Parameters are : // 1. Address of dev_t structure // 2. Starting range of device number // 3. Number of device numbers we want. // 4. Name of device which sill appeare in /proc/devices

alloc_chrdev_region(&mydev, 0, 1, "Demo Driver");

printk(KERN_INFO "Information of our driver is %s \n", format_dev_t(buffer, mydev));
return 0;
}

static void __exit chardrv_out(void)
{
printk(KERN_INFO "Character driver being unloaded. \n");

// It is used to unregister our device with kernel // Parameters are : // 1. Address of dev_t structure // 2. Number of device numbers we want.

unregister_chrdev_region(mydev, 1);
}

module_init(chardrv_in);

module_exit(chardrv_out);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Makefile
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


obj-m += driver-1.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

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

Steps to execute this driver program.

1) Open the terminal and compile this driver-1.c program using "make" command.
       "make"

2) After this type terminal in  "cat /proc/devices" for open the file and see the driver driver             name. e.g. Demo Driver 
       "cat /proc/devices "

3) Open the "syslog" file by using command "cat /var/log/syslog" or "dmesg" and see
    the printk() function output.
 -------------------------------------------------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Program Name:- driver-2.c
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



// This header file is required for __init() and __exit() function.
#include<linux/init.h>

// This header file required for load LKM into kernel.
#include<linux/module.h>

// This header file is required for KERN_INFO, KERN_ALERT macros.
#include<linux/kernel.h>

// This header file is required for alloc_chrdev_region() and unregister_chrdev_region() function.
#include<linux/fs.h>

// This header file is r
equired for the copy to user function.

#include<asm/uaccess.h>

// // This header file is use to support the kernel Driver Model
#include<linux/device.h>

// The device will appear at /dev/char using this value.
#define DEVICE_NAME "My Driver"

// The device class -- this is a character device driver.
#define CLASS_NAME "MY DEVICE DRIVER"

// The license type -- this affects available functionality.
MODULE_LICENSE("GPL");

// The author -- visible when you use modinfo.
MODULE_AUTHOR("Sunil Bhagwat");


MODULE_DESCRIPTION("My Demo Device Driver");

// A version number to inform users.
MODULE_VERSION("0.1");

// Stores the device number -- determined automatically.
static int majorNumber;

// Memory for the string that is passed from userspace.
static char message[250] = {0};

// Used to remember the size of the string stored.

static short size_of_message;

// Counts the number of times the device is opened.
static int numberOpens = 0;

// The device-driver class struct pointer.
static struct class* charClass = NULL;


static struct device* charDevice = NULL;

// The prototype functions for the character driver -- must come before the struct definition.

static int dev_open(struct inode *, struct file *);

static int dev_release(struct inode *, struct file *);

static ssize_t dev_read(struct file *, char *, size_t, loff_t *);

static ssize_t dev_write(struct file *, const char *, size_t, loff_t *);

// Initialize file_operations structure.

static struct file_operations fops = 
{
.open = dev_open,
.read = dev_read,
.write = dev_write,
.release = dev_release,
};

// Driver initialization function.



static int __init char_init(void)
{
printk(KERN_INFO "MyDriver : Driver loaded sucessfully \n");
        //Allocate a major number for the device.
majorNumber = register_chrdev(0, DEVICE_NAME, &fops);

        // If there is a problem in major number allocation .
if(majorNumber < 0)
{
printk(KERN_ALERT "MyDriver : failed to register a major number \n");
return majorNumber;
}
printk(KERN_INFO "MyDriver : reistered correctly with major number %d \n", majorNumber);

         // Register the device class.

charClass = class_create(THIS_MODULE, CLASS_NAME);

if(IS_ERR(charClass))
{
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "Failed to create the device \n");

return PTR_ERR(charClass);
}
printk(KERN_INFO "MyDriver : device class registered correctly \n");

     
// Register the device driver

charDevice = device_create(charClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);

if(IS_ERR(charDevice))
{
class_destroy(charClass);
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT  "Failed to create the device \n");
return PTR_ERR(charDevice);
}
printk(KERN_INFO "MyDriver : device class created correctly \n");
return 0;
}

// Driver cleanup function.

static void __exit char_exit(void)
{
       
// remove the device.

device_destroy(charClass, MKDEV(majorNumber, 0));
     
// unregister the device class.

class_unregister(charClass);
        // remove the device class.
class_destroy(charClass);
        // unregister the major number.
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_INFO "MyDevice : Goodbye from our driver! \n");
}

// Function which gets called when we open the device.

static int dev_open(struct inode *inodep, struct file *filep)
{
numberOpens++;
printk(KERN_INFO "MyDriver : Device has been opened %d time(s) \n", numberOpens);
return 0;
}

// Function is called whenever device is being read from user space i.e. data is

/*
filep : A pointer to a file object (defined in linux/fs.h)
buffer: The pointer to the buffer to which this function writes the data
len : The length of the buffer
offset: The offset if required
*/

static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)
{
int error_count = 0;
        // copy_to_user has the format ( * to, *from, size) and returns 0 on success.
error_count = copy_to_user(buffer, message, size_of_message);
if(error_count == 0)
{
             
// if true then have success


printk(KERN_INFO "MyDriver : Sent %d characters to the user \n", size_of_message);
return (size_of_message = 0); // clear the position to the start and return 0
}
else
{
printk(KERN_INFO "MyDriver : Failed to send %d characters to the user \n", error_count);
return -EFAULT;      // Failed -- return a bad address message (i.e. -14).
}
}

//This function is called whenever the device is being written to from user space i.e.
// data is sent to the device from the user. The data is copied to the message[] array in this
/*
filep: A pointer to a file object
buffer: The buffer to that contains the string to write to the device
len: The length of the array of data that is being passed in the const char buffer
offset: The offset if required
*/

static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset)
{
sprintf(message, "%s(%d letters)", buffer, len);   // appending received string with its length.
size_of_message = strlen(message);  
// store the length of the stored message.
printk(KERN_INFO "MyDriver : Received %d characters from the user \n",len);
return len;
}

// The device release function that is called whenever the device is closed/released by the user space program
/*
inodep: A pointer to an inode object (defined in linux/fs.h)
filep: A pointer to a file object (defined in linux/fs.h)
*/

static int dev_release(struct inode *inodep, struct file *filep) 
{
printk(KERN_INFO "MyDriver : Device successfully closed \n");
return 0;
}


module_init(char_init);
module_exit(char_exit);
--------------------------------------------------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Makefile
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

obj-m += driver-2.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

--------------------------------------------------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Program Name :- DemoDriver.c
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This program is use to perform the operation on device driver file such open, read, write and 
// release as like actual device.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<fcntl.h>
#include<string.h>
#define BUFFER_LENGTH 256               // The buffer length (crude but fine)
static char receive[BUFFER_LENGTH];     // The receive buffer from the LKM
int main(){
   int ret, fd;
   char stringToSend[BUFFER_LENGTH];
   printf("Starting device test code example...\n");
   fd = open("/dev/Marvellous Driver 1", O_RDWR);     // Open the device with read/write access
   if (fd < 0){
      perror("Failed to open the device...");
      return errno;
   }
   printf("Type in a short string to send to the kernel module:\n");
   scanf("%[^\n]%*c", stringToSend);                // Read in a string (with spaces)
   printf("Writing message to the device [%s].\n", stringToSend);
   ret = write(fd, stringToSend, strlen(stringToSend)); // Send the string to the LKM
   if (ret < 0){
      perror("Failed to write the message to the device.");
      return errno;
   }
   printf("Press ENTER to read back from the device...\n");
   getchar();
   printf("Reading from the device...\n");
   ret = read(fd, receive, BUFFER_LENGTH);        // Read the response from the LKM
   if (ret < 0){
      perror("Failed to read the message from the device.");
      return errno;
   }
   printf("The received message is: [%s]\n", receive);
   printf("End of the program\n");
   return 0;
}
--------------------------------------------------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Steps to execute this device driver program.

1) Run "make" utility to create .ko file.

2) Insert device driver in kernel image by using insmod command.
      "sudo insmod driver-2.ko"

3) Check whether our driver is successfully loaded or not by opening the file /proc/devices.
      " cat /proc/devices"

4) After this compile our "DemoDriver.c" file using gcc command and create executable file.
     " gcc DemoDriver.c -o DemoDriver "

5) Execute that executable file by using following command.
     " sudo ./DemoDriver "

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

Saturday, December 26, 2015

KERNEL MODULE PROGRAMS:-

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Program No. : 1
--------------------------------------------------------------------------------------------------------------------------
// hello-1.c
-------------------------------------------------------------------------------------------------------------------------
// This header file is require for all kernel module.
#include<linux/module.h>

// This header file is require for KERN_INFO macro.
#include<linux/kernel.h>

// This function gets called automatically when module gets loaded by insmod command

// This function returns 0 if it successfully executed otherwise it returns non zero value

int init_module(void)
{
printk(KERN_INFO "Jay ShreeKrishna: module inserted 1\n");
return 0;
}

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

void cleanup_module(void)
{
printk(KERN_INFO "Hare Ram: module removed 1\n");
}

--------------------------------------------------------------------------------------------------------------------------
// Makefile
-------------------------------------------------------------------------------------------------------------------------
obj-m += hello-1.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

--------------------------------------------------------------------------------------------------------------------------
// readme
-------------------------------------------------------------------------------------------------------------------------
module name : hello-1
build makefile
$ make

if there is any problem in our kernel then download requred linux headers as
apt-get install build-essential linux-headers-$(uname -r)

get information of our module using modinfo .ko

insert module using sudo insmod .ko

get list of all installed module as lsmod

check kernel log using /var/log/syslog file

remove kernel module using sudo rmmod  .ko

--------------------------------------------------------------------------------------------------------------------------



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Program No. :- 2
--------------------------------------------------------------------------------------------------------------------------
// hello-2.c
--------------------------------------------------------------------------------------------------------------------------

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

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

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

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

// This function returns 0 if it successfully executed otherwise it returns non zero value

static int __init hello_2_init(void)
{
printk(KERN_INFO "Jay ShreeKrishna: module inserted 2\n");
return 0;
}

// This function gets called automatically when module gets removed from memory by rmmod //command
static void __exit hello_2_exit(void)
{
printk(KERN_INFO "Hare Ram: module removed 2\n");
}

// Register our init function
module_init(hello_2_init);

// Register our cleanup function
module_exit(hello_2_exit);

--------------------------------------------------------------------------------------------------------------------------
// Makefile
-------------------------------------------------------------------------------------------------------------------------
obj-m += hello-2.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

--------------------------------------------------------------------------------------------------------------------------
// readme
-------------------------------------------------------------------------------------------------------------------------
module name : hello-2
build makefile
$ make

if there is any problem in our kernel then download requred linux headers as
apt-get install build-essential linux-headers-$(uname -r)

get information of our module using modinfo .ko

insert module using sudo insmod .ko

get list of all installed module as lsmod

check kernel log using /var/log/syslog file

remove kernel module using sudo rmmod  .ko

--------------------------------------------------------------------------------------------------------------------------


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Program No. :- 3
--------------------------------------------------------------------------------------------------------------------------
// hello-3.c
--------------------------------------------------------------------------------------------------------------------------

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

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

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

// This is used to declare variable named as hello3_data
static int hello3_data __initdata = 0;

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

// This function returns 0 if it successfully executed otherwise it returns non zero value

static int __init hello_3_init(void)
{
printk(KERN_INFO "Jay ShreeKrishna: module inserted with data %d\n", hello3_data);
return 0;
}

// This function gets called automatically when module gets removed from memory by rmmod
static void __exit hello_3_exit(void)
{
printk(KERN_INFO "Hare Ram: module removed\n");
}

// Register our init function
module_init(hello_3_init);

// Register our cleanup function
module_exit(hello_3_exit);

--------------------------------------------------------------------------------------------------------------------------
// Makefile
-------------------------------------------------------------------------------------------------------------------------
obj-m += hello-3.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

--------------------------------------------------------------------------------------------------------------------------
// readme
-------------------------------------------------------------------------------------------------------------------------
module name : hello-3
build makefile
$ make

if there is any problem in our kernel then download requred linux headers as
apt-get install build-essential linux-headers-$(uname -r)

get information of our module using modinfo .ko

insert module using sudo insmod .ko

get list of all installed module as lsmod

check kernel log using /var/log/syslog file

remove kernel module using sudo rmmod  .ko

--------------------------------------------------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Program No. :- 4
--------------------------------------------------------------------------------------------------------------------------
// hello-4.c
--------------------------------------------------------------------------------------------------------------------------

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

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

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

// Macro for name of author
#define DRIVER_AUTHOR "Sunil Bhagwat"

// Macro for module description
#define DRIVER_DESC   "Demo module"

static int __init init_hello_4(void)
{
printk(KERN_INFO "Jay ShreeKrishna: module inserted 4\n");
return 0;
}

static void __exit cleanup_hello_4(void)
{
printk(KERN_INFO "Hare Ram: module removed 4\n");
}

module_init(init_hello_4);
module_exit(cleanup_hello_4);

// Register name of licance
MODULE_LICENSE("GPL");

// Register name of author
MODULE_AUTHOR(DRIVER_AUTHOR);

// Provide module description
MODULE_DESCRIPTION(DRIVER_DESC);
--------------------------------------------------------------------------------------------------------------------------

// Makefile
-------------------------------------------------------------------------------------------------------------------------
obj-m += hello-4.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

--------------------------------------------------------------------------------------------------------------------------
// readme
-------------------------------------------------------------------------------------------------------------------------
module name : hello-4
build makefile
$ make

if there is any problem in our kernel then download requred linux headers as
apt-get install build-essential linux-headers-$(uname -r)

get information of our module using modinfo .ko

insert module using sudo insmod .ko

get list of all installed module as lsmod

check kernel log using /var/log/syslog file

remove kernel module using sudo rmmod  .ko

--------------------------------------------------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Program No. :- 5
--------------------------------------------------------------------------------------------------------------------------
// hello-5.c
--------------------------------------------------------------------------------------------------------------------------
// This header file is required by all kernel modules
#include <linux/module.h>

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

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

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

// Macro for name of author
#define DRIVER_AUTHOR "Sunil Bhagwat"

// Macro for module description
#define DRIVER_DESC   "Demo module with arguments"

int myint = 21;

/*
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
*/
module_param(myint, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(myint, "Integer variable");

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

static void __exit hello_5_exit(void)
{
printk(KERN_INFO "Hare Ram : Removing module\n");
}

module_init(hello_5_init);
module_exit(hello_5_exit);

// Register name of licance
MODULE_LICENSE("GPL");

// Register name of author
MODULE_AUTHOR(DRIVER_AUTHOR);

// Provide module description
MODULE_DESCRIPTION(DRIVER_DESC);

// we can insert our module as insmod myint=11
--------------------------------------------------------------------------------------------------------------------------

// Makefile
-------------------------------------------------------------------------------------------------------------------------
obj-m += hello-5.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

--------------------------------------------------------------------------------------------------------------------------
// readme
-------------------------------------------------------------------------------------------------------------------------
module name : hello-5
build makefile
$ make

if there is any problem in our kernel then download requred linux headers as
apt-get install build-essential linux-headers-$(uname -r)

get information of our module using modinfo .ko

insert module using sudo insmod .ko

get list of all installed module as lsmod

check kernel log using /var/log/syslog file

remove kernel module using sudo rmmod  .ko

--------------------------------------------------------------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Program No. :- 6
--------------------------------------------------------------------------------------------------------------------------
// first.c
--------------------------------------------------------------------------------------------------------------------------

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

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

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

int init_module(void)
{
              printk(KERN_INFO "Jay ShreeKrishna : Inserting module\n");
              return 0;
}

--------------------------------------------------------------------------------------------------------------------------
// second.c
--------------------------------------------------------------------------------------------------------------------------

#include <linux/kernel.h>
#include <linux/module.h>

void cleanup_module()
{
            printk(KERN_INFO "Hare Ram : Removing the module\n");
}

--------------------------------------------------------------------------------------------------------------------------

// Makefile
--------------------------------------------------------------------------------------------------------------------------
obj-m += firstsecond.o
firstsecond-objs := first.o second.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
-------------------------------------------------------------------------------------------------------------------------

// readme
--------------------------------------------------------------------------------------------------------------------------

module name : hello-6
build makefile

if there is any problem in our kernel then download requred linux headers as
apt-get install build-essential linux-headers-$(uname -r)

get information of our module using modinfo .ko

insert module using sudo insmod .ko

get list of all installed module as lsmod

check kernel log using /var/log/syslog file

remove kernel module using sudo rmmod  .ko

--------------------------------------------------------------------------------------------------------------------------

Library Development in Linux

1) Library is a set of functions which are used by another executable files.

2) Library are consider as dependable executable, which is not directly run because we have to need some executable files for linking purpose.

3) According to the linking there are two types of library:-
   i)  Static link library.
   ii) Dynamic link library.  
--------------------------------------------------------------------------------------------------------------------------

1) Static Link Library in Linux:-

    i) This type of library gets link to executable at compile time.
 
    ii) Contents of this library are attach with the executable file permanently due to which a size of              executable file get increase permanently.
 
    iii) In case of static library same library can be loaded multiple times in memory due to which                   there is an memory wastage.
 
    iv) The extension of static link library is generally ".a" .

-------------------------------------------------------------------------------------------------------------------------
/* Program to use static link library */

Step 1:- Create header file which contains prototypes of functions from our library.

// sharedfile.h
--------------------------------------------------------------------------------------------------------------------------
int DemoAdd(int, int);
int DemoMultiply(int, int);
--------------------------------------------------------------------------------------------------------------------------

Step 2:- Create normal .c file which contains the function defination for our library.

// sharedfile.c
--------------------------------------------------------------------------------------------------------------------------
int DemoAdd(int iNum1, int iNum2)
{
         return iNum1 + iNum2;
}

int DemoMultiply(int iNum1, int iNum2)
{
        return iNum1 * iNum2;
}
--------------------------------------------------------------------------------------------------------------------------

Step 3:- Create other .c file which internally calls the function of our library file.

//main.c
--------------------------------------------------------------------------------------------------------------------------
#include<stdio.h>
#include "sharedfile.h"

int main()
{
        int iAns = 0, iAns1 = 0;
        iAns = DemoAdd(10, 20);
        
        printf("The Addition of 10 and 20 is %d \n", iAns);

        iAns1 = DemoMultiply(10, 20);
        
        printf("The Multiplication of 10 and 20 is %d \n", iAns1);

        return 0;
}
--------------------------------------------------------------------------------------------------------------------------
Step 4:- Compile our library file to convert it into  .o  file.
      
          "gcc -c sharedfile.c -o sharedfile.o"

after this command .o file gets created which contains object code of our library file.

--------------------------------------------------------------------------------------------------------------------------

Step 5:- Convert this .o file into .a as a library by calling "ar" command which is use to create archieve.

         "ar rcs libdemo.a sharedfile.o"

After this command "libdemo.a" file gets created which contains all the function of our library file in executable format.
         In this command "ar" is the name of command and "rcs" is the option which is use to create relocatable compile segment. "libdemo.a" is the name of library file.
        In linux, name of library file should be start with "lib" word and extension should be ".a".

--------------------------------------------------------------------------------------------------------------------------

Step 6:- Now we have to use the command which is use to link "libdemo.a" file with "main.c" file.

        " gcc -static main.c -L. -ldemo -o main"

i)  gcc :- Command for linking.

ii) -static :- Link option.

ii) main.c :- Input file which use our library.

iv) -L ;- Location mask which specify the location of library.

v) . :- Location of library ( Indicate current location).

vi) main :- Name of executable file as  output.

After using this command we get output file as executable file named as "main".
--------------------------------------------------------------------------------------------------------------------------

Step 7:- We can execute that file using command as,
       
          " ./main"
--------------------------------------------------------------------------------------------------------------------------

We can display the contents of library i.e. static library or shared library as :-

        " nm -g libdemo.a "
-------------------------------------------------------------------------------------------------------------------------
To display the size of our executable file by using the command as :-

       " size ./main ".
-------------------------------------------------------------------------------------------------------------------------


2. Shared object or dynamic link library in Linux :-

1) Concept of shared object is same as dynamic link library in windows.

2) Extension of shared object file as ".so".

3) It is called as dynamic linking because library gets loaded in memory when executable process demands for that library.

4) If our process want to use the functionality of shared object then we have to call some function which are use to load that library in memory, get the address of desire function and unload that library.
    The major advantage of shared library is that the actual source code gets loaded in memory only once.

5) The same source code should be used by different processes simultaneously.

6) Operating system is responsible to maintain the record of library files which are loaded in memory.

--------------------------------------------------------------------------------------------------------------------------

Steps to create shared object:-

Step 1 :- Create .c as shared file, which contains the functionality which has to be shared by other application.

// sharedfile.c

#include "sharedfile.h"

void DemoFun()
{
          printf("Inside shared file");
}

--------------------------------------------------------------------------------------------------------------------------

Step 2 :- Create header file which contains the prototype of functions as

// sharedfile.h

#include<stdio.h>

extern void DemoFun();

--------------------------------------------------------------------------------------------------------------------------

Step 3 :- Create other .c file which internally uses the functionality of  ".so" file.

// main.c

#include<stdio.h>

#include<stdlib.h>

#include<dlfcn.h>
// This header file is use for shared object functions such as dlopen(), dlsym(), dlclose() etc.

int main()
{
           void *p = NULL;
         
           void (*fp)() = NULL;      // This function pointer use to hold the address of library function.

           p = dlopen("path of .so file", RTLD_LAZY);

           fp = dlsym( p, "DemoFun" );

           fp();                           // call library function.

           dlclose(p);

           return 0;
}
--------------------------------------------------------------------------------------------------------------------------
Explaination :-

dlopen() :- This function is use to load our library into memory.

dlsym() :-  This function is use to get the address of desired function from .so file.

dlclose() :- It is use to detach .so file from memory.

-------------------------------------------------------------------------------------------------------------------------

Step 4 :- Convert sharedfile.c file into sharedfile.o  i.e. object file.

              " gcc -fPIC sharedfile.c " or "gcc -c sharedfile.c -o sharedfile.o"

After this command sharedfile.o file is created.

-------------------------------------------------------------------------------------------------------------------------

Step 5 :- Now convert this sharedfile.o file into our .so file.
         
               " gcc -shared -o library.so sharedfile.o "

After this command library.so file gets created.

-------------------------------------------------------------------------------------------------------------------------

Step 6 :- Now create executable which uses .so file as

              " gcc -rdynamic -o main main.c -ldl "

After this main execuable gets created.

--------------------------------------------------------------------------------------------------------------------------

Step 7 :- We can execute that file as

                " ./main "

--------------------------------------------------------------------------------------------------------------------------

thank you,

can you regarding any query please ask me very frankly.

Mob. No. :- +91 9767623508

Email ID :- sunilbhagwat24@gmail.com

--------------------------------------------------------------------------------------------------------------------------


       

Wednesday, December 23, 2015

Writing the first kernel module

Steps to create user defined kernel module......

1) Before writing any kernel module we have to check whether require header files such as kernel.h, init.h and module.h are available with our kernel source code or not. If it is not available in our kernel module then we have to download by using...
 i) In Ubuntu:-
                       sudo apt-get install build-essential linux-headers-$(uname -r).
 ii) In Linux:-
                       main menu-->system setting-->administration-->add/remove application/software.

2) Create new folder in desktop and create two new file in that folder. One file having extention .c which contains the source code of our kernel module and other file is Makefile which is build our kernel module. Both this file is reside in our same folder.

3) Write the source code of kernel module in .c file.

4) Write a command to build our kernel module in our Makefile.

5) Run "make" utility which is use to run Makefile. If there is error in Makefile, we have to solve that error by editing the Makefile.

6) After building our kernel module successfully. We get  .ko (kernel object) and .o (object) file in our current directory.

7) We can check information of our kernel object by using the command.
                  "modinfo filename.ko"

8) After getting .ko file we have to insert that kernel object insert inside kernel image by using the command.
                    "sudo insmod filename.ko "

9) By using "insmod" command our kernel module gets inserted in kernel image whether it is successfully inserted or not is to be check by looking "/proc/module" file or "lsmod" command.

10) After inserting module inside kernel image. init_module() function gets called automatically. If that function contains printk() function call which is use to write the contents inside kernel log file. To get the contents of kernel file by using "dmesg" command or we can open the file which contains the kernel log named as "/var/log/syslog". Inside that file we get the data which is written in printk() function.

11) Now remove that module from the kernel image by using command.
                  "sudo rmmod filename.ko"

12) To check whether our module gets removed from kernel image again we have to call "lsmod" command.
--------------------------------------------------------------------------------------------------------------------------
Steps to write kernel module program.

1) Create .c file having any name.

2) Include require header files for our kernel module. For basic kernel module we have to include kernel.h, module.h and init.h header file.

3) Write a user defined function named as init_module( ) which accept nothing and it should return integer value

4) A code which is written inside that function gets executed automatically when our kernel module gets inserted into kernel by using insmod command and intial stage instead write some other logic we can write prink() function (printk() function is like a normal printf() function) which is use to write data in kernel log file.
        printk() function require two parameter :-
 i) First parameter is macro it indicate priority of our function there are 8 different macros are our arguments. If our message is high priority we can write KERN_ALERT and if priority is normal priority then we can write KERN_INFO macro.

ii) Second parameter of printk() function is like printf() function which is the string that we want to print with the desired format specifier like %d , %s etc.

5) This init_module() is return 0 to indicate the success and other value indicate the failure.

6) We have to write other user defined function named as cleanup_module() function which accept nothing and return nothing.
         Generally this function is use to write for resource deallocation which are allocated by init_module() function.
         This function gets automatically called when our kernel module is removed by rmmod command.

7) The init_module() function is similar as constructor  and cleanup_module() function is similar as destructor in C++  and JAVA language.

-------------------------------------------------------------------------------------------------------------------------
/* First  Kernel Module Program */
/* Program Name:- hello-1.c   */

// This header file is required for KERN_INFO, KERN_ALERT etc macros.
#include<linux/kernel.h>

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

// This function gets called automatically when module gets loaded by insmod command
// This function returns 0 if it successfully executed otherwise it returns non zero value

int init_module(void)
{
            printk(KERN_INFO "Hello World \n");
            return 0;
}

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

void cleanup_module(void)
{
                  printk(KERN_INFO "Good Bye \n");
}

--------------------------------------------------------------------------------------------------------------------------

/*  Makefile */
// Understand that in makefile name,  the first alphabet M should be capital otherwise compiler
// generate error.
--------------------------------------------------------------------------------------------------------------------------

obj-m += hello-1.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

--------------------------------------------------------------------------------------------------------------------------

Steps to run the kernel module

1) Open the terminal and change directory up to your folder we have to save our kernel module program.

2) Type "make" command and enter to execute the kernel module.
     "make"

3) After that we have to give any error solve it. Only changing the Makefile.

4) Type the "ls" command to see the all files. We have to check whether .ko file is created or not.

5) If .ko file is created then we have to insert it into kernel image by using the command:-
     "sudo insmod hello-1.ko"

6) To get information about our kernel module. Type "modinfo" command.
     "modinfo hello-1.ko "

7) To check whether the our kernel module is successfully insert or not. Type "lsmod" command.
    " lsmod | grep hello-1.ko"   or  "lsmod"

8)  After this to see the printk() function message in "var/log/syslog" kernel log file  or simply type "dmesg" command.
   Open that syslog file using "cat syslog" command. or "dmesg" command

9)  After the completing the kernel module task. We have to remove from kernel image by using "rmmod" command.
   
    "sudo rmmod hello-1.ko"
-------------------------------------------------------------------------------------------------------------------------
thank you,

If you have regarding any query contact us:
Mob. No. :- +91 9767623508.
Email ID:- sunilbhagwat24@gmail.com.



SYBSc (CS) Sem III : Data Structure Slip 20 Que - 2

    SAVITIBAI PHULE UNIVERSITY OF PUNE S. Y. B.Sc. (Computer Science) Semester III Practical Examination       SUBJECT: CS-233 Practical cou...