LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 05-11-2007, 09:29 AM   #1
fallen3019
LQ Newbie
 
Registered: May 2007
Distribution: Suse 10.1
Posts: 11

Rep: Reputation: 0
Include kernel header files


I want to find the offset of a member of a structure within the kernel header file sched.h. (/usr/include/linux)
(i.e. I want to found out how many bytes the element 'tasks' is from the start of the task_struct which is declared in sched.h)

Is there a way I can do that?

My plan is to use the offsetof() function in C, but since sched.h is a kernel header file, I just inserting

Code:
#include <linux/sched.h>
does not work. It gives me a looong list of errors from the includes in sched.h.

Is there a way that I can do this?

(i am using Suse 10.1 with kernel 2.6.16.13-4
 
Old 05-12-2007, 10:02 AM   #2
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
First, the easy part. offsetof is not a function, but rather a preprocessor macro. You can use it a few ways yourself:
  1. #include <linux/stddef.h>
  2. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
  3. #define offsetof(TYPE,MEMBER) __builtin_offsetof(TYPE,MEMBER)
(Number 3 can only be used on compilers that implement the __builtin_offsetof operator such as gcc-4.x)


Now for the not-so-easy part, including a linux header file from userspace is useful mostly for getting the values of certain preprocessor macros. You can’t try to access anything in between “#ifdef __KERNEL__” and its corresponding “#endif” unless you are in kernel space. Generally, a distro will “sanitize” the kernel headers (i.e., removing those sections you can’t viably use) and put them in /usr/include/linux. As you can see in an unsanitized version of sched.h, struct task_struct is armored by #ifdef __KERNEL__/#endif (for various reasons). So you can’t do operations on a task_struct unless you are in kernelspace. As for the errors from including sched.h, that is odd. You might not have good, sanitized kernel headers, or you might be inadvertently using headers from your actual kernel source. If this is still puzzling you, can you give us some output from you attempt to compile such a file.
 
Old 05-12-2007, 11:03 AM   #3
fallen3019
LQ Newbie
 
Registered: May 2007
Distribution: Suse 10.1
Posts: 11

Original Poster
Rep: Reputation: 0
Hmmm... that could pose few problems...

Well, in short my code is the following:

Code:
#include <stddef.h>
#include <linux/sched.h>
/*i've tried with #include </usr/include/linux/sched.h> too*/

main ()
{
     int A;

     A = offsetof(struct task_struct, tasks);
     printf ("d = %d \n", A);
}
the offsetof () macro isn't really the issue, because it worked when I used test data structs with it.
My problem is as you said, including sched.h to work on the task_struct.

The errors that I get, when I compile this with gcc 4.1.0
are the following:
Code:
In file included from /usr/include/linux/timex.h:61,
                 from /usr/include/linux/sched.h:11,
                 from task.c:2:
/usr/include/asm/timex.h: In function 'get_cycles':
/usr/include/asm/timex.h:40: error: 'cpu_has_tsc' undeclared (first use in this function)
/usr/include/asm/timex.h:40: error: (Each undeclared identifier is reported only once
/usr/include/asm/timex.h:40: error: for each function it appears in.)
In file included from /usr/include/linux/sched.h:12,
                 from task.c:2:
/usr/include/linux/jiffies.h: At top level:
/usr/include/linux/jiffies.h:75: error: expected ',' or ';' before 'jiffies_64'
/usr/include/linux/jiffies.h:79: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'get_jiffies_64'
In file included from /usr/include/linux/sched.h:12,
                 from task.c:2:
/usr/include/linux/jiffies.h:250:47: error: division by zero in #if
/usr/include/linux/jiffies.h: In function 'jiffies_to_msecs':
/usr/include/linux/jiffies.h:253: error: 'MSEC_PER_SEC' undeclared (first use in this function)
/usr/include/linux/jiffies.h:261:47: error: division by zero in #if
/usr/include/linux/jiffies.h: In function 'jiffies_to_usecs':
/usr/include/linux/jiffies.h:264: error: 'USEC_PER_SEC' undeclared (first use in this function)
/usr/include/linux/jiffies.h:274:47: error: division by zero in #if
/usr/include/linux/jiffies.h: In function 'msecs_to_jiffies':
/usr/include/linux/jiffies.h:277: error: 'MSEC_PER_SEC' undeclared (first use in this function)
/usr/include/linux/jiffies.h:287:47: error: division by zero in #if
/usr/include/linux/jiffies.h: In function 'usecs_to_jiffies':
/usr/include/linux/jiffies.h:290: error: 'USEC_PER_SEC' undeclared (first use in this function)
/usr/include/linux/jiffies.h: In function 'timespec_to_jiffies':
/usr/include/linux/jiffies.h:311: error: called object 'u64' is not a function
/usr/include/linux/jiffies.h:311: error: called object 'u64' is not a function
/usr/include/linux/jiffies.h:311: error: 'NSEC_PER_SEC' undeclared (first use in this function)
/usr/include/linux/jiffies.h:312: error: called object 'u64' is not a function
/usr/include/linux/jiffies.h:312: error: called object 'u64' is not a function
/usr/include/linux/jiffies.h:315: error: expected ')' before 'sec'
/usr/include/linux/jiffies.h:316: error: expected ')' before 'nsec'
/usr/include/linux/jiffies.h: In function 'jiffies_to_timespec':
and this is just a sample... it goes on to about 300 errors from the following files jiffies.h, nodemask.h, cpumask.h, bitmap.h ...these are only some of them, however all these h files that i get errors from are included in sched.h

I am using this version of sched.h

So, what you said about the kernel space, is there a way I can do that in my program? Do i have to #define something? or create some sort of makefile?
Or perhaps you can point me somewhere that explains to me how to do this?

I would also need to get this working to use the sizeof() on the struct page, as mentioned here i imagine...


Thanks

Last edited by fallen3019; 05-12-2007 at 11:06 AM.
 
Old 05-12-2007, 12:04 PM   #4
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
Quote:
Originally Posted by fallen3019
I am using this version of sched.h
If you look at that version of sched.h, you see “#ifdef __KERNEL__” occurs on line 171 (with its corresponding “#endif” on line 1479), surrounding the definition of “struct task_struct” on line 696. So even if you didn’t have those errors, you still wouldn’t have access to the struct. It also appears that at the beginning, various files are included that shouldn’t be included (this has subsequently been fixed) such that one cannot sanely include “linux/sched.h” in a userspace program without the errors that you describe.

Look for code in np.
 
Old 05-12-2007, 12:04 PM   #5
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
Here’s (rather simple) sample code that does what you want:

offset.c
Code:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/sched.h>

MODULE_AUTHOR("osor");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Finds the offset of the element tasks in struct "
                   "task_struct and relays the information to userspace "
		   "through the kernel message buffer (dmesg)");

