久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

系統(tǒng)調(diào)用和進(jìn)程切換時(shí)的寄存器信息保存在哪里?

 liang1234_ 2020-08-28

系統(tǒng)調(diào)用是什么,?,??
系統(tǒng)調(diào)用是操作系統(tǒng)為用戶提供的一系列API,;系統(tǒng)調(diào)用將用戶的請(qǐng)求發(fā)給內(nèi)核,,內(nèi)核執(zhí)行完以后,將結(jié)果返回給用戶,;
以open為例,,進(jìn)行系統(tǒng)調(diào)用:
分析Linux2.6.11版本
<1>通過在unistd.h中的函數(shù)名的拼接;
這里寫圖片描述

<2>找到對(duì)應(yīng)的系統(tǒng)調(diào)用號(hào)
這里寫圖片描述
<3>然后將此系統(tǒng)調(diào)用號(hào)通過eax寄存器告知內(nèi)核,在執(zhí)行0x80號(hào)中斷的時(shí)候,,eax寄存器中放的是5,;
<4>將用戶空間的esp等信息壓入內(nèi)核棧,在內(nèi)核棧上執(zhí)行系統(tǒng)調(diào)用,;
<5>系統(tǒng)調(diào)用執(zhí)行完畢,,將結(jié)果寫入eax寄存器中,將用戶空間的信息彈出內(nèi)核棧,,執(zhí)行用戶空間的代碼,;

系統(tǒng)調(diào)用時(shí)的當(dāng)前進(jìn)程要進(jìn)行模式的切換,要從用戶態(tài)切換到內(nèi)核態(tài),,那么用戶態(tài)的一些寄存器信息,,就要進(jìn)行壓棧的操作,壓入內(nèi)核棧,,以免下次進(jìn)行現(xiàn)場(chǎng)恢復(fù)(恢復(fù)到用戶空間)的時(shí)候,,直接從內(nèi)核棧彈出寄存器的信息,并讓eax寄存器帶上內(nèi)核完成系統(tǒng)調(diào)用時(shí)的結(jié)果,;

進(jìn)程切換來了,。。,。
當(dāng)我們進(jìn)程進(jìn)行切換的時(shí)候,,用戶態(tài)的寄存器信息,是保存在哪里的呢,?用戶態(tài)的信息是保存在task_struct里面的成員變量thread里面,;

struct task_struct {
    /**
     * 進(jìn)程狀態(tài)。
     */
    volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
    /**
     * 進(jìn)程的基本信息,。
     */
    struct thread_info *thread_info;
    atomic_t usage;
    unsigned long flags;    /* per process flags, defined below */
    unsigned long ptrace;

    int lock_depth;     /* Lock depth */

    /**
     * 進(jìn)行的動(dòng)態(tài)優(yōu)先權(quán)和靜態(tài)優(yōu)先權(quán)
     */
    int prio, static_prio;
    /**
     * 進(jìn)程所在運(yùn)行隊(duì)列,。每個(gè)優(yōu)先級(jí)對(duì)應(yīng)一個(gè)運(yùn)行隊(duì)列。
     */
    struct list_head run_list;
    /**
     * mm:指向內(nèi)存區(qū)描述符的指針
     */
    struct mm_struct *mm, *active_mm;
    struct thread_struct thread;
    ...
    }

針對(duì)上面的代碼,,我們來說一下thread和thread_info的區(qū)別,;

以下為thread的結(jié)構(gòu):

/**
 * 進(jìn)程被切換出去后,內(nèi)核把它的硬件上下文保存在這個(gè)結(jié)構(gòu)中,。
 * 它包含大部分CPU寄存器,,但是不包含eax、ebx這樣的寄存器,。
 */
struct thread_struct {
/* cached TLS descriptors. */
    struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
    unsigned long   esp0;
    unsigned long   sysenter_cs;
    unsigned long   eip;
    unsigned long   esp;
    unsigned long   fs;
    unsigned long   gs;
/* Hardware debugging registers */
    unsigned long   debugreg[8];  /* %%db0-7 debug registers */
/* fault info */
    unsigned long   cr2, trap_no, error_code;
/* floating point info */
    /**
     * 為支持選擇性裝入FPU,、MMX和XMM寄存器,引入此結(jié)構(gòu),。
     * 當(dāng)切換進(jìn)程時(shí),,將進(jìn)程的這些寄存器保存在i387結(jié)構(gòu)中,。
     */
    union i387_union    i387;
/* virtual 86 mode info */
    struct vm86_struct __user * vm86_info;
    unsigned long       screen_bitmap;
    unsigned long       v86flags, v86mask, saved_esp0;
    unsigned int        saved_fs, saved_gs;
/* IO permissions */
    unsigned long   *io_bitmap_ptr;
/* max allowed port in the bitmap, in bytes: */
    unsigned long   io_bitmap_max;
};

以上代碼可以看出來我們的thread里面保存的是一些進(jìn)程切換時(shí),寄存器中的內(nèi)容,,當(dāng)進(jìn)行進(jìn)程切換的時(shí)候,,我們需要保存寄存器的信息,把寄存器的信息賦值給thread里面的各個(gè)變量,;

thread_info的結(jié)構(gòu)如下:

