欧美性猛交xxxx免费看_牛牛在线视频国产免费_天堂草原电视剧在线观看免费_国产粉嫩高清在线观看_国产欧美日本亚洲精品一5区

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

系統(tǒng)調(diào)用:用戶棧與內(nèi)核棧的切換(上)

麥辣雞腿堡 ? 來源:技術(shù)簡說 ? 作者:董旭 ? 2023-07-31 11:27 ? 次閱讀

當(dāng)發(fā)生系統(tǒng)調(diào)用、產(chǎn)生異常,外設(shè)發(fā)生中斷等事件時,會發(fā)生用戶棧和內(nèi)核棧之間的切換,本文從系統(tǒng)調(diào)用角度分析用戶棧與內(nèi)核棧的切換。

系統(tǒng)調(diào)用的演變

x86 的系統(tǒng)調(diào)用經(jīng)歷了 int / iret 到 sysenter / sysexit 再到 syscall / sysret 實(shí)現(xiàn)方式的轉(zhuǎn)變,關(guān)于具體的演化和區(qū)別、系統(tǒng)調(diào)用的其他細(xì)節(jié)等將在以后的系統(tǒng)調(diào)用專欄里分析。本文從系統(tǒng)調(diào)用最原始的int 0x80開始分析用戶棧與內(nèi)核棧的切換,重點(diǎn)看系統(tǒng)調(diào)用過程用戶棧與內(nèi)核棧切換的過程中的一些細(xì)節(jié)。

系統(tǒng)調(diào)用-分析從用戶棧切換內(nèi)核棧

內(nèi)核SYSCALL 入口代碼在entry_64.S中:

//arch/x86/entry/entry_64.S
ENTRY(entry_SYSCALL_64)
 UNWIND_HINT_EMPTY
 /* Interrupts are off on entry. */
 swapgs
 // 將用戶棧偏移保存到 per-cpu 變量 rsp_scratch 中
 movq %rsp, PER_CPU_VAR(rsp_scratch)
 // 切換到進(jìn)程內(nèi)核棧
 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp

 /* 在棧中倒序構(gòu)建 struct pt_regs */
 pushq $__USER_DS   /* pt_regs- >ss */
 pushq PER_CPU_VAR(rsp_scratch) /* pt_regs- >sp */
 pushq %r11    /* pt_regs- >flags */
 pushq $__USER_CS   /* pt_regs- >cs */
 pushq %rcx    /* pt_regs- >ip */
GLOBAL(entry_SYSCALL_64_after_hwframe)
 //rax 保存著系統(tǒng)調(diào)用號
 pushq %rax    /* pt_regs- >orig_ax */

 PUSH_AND_CLEAR_REGS rax=$-ENOSYS

 TRACE_IRQS_OFF

 /* 保存參數(shù)寄存器,調(diào)用do_syscall_64函數(shù) */
 movq %rax, %rdi
 movq %rsp, %rsi
call do_syscall_64  /* returns with IRQs disabled */

上面的匯編指令中先將當(dāng)前用戶棧(用戶空間棧頂)記錄在CPU獨(dú)占變量區(qū)域里(PER_CPU變量),如下所示:

movq %rsp, PER_CPU_VAR(rsp_scratch)

然后將CPU獨(dú)占區(qū)域里記錄的內(nèi)核棧頂放入rsp/esp寄存器

movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp

就是這么簡潔,**上面兩句匯編:就 將用戶棧頂保存在了當(dāng)前CPU的rsp_scratch這樣一個PER_CPU變量里,完成了用戶棧的保存 ,然后 將當(dāng)前內(nèi)核棧的地址存放到當(dāng)前棧指針寄存器中 ,**那么此時棧寄存器指向的就是內(nèi)核棧的棧頂,由此優(yōu)雅、完美地完成了用戶棧到內(nèi)核棧的切換!

接下來所有的壓棧操作都是在內(nèi)核棧里操作了,依次將用戶空間寄存器壓棧,此時也是往內(nèi)核棧push的, 內(nèi)核使用struct pt_regs初始化內(nèi)核棧,也就是通過push保存寄存器的值 (將用戶棧信息:用戶調(diào)用的系統(tǒng)調(diào)用號、參數(shù)、代碼段地址、數(shù)據(jù)段地址等以struct pt_regs形式壓入棧) ,形成一個pt_regs結(jié)構(gòu) ,如下圖(源于上篇文章中的分析):

