µ±Ç°Î»ÖãºLinux½Ì³Ì - Linux - ¹ØÓÚÄÚºËÏß³Ì(kernel_thread)

¹ØÓÚÄÚºËÏß³Ì(kernel_thread)

ÌÆÓî [email protected]

ÎÒÃÇÖªµÀLinuxÄÚºËʹÓÃÄÚºËÏß³ÌÀ´½«Äں˷ֳɼ¸¸ö¹¦ÄÜÄ£¿é,
Ïñkswapd,kflushdµÈ,ϵͳÖеÄinit½ø³ÌÒ²ÊÇÓÉidle½ø³Ìµ÷ÓÃ
kernel_thread()À´ÊµÏÖ²úÉúµÄ.

ÎÒÃÇÏÈÀ´¿´¿´ÄÚºËÏ̵߳ÄʵÏÖ,ÔÙÀ´·ÖÎöÄÚºËÏ̵߳ÄÐÔÖÊ.
int kernel_thread(int(*fn)(void*arg),void *arg,int flags)
{
long retval,d0; /* ÖÁÉÙÊÇÁ½¸ö¾Ö²¿±äÁ¿ */

__asm__ __volitate__(
"movl %%esp,%%esint"
"int $0x80nt"
"cmpl %%esp,%%esint"
"je 1f nt"
"movl %4,%%eaxnt"
"pushl %%eaxnt"
"call *%5nt"
"movl %3,%0nt"
"int $0x80nt"
"1:t"
:"=&a"(retval),"=&S"(d0)
:"0"(__NR_clone),"i"(__NR_exit),
"r"(arg),"r"(fn),
"b"(flags | CLONE_VM)
:"memory"
);

return retval;
}

Õâ¶Î´úÂë·­Òë³ÉÖ±¹ÛµÄASMÂë:
{
movl __NR_clone,%0; /* ½«cloneµÄϵͳµ÷ÓúÅÔØÈëreg */
movl __NR_exit,%3; /* ½«exitµÄϵͳµ÷ÓúÅÔØÈëreg */
movl arg,%4; /* ½«º¯ÊýfnµÄ²ÎÊýÔØÈëreg */
movl fn,%5; /* ½«º¯ÊýfnµÄÖ¸ÕëÔØÈëreg */
movl flags|CLONE_VM,%ebx; /* ½«flagsÒÆÈë%ebxÖÐ */
mov %%esp,%%esi; /* ½«¼Ä´æÆ÷%esp±£´æÔÚ%esiÖÐ */
int $0x80; /* ÓÉÓÚ%eaxÖÐÊÇcloneµÄϵͳµ÷ÓúÅ,ËùÒÔ
sys_clone»á±»µ÷ÓÃ,ͬʱÓÖÓÉÓÚϵͳµ÷ÓÃÃÅ
»á°ÑËùÓеļĴæÆ÷ѹջ,ËùÒÔ×Ó½ø³Ì»áÔÚÏàÓ¦
µÄ¼Ä´æÆ÷ÖлñÈ¡flags,fn,__NR_exitµÈ,ϵͳµ÷ÓÃ
·µ»Øºó,×Ó½ø³Ì¼¸ºõ¼Ì³ÐÁ˸¸½ø³ÌµÄÒ»ÇÐ,µ«ÊÇÓÉ
ÎÒÃǶÔdo_forkµÄ·ÖÎö¿ÉÖª,×Ó½ø³Ì½«»ñȡеÄÄÚºËÕ»,
Õ»ÉϾÍÊǸ÷¼Ä´æÆ÷µÄÄÚÈÝ,ͬʱÐÞ¸ÄTSSʹ:
EIP=ret_from_fork,
ESP=еÄÄÚºËÕ»µ×-sizeof(pt_regs),
SSO=__KERNEL_DS,
ESP0=еÄÄÚºËÕ»¶¥,
(??)ÐÞ¸ÄÕ»ÉϵÄOLDESP=еÄÄÚºËÕ»µ×

×Ó½ø³Ì»Ö¸´Ö´Ðкó,¼ÓÔØeip,esp,µ±RESTORE_ALLÖ´Ðкó
(pops,iret),¼Ä´æÆ÷±»»Ö¸´ÁË,ͬʱÎÒÃÇÖªµÀµ±Ç°µÄESP
ÓëESIÒÑÊDz»Í¬ÁË.
*/

cmpl %%esp,%%esi;
je 1f; /* %esp,%esiÏàͬ,ÔòÊǸ¸½ø³Ì */
movl %4,%%eax; /* ½«²ÎÊýÔØÈëEAX,ÕâÑù²»¹ÜfnÊÇ·ñʹÓÃ-mregparamÊôÐÔ
²Î¿´GCC manual for more information
*/
pushl %%eax /* ½«²ÎÊýѹջ */
call *%5; /* µ÷ÓÃfn */
movl %3,%0;
int $0x80; /* ϵͳµ÷ÓÃexitÍ˳ö */
1: movl %%eax,retval /* ½«×Ó½ø³ÌµÄpid¸¶¸øretval(ϵͳµ÷Óõķµ»ØÖµÔÚ%eaxÖÐ) */
movl %%esi,d0 /* ?? */
}