int init_module()
{
	printk(KERN_INFO "offsetof tasks in task_struct is %d\n", offsetof(struct task_struct, tasks));
	return 0;
}

void cleanup_module() { }
Makefile
Code:
ifndef KERNELDIR
	KERNELDIR  := /lib/modules/$(shell uname -r)/build
endif

obj-m := offset.o

all:
	$(MAKE) -C $(KERNELDIR) M=$(PWD)

clean:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) clean

install:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
	/sbin/depmod -ae
To run, just do something like:
Code:
$ make
make -C /lib/modules/2.6.21/build M=/home/osor/src/offset
make[1]: Entering directory `/usr/src/linux-2.6.21'
  LD      /home/osor/src/offset/built-in.o
  CC [M]  /home/osor/src/offset/offset.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/osor/src/offset/offset.mod.o
  LD [M]  /home/osor/src/offset/offset.ko
make[1]: Leaving directory `/usr/src/linux-2.6.21'
$ sudo insmod offset.ko
$ dmesg | tail -n 1
[ 5198.335455] offsetof tasks in task_struct is 200

Last edited by osor; 05-12-2007 at 12:11 PM. Reason: typo
 
Old 05-12-2007, 01:17 PM   #6
fallen3019
LQ Newbie
 
Registered: May 2007
Distribution: Suse 10.1
Posts: 11

Original Poster
Rep: Reputation: 0
Ah, the kernel modules... Yes, I should have known... what better way than to use Kernel space?


Though.... those caused me another branch of problems with the makefiles.
But i think its a small one actually....

When i create a makefile, I always get the same error...

Code:
make -C /lib/modules/2.6.16.13-4-default/build M=/home/fallen/code/offset
make[1]: Entering directory '/usr/src/linux-2.6.16.13-4-obj/i386/default'
make[1]: *** No targets specified and no makefile found. Stop.
make[1]: Leaving directory '/usr/src/linux-2.6.16.13-4-obj/i386/default'
make: ***[all] Error 2
I think it has something to do with the directories though...
Because the sched.h i need is in /usr/include/linux rather than
/usr/src/linux-2.6.16.13-4-obj/i386/default.

I actually have this problem with any kernel module i try... including those in the LKMPG tutorial...

I have never been well acquanted with makefiles, only what i know from tinkering with them here and there, and that wasn't that much...


thanks loads, your help is proving invaluble, seriously. I have been stuck on this problem for ages
 
