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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux中断与进程切换,结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程...

發(fā)布時間:2024/10/8 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux中断与进程切换,结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

@

實驗環(huán)境

OS

Linux cj-virtual-machine 5.3.0-51-generic

虛擬機

QEMU

內(nèi)核版本

5.3.4

調(diào)式方法

GDB

PS:調(diào)試環(huán)境安裝請看上一篇博客匯編級理解Linux系統(tǒng)調(diào)用

fork系統(tǒng)調(diào)用過程

和普通系統(tǒng)系統(tǒng)調(diào)用對比

正常的?個系統(tǒng)調(diào)?都是陷?內(nèi)核態(tài),再返回到?戶態(tài),然后繼續(xù)執(zhí)?系統(tǒng)調(diào)?后的下?條指令。

fork和其他系統(tǒng)調(diào)?不同之處是它在陷?內(nèi)核態(tài)之后有兩次返回,第?次返回到原來的?進程的位置繼續(xù)向下執(zhí)?,這和其他的系統(tǒng)調(diào)?是?樣的。

在?進程中fork也返回了?次,會返回到?個特 定的點——ret_from_fork,通過內(nèi)核構(gòu)造的堆棧環(huán)境,它可以正常系統(tǒng)調(diào)?返回到?戶態(tài)

_do_fork系統(tǒng)調(diào)用流程概述

源碼在/linux/kernel/fork.c目錄下,由于代碼太多,只是大概了解

long _do_fork(struct kernel_clone_args *args) {

.....

//復制進程描述符和執(zhí)?時所需的其他數(shù)據(jù)結(jié)構(gòu)

p = copy_process(NULL, trace, NUMA_NO_NODE, args);

......

wake_up_new_task(p);//將?進程添加到就緒隊列

.......

return nr;//返回?進程pid(?進程中fork返回值為?進程的pid)

}

_do_fork

copy_process 復制進程描述符和執(zhí)?時所需的其他數(shù)據(jù)結(jié)構(gòu)

dup_task_struct 復制進程描述符task_struct、創(chuàng)建內(nèi)核堆棧等

copy_thread_tls 初始化?進程內(nèi)核棧和thread

wake_up_new_task 將?進程添加到就緒隊列

系統(tǒng)調(diào)用返回

總的來說,進程的創(chuàng)建過程?致是?進程通過fork系統(tǒng)調(diào)?進?內(nèi)核_do_fork函數(shù),如圖所示復制進程描述符及相關進程 資源(采?寫時復制技術)、分配?進程的內(nèi)核堆棧并對內(nèi)核堆棧和thread等進程關鍵上下?進?初始化,最后將?進程 放?就緒隊列,fork系統(tǒng)調(diào)?返回;??進程則在被調(diào)度執(zhí)?時根據(jù)設置的內(nèi)核堆棧和thread等進程關鍵上下?開始執(zhí)?。

普通系統(tǒng)調(diào)用和fork子進程內(nèi)核堆棧對比

fork系統(tǒng)調(diào)用子進程的內(nèi)核堆棧和普通系統(tǒng)調(diào)用堆棧相比多了一個,inactive_task_frame,該結(jié)構(gòu)主要用于進程切換過程。

fork系統(tǒng)調(diào)用實驗

編寫程序,使用fork() 函數(shù)

#include

#include

#include

#include

#include

int main(int argc, char* argv[])

{

int pid;

pid = fork();

if(pid<0)

{

//error

fprintf(stderr,"For Failed");

exit(-1);

}

else if(pid==0)

{

//child

printf("this is child process \n");

}

else

{

//parent

printf("this is Parent process \n");

wait(NULL);

printf("child complete \n");

}

return 0;

}

編譯后執(zhí)行

gcc -o fork fork.c -static

./fork

反匯編objdump -S fork -o fork.s,查看fock.s中使用的系統(tǒng)調(diào)用為56號,查/linux-5.4.34/arch/x86/entry/syscalls/syscall_64.tbl表得到內(nèi)核函數(shù)__x64_sys_clone