ËüµÄαCÂëΪ:
int kernel_thread()
{
pid=clone(flags);
if(child)
{
fn(arg);
exit(0);
}
return pid;
}

´ÓÉÏÃæµÄ´úÂë¿ÉÒÔ¿´³ö,ÄÚºËÏß³ÌÓÐÒÔÏÂÐÔÖÊ:
1.
ÄÚºËÏß³ÌÊÇͨ¹ýϵͳµ÷ÓÃclone()À´ÊµÏÖµÄ,ʹÓÃCLONE_VM±êÖ¾(Óû§»¹¿ÉÒÔ
ÌṩÆäËû±êÖ¾,CLONE_PID,CLONE_FS,CLONE_FILESµÈ),Òò´ËÄÚºËÏß³ÌÓëµ÷ÓÃ
µÄ½ø³Ì(current)¾ßÓÐÏàͬµÄ½ø³Ì¿Õ¼ä.

2.
ÓÉÓÚµ÷Óýø³ÌÊÇÔÚÄÚºËÀïµ÷ÓÃkernel_thread(),Òò´Ëµ±ÏµÍ³µ÷Ó÷µ»Øʱ,×Ó½ø³ÌÒ²´¦ÓÚ
ÄÚºË̬ÖÐ,¶ø×Ó½ø³ÌËæºóµ÷ÓÃfn,µ±fnÍ˳öʱ,×Ó½ø³Ìµ÷ÓÃexit()Í˳ö,ËùÒÔ×Ó½ø³ÌÊÇÔÚ
ÄÚºË̬ÔËÐеÄ.

3.
ÓÉÓÚÄÚºËÏß³ÌÊÇÔÚÄÚºË̬ÔËÐеÄ,Òò´ËÄÚºËÏ߳̿ÉÒÔ·ÃÎÊÄÚºËÖÐÊý¾Ý,µ÷ÓÃÄں˺¯Êý.
ÔËÐйý³ÌÖв»Äܱ»ÇÀÕ¼µÈµÈ.

Çë×¢ÒâÔÚkernel_threadÊÇÈçºÎµ÷ÓÃϵͳµ÷ÓõÄ,ÎÒÃÇÖªµÀkernel_threadÊÇÔÚÄÚºËÖÐ
µ÷ÓÃ,ËùÒÔËûÊÇ¿ÉÒÔÖ±½Óµ÷ÓÃϵͳµ÷ÓõÄ,Ïñsys_open()µÈ,µ«ÊÇÔÚÕâÀïkernel_thread
ͨ¹ýϵͳµ÷ÓÃÃÅ(int$80)À´¼ä½Óµ÷ÓÃclone()º¯Êý,¾ÍÌá³öÒÔÏÂÎÊÌâ:
1.ΪʲôÕâÑù?
2.Èç¹ûÎÒÃÇÖ±½Óµ÷ÓÃsys_clone()»áÓÐʲôÑùµÄ½á¹ûÄØ?

int kernel_thread()
{
int pid;
pid=sys_clone();
if(!pid)
{
/* child */
exit();
}
return pid;
}