Old 05-12-2007, 02:32 PM   #7
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
My first question is this: do you have the buildtree for the kernel you are running? Perhaps you might elucidate the situation by posting the output of the following:
Code:
$ ls -ld /lib/modules/`uname -r`/{build,source}
$ ls -lH /lib/modules/`uname -r`/{build,source}
Without knowing the output of the previous commands, I will make a blind suggestion of changing one line in the Makefile: in line 2, change “build” to “source”. Alternatively, if you already know the kernel buildtree location, pass it to the make command (e.g., for me, I would say “KERNELDIR=/usr/src/linux-2.6.21 make” instead of “make”).
Quote:
Originally Posted by fallen3019
Because the sched.h i need is in /usr/include/linux rather than
/usr/src/linux-2.6.16.13-4-obj/i386/default.
I sincerely doubt it. The headers in /usr/include/linux are santized for userspace. The kernel tree has its own headers (on which the aforementioned headers are based). Generally, these would reside in /lib/modules/`uname -r`/build/include/linux.
 
Old 05-12-2007, 02:33 PM   #8
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
Also, I’m not too familiar with SUSE, so if anyone else knows how it manages kernels and their source/buildtrees, feel free to chime in.
 
Old 05-12-2007, 03:36 PM   #9
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
If you haven’t already, see here and here for similar problems (and solutions).
 
Old 05-12-2007, 04:11 PM   #10
fallen3019
LQ Newbie
 
Registered: May 2007
Distribution: Suse 10.1
Posts: 11

Original Poster
Rep: Reputation: 0
I think you hit on the problem

Output from:
Code:
$ ls -ld /lib/modules/`uname -r`/build
lrwxrwxrwx 1 root root 43 2007-05-05 17:00 /lib/modules/2.6.16.13-4-default/build -> /usr/src/linux-2.6.16.13-4-obj/i386/default

$ ls -ld /lib/modules/`uname -r`/build
lrwxrwxrwx 1 root root 26 2007-05-05 17:00 /lib/modules/2.6.16.13-4-default/source -> /usr/src/linux- 2.6.16.13-4


$ ls -lH /lib/modules/`uname -r`/source
/bin/ls: /lib/modules/2.6.16.13-4-default/source: No such file or directory


$ ls -lH /lib/modules/`uname -r`/build
total 268
-rw-r--r-- 1 root root 270819 2006-05-03 12:44 Module.symvers
When i check in GUI, in /lib/modules/'uname -r'
the build directory only contains Module.symbers

and there is a source shortcut which has an invalid link

That does not really bode well, does it?
If i'm not mistaken, source should link to /usr/src/'uname -r'

'uname -r' is actually 2.6.16.13-4-default, however /usr/src contains a direcory called 2.6.16.13-4-obj



also:
Code:
$ sudo insmod offset.ko
root's password
sudo: insmod: command not found
all these problems...this clearly does not desire to work!
 
Old 05-12-2007, 08:35 PM   #11
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
It seems you don’t have the correct package(s) for building kernel modules. Here is a guide for doing kernel related stuff in SUSE (check specifically the section entitled “Building additional (external) modules”).
Quote:
Originally Posted by fallen3019
If i'm not mistaken, source should link to /usr/src/'uname -r'
This is not necessarily true (in fact, that’s why we use “/lib/modules/`uname -r`/source” rather than “/usr/src/linux-`uname -r`”). Source is just a symlink to wherever you keep the kernel source. When people compile their own custom kernels, source and build often point to the same location (often somewhere in the $HOME directory). If you read the document I linked to, it explains the SUSE method of doing kernels (and the symlink naming scheme).
Quote:
Originally Posted by fallen3019
also:
Code:
$ sudo insmod offset.ko
root's password
sudo: insmod: command not found
That’s very odd (not to have insmod on a functional desktop)…
The insmod utility is generally part of the module-init-utils package. It is in the same boat as modprobe and depmod (I think). So find out if you have module-init-utils installed and if you do, find out what files are contributed by the package (and where they’re located). Or perhaps the problem is your sudo is somehow trying to preserve $PATH. Try as root or with the full path (or add /sbin to your PATH).
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Where are kernel header files? sheintze Debian 6 03-17-2007 04:50 AM
Kernel header (include) files - where do i find these walkerx Mandriva 2 04-17-2005 08:19 AM
Problem with C++ include/header files! Pisces107 Programming 12 12-23-2003 11:06 PM
Kernel Header Files? kholdstayr Slackware 1 12-22-2003 04:45 PM
where are the kernel header files? vance Linux - Software 5 03-05-2002 01:51 AM


All times are GMT -5. The time now is 09:16 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration