LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   LKMPG (Linux Kernel Module Programming Guide) and me.....Help!!! (https://www.linuxquestions.org/questions/linux-newbie-8/lkmpg-linux-kernel-module-programming-guide-and-me-help-724648/)

gauravholey 05-08-2009 06:29 AM

LKMPG (Linux Kernel Module Programming Guide) and me.....Help!!!
 
hi there,

this is gaurav.i trying to explore the magic of kernel programming through LKMPG(Linux Kernel Module Programming Guide).Somehow manage to sailed easily through the initial topics...but facing problem while implementing the advance topics...like k/b led on-off,scheduler....i'm using Fedora core 8,kernel 2.6.25,working on AMD64 Athlon x2 platform.i doesnt have previous programming experience for kernel.i am an embedded engineer with experience of progamming for 8,16,32 bit processors.For the scheduler module....i m getting following errors....


[root@localhost src]# make
make -C /lib/modules/2.6.25/build M=/usr/src modules
make[1]: Entering directory `/usr/src/linux-2.6.25'
CC [M] /usr/src/sched.o
/usr/src/sched.c:21:45: error: macro "DECLARE_WORK" passed 3 arguments, but takes just 2
/usr/src/sched.c:21: warning: type defaults to ‘int’ in declaration of ‘DECLARE_WORK’
/usr/src/sched.c: In function ‘intrpt_routine’:
/usr/src/sched.c:27: warning: passing argument 2 of ‘queue_delayed_work’ from incompatible pointer type
/usr/src/sched.c: In function ‘init_module’:
/usr/src/sched.c:64: warning: passing argument 2 of ‘queue_delayed_work’ from incompatible pointer type
/usr/src/sched.c: In function ‘cleanup_module’:
/usr/src/sched.c:76: warning: passing argument 1 of ‘cancel_delayed_work’ from incompatible pointer type
make[2]: *** [/usr/src/sched.o] Error 1
make[1]: *** [_module_/usr/src] Error 2
make[1]: Leaving directory `/usr/src/linux-2.6.25'
make: *** [all] Error 2

your valuable guidance needed.....plz help

Best Regards,
Gaurav Holey

sarin 05-08-2009 06:52 AM

Wrong forum. But, may be some mod will move it. Anyway, It looks like you are looking at a tutorial that is dated. The current DECLARE_WORK macro takes only two arguments. The first one is the name of the task structure and the next is the function that need to be run. Had a quick look at the tut that you were mentioning. Open you sched.c and look for

Quote:

static struct work_struct Task;
static DECLARE_WORK(Task, intrpt_routine, NULL);
Change this to

Quote:

static DECLARE_WORK(Task, intrpt_routine);
Now try compiling. It should mostly work.

gauravholey 05-14-2009 02:57 AM

hi there,

lately i have tried removing the 3rd argument from macro DECLARE_WORK as per new kernel standards....my code got compiled with few warnings as under...

[root@localhost src]# make
make -C /lib/modules/2.6.25/build M=/usr/src modules
make[1]: Entering directory `/usr/src/linux-2.6.25'
CC [M] /usr/src/sched.o
/usr/src/sched.c:21: warning: initialization from incompatible pointer type
/usr/src/sched.c: In function ‘intrpt_routine’:
/usr/src/sched.c:27: warning: passing argument 2 of ‘queue_delayed_work’ from incompatible pointer type
/usr/src/sched.c: In function ‘init_module’:
/usr/src/sched.c:64: warning: passing argument 2 of ‘queue_delayed_work’ from incompatible pointer type
/usr/src/sched.c: In function ‘cleanup_module’:
/usr/src/sched.c:76: warning: passing argument 1 of ‘cancel_delayed_work’ from incompatible pointer type
Building modules, stage 2.
MODPOST 5 modules
LD [M] /usr/src/sched.ko
make[1]: Leaving directory `/usr/src/linux-2.6.25'


i have tried insmoding it but system hangs and i have to reboot it forcefully....and very foolish thing i should mention that i am unable to find out the exact output and working of this particular module...need your help....


Best Regards,
Gaurav Holey

gauravholey 05-14-2009 05:35 AM

LKMPG (Linux Kernel Module Programming Guide) and Help me AGAIN...!!
 
hi there,

This is in reference with the my first post...."LKMPG (Linux Kernel Module Programming Guide) and me...HELP!!!"

lately i have tried removing the 3rd argument from macro DECLARE_WORK as per new kernel standards....my code got compiled with few warnings as under...

[root@localhost src]# make
make -C /lib/modules/2.6.25/build M=/usr/src modules
make[1]: Entering directory `/usr/src/linux-2.6.25'
CC [M] /usr/src/sched.o
/usr/src/sched.c:21: warning: initialization from incompatible pointer type
/usr/src/sched.c: In function ‘intrpt_routine’:
/usr/src/sched.c:27: warning: passing argument 2 of ‘queue_delayed_work’ from incompatible pointer type
/usr/src/sched.c: In function ‘init_module’:
/usr/src/sched.c:64: warning: passing argument 2 of ‘queue_delayed_work’ from incompatible pointer type
/usr/src/sched.c: In function ‘cleanup_module’:
/usr/src/sched.c:76: warning: passing argument 1 of ‘cancel_delayed_work’ from incompatible pointer type
Building modules, stage 2.
MODPOST 5 modules
LD [M] /usr/src/sched.ko
make[1]: Leaving directory `/usr/src/linux-2.6.25'


i have tried insmoding it but system hangs and i have to reboot it forcefully....and very foolish thing i should mention that i am unable to find out the exact output and working of this particular module...need your help....


Best Regards,
Gaurav Holey

estabroo 05-14-2009 07:17 AM

You need to look at what the kernel your working with requires, take a look at those functions/macros and see what you should be passing them.

pixellany 05-14-2009 07:24 AM

Quote:

Originally Posted by gauravholey (Post 3540334)
hi there,
This is in reference with the my first post...."LKMPG (Linux Kernel Module Programming Guide) and me...HELP!!!"

Please do not do this----keep all your related discussions in the same thread.

I have merged your two threads.

sarin 05-14-2009 12:57 PM

Corrected for 2.6.23-17. Hope this will work on 2.6.25.

Code:

/*
 *  sched.c - scheduale a function to be called on every timer interrupt.
 *
 *  Copyright (C) 2001 by Peter Jay Salzman
 */

/*
 * The necessary header files
 */

/*
 * Standard in kernel modules
 */
#include <linux/kernel.h>        /* We're doing kernel work */
#include <linux/module.h>        /* Specifically, a module */
#include <linux/proc_fs.h>        /* Necessary because we use the proc fs */
#include <linux/workqueue.h>        /* We scheduale tasks here */
#include <linux/sched.h>        /* We need to put ourselves to sleep
                                  and wake up later */
#include <linux/init.h>                /* For __init and __exit */
#include <linux/interrupt.h>        /* For irqreturn_t */

struct proc_dir_entry *Our_Proc_File;
#define PROC_ENTRY_FILENAME "sched"
#define MY_WORK_QUEUE_NAME "WQsched.c"

/*
 * The number of times the timer interrupt has been called so far
 */
static int TimerIntrpt = 0;

void intrpt_routine(struct work_struct *test);

static int die = 0;                /* set this to 1 for shutdown */

/*
 * The work queue structure for this task, from workqueue.h
 */
static struct workqueue_struct *my_workqueue;

static DECLARE_DELAYED_WORK(Task, intrpt_routine);

/*
 * This function will be called on every timer interrupt. Notice the void*
 * pointer - task functions can be used for more than one purpose, each time
 * getting a different parameter.
 */
void intrpt_routine(struct work_struct *test)
{
        /*
        * Increment the counter
        */
        TimerIntrpt++;

        /*
        * If cleanup wants us to die
        */
        if (die == 0)
                queue_delayed_work(my_workqueue, &Task, 100);
}

/*
 * Put data into the proc fs file.
 */
ssize_t
procfile_read(char *buffer,
              char **buffer_location,
              off_t offset, int buffer_length, int *eof, void *data)
{
        int len;                /* The number of bytes actually used */

        /*
        * It's static so it will still be in memory
        * when we leave this function
        */
        static char my_buffer[80];

        /*
        * We give all of our information in one go, so if anybody asks us
        * if we have more information the answer should always be no.
        */
        if (offset > 0)
                return 0;

        /*
        * Fill the buffer and get its length
        */
        len = sprintf(my_buffer, "Timer called %d times so far\n", TimerIntrpt);

        /*
        * Tell the function which called us where the buffer is
        */
        *buffer_location = my_buffer;

        /*
        * Return the length
        */
        return len;
}

/*
 * Initialize the module - register the proc file
 */
int __init init_module()
{
        /*
        * Create our /proc file
        */
        Our_Proc_File = create_proc_entry(PROC_ENTRY_FILENAME, 0644, NULL);
       
        if (Our_Proc_File == NULL) {
                remove_proc_entry(PROC_ENTRY_FILENAME, &proc_root);
                printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
                      PROC_ENTRY_FILENAME);
                return -ENOMEM;
        }

        Our_Proc_File->read_proc = procfile_read;
        Our_Proc_File->owner = THIS_MODULE;
        Our_Proc_File->mode = S_IFREG | S_IRUGO;
        Our_Proc_File->uid = 0;
        Our_Proc_File->gid = 0;
        Our_Proc_File->size = 80;

        /*
        * Put the task in the work_timer task queue, so it will be executed at
        * next timer interrupt
        */
        my_workqueue = create_workqueue(MY_WORK_QUEUE_NAME);
        queue_delayed_work(my_workqueue, &Task, 100);
       
       
        printk(KERN_INFO "/proc/%s created\n", PROC_ENTRY_FILENAME);
       
        return 0;
}