在 /linux/kernel/fork.c中,發(fā)現(xiàn),__x64_sys_clone是調(diào)用了內(nèi)核中的_do_fork函數(shù)。

開啟虛擬機,在__x64_sys_clone ,_do_fork,cpoy_process,dup_task_struct,copy_thread_tls下斷點,shell下運行fork可執(zhí)行文件,查看此時函數(shù)棧

結(jié)果

execve系統(tǒng)調(diào)用

圖示

和普通系統(tǒng)系統(tǒng)調(diào)用對比

當前的可執(zhí)?程序在執(zhí)?,執(zhí)?到execve系統(tǒng)調(diào)?時陷?內(nèi)核態(tài),在內(nèi)核???do_execve加載可執(zhí)??件,把當前進程的可執(zhí)?程序給覆蓋掉。當execve系統(tǒng)調(diào)?返回 時,返回的已經(jīng)不是原來的那個可執(zhí)?程序了,?是新的可執(zhí)?程序。

execve返回的是新的可執(zhí)?程序執(zhí)?的起點,靜態(tài)鏈接的可執(zhí)??件也就是main函數(shù)的?致位置,動態(tài)鏈接的可執(zhí)??件還需 要ld鏈接好動態(tài)鏈接庫再從main函數(shù)開始執(zhí)?。

Linux系統(tǒng)?般會提供了execl、execlp、execle、execv、execvp和execve等6個?以加載執(zhí)? ?個可執(zhí)??件的庫函數(shù),這些庫函數(shù)統(tǒng)稱為exec函數(shù),差異在于對命令?參數(shù)和環(huán)境變量參數(shù) 的傳遞?式不同。

exec函數(shù)都是通過execve系統(tǒng)調(diào)?進?內(nèi)核,對應的系統(tǒng)調(diào)?內(nèi)核處理函數(shù)為sys_execve或__x64_sys_execve,它們都是通過調(diào)?do_execve來具體執(zhí)?加載可執(zhí)??件的 ?作。

整體的調(diào)?的遞進關系為:

sys_execve()或__x64_sys_execve -> // 內(nèi)核處理函數(shù)

do_execve() –> // 系統(tǒng)調(diào)用函數(shù)

do_execveat_common() -> // 系統(tǒng)調(diào)用函數(shù)

__do_execve_?le ->

exec_binprm()-> // 根據(jù)讀入文件頭部,尋找該文件的處理函數(shù)

search_binary_handler() ->

load_elf_binary() -> // 加載elf文件到內(nèi)存中

start_thread() // 開始新進程

進程切換

進程切換時機

?戶進程上下?中主動調(diào)?特定的系統(tǒng)調(diào)?進?中斷上下?,系統(tǒng)調(diào)?返回 ?戶態(tài)之前進?進程調(diào)度。

內(nèi)核線程或可中斷的中斷處理程序,執(zhí)?過程中發(fā)?中斷進?中斷上下?, 在中斷返回前進?進程調(diào)度。

內(nèi)核線程主動調(diào)?schedule函數(shù)進?進程調(diào)度

進程上下?

?戶地址空間:包括程序代碼、數(shù)據(jù)、?戶堆棧等。 (CR3寄存器代表進程??錄表,即地址空間、數(shù)據(jù))

控制信息:進程描述符(thread)、內(nèi)核堆棧(sp寄存器)等。

進程的CPU上下?,相關寄存器的值(指令指針寄存器ip代表進程的CPU上下?)。

進程切換過過程

切換?全局?錄(CR3)以安裝?個新的地址空間,這樣不同進程的虛擬地 址如0x8048400(32位x86)就會經(jīng)過不同的?表轉(zhuǎn)換為不同的物理地址。

切換內(nèi)核態(tài)堆棧和進程的CPU上下?,因為進程的CPU上下?提供了內(nèi)核執(zhí) ?新進程所需要的所有信息,包含所有CPU寄存器狀態(tài)。

核心代碼

((last) = __switch_to_asm((prev), (next)));

ENTRY(__switch_to_asm)

pushq %rbp

pushq %rbx

pushq %r12

pushq %r13

pushq %r14

pushq %r15

/* switch stack */

movq %rsp, TASK_threadsp(%rdi)

movq TASK_threadsp(%rsi), %rsp

popq %r15

popq %r14

popq %r13

popq %r12

popq %rbx

popq %rbp

jmp __switch_to END(__switch_to)

__switch_to_asm是在C代碼中調(diào)?的,也就是使?call指令,?這段匯編的結(jié)尾是jmp __switch_to, __switch_to函數(shù)是C代碼最后有個return,也就是ret指令。將__switch_to_asm和__switch_to結(jié)合起來,正好是call指令和ret指令的配對出現(xiàn)。

call指令壓棧RIP寄存器到進程切換前的prev進程內(nèi)核堆棧;?ret指令出棧存?RIP 寄存器的是進程切換之后的next進程的內(nèi)核堆棧棧頂數(shù)據(jù)。

由此完成了進程的切換。

中斷上下文和進程上下文對比

中斷上下文的切換

中斷是由CPU實現(xiàn)的,所以中斷上下?切換過程中最關鍵的棧頂寄存器sp和指令指針寄存器 ip 是由CPU協(xié)助完成的。

進程上下文的切換

進程切換是由內(nèi)核實現(xiàn)的(且一般情況下,進程上下文切換嵌套在中斷中),所以進程上下?切換過程最關鍵的棧頂寄存器sp切換是通過進程描述符的thread.sp實現(xiàn)的,指令指針 寄存器ip的切換是在內(nèi)核堆棧切換的基礎上巧妙利?call/ret指令實現(xiàn)的。

Linux系統(tǒng)的一般執(zhí)行過程(含中斷與進程切換)

一般函數(shù)調(diào)用框架

(1)正在運?的?戶態(tài)進程X。

(2)發(fā)?中斷(包括異常、系統(tǒng)調(diào)?等),CPU完成load cs:rip(entry of a speci?c ISR),即跳轉(zhuǎn)到中斷處理程序??。

(3)中斷上下?切換,具體包括如下?點:

swapgs指令保存現(xiàn)場,可以理解CPU通過swapgs指令給當前CPU寄存器狀態(tài)做了?個快照。

rsp point to kernel stack,加載當前進程內(nèi)核堆棧棧頂?shù)刂返絉SP寄存器。快速系統(tǒng)調(diào)?是由系統(tǒng)調(diào)???處的匯編代碼實現(xiàn)?戶堆棧和內(nèi)核堆棧的切換。

save cs:rip/ss:rsp/r?ags:將當前CPU關鍵上下?壓?進程X的內(nèi)核堆棧,快速系統(tǒng)調(diào)?是由系統(tǒng)調(diào)???處的匯編代碼實現(xiàn)的。

此時完成了中斷上下?切換,即從進程X的?戶態(tài)到進程X的內(nèi)核態(tài)。

(4)中斷處理過程中或中斷返回前調(diào)?了schedule函數(shù),其中完成了進程調(diào)度算法選擇next進程、進程地址空間切換、以及switch_to關鍵的進程上下?切換等。

(5)switch_to調(diào)?了__switch_to_asm匯編代碼做了關鍵的進程上下?切換。將當前進程X的內(nèi)核堆棧切換到進程調(diào)度算法選出來的next進程(本例假定為進程Y)的內(nèi)核堆棧,并完成了進程上下?所需的指令指針寄存器狀態(tài)切換。之后開始運?進程Y(這?進程Y曾經(jīng)通過以上步驟被切換出去,因此可以從switch_to下??代碼繼續(xù)執(zhí)?)。

(6)中斷上下?恢復,與(3)中斷上下?切換相對應。注意這?是進程Y的中斷處理過程中,?(3)中斷上下?切換是在進程X的中斷處理過程中,因為內(nèi)核堆棧從進程X 切換到進程Y了。

(7)為了對應起?,中斷上下?恢復的最后?步單獨拿出來(6的最后?步即是7)iret - pop cs:rip/ss:rsp/r?ags,從Y進程的內(nèi)核堆棧中彈出(3)中對應的壓棧內(nèi)容。此時完 成了中斷上下?的切換,即從進程Y的內(nèi)核態(tài)返回到進程Y的?戶態(tài)。注意快速系統(tǒng)調(diào)?返回sysret與iret的處理略有不同。

(8)繼續(xù)運??戶態(tài)進程Y。

總結(jié)

以上是生活随笔為你收集整理的Linux中断与进程切换,结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 久久亚洲精少妇毛片午夜无码 | juliaann欧美二区三区 | 麻豆精品在线视频 | 99久久久久成人国产免费 | 欧美成人精品一区二区免费看片 | 免费在线视频你懂的 | 日本成人在线一区 | 俄罗斯破处 | 日韩中文无 | h片在线免费看 | 亚洲国产123 | 日本不卡在线播放 | www.九九九| 精品国产一二三区 | 欧美黑人性猛交xxxx | 吻胸摸激情床激烈视频 | 久久久国产精品黄毛片 | 亚洲亚裔videos黑人hd | 日本欧美精品 | 亚洲综合色自拍一区 | 久久精品免费网站 | 哈利波特3在线观看免费版英文版 | 亚洲精品亚洲 | 欧美最猛黑人xxxx | 欧美男女性生活视频 | 国产美女网| 久久久久亚洲日日精品 | 青青青草视频在线观看 | 国产一级黄色av | 日韩欧美一区二区三区在线观看 | 欧美成片vs欧美 | h视频在线免费观看 | 超碰在线免费97 | 夜夜爽av| 97神马影院 | 青青草综合视频 | 中文字幕永久在线视频 | 日本免费视频 | 18xxxx日本| 午夜伦理一区二区 | 日本www黄| 日本亲子乱子伦xxxx | 午夜xxxxx| av网站观看 | 成人免费公开视频 | 黄色日韩在线 | 欧美一区二区不卡视频 | 日韩第六页 | 围产精品久久久久久久 | 婷婷综合另类小说色区 | 一区二区三区福利 | 羽月希奶水一区二区三区 | 综合国产视频 | 亚洲精品一区二 | 午夜羞羞羞 | 中文字幕乱码在线观看 | 色呦呦麻豆 | 麻豆精品免费视频 | 艳母免费在线观看 | 白嫩初高中害羞小美女 | 免费在线观看你懂的 | 日韩av地址| 日韩欧美自拍 | 亚洲永久无码精品 | 免费人成网站 | 亚洲高清色 | 四虎永久在线视频 | 东京久久| 成人免费视屏 | 性福宝av | 三级免费观看 | 国内毛片毛片毛片毛片 | 91亚洲国产成人久久精品麻豆 | 欧美老肥熟 | 解开人妻的裙子猛烈进入 | 国产欧美一区二区精品性色99 | 窝窝午夜理论片影院 | 污污的网站在线观看 | 又黄又爽的视频 | 美女被c出水 | 日本三级一区二区三区 | 久久狠狠高潮亚洲精品 | 国内偷拍久久 | 国产免费激情 | 中文日韩av | 加勒比毛片 | 91国产免费观看 | a级成人毛片 | 91久久婷婷 | av在线播放网 | 国产成人啪一区二区 | 黄色aaa毛片 | 先锋资源久久 | 一级片99| 色偷偷人人澡人人爽人人模 | 国产午夜精品理论片 | 香蕉视频ap | 女人被男人躁得好爽免费视频 | 30一40一50女人毛片 |