Article title: Linux kernel obtains the current process pointer. Linux is a technology channel of the IT lab in China. Including desktop applications, Linux system management, kernel research, embedded systems and open source, and other basic categories I. memory data representation:
In teaching materials or reading, we often need to intuitively use diagrams to show the distribution of data in the memory. how is the data organized in the memory? Different machines have different representations. We use the most commonIntel X86The series of computers are used as an example to illustrate this problem.
Memory: The memory is low. Memory High address, memory unit:16bit. ForIntel i386The architecture of the computer, the system uses the small-end byte order to store data, the so-called small-end byte order refers to the low-order byte low address, high-order byte High address(Memory address increase direction)The large-end byte order. Conversely, the byte order used by the given system is called the host byte order;CPUIt also reads data in a small byte order, as shown in, if the variableNumYes16BitShortFor short integer typeCPURead from memoryNum = 0x1234IfNumYes32BitIntTypeCPUWhich of the following statements is read from the memory?Num = 0x56781234,WhereNumThe address isZero x 12345678, That is& Num = 0x12345678
II, LinuxThe kernel obtains the pointer of the process task structure.
Understand the system memory data representation. let's take a look at it now.LinuxHow does the kernel obtain the task structure pointer of the current process? refer to the following code:LinuxKernel2.4.0Source code.
InInclude \ asm-i386 \ current. hMedium
# Ifndef _ i1__current_h
# Define _ i1__current_h
Struct task_struct;
Static inline struct task_struct * get_current (void)
{
Struct task_struct * current;
_ Asm _ ("andl % esp, % 0;": "= r" (current): "0 "(~ 8191UL ));
Return current;
}
# Define current get_current ()
# Endif /*! (_ I1__current_h )*/
Each process hasTask_structThe task structure is associated with a storage space used for the system space stack. They are also associated with the physical memory space.Task_structWhen the task structure space is used, the system allocates the space together with the system's stack space, such as the memory diagram for a process switching time:
The following code is used to analyze how the system obtains the task structure pointer of a process in the kernel through a series of operations:
BecauseLinuxWhen the kernel allocates the process task structure space8 KB (2Page space, that is2 ^ 1*4 KB,LinuxWhen managing physical and virtual memory spaces, the size of the page unit must be4 KB)So the memory application address is8 KB (2 ^ 13)An integer multiple of, that is, the pointer address is low.13All bits are0Therefore, according to the small-end byte order, the returned address of the allocated memory should be directedStruct task_structStructure0xc2342000The address indicates that the kernel considers the efficiency of the code instead of directly storing the pointer in a global variable for supply, here we will only explain the code:
According to the memoryEspThe content must be in0xc2342000And0xc2344000A value between them. we assume that0xc2343ffe (Stack pressureEIP, Return address, internal data and other related data, the address value should be reduced; as long as0xc2342xxx,0xc2343xxxThe address pointers are correct.)To check whether code operations are performed.CurrentThe pointer is0xc2342000.
_ Asm _ ("andl % esp, % 0;": "= r" (current): "0 "(~ 8191UL ));
The statement indicatesESPContent and8191ULAnd then assign the resultCurrent, Where8191UL = 8192-1 = 2 ^ 13-1,The calculation process is as follows:
8192UL = 2 ^ 13 0000 0000 0000 0000 0010 0000 0000
8191UL 0000 0000 0000 0000 0001 1111 1111
~ 8191UL (Reverse Code) 1111 1111 1111 1111 1110 0000 0000 0000
0xc2343ffe 1100 0010 0011 0100 0011 1111 1111
AndlResult:1100 0010 0011 0100 0010 0000 0000
| (Check against)
0x c 2 3 4 2 0 0 0
So the result bit after the bitwise AND operation0xc2342000, ExactlyStruct task_structStructure address pointer.Through observation, we can see that as long as0xc2342xxx,0xc2343xxxThe address pointer of the kernel process can be obtained through the same calculation.
In addition, macro operations referenced when an interrupt or system call occurs(Include \ asm-i386 \ hw_irq.h ):
# Define GET_CURRENT \
"Movl % esp, % ebx \ n \ t "\
"Andl $-8192, % ebx \ n \ t"
The principle is also consistent with the above description.