/*
 * Cleanup
 */
void __exit cleanup_module()
{
        /*
        * Unregister our /proc file
        */
        remove_proc_entry(PROC_ENTRY_FILENAME, &proc_root);
        printk(KERN_INFO "/proc/%s removed\n", PROC_ENTRY_FILENAME);

        die = 1;                /* keep intrp_routine from queueing itself */
        cancel_delayed_work(&Task);        /* no "new ones" */
        flush_workqueue(my_workqueue);        /* wait till all "old ones" finished */
        destroy_workqueue(my_workqueue);

        /*
        * Sleep until intrpt_routine is called one last time. This is
        * necessary, because otherwise we'll deallocate the memory holding
        * intrpt_routine and Task while work_timer still references them.
        * Notice that here we don't allow signals to interrupt us.
        *
        * Since WaitQ is now not NULL, this automatically tells the interrupt
        * routine it's time to die.
        */

}

/*
 * some work_queue related functions
 * are just available to GPL licensed Modules
 */
MODULE_LICENSE("GPL");

After inserting, run the following command,

while true; do cat /proc/sched;sleep 3; done

To exit, press "ctrl-c". "rmmod sched" after testing and do "ls /proc/sched". You will find that the file has disappeared.

What does it do?
Schedules the function intrpt_routine. This function can schedule itself once called. The same function increments a variable TimerIntrpt. When you read /proc/sched, you get the value of TimerIntrpt.

