這篇文章主要介紹“l(fā)inux內(nèi)核中init進程是什么”,在日常操作中,相信很多人在linux內(nèi)核中init進程是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”linux內(nèi)核中init進程是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供安遠網(wǎng)站建設(shè)、安遠做網(wǎng)站、安遠網(wǎng)站設(shè)計、安遠網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、安遠企業(yè)網(wǎng)站模板建站服務(wù),十年安遠做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
一、init進程完成了從內(nèi)核態(tài)向用戶態(tài)的轉(zhuǎn)變:
1、一個進程2種狀態(tài):
這里所說的一個進程兩種狀態(tài),說的是進程狀態(tài)的轉(zhuǎn)換;首先在介紹這種狀態(tài)的轉(zhuǎn)換之前,我們來了解一下什么是init進程,它其實是linux系統(tǒng)在啟動后運行的第一個進程(這里關(guān)于進程的學習,可以去看我之前分享的linux應(yīng)用編程專輯,有很詳細的介紹);而init進程剛開始運行的時候是內(nèi)核態(tài),它屬于一個內(nèi)核線程,然后他自己運行了一個用戶態(tài)下面的程序后把自己強行轉(zhuǎn)成了用戶態(tài)。因為init進程自身完成了從內(nèi)核態(tài)到用戶態(tài)的過度,因此后續(xù)的其他進程都可以工作在用戶態(tài)下面了。
2、內(nèi)核態(tài)下做了什么?
內(nèi)核狀態(tài)下重點就做了一件事情,就是掛載根文件系統(tǒng)并試圖找到用戶態(tài)下的那個init程序。init進程要把自己轉(zhuǎn)成用戶態(tài)就必須運行一個用戶態(tài)的應(yīng)用程序(這個應(yīng)用程序名字一般也叫init),要運行這個應(yīng)用程序就必須得找到這個應(yīng)用程序,要找到它就必須得掛載根文件系統(tǒng),因為所有的應(yīng)用程序都在文件系統(tǒng)中。內(nèi)核源代碼中的所有函數(shù)都是內(nèi)核態(tài)下面的,執(zhí)行任何一個都不能脫離內(nèi)核態(tài)。應(yīng)用程序必須不屬于內(nèi)核源代碼,這樣才能保證自己是用戶態(tài)。也就是說我們這里執(zhí)行的這個init程序和內(nèi)核不在一起,他是另外提供的。提供這個init程序的那個人就是根文件系統(tǒng)。
打個不恰當?shù)谋扔?,比如大家都知道的建房子,在這之前,你必須打好地基,打好了地基之后,你才能開始動工在地基上砌磚頭了,也就是各種操作了。
3、用戶態(tài)下做了什么?
init進程大部分有意義的工作都是在用戶態(tài)下進行的。init進程對我們操作系統(tǒng)的意義在于:其他所有的用戶進程都直接或者間接派生自init進程。
4、如何從內(nèi)核態(tài)跳躍到用戶態(tài)?還能回來不?
init進程在內(nèi)核態(tài)下面時,通過一個函數(shù)kernel_execve來執(zhí)行一個用戶空間編譯連接的應(yīng)用程序就跳躍到用戶態(tài)了。注意這個跳躍過程中進程號是沒有改變的,所以一直是進程1.這個跳躍過程是單向的,也就是說一旦執(zhí)行了init程序轉(zhuǎn)到了用戶態(tài)下整個操作系統(tǒng)就算真正的運轉(zhuǎn)起來了,以后只能在用戶態(tài)下工作了,用戶態(tài)下想要進入內(nèi)核態(tài)只有走API這一條路了。這就是大家經(jīng)??床僮飨到y(tǒng)大致框架都是這樣描述的:
上層:表示我們的應(yīng)用程序,在linux里面我們會有相應(yīng)的api(或者自己寫的)
中間層:就是我們的內(nèi)核了,也就是操作系統(tǒng)了
底層:就是實實在在的硬件電路(當然在os和硬件之間有一個啟動程序,也就是我們常說的uboot)。
具體kernel_execve函數(shù)如下(這里贊不分析,暫時讓大家理性的感受一下第一次看linux內(nèi)核代碼的感受,這里主要面向第一次接觸linux代碼的小伙伴哦。):
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
struct pt_regs regs;
int ret;
memset(®s, 0, sizeof(struct pt_regs));
ret = do_execve((char *)filename, (char __user * __user *)argv,
(char __user * __user *)envp, ®s);
if (ret < 0)
goto out;
/*
* Save argc to the register structure for userspace.
*/
regs.ARM_r0 = ret;
/*
* We were successful. We won't be returning to our caller, but
* instead to user space by manipulating the kernel stack.
*/
asm( "add r0, %0, %1\n\t"
"mov r1, %2\n\t"
"mov r2, %3\n\t"
"bl memmove\n\t" /* copy regs to top of stack */
"mov r8, #0\n\t" /* not a syscall */
"mov r9, %0\n\t" /* thread structure */
"mov sp, r0\n\t" /* reposition stack pointer */
"b ret_to_user"
:
: "r" (current_thread_info()),
"Ir" (THREAD_START_SP - sizeof(regs)),
"r" (®s),
"Ir" (sizeof(regs))
: "r0", "r1", "r2", "r3", "ip", "lr", "memory");
out:
return ret;
}
二、init進程構(gòu)建了用戶交互界面:
在上面也說了,在init進程切換到用戶狀態(tài)后,以后對操作系統(tǒng)操作的話就能只能在用戶狀態(tài)下操作了,而這各種操作也就是我們的進程操作了,和windows里面的實際應(yīng)用程序一樣,一個程序就是一個進程,比如我們在windows任務(wù)管理器里面就可以看到如下圖所示:
在我們linux系統(tǒng)里面的話,在init進程轉(zhuǎn)換為用戶狀態(tài)下后,后面有一些我們比較熟悉的進程操作:login進程、命令行進程、shell進程(shell,我們都很熟悉,人機交互圖像話界面),并且shell進程又會啟動了其他用戶進程;然后在命令行和shell進程一旦工作了,用戶就可以在命令行下通過./xx的方式來執(zhí)行其他應(yīng)用程序,每一個應(yīng)用程序的運行就是一個進程。
到此,關(guān)于“l(fā)inux內(nèi)核中init進程是什么”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
網(wǎng)頁標題:linux內(nèi)核中init進程是什么
標題來源:http://weahome.cn/article/pechpp.html