struct thread_info {
    struct task_struct  *task;      /* main task structure */
    struct exec_domain  *exec_domain;   /* execution domain */
    /**
     * 如果有TIF_NEED_RESCHED標(biāo)志,,則必須調(diào)用調(diào)度程序。
     */
    unsigned long       flags;      /* low level flags */
    /**
     * 線程標(biāo)志:
     *     TS_USEDFPU:表示進(jìn)程在當(dāng)前執(zhí)行過程中,,是否使用過FPU,、MMX和XMM寄存器。
     */
    unsigned long       status;     /* thread-synchronous flags */
    /**
     * 可運(yùn)行進(jìn)程所在運(yùn)行隊(duì)列的CPU邏輯號(hào),。
     */
    __u32           cpu;        /* current CPU */
    __s32           preempt_count; /* 0 => preemptable, <0 => BUG */


    mm_segment_t        addr_limit; /* thread address space:
                           0-0xBFFFFFFF for user-thead
                           0-0xFFFFFFFF for kernel-thread
                        */
    struct restart_block    restart_block;

    unsigned long           previous_esp;   /* ESP of the previous stack in case
                           of nested (IRQ) stacks
                        */
    __u8            supervisor_stack[0];
};

thread_info是保存不同體系下進(jìn)程的信息,,不同的體系結(jié)構(gòu)可能進(jìn)程需要存儲(chǔ)的信息不盡相同, 這就需要我們實(shí)現(xiàn)一種通用的方式, 我們將體系結(jié)構(gòu)相關(guān)的部分和無關(guān)的部門進(jìn)行分離,這就是thread_info的作用,;

是不是會(huì)有小伙伴會(huì)問那當(dāng)我一個(gè)進(jìn)程進(jìn)行系統(tǒng)調(diào)用的時(shí)候,,其實(shí)我并不知道,當(dāng)我的系統(tǒng)調(diào)用返回的時(shí)候,,會(huì)不會(huì)發(fā)生進(jìn)程切換,,我進(jìn)程系統(tǒng)調(diào)用前是不知道的,那么我們?yōu)槭裁催M(jìn)行模式切換時(shí),,要把用戶的棧信息,,壓入內(nèi)核棧呢?我們?yōu)槭裁床恢苯颖4嬖趖hread里面,,這樣的話,,當(dāng)系統(tǒng)調(diào)用返回的時(shí)候,如果剛好又要進(jìn)行切換的時(shí)候,,我們的用戶棧信息,,已經(jīng)保存在thread里面了,不就好了么,?,??

其實(shí),,對(duì)于這個(gè)問題,我自己也是很郁悶,,通過問蘇老師,,我終于才懂了;
蘇大神說:當(dāng)進(jìn)行系統(tǒng)調(diào)用的時(shí)候,,當(dāng)前進(jìn)程的時(shí)間片就停止了,,由內(nèi)核去完成系統(tǒng)調(diào)用,,當(dāng)我們系統(tǒng)調(diào)用返回的時(shí)候,時(shí)間片就可以重新開始計(jì)時(shí),,無論怎么樣,,系統(tǒng)調(diào)用以后,一定是有時(shí)間讓內(nèi)核把信息,,返回給用戶,,系統(tǒng)調(diào)用的結(jié)果會(huì)保存在eax寄存器中,如果系統(tǒng)剛調(diào)用完畢,,準(zhǔn)備返回用戶空間,,就在此時(shí),發(fā)生了進(jìn)程切換,,那么別的進(jìn)程就會(huì)改掉eax的值,,那么當(dāng)我下次進(jìn)行恢復(fù)的時(shí)候,還得重新調(diào)用系統(tǒng)調(diào)用,,這樣子的話,,對(duì)于系統(tǒng)的資源就態(tài)浪費(fèi)了;所以說進(jìn)行系統(tǒng)調(diào)用的返回值一定是返回給用戶的,,當(dāng)用戶吧eax寄存器的值保存起來以后,,標(biāo)志這系統(tǒng)調(diào)用完畢,接下來切不切換進(jìn)程就沒有啥影響了,;

當(dāng)發(fā)生系統(tǒng)調(diào)用或者中斷的時(shí)候,,中斷發(fā)生前夕,要把所有相關(guān)寄存器的內(nèi)容都保存在內(nèi)核堆棧中,,由宏SAVE_ALL宏完成 :

#define SAVE_ALL \ 
cld; \ 
pushl %es; \ 
pushl %ds; \ 
pushl %eax; \ 
pushl %ebp; \ 
pushl %edi; \ 
pushl %esi; \ 
pushl %edx; \ 
pushl %ecx; \ 
pushl %ebx; \ 
movl $(__KERNEL_DS),%edx; \ 
movl %edx,%ds; \ 
movl %edx,%es;

恢復(fù)現(xiàn)場(chǎng)的宏RESTORE_ALL :
從中斷返回時(shí),,恢復(fù)相關(guān)寄存器的內(nèi)容,這是通過RESTORE_ALL宏完成的:


#define RESTORE_ALL \ 
popl %ebx; \ 
popl %ecx; \ 
popl %edx; \ 
popl %esi; \ 
popl %edi; \ 
popl %ebp; \ 
popl %eax; \ 
1: popl %ds; \ 
2: popl %es; \ 
addl $4,%esp; \ 
3: iret;

總結(jié):系統(tǒng)調(diào)用的時(shí)候,,用戶態(tài)的棧信息壓入內(nèi)核棧,;進(jìn)程切換的時(shí)候,用戶態(tài)的棧信息保存在task_struct中的成員thread中,;

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多