圖片

在棧中順序固定且倒序壓棧(在x86_64中,內(nèi)核棧rbx rbp r12 r13 r14 r15不是必須保存的項(為了訪問不越界相應(yīng)空間必須保留),根據(jù)需要保存,linux后續(xù)版本采取都保存方式),其中rax保存系統(tǒng)調(diào)用號

//rax 保存著系統(tǒng)調(diào)用號
 pushq %rax    /* pt_regs- >orig_ax */
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1383

    瀏覽量

    40438
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11350

    瀏覽量

    210477
收藏 人收藏

    評論

    相關(guān)推薦

    C函數(shù)調(diào)用機(jī)制與幀原理詳解

    當(dāng)一個C函數(shù)被調(diào)用時,函數(shù)的參數(shù)如何傳遞、堆棧指針如何變化、幀是如何被建立以及如何被消除的,一直缺乏系統(tǒng)性的理解,因此決定花時間學(xué)習(xí)下函數(shù)調(diào)用時整個
    發(fā)表于 06-08 10:49 ?1482次閱讀
    C函數(shù)<b class='flag-5'>調(diào)用</b>機(jī)制與<b class='flag-5'>棧</b>幀原理詳解

    操作系統(tǒng)為什么分內(nèi)核態(tài)和用戶態(tài)?這兩者如何切換?

    操作系統(tǒng)為什么分內(nèi)核態(tài)和用戶態(tài),這兩者如何切換?進(jìn)程在地址空間會劃分為哪些區(qū)域?堆和有什么區(qū)別?
    發(fā)表于 07-23 09:01

    ARMv8的函數(shù)調(diào)用是什么意思?調(diào)用的內(nèi)存管理是怎樣的

    調(diào)用解析概念: 任意體系結(jié)構(gòu)的CPU,都設(shè)計了一套通用寄存器、狀態(tài)寄存器及其他控制寄存器,用以維系系統(tǒng)的正常運(yùn)行。函數(shù)調(diào)用過程中,CPU一般都需要處理幾件事情:保存母函數(shù)現(xiàn)場(寄存器
    發(fā)表于 05-13 10:36

    用一個實(shí)例展示一下Linux內(nèi)核幀的入和退過程

    1、Linux內(nèi)核調(diào)試方法總結(jié)之幀  幀  幀和指針可以說是C語言的精髓。幀是一種特殊的數(shù)據(jù)結(jié)構(gòu),在C語言函數(shù)
    發(fā)表于 11-04 15:47

    一文詳解Linux內(nèi)核回溯與妙用

    網(wǎng)上或多或少都能找到回溯的一些文章,但是講的都并不完整,沒有將內(nèi)核回溯的功能用于實(shí)際的內(nèi)核、應(yīng)用程序調(diào)試,這是本篇文章的核心:盡可能引導(dǎo)讀者將
    的頭像 發(fā)表于 10-05 10:02 ?5458次閱讀
    一文詳解Linux<b class='flag-5'>內(nèi)核</b>的<b class='flag-5'>棧</b>回溯與妙用

    對Linux的進(jìn)程內(nèi)核的認(rèn)識

    在每一個進(jìn)程的生命周期中,必然會通過到系統(tǒng)調(diào)用陷入內(nèi)核。在執(zhí)行系統(tǒng)調(diào)用陷入內(nèi)核之后,這些
    發(fā)表于 05-12 08:53 ?640次閱讀
    對Linux的進(jìn)程<b class='flag-5'>內(nèi)核</b><b class='flag-5'>棧</b>的認(rèn)識

    帶你了解嵌入式C語言函數(shù)調(diào)用

    大家都知道函數(shù)調(diào)用是通過來實(shí)現(xiàn)的,而且知道在中存放著該函數(shù)的局部變量。但是對于的實(shí)現(xiàn)細(xì)節(jié)可能不一定清楚。
    發(fā)表于 07-12 17:08 ?2145次閱讀
    帶你了解嵌入式C語言函數(shù)<b class='flag-5'>調(diào)用</b><b class='flag-5'>棧</b>

    淺談鴻蒙內(nèi)核源碼的CPU四次換,寄存器改值

    本篇有相當(dāng)?shù)碾y度,涉及用戶內(nèi)核的兩輪切換,CPU四次換,寄存器改值,將圍繞下圖來說明.?
    的頭像 發(fā)表于 04-28 16:56 ?1653次閱讀
    淺談鴻蒙<b class='flag-5'>內(nèi)核</b>源碼的CPU四次換<b class='flag-5'>棧</b>,寄存器改值

    淺談鴻蒙內(nèi)核源碼的

    上面的代碼和鴻蒙內(nèi)核方式一樣,都采用了遞減滿的方式, 什么是遞減滿?
    的頭像 發(fā)表于 04-24 11:21 ?1476次閱讀
    淺談鴻蒙<b class='flag-5'>內(nèi)核</b>源碼的<b class='flag-5'>棧</b>

    鴻蒙內(nèi)核源碼分析:用戶內(nèi)核的兩次切換

    這是系統(tǒng)調(diào)用的總?cè)肟?所有的系統(tǒng)調(diào)用都要跑這里要統(tǒng)一處理.通過系統(tǒng)號(保存在R7),找到注冊函數(shù)并回調(diào).完成
    的頭像 發(fā)表于 04-23 17:17 ?1964次閱讀
    鴻蒙<b class='flag-5'>內(nèi)核</b>源碼分析:<b class='flag-5'>用戶</b><b class='flag-5'>棧</b>和<b class='flag-5'>內(nèi)核</b><b class='flag-5'>棧</b>的兩次<b class='flag-5'>切換</b>

    是什么?有什么作用?

    大多數(shù)的處理器架構(gòu),都有實(shí)現(xiàn)硬件。有專門的指針寄存器,以及特定的硬件指令來完成 入/出 的操作。例如在 ARM 架構(gòu),R13 (S
    的頭像 發(fā)表于 06-17 11:19 ?1.3w次閱讀

    Linux中的進(jìn)程、線程內(nèi)核以及中斷

    首先, (stack) 是一種串列形式的 數(shù)據(jù)結(jié)構(gòu)。這種數(shù)據(jù)結(jié)構(gòu)的特點(diǎn)是 后入先出 (LIFO, Last In First Out),數(shù)據(jù)只能在串列的一端 (稱為:頂 top) 進(jìn)行 推入
    的頭像 發(fā)表于 05-14 09:30 ?771次閱讀
    Linux中的進(jìn)程<b class='flag-5'>棧</b>、線程<b class='flag-5'>棧</b>、<b class='flag-5'>內(nèi)核</b><b class='flag-5'>棧</b>以及中斷<b class='flag-5'>棧</b>

    系統(tǒng)調(diào)用用戶內(nèi)核切換(下)

    , regs- >dx, regs- >r10, regs- >r8, regs- >r9) ; } syscall_return_slowpath( regs ) ; }
    的頭像 發(fā)表于 07-31 11:29 ?701次閱讀

    linux中的進(jìn)程,線程,內(nèi)核的區(qū)別

    大多數(shù)的處理器架構(gòu),都有實(shí)現(xiàn)硬件。有專門的指針寄存器,以及特定的硬件指令來完成 入/出 的操作。例如在 ARM 架構(gòu),R13 (S
    發(fā)表于 08-18 10:57 ?554次閱讀
    linux中的進(jìn)程<b class='flag-5'>棧</b>,線程<b class='flag-5'>棧</b>,<b class='flag-5'>內(nèi)核</b><b class='flag-5'>棧</b>的區(qū)別

    malloc在Linux執(zhí)行的是哪個系統(tǒng)調(diào)用

    ()和mmap(),至于為什么是兩個,這跟ptmalloc內(nèi)存池的分配策略有關(guān),稍后介紹。 既然是系統(tǒng)調(diào)用,那么就必須處于內(nèi)核態(tài)去處理,而系統(tǒng)內(nèi)核
    的頭像 發(fā)表于 11-13 10:36 ?1078次閱讀
    malloc在Linux<b class='flag-5'>上</b>執(zhí)行的是哪個<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>調(diào)用</b>