Thursday 20 February 2014

Hello World Kernel Module

Hello World Kernel

file hello.c

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


#define HELLO_AUTHOR "Rajesh6115 <sahoorajesh.d@gmail.com>"
#define HELLO_DESC "A Simple Hello World Module"

static int __init hello_init(void);
static void __exit hello_exit(void);

MODULE_LICENSE("GPL");
MODULE_AUTHOR(HELLO_AUTHOR); /* Who wrote this module? */
MODULE_DESCRIPTION(HELLO_DESC); /* What does this module do */

static int __init hello_init(void){
    printk(KERN_INFO "Hello World Linux Kernel --------INIT Message");
return 0;
}

static void __exit hello_exit(void){
    printk(KERN_INFO "Good Bye Linux Kernel --------EXIT Message");
}

module_init(hello_init);
module_exit(hello_exit);

BUILD AND RUNNIG A Hello MODULE

For Building a Module We Normally Take the help of Kernel Build Script.
which present in '/lib/modules/<kernel version>/build' path.

Make File for Hello Module

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

Compile by make command

Out put in my system

rajesh@ubuntu:~/rajesh/kernelmod/hello$ make
make -C /lib/modules/3.12.6-rajesh-first/build M=/home/rajesh/rajesh/kernelmod/hello modules
make[1]: Entering directory `/host/linux-3.12.6'
  CC [M]  /home/rajesh/rajesh/kernelmod/hello/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/rajesh/rajesh/kernelmod/hello/hello.mod.o
  LD [M]  /home/rajesh/rajesh/kernelmod/hello/hello.ko
make[1]: Leaving directory `/host/linux-3.12.6'
rajesh@ubuntu:~/rajesh/kernelmod/hello$
Some New files will generate in same directory
And our driver file is 'hello.ko'

Run/Load the module by using 'insmod' Command
To execute that Command you should be root user or use sudo to execute

rajesh@ubuntu:~/rajesh/kernelmod/hello$ sudo insmod ./hello.ko
[sudo] password for rajesh:
rajesh@ubuntu:~/rajesh/kernelmod/hello$
'printk' function log the message to kernel log file.And we can see the same by 'dmesg' command
rajesh@ubuntu:~/rajesh/kernelmod/hello$ dmesg | tail -5
[ 1094.480372] audit_printk_skb: 177 callbacks suppressed
[ 1094.480375] type=1400 audit(1392792445.131:71): apparmor="DENIED" operation="capable" parent=1 profile="/usr/sbin/cupsd" pid=797 comm="cupsd" pid=797 comm="cupsd" capability=36  capname="block_suspend"
[ 1599.091190] perf samples too long (2510 > 2500), lowering kernel.perf_event_max_sample_rate to 50000
[ 6380.140339] Hello World Linux Kernel --------INIT Message

Unload/Remove the module by using 'rmmod' Command
To execute that Command you should be root user or use sudo to execute

rajesh@ubuntu:~/rajesh/kernelmod/hello$ sudo rmmod hello
Again we will see exit message using 'dmesg'
rajesh@ubuntu:~/rajesh/kernelmod/hello$ dmesg | tail -5
[ 1094.480375] type=1400 audit(1392792445.131:71): apparmor="DENIED" operation="capable" parent=1 profile="/usr/sbin/cupsd" pid=797 comm="cupsd" pid=797 comm="cupsd" capability=36  capname="block_suspend"
[ 1599.091190] perf samples too long (2510 > 2500), lowering kernel.perf_event_max_sample_rate to 50000
[ 6380.140339] Hello World Linux Kernel
[ 6423.920972] Good Bye Linux Kernel --------EXIT Message

Find Same Code in github at 

https://github.com/rajesh6115/kernelStudy/tree/master/hello

Tuesday 21 January 2014

Multiple User Timers in Linux using C

User Level Timers for Linux System. Small Demo Code for How to Implement User Level Timers In C

Main Small Implementation of Timer.


#include <stdio.h>
#include <string.h>
//#include <unistd.h>
#include <time.h>
#include <stdlib.h>
unsigned int IS_TIMER_TH_RUN;
unsigned int ST_TIMER_TH;
struct mytimer;
struct mytimer{
        time_t tm_start;
        time_t tm_ticks;
        unsigned int ui_auto_reload;
        unsigned int ui_timer_id;
        unsigned int si_is_active;
        void (*callback)(const char *name, unsigned int id);
        struct mytimer *link;
        char pc_name[32];
};      
typedef struct mytimer mytimer_t;
/*
struct mylist{
        struct mylist *link;
        mytimer_t data;
};      
*/              
static mytimer_t *timer_list_head;
static mytimer_t *timer_list_tail;
                        
int timer_list_add(mytimer_t *new){
        if(new == NULL)
                return 0;
        if(timer_list_head == NULL){
                timer_list_tail = new;
                timer_list_head = new;
        }else{ 
                timer_list_tail->link = new;
                timer_list_tail = new;
        }
        return 1;
}       

int timer_list_free(mytimer_t *head){
        mytimer_t *temp;
        while(head){
                temp = head;
                head = head->link;
                free(temp);
        }
}
int timer_list_remove(mytimer_t *prev, mytimer_t *node){

        if(prev == timer_list_head){
                timer_list_head=node->link;
                //timer_list_head = NULL;

                //timer_list_tail = NULL;
        }else{
                prev->link = node->link;
                if(node->link == NULL){
                        timer_list_tail=prev;
                }
        }
        free(node);
        return 1;
}

void * timer_thread(void *arg){
        mytimer_t *iterator,*temp;
        time_t tm_cur_time;
        ST_TIMER_TH = 1;
        while(IS_TIMER_TH_RUN){
                if(timer_list_head==NULL){
                        usleep(10000);
                        continue;
                }
                iterator = timer_list_head;
                while(iterator){
                        if(iterator->si_is_active){
                                tm_cur_time = time(NULL);
                                temp = iterator;
                                iterator = iterator->link;
                                if((tm_cur_time - (temp->tm_start )) >= (temp->tm_ticks)){
                                        if(temp->callback != NULL){
                                                printf("Calling Call Back timer=%p cur= %u start=%u ticks=%u \n", temp, tm_cur_time,temp->tm_start,temp->tm_ticks);
                                                (*(temp->callback))(temp->pc_name,temp->ui_timer_id);
                                                //printf("sucess Call Back\n");

                                                temp->si_is_active=0;
                                                //mytimer_stop(temp);
                                        }
                                        //if auto reload re-start
                                        //remove from list here only
                                }
                        }else{
                                iterator = iterator->link;
                        }
                        usleep(5000);
                }
        }
        ST_TIMER_TH = 0;
}

int mytimer_init(void){
        pthread_t thId;
        timer_list_head = NULL;
        timer_list_tail = NULL;
        IS_TIMER_TH_RUN = 1;
        ST_TIMER_TH =0;

        if(pthread_create(&thId, NULL, timer_thread, NULL)==0){
                return 1;
        }
        else{
                return 0;
        }

}

void mytimer_cleanup(void){
        IS_TIMER_TH_RUN=0;
        timer_list_free(timer_list_head);
}

mytimer_t * mytimer_create(const char *pc_name, time_t t_ticks, unsigned int ui_auto_reload, unsigned int ui_timer_id, void (*callback)(const char *name, unsigned int id)){
        mytimer_t *tmp;
        printf("size of timer_t=%d and struct =%d \n",sizeof(timer_t),sizeof(struct mytimer));
        tmp = (mytimer_t *) malloc(sizeof(struct mytimer));
        if(tmp == NULL){
                return NULL;
        }
        memset(tmp,0x00,sizeof(timer_t));
        tmp->tm_start = 0;
        strcpy((tmp->pc_name), pc_name);
        tmp->tm_ticks = t_ticks;
        tmp->ui_auto_reload = ui_auto_reload;
        tmp->ui_timer_id=ui_timer_id;
        tmp->callback=callback;
        tmp->link = NULL;
        printf("Ticks = %u\n", tmp->tm_ticks);
        return tmp;
}

int mytimer_start(mytimer_t *obj){
        obj->tm_start = time(NULL);
        obj->si_is_active = 1;
        timer_list_add(obj);
        return 1;
}
int mytimer_stop(mytimer_t *obj){
        mytimer_t *iterator,*prev;
        iterator = timer_list_head;
        while(iterator){
                if(iterator->link == obj){
                        break;
                }else{
                        iterator = iterator->link;

                }
        }
        if(iterator == NULL)
                return 0;
        timer_list_remove(iterator,obj);
        return 1;
}

int mytimer_is_expire(mytimer_t *obj){
        time_t tm_cur_time;
        tm_cur_time = time(NULL);

        if((tm_cur_time - obj->tm_start) >= obj->tm_ticks){
                return 1;
        }else{
                return 0;
        }
}

int myimer_auto_reload(mytimer_t *obj){
        return 1;
}

Header File For mytimer.c file


#ifndef __MY_TIMER_H_
#define __MY_TIMER_H_
#include <string.h>
#include <stdlib.h>
#include <time.h>

struct mytimer;
typedef struct mytimer mytimer_t;

