For Kernel_Newbies By a Kernel_Newbie
But how does a Child Thread created through a fork or a clone gets handled ?
Which route does it take ? fork,and clones take a slightly different route in
the sense that they dont first reach ret_from_sys_call. Thats again a fantastic
trick which is performed in copy_thread call to fork (check out kernel/fork.c).
The copy_thread routine defined in (arch/i386/kernel/process.c) also justifies
the glaring fact,that would appear in most of the hackers guide.
The stack pointer is aligned on a 2 page boundary (page = 1 << 12)
with the \"current\" process pointer. Meaning- The Kernel Stack associated with
each process is aligned with the Process Pointer on a THREAD_SIZE ( 1 <<
13 ) boundary.
The significance of this statement lies in the extraction of the \"current\"
pointer justified in arch/i386/entry.S (check out lcall7,lcall27 handlers for
usage and GET_CURRENT for definition.) The definition is pretty simple if one
knows to align something on a specific boundary.(\"AND\" with the complement of a
X-1, if you want to align on the nearest X boundary.) Also note that the current
pointer is kept in \"bx\".If you want to find \"current\" from the stack
pointer,just \"AND.\" it with the complement of 8191 or -8192 or THREAD_SIZE -
1.(A good explanation of this is given in kernelnewbies.org-
get_current,although GET_CURRENT in entry.S should say it all as there is no
usage of gcc inline asm.(\"movl %esp, %bx; andl $-8192, %bx;\" ) The copy_thread
routine sets up a struct pt_regs pointer to POINT to: (struct pt_regs
*)(THREAD_SIZE + (unsigned long)task_pointer) - 1 and does a struct_copy of the
registers from the parent_thread. (The thread that invoked fork.) This way it
ensures that the state of the stack for a ret_from_sys_call is just about right
for an \"iret\" to user_space. It confirms the return state of the child thread by
setting up the task->thread.eip to ret_from_fork. (check out entry.S again.)
The thread_struct structure associated with a task,keeps status information
about the thread,like the threads esp (stack pointer),esp0 (upper limit,-Squeeze
me-. but p->thread.esp0 is set to THREAD_SIZE + (unsigned long)task_pointer),
fs and gs register values,along with debug register values (8 debug registers).
Merely setting up the task->thread.eip (instruction pointer) will not put it
in the ret_from_fork path. The trick lies in switch_to (inlined_asm defined in
- « first
- ‹ previous
- of 24
- next ›
- last »