- Welcome to Geeksww.com
Linux kernel data structures (Part 1) - the current macro
Note: I have used linux kernels 2.4.18 and 2.6.0 for this tutorial.
The Linux kernel uses this macro to find the current process. The current macro is defined in include/asm-i386/current.h (line 13) in both 2.6.0 and 2.4.18 kernels. This macro calls another function get_current(). The difference is that, in Linux 2.4.18 get_current()(line 6 – 11, include/asmi386/current.h) is itself used to find the address of the current process but in Linux 2.6.0 get_current() in turn calls another function current_thread_info() defined in include/asm-i386/thread_info.h (lines 81 – 86).
For 2.4.18, struct task_struct* get_current() contains:
struct task_struct *current; __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL)); return current;
For 2.6.0, struct thread_info* current_thread_info() contains:
struct thread_info *ti; __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~8191UL)); return ti;
Note: The use of 8191. I'll explain that in detail below.
In 2.6.0, on return from current_thread_info(), get_current() simply returns the value of the task pointer by doing the following (line 10, include/asm-i386/current.h):
return current_thread_info()->task;
For both kernels, the main functions do the following:
The value of the kernel stack pointer is somewhere within the task_union (or thread_union for 2.6.0); (will talk about them later) 8191 decimal is 0001 1111 1111 1111 binary. Inverting that gives 1110 0000 0000 0000. This effectively strips off the low-order 13 bits of the stack pointer value, aligning it at the beginning of the task_union(or thread_union for 2.6.0). This is also the beginning of the task_struct (for 2.4.18) and thread_info (for 2.6.0).
What are task_union (2.4.18) and thread_union (2.6.0)?
They are unions that share space with an array of unsigned long. Both these structures are defined in include/linux/sched.h. Definition is below.
For 2.4.18:
507: #ifndef INIT_TASK_SIZE 508: # define INIT_TASK_SIZE 2048*sizeof(long) 509: #endif 510: 511: union task_union { 512: struct task_struct task; 513: unsigned long stack[INIT_TASK_SIZE/sizeof(long)]; 514: };
For 2.6.0:
536: #ifndef INIT_THREAD_SIZE 537: # define INIT_THREAD_SIZE 2048*sizeof(long) 538: #endif 539: 540: union thread_union { 541: struct thread_info thread_info; 542: unsigned long stack[INIT_THREAD_SIZE/sizeof(long)]; 543: };
Did this tutorial help a little? How about buy me a cup of coffee?
Please feel free to use the comments form below if you have any questions or need more explanation on anything. I do not guarantee a response.
IMPORTANT: You must thoroughy test any instructions on a production-like test environment first before trying anything on production systems. And, make sure it is tested for security, privacy, and safety. See our terms here.
tags cloud
popular searches
free download for mysql database server 5.1.5, bison, gearman, source code, php, install cairo, laptop, mysql, java, linux, install mysql, mysql initialization, mysql mysql, tools, ubuntu
Similar Tutorials:
- How to setup Spamassasin to run as a deamon?
- Installing Oracle Berkeley DB on Ubuntu Linux
- Installing OpenSSL on Ubuntu Linux
- Installing Gearman application framework on Debian Linux
- How to install libevent on Debian/Ubuntu/Centos Linux?
Tutorials in 'Operating Systems > Linux' (more):
- Bash script to compare remote directory's files using file size
- Script to transfer files to remote server with verification
- setfacl: command not found
- How to download, compile, and install CMake on Linux
- How to download, compile, and install GNU ncurses on Debian/Ubuntu Linux?
Comments (write a comment):
Good post..!! Posted by: it i on Oct 30, 2012
leave a comment