int mytimer_init(void);
void mytimer_cleanup(void);
mytimer_t * mytimer_create(const char *pc_name, time_t t_ticks, unsigned int ui_auto_reload, unsigned int ui_timer_id, void (*callback)(const char *name, unsigned int id));
int mytimer_start(mytimer_t *obj);
int mytimer_stop(mytimer_t *obj);
int mytimer_is_expire(mytimer_t *obj);
int myimer_auto_reload(mytimer_t *obj);

#endif

Main File to Check The Code


#include <stdio.h>
#include "timer.h"
int IS_RUN;
int timer_cnt;
void timeout_fun(const char *name, unsigned int id){
        printf("timer ID=%d NAME=%s is over flow\n", id, name);
        timer_cnt--;
        if(timer_cnt <=0)
                IS_RUN = 0;
}

int main(int argc, char *argv[]){
        mytimer_t *t1,*t2,*t3,*t4;
        timer_cnt=0;
        IS_RUN=1;
        mytimer_init();
//      const char *pc_name, const time_t t_ticks, unsigned int ui_auto_reload, unsigned int ui_timer_id,
        t1 = mytimer_create("rajesh",10,0,20,timeout_fun);
        printf("t1=%p\n",t1);
        mytimer_start(t1);
        timer_cnt++;
        t2 = mytimer_create("rajesh1",20,0,2,timeout_fun);
        printf("t2=%p\n",t2);
        mytimer_start(t2);
        timer_cnt++;
        t3 = mytimer_create("rajesh3",30,0,3,timeout_fun);
        printf("t3=%p\n",t3);
        mytimer_start(t3);
        timer_cnt++;
        t4 = mytimer_create("rajesh4",10,0,4,timeout_fun);
        mytimer_start(t4);
        printf("t4=%p\n",t4);
        timer_cnt++;
        
        while(IS_RUN){
                sleep(10);
                printf("In main Sleep for 10 Sec\n");
        }
        
        return 0;
}

Friday 10 January 2014

make comparison between numbers in c

Making Comparison Between Two Numbers/Integers

Result of Comparison Can be
1.Equal
2.Less Than
3.Greater Than

1. Comparison For Equality

Using equality operator(==)


int is_equal(int a, int b){
        return (a==b);
}

Using EX-OR bitwise Operator(^)


int is_equal(int a, int b){
        return (!(a^b));
}

Using Pre-Processor Macro(Preferred Method)


#define IS_EQUAL(A,B) (!(A^B))

OR


#define IS_EQUAL(A,B) (A==B)

Complete Program Using all above code snippet


#include <stdio.h>
#define IS_EQUAL(A,B) (A==B)
#define IS_EQUAL1(A,B) (!(A^B))

int is_equal(int a, int b){
        return (a==b);
}

int is_equal1(int a, int b){
        return (!(a^b));
}

int main(int argc, char *argv[]){
        printf("isequal=%d\n", is_equal(10,10));
        printf("isequal=%d\n", is_equal1(10,10));
        printf("isequal=%d\n", IS_EQUAL(10,10));
        printf("isequal=%d\n", IS_EQUAL1(10,10));
        return 0;
}

2. Comparison For Smaller or Lesser Number

Using less than operator(<)


int is_less(int a, int b){
        return (a<b);
}

Using Pre-Processor Macro(Preferred Method)


#define IS_LESS(A,B) (A<B)

Complete Program using above methods


#include <stdio.h>
#define IS_LESS(A,B) (A<B)

int is_less(int a, int b){
        return (a<b);
}

int main(int argc, char *argv[]){
        int num1,num2;
        num1=20;
        num2=10;
        if(is_less(num1,num2))
                printf("%d is less than %d\n", num1, num2);
        if(IS_LESS(num1,num2))
                printf("%d is less than %d\n", num1, num2);
        if(num1<num2)
                printf("%d is less than %d\n", num1, num2);
        return 0;
}

3. Comparison For Greater or Larger Number

Using less than operator(>)


int is_less(int a, int b){
        return (a>b);
}

Using Pre-Processor Macro(Preferred Method)


#define IS_LESS(A,B) (A>B)

Complete Program using above methods


#include <stdio.h>
#define IS_LESS(A,B) (A>B)

int is_less(int a, int b){
        return (a>b);
}

int main(int argc, char *argv[]){
        int num1,num2;
        num1=20;
        num2=10;
        if(is_less(num1,num2))
                printf("%d is greater than %d\n", num1, num2);
        if(IS_LESS(num1,num2))
                printf("%d is greater than %d\n", num1, num2);
        if(num1>num2)
                printf("%d is greater than %d\n", num1, num2);
        return 0;
}


printing hello world without using semicolon in c


#include<stdio.h>

int main(){
        // Printing Hello World without using ; in C
        if(printf("Hello World\n"));

        // printing semicolon(;) without using ; in C
        if(printf(";\n")); 
        return 0;
}