專門用語:
- 使用打字機(Courier New)字體表示原始碼。
- task/process即為Linux中的thread。
- 文中的Linux與Linux kernel指的皆為作業系統核心。
- 使用斜體字型標示Linux中的資料結構,變數或函式名稱。
Kernel版本:
- v2.6.24.3
User thread:
應用程式使用fork,vfork,或clone函式建立新的user threads,這些函式分別透過Linux system call呼叫sys_fork,sys_vfork,或sys_clone kernel function建立新threads,而sys_fork,sys_vfork,與sys_clone共同呼叫的函式為do_fork1。
asmlinkage int sys_fork(struct pt_regs regs)
{
return do_fork(SIGCHLD, regs.esp, ®s, 0, NULL, NULL);
}
asmlinkage int sys_clone(struct pt_regs regs)
{
unsigned long clone_flags;
unsigned long newsp;
int __user *parent_tidptr, *child_tidptr;
clone_flags = regs.ebx;
newsp = regs.ecx;
parent_tidptr = (int __user *)regs.edx;
child_tidptr = (int __user *)regs.edi;
if (!newsp)
newsp = regs.esp;
return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr);
}
asmlinkage int sys_vfork(struct pt_regs regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL, NULL);
}
上面三個函式都只為新thread準備好task_struct,task_thread_info,與堆疊空間,至於新的thread該執行哪些程式碼則毫無著墨。應用程式一般以呼叫執行檔的方式啟動2,便是將執行檔的binary內容讀取到記憶體中執行,這個步驟則是透過sys_execve函式呼叫do_execve函式完成,因此一般建立新user thread時sys_execve會搭配於task_struct,task_thread_info,與堆疊空間建制完成之後執行將執行檔載入記憶體。
asmlinkage int sys_execve(struct pt_regs regs)
{
int error;
char * filename;
filename = getname((char __user *) regs.ebx);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename,
(char __user * __user *) regs.ecx,
(char __user * __user *) regs.edx,
®s);
if (error == 0) {
task_lock(current);
current->ptrace &= ~PT_DTRACE;
task_unlock(current);
/* Make sure we don't return using sysenter.. */
set_thread_flag(TIF_IRET);
}
putname(filename);
out:
return error;
}
1 kernel_thread最後也是呼叫do_fork。
2 例如開啟Firefox網頁瀏覽器。
No comments:
Post a Comment