gauravholey 05-14-2009 01:05 PM

sorry for my shabby work....i'll keep that thing in mind.....my question still remains unanswered....how should i approach the problem .....plz help...i m stuck...

hgaurav

sarin 05-14-2009 01:08 PM

For the approach, look at the post by estabroo. For the solution, look at my post above.

gauravholey 05-15-2009 04:10 AM

hi there,

thanks,finally it worked...but while going through the sarin's code the two changes observed are...the use of Macro DECLARE_DELAYED_WORK and the function intrpt_routine.... i have gone through the interrupt.h and the other related header files but not able to understand the parameter pass to this function....please guide...


Best Regards,
Gaurav Holey

naek 09-18-2009 08:02 AM

still about the warnings
 
I recently have had some warnings on the same function DECLARE_WORK and all the places in code i have the first term of DECLARE_WORK.
As far as i know it's not ok to have warnings, and in general it is always possible to get rid of them.
so i have:
static struct task;
DECLARE_WORK(task, function);
i have a warning for this:
warning: initialization from incompatible pointer type

and after that
queue_delayed_work(my_queue, &task, 1);


anyway all the places i use task i got errors:

warning: passing argument 2 of ‘queue_delayed_work’ from incompatible pointer type

what is the problem actually, does someone know?

Thanks in advance, and yes all i want is just to get rid of those warnings.

superSmash09 07-21-2010 09:29 AM

Thanks alot to sarin and estabroo. I signed up to say thanx. You gave me the lead I needed, both working code and a point in the right direction as to where to look for such info. Gracias
OGRE


All times are GMT -5. The time now is 02:29 AM.