日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux内核分析--操作系统是如何工作的

發(fā)布時間:2025/3/21 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux内核分析--操作系统是如何工作的 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

“平安的祝福 + 原創(chuàng)作品轉(zhuǎn)載請注明出處 + 《Linux內(nèi)核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000?”

一、初始化進(jìn)程

操作系統(tǒng)內(nèi)核啟動入口函數(shù)是void __init my_start_kernel(void);

在這里簡單定義進(jìn)程的的兩個cpu狀態(tài):

struct Thread {
??? unsigned long?? ??? ?ip; //表示eip指令
??? unsigned long?? ??? ?sp;//表示esp,棧頂指針
};

在此函數(shù)中初始化第一個進(jìn)程--pid=0;一切進(jìn)程都是以它為父進(jìn)程。

在初始化第一個進(jìn)程時,分配進(jìn)程pid=0,指定棧頂指針,初始化pcb的命令即ip的值--進(jìn)程my_process的入口地址。

運(yùn)行第一個進(jìn)程的流程

設(shè)置進(jìn)程狀態(tài)為正在運(yùn)行,通過嵌入式匯編程序使進(jìn)程占據(jù)cpu運(yùn)行

asm volatile(
?? ??? ?"movl %1,%%esp\n\t" ?? ?/* set task[pid].thread.sp to esp */
?? ??? ?"pushl %1\n\t" ?? ???????? /* push ebp */
?? ??? ?"pushl %0\n\t" ?? ???????? /* push task[pid].thread.ip */
?? ??? ?"ret\n\t" ?? ???????????? /* pop task[pid].thread.ip to eip */
?? ??? ?"popl %%ebp\n\t"
?? ??? ?:
?? ??? ?: "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)?? ?/* input c or d mean %ecx/%edx*/
?? ?);

首先esp跳轉(zhuǎn)到該進(jìn)程的棧頂位置,將該進(jìn)程ebp壓入棧(由于第一個進(jìn)程ebp==esp),將該進(jìn)程的ip壓入棧頂。然后將ret指令,可以修改eip的值,使得該進(jìn)程獲得cpu的指令權(quán)限。再彈出ebp,恢復(fù)棧底的位置。

?

二、進(jìn)程的切換

本次小的時間片輪轉(zhuǎn)的采用的是時鐘中斷的方法進(jìn)行調(diào)度。在my_process的進(jìn)程中,檢測中斷的標(biāo)志,有的話,就進(jìn)行進(jìn)程切換。

進(jìn)程切換分兩種情況,一種是正在運(yùn)行的進(jìn)程切換,另一種是沒有運(yùn)行的進(jìn)程切換

正在運(yùn)行的進(jìn)程切換

通過下面的一段嵌入式匯編實(shí)現(xiàn)切換,然后使下一個進(jìn)程轉(zhuǎn)換成正在運(yùn)行的狀態(tài)

asm volatile(?? ?
?????? ??? ?"pushl %%ebp\n\t" ?? ???? /* save ebp */
?????? ??? ?"movl %%esp,%0\n\t" ?? ?/* save esp */
?????? ??? ?"movl %2,%%esp\n\t"???? /* restore? esp */
?????? ??? ?"movl $1f,%1\n\t"?????? /* save eip */?? ?
?????? ??? ?"pushl %3\n\t"
?????? ??? ?"ret\n\t" ?? ???????????? /* restore? eip */
?????? ??? ?"1:\t"????????????????? /* next process start here */
?????? ??? ?"popl %%ebp\n\t"
?????? ??? ?: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
?????? ??? ?: "m" (next->thread.sp),"m" (next->thread.ip)
?? ??? ?);

首先保存原來的ebp,esp,ip,通過將ebp壓棧,進(jìn)程cpu狀態(tài)保存esp的值和ip的值。

接下來將esp跳轉(zhuǎn)到要切換的棧頂,將其ip值壓棧,然后ret指令使eip獲得其cpu指令權(quán),最后將ebp等于原來進(jìn)程ebp的值。即棧底不變。

沒有在cpu上運(yùn)行的進(jìn)程切換

首先轉(zhuǎn)換進(jìn)程的狀態(tài)成正在運(yùn)行,然后通過下面的一段嵌入式匯編實(shí)現(xiàn)切換

asm volatile(?? ?
?????? ??? ?"pushl %%ebp\n\t" ?? ???? /* save ebp */
?????? ??? ?"movl %%esp,%0\n\t" ?? ?/* save esp */
?????? ??? ?"movl %2,%%esp\n\t"???? /* restore? esp */
?????? ??? ?"movl %2,%%ebp\n\t"???? /* restore? ebp */
?????? ??? ?"movl $1f,%1\n\t"?????? /* save eip */?? ?
?????? ??? ?"pushl %3\n\t"
?????? ??? ?"ret\n\t" ?? ???????????? /* restore? eip */
?????? ??? ?: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
?????? ??? ?: "m" (next->thread.sp),"m" (next->thread.ip)
?? ??? ?);??????

首先保存原來的ebp,esp,ip,通過將ebp壓棧,進(jìn)程cpu狀態(tài)保存esp的值和ip的值。

接下來將esp跳轉(zhuǎn)到要切換的棧頂,ebp跳轉(zhuǎn)到要切換的棧底,由于進(jìn)程沒有運(yùn)行所以ebp=esp,將其ip值壓棧,然后ret指令使eip獲得其cpu指令權(quán)。

下面是內(nèi)核編譯完成的圖片:

下面這張是進(jìn)程在切換時的圖片

?

三、總結(jié)

操作系統(tǒng)首先進(jìn)入初始化啟動內(nèi)核,在啟動內(nèi)核時先完成第一個0號進(jìn)程,然后根據(jù)需要不斷創(chuàng)建進(jìn)程。并根據(jù)一定的調(diào)度算法進(jìn)行進(jìn)程的切換。

轉(zhuǎn)載于:https://www.cnblogs.com/pingandezhufu/p/4356546.html

總結(jié)

以上是生活随笔為你收集整理的Linux内核分析--操作系统是如何工作的的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。