加入收藏 | 设为首页 | 会员中心 | 我要投稿 佛山站长网 (https://www.0757zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

kernel学习之sys_fork,sys_vfork,sys_clone和kernel_thread

发布时间:2016-10-08 19:13:47 所属栏目:Unix 来源:网络整理
导读:用户空间进程创建接口:fork,vfork,clone函数,这里只做简单说明。 fork:使用该系统调用时,子进程复制父进程的全部资源。由于要复制父进程进程描述符给子进

内核线程是一种特殊的进程,它只能运行在内核态,不能访问用户空间的内容。内核线程除了各自的栈和硬件上下文外,共享所用资源。内核利用内核线程来完成一些后台工作如kswapd,ksoftirqd。内核线程有kernel_thread创建。

在linux2.6.xxx/arch/x86/include/asm/processor.h
/*
 * create a kernel thread without removing itfrom tasklists
 */
extern intkernel_thread(int (*fn)(void *), void *arg, unsigned long flags);

在linux2.6.xxx/arch/arm/include/asm/processor.h

/*
 * Create a new kernel thread
 */
extern intkernel_thread(int (*fn)(void *), void *arg, unsigned long flags);

参数说明:

fn:新创建的内核线程要执行的函数。

arg:fn的参数。

flags:和do_fork中的clone_flags作用相似。

kernel_thread函数分析:

在linux2.6.xxx/arch/x86/kernel/process.c

/*
 * Create a kernel thread
 */
intkernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
     struct pt_regs regs;//保存进程的硬件上下文
 
     memset(®s, 0, sizeof(regs));
     regs.si = (unsigned long) fn;
     regs.di = (unsigned long) arg;
 
#ifdefCONFIG_X86_32
     regs.ds = __USER_DS;
     regs.es = __USER_DS;
     regs.fs = __KERNEL_PERCPU;
     regs.gs = __KERNEL_STACK_CANARY;
#else
     regs.ss = __KERNEL_DS;
#endif
 
     regs.orig_ax = -1;
     regs.ip = (unsigned long)kernel_thread_helper;
     regs.cs = __KERNEL_CS | get_kernel_rpl();
     regs.flags = X86_EFLAGS_IF | 0x2;
 
     /* Ok, create the new process.. */
     return do_fork(flags | CLONE_VM |CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
}

分析:

从这段代码可知,内核线程的创建最终还是调用了do_fork。

arm架构的kernel_thread实现:

/*
 * Create a kernel thread.
 */
pid_tkernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
     struct pt_regs regs;
 
     memset(®s, 0, sizeof(regs));
 
     regs.ARM_r4 = (unsigned long)arg;
     regs.ARM_r5 = (unsigned long)fn;
     regs.ARM_r6 = (unsignedlong)kernel_thread_exit;
     regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE |PSR_ISETSTATE;
     regs.ARM_pc = (unsignedlong)kernel_thread_helper;
     regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
 
     return do_fork(flags|CLONE_VM|CLONE_UNTRACED,0, ®s, 0, NULL, NULL);
}
 
/*
 * Shuffle the argument into the correctregister before calling the
 * thread function.  r4 is the thread argument, r5 is the pointerto
 * the thread function, and r6 points to theexit function.
 */
extern voidkernel_thread_helper(void);
asm( ".pushsection .textn"
"    .alignn"
"    .type    kernel_thread_helper,#functionn"
"kernel_thread_helper:n"
#ifdefCONFIG_TRACE_IRQFLAGS
"    bl   trace_hardirqs_onn"
#endif
"    msr  cpsr_c,r7n"
"    mov  r0,r4n"
"    mov  lr,r6n"
"    mov  pc,r5n"
"    .size    kernel_thread_helper,. - kernel_thread_helpern"
"    .popsection");

出处:http://blog.csdn.net/muge0913/article/details/7479379

(编辑:佛山站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读