• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            jake1036

            linux0.11---fork.c函數(shù)分析

            1 功能描述 
              fork()系統(tǒng)調(diào)用用于創(chuàng)建子進(jìn)程,Linux中所有的進(jìn)程都是進(jìn)程0的子進(jìn)程。

                copy_process()函數(shù)用于創(chuàng)建并復(fù)制進(jìn)程代碼段和數(shù)據(jù)段以及環(huán)境,在進(jìn)程復(fù)制的過(guò)程中,工作主要牽涉到進(jìn)程數(shù)據(jù)結(jié)構(gòu)中信息的設(shè)置。
                系統(tǒng)首先為新建進(jìn)程在主內(nèi)存區(qū)申請(qǐng)一頁(yè)內(nèi)存來(lái)存放任務(wù)數(shù)據(jù)結(jié)構(gòu)信息,并復(fù)制當(dāng)前進(jìn)程任務(wù)數(shù)據(jù)結(jié)構(gòu)中的所有內(nèi)容作為新進(jìn)程任務(wù)數(shù)據(jù)結(jié)構(gòu)的模板。
                隨后對(duì)已經(jīng)復(fù)制的任務(wù)數(shù)據(jù)結(jié)構(gòu)內(nèi)容進(jìn)行修改。把當(dāng)前進(jìn)程設(shè)置為新進(jìn)程的父進(jìn)程,清除信號(hào)位圖并復(fù)位新進(jìn)程的各個(gè)統(tǒng)計(jì)值。接著根據(jù)當(dāng)前進(jìn)程環(huán)境設(shè)置新進(jìn)程任務(wù)狀態(tài)段TSS中各個(gè)寄存器的值,新建進(jìn)程內(nèi)核態(tài)堆棧指針tss.esp0被設(shè)置成為任務(wù)數(shù)據(jù)結(jié)構(gòu)所在內(nèi)存頁(yè)面的頂端,而tss.ss0被設(shè)置為內(nèi)核數(shù)據(jù)段選擇符。
              每當(dāng)任務(wù)進(jìn)入內(nèi)核態(tài)運(yùn)行的時(shí)候,其內(nèi)核態(tài)堆棧指針初始位置不變,均為任務(wù)數(shù)據(jù)所在頁(yè)面的頂端。

             

             


              2源代碼分析

               
             #include <errno.h>
            #include 
            <linux/sched.h>
            #include 
            <linux/kernel.h>
            #include 
            <asm/segment.h>
            #include 
            <asm/system.h>

            extern void write_verify(unsigned long address) ;
            long last_pid = 0//最新進(jìn)程號(hào),其值會(huì)由get_empty_process生成
            void verify_area(void * addr ,  int size)
            {
               unsigned 
            long start ;
               start 
            = (unsigned long) addr ;
               size 
            += start & 0xfff ;
               start 
            &= 0xfffff000 ;
               start 
            += get_base(current->ldt[2]) ;
               
            while(size > 0){
                 size 
            -= 4096 ;  
                 write_verify(start) ;
                 start 
            += 4096 ;
               }

            }


            //該函數(shù)為新的進(jìn)程在線性地址空間中設(shè)置新的代碼段和數(shù)據(jù)段基地址和限長(zhǎng)
            int copy_mem(int nr , struct task_struct * p)
            {
               unsigned 
            long old_data_base , new_data_base , data_limit ;
               unsigned 
            long old_code_base , new_code_base , code_limit ;
               code_limit 
            = get_limit(0x0f) ;
               data_limit 
            = get_limit(0x17) ;
               old_code_base 
            = get_base(current->ldt[1]) ;
               old_data_base 
            = get_base(current->ldt[2]) ;
               
            if(old_code_base != old_data_base)
                 panic(
            "We donot support seperate ID") ;
               
            if(data_limit < code_limit) 
                 panic(
            "Bad data_limit") ;

               new_data_base 
            = new_code_base = nr * 0x4000000 ; //nr * 64MB
               p->start_code = new_code_base ;
               set_base(p
            ->ldt[1] , new_code_base) ;
               set_base(p
            ->ldt[2] , new_data_base) ;
               
            if(copy_page_tables(old_data_base , new_data_base , data_limit))
                
            {
                  free_page_tables(new_data_base , data_limit) ;
                  
            return -ENOMEM ;

                }

                
            return 0 ;   
            }


            //下面是主要的fork程序,負(fù)責(zé)復(fù)制系統(tǒng)進(jìn)程信息
            //并且設(shè)置必要的寄存器,還整個(gè)地復(fù)制數(shù)據(jù)段

            int copy_process(int nr , long ebp , long edi , long esi , long gs , long none ,
             
            long ebx , long ecx , long edx , long fs , long es , long ds , long eip ,
            long cs , long eflags , long esp , long ss)
            {
              
            struct task_struct * p ;
              
            int i ;
              
            struct file * f ;
              p 
            = (struct task_struct *) get_free_page() ;
              
            if(!p)
                
            return -EAGAIN ;
              task[nr] 
            = p ;       
              
            *= * current ; //并不是指針的賦值 ,而是直接申請(qǐng)了一個(gè)空間 
              
            //下面開(kāi)始修改任務(wù)數(shù)據(jù)結(jié)構(gòu)的值
              p->state = TASK_UNINTERRUPTIBLE ; 
              p
            ->pid = last_pid ;
              p
            ->father = current->pid ;
              p
            ->counter = p->priority ;//設(shè)置時(shí)間片
              p->signal = 0 ;   //信號(hào)位圖置0
              p->alarm = 0 ; //報(bào)警定時(shí)器值
              p->leader = 0 ;//進(jìn)程的領(lǐng)導(dǎo)權(quán)
              p->utime = p->stime = 0 ; //用戶態(tài)號(hào)和心態(tài)的運(yùn)行時(shí)間
              p->cutime = p->cstime = 0 ;//子進(jìn)程用戶態(tài)和和核心態(tài)的運(yùn)行時(shí)間  
              p->start_time = jiffies ; //進(jìn)程當(dāng)前的運(yùn)行時(shí)間
              

              p
            ->tss.back_link = 0  ;
              p
            ->tss.esp0 = PAGE_SIZE + (long) p ; //任務(wù)內(nèi)核態(tài)棧指針
              p->tss.ss0 = 0x10 ;       //內(nèi)核態(tài)的段選擇符,與數(shù)據(jù)段選擇符相同
              p->tss.eip = eip  ;
              p
            ->tss.eflags = eflags ; 
              p
            ->tss.eax = 0 ; //這是當(dāng)fork()調(diào)用返回時(shí) 新進(jìn)程會(huì)返回0的原因
              p->tss.ecx = ecx ;
              p
            ->tss.edx = edx ;
              p
            ->tss.ebx = ebx ; 
              p
            ->tss.esp = esp ;
              p
            ->tss.ebp = ebp ;
              p
            ->tss.esi = esi ;
              p
            ->tss.edi = edi ;
              p
            ->tss.es = es & 0xffff ;
              p
            ->tss.cs = cs & 0xffff ;
              p
            ->tss.ss = ss & 0xffff ;
              p
            ->tss.ds = ds & 0xffff ;
              p
            ->tss.fs = fs & 0xffff ;
              p
            ->tss.gs = gs & 0xffff ;
              p
            ->tss.ldt = _LDT(nr) ;  
              p
            ->tss.trace_bitmap = 0x80000000 ;
              

              
            if(last_task_used_math == current)
               __asm__(
            "clts ; fnsave %0" ::"m"(p->tss.i387)) ;
              
            //接下來(lái)復(fù)制進(jìn)程頁(yè)表,即在線性地址空間設(shè)置新任務(wù)代碼段和數(shù)據(jù)段描述符中的基地址和限長(zhǎng),并復(fù)制頁(yè)表。  
              if(copy_mem(nr , p)){
                task[nr] 
            = NULL ;
                free_page((
            long)p) ;
                
            return -EAGAIN ;
              }


              
            //如果父進(jìn)程中有些文件是打開(kāi)的,則將對(duì)應(yīng)文件的打開(kāi)次數(shù)加1 ,因?yàn)樽舆M(jìn)程會(huì)共享父進(jìn)程打開(kāi)的這些文件
              for(i = 0 ; i < NR_OPEN ; i++)  
                
            if(f = p->filp[i])
                 f
            ->f_count++ ;
              
            if(current->pwd)
                 current
            ->pwd->i_count++ ;
              
            if(current->root)
                current
            ->root->i_count++ ;
              
            if(current->executable)
                current
            ->executable->i_count++ ;

              
            //最后在GDT表中設(shè)置新任務(wù)TSS段和LDT段描述符
              set_tss_desc(gdt + (nr<<1+ FIRST_TSS_ENTRY , &(p->tss)) ;
              set_ldt_desc(gdt 
            + (nr<<1+ FIRST_LDT_ENTRY , &(p->ldt)) ;
              p
            ->state = TASK_RUNNING ;  
               
              
            return last_pid ;
            }


            //為新進(jìn)程取得不重復(fù)的進(jìn)程號(hào)last_pid ,函數(shù)返回在任務(wù)數(shù)組中的任務(wù)號(hào)
             int find_empty_process(void)
            {
              
            int i ; 
              repeat:
                
            if((++last_pid) < 0) last_pid = 1 ;
                
            for(i = 0 ; i < NR_TASKS ; i++)
                   
            if(task[i] && task[i]->pid == last_pid)
                       
            goto repeat ;

                
            for(i = 1 ; i < NR_TASKS ; i++)  
                   
            if(!task[i])
                      
            return i ;

                
            return -EAGAIN ; 
            }










              

            posted on 2010-11-08 19:48 kahn 閱讀(1040) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久精品中文字幕一区| 亚洲色大成网站www久久九| 国产真实乱对白精彩久久| 色婷婷久久综合中文久久一本| 日韩亚洲欧美久久久www综合网 | 久久精品国产半推半就| 精品国产综合区久久久久久 | 日韩久久久久中文字幕人妻| 亚洲色欲久久久综合网东京热| 国产成人99久久亚洲综合精品| 影音先锋女人AV鲁色资源网久久| 久久99亚洲综合精品首页| 少妇高潮惨叫久久久久久| 亚洲国产天堂久久综合| 国产精品免费久久| 久久精品人人槡人妻人人玩AV| 99久久这里只精品国产免费| 国产亚州精品女人久久久久久 | 久久久久久久波多野结衣高潮| 香港aa三级久久三级| 久久亚洲精品国产精品| 久久这里有精品| 久久久综合香蕉尹人综合网| 国产99精品久久| 色综合久久久久综合体桃花网| 伊人久久大香线蕉综合5g| 久久se精品一区精品二区国产| 2021久久国自产拍精品| 99久久中文字幕| 精品久久久无码人妻中文字幕豆芽| 久久精品国产亚洲AV蜜臀色欲| 久久久久97国产精华液好用吗| 一本久久久久久久| 国产精品伊人久久伊人电影 | 久久有码中文字幕| 一级A毛片免费观看久久精品| 久久免费99精品国产自在现线 | 四虎影视久久久免费| 亚洲欧美另类日本久久国产真实乱对白| 成人国内精品久久久久影院VR| 91精品国产高清久久久久久91|