• <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>
            隨筆-80  評(píng)論-24  文章-0  trackbacks-0
            初始化進(jìn)程控制塊數(shù)組的操作是在init_proc_list()內(nèi)完成的,它只被cbegin()函數(shù)調(diào)用,其實(shí)它的工作很簡(jiǎn)單,就是將進(jìn)程控制塊中的各個(gè)項(xiàng)初始化成初始值。并且將相應(yīng)進(jìn)程的LDT在GDT中的描述符初始化。這樣當(dāng)啟動(dòng)一個(gè)進(jìn)程的時(shí)候,只需要在進(jìn)程自己的LDT和TSS中填入適當(dāng)?shù)闹导纯桑恍枰頃?huì)LDT和TSS在GDT中的描述符內(nèi)容。

              1 //初始化init和sys進(jìn)程
              2 //主要包括進(jìn)程pid、進(jìn)程名、ldt、tss以及init進(jìn)程在gdt中對(duì)應(yīng)的項(xiàng)的初始化
              3 static void init_proc01()
              4 {
              5     struct seg_struct ldt_temp[3= {{0x00000x00000x000x000x000x00}, 
              6                                      {0xffff0x00000x000xfa0xcf0x00}, 
              7                                      {0xffff0x00000x000xf20xcf0x00}};
              8 
              9     //pid為0
             10     //進(jìn)程名為"init"
             11     proc_list[0].pid                = 0;
             12     proc_list[0].ppid                = -1;
             13     proc_list[0].state                = PROC_RUNNING;
             14     proc_list[0].priority            = 15;
             15     proc_list[0].time_slices        = proc_list[0].priority;
             16     proc_list[0].running_time        = 0;
             17     strcpy(proc_list[0].name, "init");
             18     //ldt共包括三項(xiàng),0->空,1->cs,2->ds&ss
             19     proc_list[0].ldt[0]                = ldt_temp[0];
             20     proc_list[0].ldt[1]                = ldt_temp[1];
             21     proc_list[0].ldt[2]                = ldt_temp[2];
             22     proc_list[0].tss.back_link        = 0;
             23     proc_list[0].tss.esp0            = KSTACKTOP(0); //內(nèi)核態(tài)堆棧頂
             24     proc_list[0].tss.ss0            = KERNEL_SS_SELECTOR;
             25     proc_list[0].tss.esp1            = 0;
             26     proc_list[0].tss.ss1            = 0;
             27     proc_list[0].tss.esp2            = 0;
             28     proc_list[0].tss.ss2            = 0;
             29     proc_list[0].tss.cr3            = (uint32)page_dir; //頁(yè)目錄表地址
             30     proc_list[0].tss.eip            = 0;
             31     proc_list[0].tss.eflags            = 0;
             32     proc_list[0].tss.eax            = 0;
             33     proc_list[0].tss.ecx            = 0;
             34     proc_list[0].tss.edx            = 0;
             35     proc_list[0].tss.ebx            = 0;
             36     proc_list[0].tss.esp            = 0;
             37     proc_list[0].tss.ebp            = 0;
             38     proc_list[0].tss.esi            = 0;
             39     proc_list[0].tss.edi            = 0;
             40     proc_list[0].tss.es                = 0x17//指向ldt中的選擇子
             41     proc_list[0].tss.cs                = 0x0f//指向ldt中的選擇子
             42     proc_list[0].tss.ss                = 0x17//指向ldt中的選擇子
             43     proc_list[0].tss.ds                = 0x17//指向ldt中的選擇子
             44     proc_list[0].tss.fs                = 0x17//指向ldt中的選擇子
             45     proc_list[0].tss.gs                = 0x17//指向ldt中的選擇子
             46     proc_list[0].tss.ldt            = LDT_SELECTOR(0);
             47     proc_list[0].tss.trace_bitmap    = 0x80000000;
             48 
             49     set_tss_seg(FIRST_TSS_INDEX, &(proc_list[0].tss));
             50     set_ldt_seg(FIRST_LDT_INDEX, proc_list[0].ldt);
             51 
             52     //pid為1
             53     //進(jìn)程名為"sys"
             54     proc_list[1].pid                = 1;
             55     proc_list[1].ppid                = 0;
             56     proc_list[1].state                = PROC_RUNNING;
             57     proc_list[1].priority            = 15;
             58     proc_list[1].time_slices        = proc_list[1].priority;
             59     proc_list[1].running_time        = 0;
             60     strcpy(proc_list[1].name, "sys");
             61     //ldt共包括三項(xiàng),0->空,1->cs,2->ds&ss
             62     proc_list[1].ldt[0]                = ldt_temp[0];
             63     proc_list[1].ldt[1]                = ldt_temp[1];
             64     proc_list[1].ldt[2]                = ldt_temp[2];
             65     proc_list[1].tss.back_link        = 0;
             66     proc_list[1].tss.esp0            = KSTACKTOP(1); //內(nèi)核態(tài)堆棧頂
             67     proc_list[1].tss.ss0            = KERNEL_SS_SELECTOR;
             68     proc_list[1].tss.esp1            = 0;
             69     proc_list[1].tss.ss1            = 0;
             70     proc_list[1].tss.esp2            = 0;
             71     proc_list[1].tss.ss2            = 0;
             72     proc_list[1].tss.cr3            = (uint32)page_dir; //頁(yè)目錄表地址
             73     proc_list[1].tss.eip            = (uint32)sys;
             74     proc_list[1].tss.eflags            = 0x1202;
             75     proc_list[1].tss.eax            = 0;
             76     proc_list[1].tss.ecx            = 0;
             77     proc_list[1].tss.edx            = 0;
             78     proc_list[1].tss.ebx            = 0;
             79     proc_list[1].tss.esp            = USTACKTOP(1);
             80     proc_list[1].tss.ebp            = USTACKTOP(1);
             81     proc_list[1].tss.esi            = 0;
             82     proc_list[1].tss.edi            = 0;
             83     proc_list[1].tss.es                = 0x17//指向ldt中的選擇子
             84     proc_list[1].tss.cs                = 0x0f//指向ldt中的選擇子
             85     proc_list[1].tss.ss                = 0x17//指向ldt中的選擇子
             86     proc_list[1].tss.ds                = 0x17//指向ldt中的選擇子
             87     proc_list[1].tss.fs                = 0x17//指向ldt中的選擇子
             88     proc_list[1].tss.gs                = 0x17//指向ldt中的選擇子
             89     proc_list[1].tss.ldt            = LDT_SELECTOR(1);
             90     proc_list[1].tss.trace_bitmap    = 0x80000000;
             91 
             92     set_tss_seg(FIRST_TSS_INDEX + 2&(proc_list[1].tss));
             93     set_ldt_seg(FIRST_LDT_INDEX + 2, proc_list[1].ldt);
             94 }
             95 
             96 void init_proc_list()
             97 {
             98     int i;
             99     for (i = 0; i < NR_PROCS; ++i)
            100     {
            101         proc_list[i].pid            = -1;
            102         proc_list[i].ppid            = -1;
            103         proc_list[i].state            = PROC_STOPPED;
            104         proc_list[i].priority        = 0;
            105         proc_list[i].time_slices    = 0;
            106         proc_list[i].running_time    = 0;
            107         memset(proc_list[i].name, 0, PROC_NAME_LEN);
            108         memset(proc_list[i].ldt, 03 * sizeof(struct seg_struct));
            109         memset(&(proc_list[i].tss), 0sizeof(TSS));
            110         set_tss_seg(FIRST_TSS_INDEX + i * 2&(proc_list[i].tss));
            111         set_ldt_seg(FIRST_LDT_INDEX + i * 2, proc_list[i].ldt);
            112     }
            113 
            114     //啟動(dòng)的第一個(gè)進(jìn)程是進(jìn)程鏈表proc_list中第一個(gè)進(jìn)程,為init進(jìn)程
            115     current    = proc_list;
            116 }
            117 

            注意到在process.c文件中有一個(gè)current變量,它是proc_struct類型指針,是全局變量,這從linux借鑒過(guò)來(lái),用于指向當(dāng)前正在運(yùn)行的進(jìn)程。
            下面著重看init_proc01()函數(shù)。
            它的作用是在proc_list[0]和proc_list[1]中填入適當(dāng)?shù)闹担詾閱?dòng)進(jìn)程init(0號(hào)進(jìn)程)和sys(1號(hào)進(jìn)程)做準(zhǔn)備。
            我們只研究init進(jìn)程控制塊的填入過(guò)程:
            進(jìn)程id為0,父進(jìn)程id為-1(因?yàn)樗撬羞M(jìn)程的父進(jìn)程,它沒(méi)有父進(jìn)程),優(yōu)先級(jí)為15,因此初始時(shí)間片為15。仔細(xì)研究ldt_temp[]發(fā)現(xiàn)ldt中的cs段描述符屬性為:地址空間為0-4G,DPL=3,說(shuō)明是用戶級(jí)別進(jìn)程代碼段;ds段描述符屬性為:地址空間為0-4G,DPL=3,說(shuō)明是用戶級(jí)別數(shù)據(jù)段。再看tss中各字段的填入過(guò)程,重要的幾個(gè)字段分別是:esp0、ss0、cr3、eip、eflags、esp、ebp、以及es、cs、ss、ds、fs、gs以及l(fā)dt,對(duì)于init進(jìn)程,由于我們會(huì)在后面手工啟動(dòng),所以有些字段可以不填,但是對(duì)于其他進(jìn)程的初始化,這些字段都是必須填寫(xiě)合適并完整的。

            最后看手工啟動(dòng)進(jìn)程init的函數(shù),該函數(shù)非常重要,啟動(dòng)init之后我們的操作系統(tǒng)便有了質(zhì)的飛躍。

             1 void start_proc0()
             2 {
             3     //初始化init進(jìn)程
             4     init_proc01();
             5 
             6     uint32 ss        = 0x17;
             7     uint32 esp        = USTACKTOP(0);
             8     uint32 eflags    = 0x1202//init進(jìn)程可以使用I/O命令,同時(shí)要求init進(jìn)程允許中斷
             9     uint32 cs        = 0x0f;
            10     uint32 eip        = (uint32)init;
            11 
            12     /**********************************************************
            13      * 下面調(diào)試了很久!!!!!!!!!!!!!!!!!
            14      * 不能將enable_hwint(CLOCK_IV);語(yǔ)句放到緊挨sti()的前面
            15      * 因?yàn)閑nable_hwint(CLOCK_IV)是c語(yǔ)句宏,展開(kāi)之后會(huì)
            16      * 用到堆棧,就會(huì)把剛push進(jìn)去的ss、esp、eflags、cs、eip
            17      * 給覆蓋掉!!!!!!!!!!!!!!!!!!!!!!
            18      * 將enable_hwint()放到init_clock()里面
            19      **********************************************************/
            20 
            21     //加載init進(jìn)程對(duì)應(yīng)的tss
            22     //加載init進(jìn)程對(duì)應(yīng)的ldt
            23     ltr(TSS_SELECTOR(0));
            24     lldt(LDT_SELECTOR(0));
            25     push(ss);                //push ss
            26     push(esp);                //push esp
            27     push(eflags);            //push eflags
            28     push(cs);                //push cs
            29     push(eip);                //push eip
            30     init_segr();            //初始化ds、es、gs、fs四個(gè)段寄存器, 使其指向ldt中的數(shù)據(jù)段描述符
            31     sti();                    //打開(kāi)中斷,從現(xiàn)在開(kāi)始內(nèi)核態(tài)將允許中斷
            32     iretd();                //iretd這條指令之后第一個(gè)進(jìn)程init進(jìn)程便開(kāi)始運(yùn)行了
            33 }
            34 

            手工啟動(dòng)進(jìn)程的過(guò)程我們采用minix的做法,在內(nèi)核棧中我們偽造一個(gè)現(xiàn)場(chǎng),使得其看似是正在運(yùn)行進(jìn)程init然后發(fā)生時(shí)鐘中斷后的現(xiàn)場(chǎng),這樣的現(xiàn)場(chǎng)應(yīng)該是這樣的:
            進(jìn)程init的ss、esp、eflags、cs、eip應(yīng)該已經(jīng)被壓入棧中,寄存器tr應(yīng)該存有進(jìn)程init在GDT中的tss選擇子,寄存器ldtr應(yīng)該存有進(jìn)程init在GDT中的ldt選擇子,各個(gè)段寄存器應(yīng)該是指向ldt中的選擇子。如果這些都準(zhǔn)備好了那就和時(shí)鐘中斷處理程序返回前沒(méi)什么兩樣了,這樣就可以打開(kāi)中斷,然后使用一條iret指令就可以了。iret指令會(huì)依次從堆棧中彈出eip、cs、eflags、esp、ss,然后切換到進(jìn)程init的用戶態(tài)繼續(xù)執(zhí)行代碼,這樣我們的第一個(gè)init進(jìn)程就啟動(dòng)起來(lái)了!!!
            posted on 2012-02-14 19:34 myjfm 閱讀(348) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 操作系統(tǒng)
            99精品国产综合久久久久五月天| 久久人人添人人爽添人人片牛牛| 国产精品久久久久久久久| 浪潮AV色综合久久天堂| 欧美亚洲另类久久综合| 久久国产香蕉视频| 久久66热人妻偷产精品9| 久久九九亚洲精品| 久久午夜无码鲁丝片秋霞| 国产精品久久国产精麻豆99网站| 久久久久国产| 久久久久久久人妻无码中文字幕爆| 国产成年无码久久久久毛片| 久久久久国产一区二区三区| 亚洲国产精品无码久久久蜜芽| 91超碰碰碰碰久久久久久综合| 久久婷婷五月综合成人D啪| 色综合久久综精品| 久久av无码专区亚洲av桃花岛| 久久国产成人午夜AV影院| 99久久99久久久精品齐齐| 精品久久久久国产免费 | 久久婷婷国产综合精品| 少妇被又大又粗又爽毛片久久黑人 | 伊人久久大香线蕉综合热线| 99久久精品免费观看国产| 狠狠色婷婷综合天天久久丁香| 久久乐国产综合亚洲精品| 久久国产精品-国产精品| 18岁日韩内射颜射午夜久久成人| 亚洲国产成人乱码精品女人久久久不卡 | 久久w5ww成w人免费| 欧美一区二区三区久久综合| 偷偷做久久久久网站| 久久人妻少妇嫩草AV无码蜜桃| 久久91精品国产91久久小草| 99久久99久久| 69久久夜色精品国产69| 久久综合久久久| 国产成人综合久久久久久| 久久国产成人午夜AV影院|