<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 七、 來源:[JOS學習筆記(七)](http://blog.csdn.net/roger__wong/article/details/8716419) 接前一篇。 上篇日志主要是完成了一些分頁相關機制的工作,但還沒有真正的去使用這個分頁系統。Lab2的part3部分主要就是讓我們使用part2中完成的映射機制來初始化內核的頁目錄和頁表,并將此頁目錄加載到cr3里,讓os真正去使用我們初始化之后的頁目錄以取代kernpgdir.c里面簡單的頁目錄。 在開始之前讓我們看一下JOS的虛擬內存分布圖,在part3里的所有工作就是照著此圖實現其中的部分映射。 ![](https://box.kancloud.cn/2015-12-24_567b6e7643c56.jpg) 首先從高位地址說起,kernbase到最高為4g是一塊remapped內存,這塊很大的內存從低到高要映射整塊物理內存。 其次kernbase往下PTSIZE(貌似是4M)是無用內存,再往下是KERNSTACKTOP也就是內核棧的棧頂,眾所周知棧的生長順序是從高地址向低地址生長,所以這個位置也就是棧開始生長的位置。從KERNSTACKTOP往下KSTKSIZE為內核棧區域,大概是8個頁面,內核棧不能超過這個區域。從KERNSTACKTOP往下一個PTSIZE這塊區域除了內核棧之外還有一塊空白區域,防止棧溢出的時候復寫用戶空間的數據。 接著是ULIM,代表用戶空間的最高地址,換句話說此位置往下所有空間為用戶空間,用戶空間有很多東西,之后的LAB會詳細說明,在此只說UPAGES。 UPAGES是JOS用戶記錄物理頁面使用情況的數據結構,為了使用戶空間能訪問這塊數據結構,會將PAGES映射到UPAGES位置。 好總結一下,是要總共要求映射3塊區域,,1是映射UPAGES結構,,2是映射內核棧,3映射整塊物理內存。 ## 1、UPAGES的映射 所謂映射就是將某個虛擬內存地址(符號地址)映射到實際的物理地址,UPAGES映射到pages也就是通過UPAGES訪問到的地址恰恰是pages這個符號指向的物理地址的內容。而映射的實質就是往頁表和頁目錄里寫入相應的值,使UPAGES這個符號經過地址變換之后指向的地址恰好是pages的物理地址。 實現的方式很簡單,先獲取pages數組的大小,并向上對齊到PGSIZE得到要映射的頁面,然后一個頁面一個頁面分別映射即可。 容易出錯的地方:(1)不能使用sizeof獲取pages數組的大小,因為此數組是動態分配的,使用sizeof只會獲取到pages這個指針本身的大小(4B)。(2)一個頁面地址映射一次即可,映射的最小單位是頁面,一個頁面內的地址不需要反復映射。 ![](https://box.kancloud.cn/2015-12-24_567b6e784b88c.jpg) ## 2、內核棧的映射。 目前內核棧的符號地址是bootstack表示棧底(棧的低地址,不是邏輯上的棧底反而是邏輯上的棧頂,因為向下生長),需要將KSTACKTOP-KSTKSIZE映射到這個位置,并向上按順序映射KSTKSIZE大小的內存區域。 其余部分不用管,雖然函數說明中寫了很多。 ![](https://box.kancloud.cn/2015-12-24_567b6e78639d1.jpg) ## 3、映射整塊內存區域。 要映射KERNBASE到0xffffffff總共256M內存的空間到從0開始的物理地址。雖然我們沒有足夠的物理空間,但we just set up the mapping anyway。什么叫just set up the mapping anyway啊,沒有就是沒有,不夠就是不夠,你讓我映射到哪里去?!抱怨歸抱怨,但我都給映射到了物理的0地址上去了,也算是沒有辦法的辦法。 但這么映射整塊物理內存會出問題。在page_insert操作中會將該Page結構的pp_ref++,但映射整塊物理內存的過程實際是便利了整個pages數組,這就會導致所有的Page結構的pp_ref++。但別忘了還有個page_free_list串起來了空閑的Page,這些空閑的Page理所應當的pp_ref也被增加了,最后的結果是page_free_list里面頁面的pp_ref不為0。在空閑鏈表中的頁面的引用次數不為0,這很明顯是不符合邏輯的,因此要進行--操作。 當然還有一種解釋是:不這么做通不過check,至于愿意相信哪種隨你好了。 通過這個問題我覺得這算是JOS設計不合理的一個地方,映射和頁面被引用是否是一個概念?誰負責維護pp_ref的信息,是這個頁面的申請者還是page_insert函數還是page_insert的調用者?感覺這些地方還有待商榷。但之前1和2的映射不用考慮這個問題是因為牽扯到的頁面不在free_page_list里,這在free_page_list初始化的時候就把里面的頁面剔除了。 ![](https://box.kancloud.cn/2015-12-24_567b6e787dc47.jpg) 最后,可以看到通過check。 ![](https://box.kancloud.cn/2015-12-24_567b6e78942d0.jpg) lab2到此結束,lab2和lab1的代碼我上傳到自己的資源里歡迎下載。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看