• <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  評論-24  文章-0  trackbacks-0
            初始化進程控制塊數組的操作是在init_proc_list()內完成的,它只被cbegin()函數調用,其實它的工作很簡單,就是將進程控制塊中的各個項初始化成初始值。并且將相應進程的LDT在GDT中的描述符初始化。這樣當啟動一個進程的時候,只需要在進程自己的LDT和TSS中填入適當的值即可,不需要理會LDT和TSS在GDT中的描述符內容。

              1 //初始化init和sys進程
              2 //主要包括進程pid、進程名、ldt、tss以及init進程在gdt中對應的項的初始化
              3 static void init_proc01()
              4 {
              5     struct seg_struct ldt_temp[3= {{0x00000x00000x000x000x000x00}, 
              6                                      {0xffff0x00000x000xfa0xcf0x00}, 
              7                                      {0xffff0x00000x000xf20xcf0x00}};
              8 
              9     //pid為0
             10     //進程名為"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共包括三項,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); //內核態堆棧頂
             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; //頁目錄表地址
             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     //進程名為"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共包括三項,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); //內核態堆棧頂
             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; //頁目錄表地址
             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     //啟動的第一個進程是進程鏈表proc_list中第一個進程,為init進程
            115     current    = proc_list;
            116 }
            117 

            注意到在process.c文件中有一個current變量,它是proc_struct類型指針,是全局變量,這從linux借鑒過來,用于指向當前正在運行的進程。
            下面著重看init_proc01()函數。
            它的作用是在proc_list[0]和proc_list[1]中填入適當的值,以為啟動進程init(0號進程)和sys(1號進程)做準備。
            我們只研究init進程控制塊的填入過程:
            進程id為0,父進程id為-1(因為它是所有進程的父進程,它沒有父進程),優先級為15,因此初始時間片為15。仔細研究ldt_temp[]發現ldt中的cs段描述符屬性為:地址空間為0-4G,DPL=3,說明是用戶級別進程代碼段;ds段描述符屬性為:地址空間為0-4G,DPL=3,說明是用戶級別數據段。再看tss中各字段的填入過程,重要的幾個字段分別是:esp0、ss0、cr3、eip、eflags、esp、ebp、以及es、cs、ss、ds、fs、gs以及ldt,對于init進程,由于我們會在后面手工啟動,所以有些字段可以不填,但是對于其他進程的初始化,這些字段都是必須填寫合適并完整的。

            最后看手工啟動進程init的函數,該函數非常重要,啟動init之后我們的操作系統便有了質的飛躍。

             1 void start_proc0()
             2 {
             3     //初始化init進程
             4     init_proc01();
             5 
             6     uint32 ss        = 0x17;
             7     uint32 esp        = USTACKTOP(0);
             8     uint32 eflags    = 0x1202//init進程可以使用I/O命令,同時要求init進程允許中斷
             9     uint32 cs        = 0x0f;
            10     uint32 eip        = (uint32)init;
            11 
            12     /**********************************************************
            13      * 下面調試了很久!!!!!!!!!!!!!!!!!
            14      * 不能將enable_hwint(CLOCK_IV);語句放到緊挨sti()的前面
            15      * 因為enable_hwint(CLOCK_IV)是c語句宏,展開之后會
            16      * 用到堆棧,就會把剛push進去的ss、esp、eflags、cs、eip
            17      * 給覆蓋掉!!!!!!!!!!!!!!!!!!!!!!
            18      * 將enable_hwint()放到init_clock()里面
            19      **********************************************************/
            20 
            21     //加載init進程對應的tss
            22     //加載init進程對應的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四個段寄存器, 使其指向ldt中的數據段描述符
            31     sti();                    //打開中斷,從現在開始內核態將允許中斷
            32     iretd();                //iretd這條指令之后第一個進程init進程便開始運行了
            33 }
            34 

            手工啟動進程的過程我們采用minix的做法,在內核棧中我們偽造一個現場,使得其看似是正在運行進程init然后發生時鐘中斷后的現場,這樣的現場應該是這樣的:
            進程init的ss、esp、eflags、cs、eip應該已經被壓入棧中,寄存器tr應該存有進程init在GDT中的tss選擇子,寄存器ldtr應該存有進程init在GDT中的ldt選擇子,各個段寄存器應該是指向ldt中的選擇子。如果這些都準備好了那就和時鐘中斷處理程序返回前沒什么兩樣了,這樣就可以打開中斷,然后使用一條iret指令就可以了。iret指令會依次從堆棧中彈出eip、cs、eflags、esp、ss,然后切換到進程init的用戶態繼續執行代碼,這樣我們的第一個init進程就啟動起來了!!!
            posted on 2012-02-14 19:34 myjfm 閱讀(338) 評論(0)  編輯 收藏 引用 所屬分類: 操作系統
            久久久久人妻精品一区三寸蜜桃| 91视频国产91久久久| 久久无码AV中文出轨人妻| 热久久国产欧美一区二区精品| 午夜精品久久影院蜜桃| 精品多毛少妇人妻AV免费久久| 无码国内精品久久人妻蜜桃| 99久久国产主播综合精品| 99久久香蕉国产线看观香| 成人久久精品一区二区三区| 亚洲国产成人精品女人久久久| 久久精品国产亚洲AV麻豆网站| 久久天天躁狠狠躁夜夜2020老熟妇| 久久久久亚洲AV无码网站| 精品欧美一区二区三区久久久| 亚洲AV无一区二区三区久久| 久久久久国产精品嫩草影院| 国产午夜免费高清久久影院| 亚洲国产成人精品91久久久| 久久福利青草精品资源站| 久久国产劲爆AV内射—百度| 国产精品成人久久久久三级午夜电影| 777午夜精品久久av蜜臀| 国产一区二区三精品久久久无广告 | 精品久久久久久久国产潘金莲| 97久久久久人妻精品专区| 香蕉99久久国产综合精品宅男自 | 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 久久精品国产网红主播| 国内精品伊人久久久久妇| 久久午夜综合久久| 久久九九久精品国产免费直播| 99国产欧美久久久精品蜜芽| 久久久久亚洲AV片无码下载蜜桃| 久久精品国产亚洲5555| 精品久久久久久久中文字幕| 51久久夜色精品国产| 国产精品99久久久久久董美香| 亚洲国产精品久久久久| 国产高潮国产高潮久久久91| 久久久久无码中|