ÕâÑù,µ±×Ó½ø³Ì»ñÈ¡CPU×ÊԴʱ(ÔËÐÐʱ),´Óret_from_fork»Ö¸´Ö´ÐÐ,Õ»²¼¾Ö¶ÔÓÚ×Ó½ø³Ì¶øÑÔ
ÊDz»¶ÔµÄ,ÎÊÌâÔÚÓÚµ±×Ó½ø³ÌÔËÐе½RESTORE_ALLµÄIRET,×ÐϸÏëÒ»ÏëÕ»²¼¾ÖµÄ±ä»¯.

ÓÉsys_clone()µÄÉêÃ÷¿ÉÖªµ÷ÓÃsys_cloneÐèÒªpt_regsµÄÕ»½á¹¹,Èç¹ûÎÒÃÇÖ±½Óµ÷ÓÃsys_clone
ÊÇûÓð취×öµ½µÄ(Èç¹û¿ÉÒÔÎÒÃÇÒ²ÐèÒª¾«ÐÄΪËü×¼±¸Õ»,//:-(,ÕæÊÇÉËÉñ)
ͬÀí,ÆäËûµÄÀàËÆϵͳµ÷ÓÃ,ÎÒÃÇÒ²±ØÐëͨ¹ýint$80µÄϵͳµ÷ÓÃÃÅÀ´ÊµÏÖ.
¶ø¶ÔÓÚsys_execl,sys_open,sys_close,sys_exit,Ôò¿ÉÒÔÖ±½Óµ÷ÓÃ.//xixi,ÎÒÃÇ¿ÉÒÔ
¸Ä¶¯kernel_threadÀ´²âÊÔsys_exitÊÇ·ñ¿ÉÒÔÖ±½Óµ÷ÓÃ,ͬʱҲ¿ÉÒÔʹÓÃsys_cloneµÄÖ±½Óµ÷ÓÃ
À´Ö¤Ã÷ÎÒÃǵķÖÎöÊÇ·ñÕýÈ·.

¶øÈç¹ûÎÒÃÇʹÓÃϵͳµ÷ÓÃÃÅ(int$80)À´½â¾öÎÊÌâ,ÎÒÃÇʹÓÃͬÑùµÄ·½·¨À´·ÖÎö:
A2)
ebx <-- ( esp after save all ,ready for syscalls )
ecx
...
oldeip <-- ( esp before SAVE_ALL which construct stack for syscalls )
oldcs
eflags
d0 <- ( space for local variables )
retval
fn <- ( arguments for kernel_thread )
arg
clone_flags
eip <- ( retore ip for kernel_thread )
..

ÓÉÓÚkernel_threadÔÚÄں˵ĴúÂë¶ÎÖÐ,ËùÒÔûÓз¢ÉúÕ»Çл»,ËùÓеÄѹջ/ÍËÕ»¶¼ÊÇÔÚ
ÄÚºËÕ»ÖнøÐеÄ.Çë×¢ÒâÕâÑùÕ»ÖбãûÓÐ(OLDSS,OLDESP),ËùÒÔÔÚkernel_threadÉùÃ÷ÁË
Á½¸ö¾Ö²¿²ÎÊý(retval,d0),¶ÔÓÚretvalµÄÒâÒåÊÇÃ÷ÏÔµÄ,¶ød0´ó¸ÅÊÇ(dummy local
variable
0,...n)µÄÒâ˼°É,:)


B2)×Ó½ø³ÌÔËÐÐÇ°:
×Ó½ø³ÌµÄTSS,Õ»²¼¾Ö

ebx <- esp
ecx
...
oldeip
oldcs
eflags
d0 <- (¾Ö²¿±äÁ¿d0)
retval <- (¾Ö²¿±äÁ¿retval)


ÔËÐе½RESTORE_ALLʱ,½«»Ö¸´CPU¸÷¼Ä´æÆ÷,µ±ÔËÐе½IRETʱ,
ÓÉÓÚÔÚÏàͬÌØȨµÈ¼¶µÄתÒÆ,ËùÒÔûÓз¢ÉúÌØȨ¼¶Çл»,ËùÒÔESP,SSûÓз¢Éú±ä»¯.

BTW,ÓÉÉÏÃæµÄ·ÖÎö¿ÉÖª,kernel_thread´´½¨µÄ½ø³ÌÊDz»ÄÜתµ½Óû§Ì¬ÔËÐеÄ.