日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

操作系统实验二:物理内存管理系统

發布時間:2023/12/14 windows 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统实验二:物理内存管理系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

操作系統實驗二:物理內存管理系統

  • 一、 實驗目的
  • 二、 實驗內容
  • 三、 實驗準備
    • 【實驗概述】
    • 【關鍵數據結構】
    • 【執行流程】
  • 四、 實驗步驟
    • (一) 練習0:填寫已有實驗
    • (二) 練習1:實現 first-fit 連續物理內存分配算法
    • (三) 練習2:實現尋找虛擬地址對應的頁表項
    • (四) 練習3:釋放某虛地址所在的頁并取消對應二級頁表項的映射
    • (五) 擴展練習1:在ucore中實現buddy system(未能完全完成)
    • (六) 測試
  • 五、 總結
  • 六、 附錄

一、 實驗目的

  • 理解基于段頁式內存地址的轉換機制
  • 理解頁表的建立和使用方法
  • 理解物理內存的管理方法
  • 二、 實驗內容

  • 了解如何發現系統中的物理內存;
  • 了解如何建立對物理內 存的初步管理,即了解連續物理內存管理;
  • 了解頁表相關的操作,即如何建立頁表來實現虛擬內存到物理內存之間的映射,對段頁 式內存管理機制有一個比較全面的了解;
  • 三、 實驗準備

    在開始練習之前首先需要進行實驗的大致流程以及關鍵數據結構進行學習與理解;

    【實驗概述】

    本次實驗主要完成ucore內核對物理內存的管理工作。
    參考ucore總控函數kern_init的代碼,可以清楚地看到在調用完成物理內存初始化的pmm_init函數之前和之后,是已有lab1實驗的工作。
    其實lab2有些修改,ucore主要有三個方面的擴展。

    • boot/bootasm.S:增加了對計算機系統中物理內存布局的探測功能;
    • kern/init/entry.S:根據臨時段表重新暫時建立好新的段空間,為進行分頁做好準備。
    • kern/mm/default_pmm.[ch]:提供基本的基于鏈表方法的物理內存管理(分配單位為頁,即4096字節);

    首先,bootloader的工作有增加,在bootloader中,完成了對物理內存資源的探測工作,讓ucore kernel在后續執行中能夠基于bootloader探測出的物理內存情況進行物理內存管理初始化工作。
    其次,bootloader不像lab1那樣,直接調用kern_init函數,而是先調用位于lab2/kern/init/entry.S中的kern_entry函數。kern_entry函數的主要任務是為執行kern_init建立一個良好的運行環境。完成這些工作后,才調用kern_init函數。
    kern_init函數在完成一些輸出并對lab1實驗結果的檢查后,將進入物理內存管理初始化的工作,即調用pmm_init函數完成物理內存的管理,是lab2的內容。

    【關鍵數據結構】

    首先看一下Page的結構:

    struct Page { int ref; // page frame's reference counter uint32_t flags; // array of flags that describe the status of the page frame unsigned int property; // the num of free block, used in first fit pm manager list_entry_t page_link; // free list link }; typedef struct list_entry list_entry_t; struct list_entry {struct list_entry *prev, *next; };

    這里使用的雙向鏈表借鑒了linux內核的雙向鏈表結構,鏈表結構不包含傳統數據域data,而是在具體的數據結構中包含鏈表節點。在本實驗中,使用如下結構對頁進行總體的管理。在Default.c中含鏈表free_area_t的結構:

    free_area_t free_area; //global page manager #define free_list (free_area.free_list) #define nr_free (free_area.nr_free) /* free_area_t - maintains a doubly linked list to record free (unused) pages */ typedef struct {list_entry_t free_list; // the list headerunsigned int nr_free; // # of free pages in this free list } free_area_t;

    free_list是整個雙向鏈表的頭節點,同時nr_free表示空閑頁的數量。
    下圖是整個空閑頁雙向鏈表的簡易示意圖(將鏈表和數據域隔離)

    【執行流程】

    內存管理相關的總體控制函數是pmm_init函數,它完成的主要工作包括:
    ①初始化物理內存頁管理器框架pmm_manager;
    ②建立空閑的page鏈表,這樣就可以分配以頁(4KB)為單位的空閑內存了;
    ③檢查物理內存頁分配算法;
    ④為確保切換到分頁機制后,代碼能夠正常執行,先建立一個臨時二級頁表;
    ⑤建立一一映射關系的二級頁表;
    ⑥使能分頁機制;
    ⑦從新設置全局段描述符表;
    ⑧取消臨時二級頁表;
    ⑨檢查頁表建立是否正確;
    ⑩通過自映射機制完成頁表的打印輸出(這部分是擴展知識)

    四、 實驗步驟

    (一) 練習0:填寫已有實驗

    將LAB1中完成的代碼(不包含拓展練習)移植到了lab2的框架中,涉及到的文件為kern/debug/kdebug.c和kern/trap/trap.c,具體內容已在LAB1報告中進行說明,此處不再贅述;

    (二) 練習1:實現 first-fit 連續物理內存分配算法

    在實現first fit 內存分配算法的回收函數時,要考慮地址連續的空閑塊之間的合并操作。提示:在建立空閑頁塊鏈表時,需要按照空閑頁塊起始地址來排序,形成一個有序的鏈表。

    在ucore中采用面向對象編程的思想,將物理內存管理的內容抽象成若干個特定的函數,并且使用結構體pmm_manager來將這些函數的指針封裝起來,使得具體使用到物理內存管理所提供的服務的時候,只需要調用已經初始化完成的pmm_manager的實例中的函數指針即可,這樣就實現了將物理內存管理的具體實現與ucore其他部分隔離開來的效果。
    其中,上述若干個封裝在pmm_manager中的提供物理內存管理服務的函數分別如下:

    init:對物理內存管理器的初始化; init_memmap:對管理的空閑頁的數據進行初始化;
    alloc_pages:申請分配指定數量的物理頁; free_pages: 申請釋放若干指定物理頁;
    nr_free_pages:查詢當前的空閑頁總數; check: 對物理內存管理器進行測試;

    查看default_pmm.c文件可以發現,最終ucore中所使用的物理內存管理器中的函數指針分別指向了default_init, default_init_memmap等若干函數,在lab中,通過對這些函數的實現進行修改來實現first-fit 連續內存分配算法;

  • default_init函數
    查看default_init中的內容,發現僅有對空閑內存塊鏈表的初始化以及將總空閑數目置零的操作,這是與具體物理內存分配算法無關的,因此直接使用默認的函數實現即可;
  • list_init(&free_list); nr_free = 0;
  • default_init_memmp函數
    然后分析default_init_memmap函數,該函數的具體作用為對最初的一整塊未被占用的物理內存空間中的每一頁所對應的Page結構(用于描述這些頁的狀態)進行初始化,考慮到相鄰的物理頁對應的Page結構在內存上也是同樣相鄰的,因此可以直接通過第一個空閑物理頁對應的Page結構加上一個偏移量的方式來訪問所有的空閑的物理頁的Page結構,具體初始化方式為:
    遍歷所有空閑物理頁的Page結構,將Page結構的描述空閑塊的數目的成員變量置零(因此該成員變量只有在整個空閑塊的第一個Page中才有意義),然后清空這些物理頁的引用計數,然后通過設置flags的位的方式將其標記為空閑,實現代碼如下:
  • struct Page *p = base; for (; p != base + n; p ++) {assert(PageReserved(p));p->flags = p->property = 0;set_page_ref(p, 0);SetPageProperty(p); }

    接下來對空閑塊的第一個頁的Page結構進行初始化,具體實現為將其表示空閑塊大小的成員變量設置為作為參數傳入的空閑塊大小(單位為頁),然后更新存儲所有空閑頁數量,然后將這個空閑塊插入到空閑內存塊鏈表中(只需要將第一個Page的page_link插入即可);具體的代碼實現如下所示:

    base->property = n; nr_free += n; list_add(&free_list, &(base->page_link));}
  • default_alloc_pages函數
    接下來考慮實現分配空閑頁函數default_alloc_pages:該函數的具體功能為分配指定頁數的連續空閑物理空間,并且將第一頁的Page結構的指針作為結果返回;
    3.1. 首先對參數進行合法性檢查,并且查詢總的空閑物理頁數目是否足夠進行分配,
    如果不足夠進行分配,直接返回NULL,表示分配失敗;
    3.2. 接著從頭開始遍歷保存空閑物理內存塊的鏈表(按照物理地址的從小到大順序),如果找 到某一個連續內存塊的大小不小于當前需要的連續內存塊大小,則說明可以進行成功分 配(第一個滿足條件的空閑內存塊),代碼實現如下:
  • struct Page *page = NULL; list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) {struct Page *p = le2page(le, page_link);if (p->property >= n) {page = p;break;}}

    3.3. 接下來考慮對獲得的滿足條件的空閑內存塊進行處理,如果該內存塊的大小大于需要的 內存大小,則將空閑內存塊分裂成兩塊,物理地址較小的一塊分配出來進行使用(大小 恰好為需要的物理內存的大小),而物理地址較大的那一塊進行以下操作
    ①對第一個Page的page_link中property設置為原先的空閑塊大小減掉分配的大小
    ②將這個分裂出來的空閑塊插入到空閑塊鏈表中
    于此同時,對分配出去的物理內存的每一個的描述信息(即對應的Page結構)修改flags成員變量來將這些Page標記為非空閑,最后將原始空閑塊在空閑塊鏈表中刪除掉,并且更新表示總空閑頁數量的全局變量;最后用于表示分配到的物理內存的Page結構指針返回;

    if (page != NULL) { // 如果尋找到了滿足條件的空閑內存塊for (struct Page *p = page; p != (page + n); ++p) {ClearPageProperty(p); // 將分配出去的內存頁標記為非空閑}if (page->property > n) { // 如果原先找到的空閑塊大小大于需要的分配內存大小,進行分裂struct Page *p = page + n; // 獲得分裂出來的新的小空閑塊的第一個頁的描述信息p->property = page->property - n; // 更新新的空閑塊的大小信息list_add(&(page->page_link), &(p->page_link)); // 將新空閑塊插入空閑塊列表中}list_del(&(page->page_link)); // 刪除空閑鏈表中的原先的空閑塊nr_free -= n; // 更新總空閑物理頁的數量}
  • default_free_pages函數
    接下來考慮釋放占用的內存塊的函數default_free_pages,該函數的具體功能為釋放指定的某一物理頁開始的若干個連續物理頁,并且完成first-fit算法中需要的若干信息的維護,具體的實現如下所示:
    4.1. 首先考慮遍歷需要釋放的物理頁的描述信息(即對應的Page結構),對其進行更新;
    ①判斷原先這些物理頁是否真的被占用了,如果釋放未被占用的物理頁,這說明出現了異常情況;
    ②設置flags來將這些物理頁標記為空閑;
    ③清空這些物理頁的引用計數;
  • struct Page *p = base; for (; p != (base + n); p ++) {assert(!PageReserved(p) && !PageProperty(p)); // 進行檢查SetPageProperty(p); // 標記為空閑set_page_ref(p, 0); // 清空引用計數

    接下來將這一新的空閑塊插入到空閑塊鏈表中:

    base->property = n; // 設置空閑塊大小 list_entry_t *le = list_next(&free_list); for (; le != (&free_list) && le < (&(base->page_link)); le = list_next(le)); // 尋找新的空閑塊在空閑塊鏈表中應當處于的位置 list_add_before(le, &(base->page_link)); // 將空閑塊插入到鏈表中 nr_free += n; // 更新空閑物理頁總量

    最后需要對空閑塊跟其相鄰的空閑塊(如果存在的話)進行合并,分別是檢查能與前一項合并與后一項合并的操作,我的合并方式是循環遍歷鏈表,進行空閑塊相鄰的判斷,相鄰則合并;

    while (le != &free_list) { // 迭代空閑鏈表中的每一個節點// 獲得節點對應的Page結構p = le2page(le, page_link);le = list_next(le);if (base + base->property == p) {// 如果尾部正好能和下一個連上則合并base->property += p->property;ClearPageProperty(p);list_del(&(p->page_link));}else if (p + p->property == base) { // 如果頭部與上一個連上則合并p->property += base->property;ClearPageProperty(base);base = p;list_del(&(p->page_link));} }
  • 回答問題:你的first fit算法是否有進一步的改進空間?
    在本實驗中所實現的first fit算法仍然有著相當的改進空間;
    改進方向就在于時間復雜度上,每次查詢第一塊符合條件的空閑內存塊時,最壞情況需要找遍整個鏈表,這樣的話時間復雜度是O(N),N表示當前的鏈表大小,考慮針對時間效率的優化方式如下:
    如果采用平衡二叉樹結構來取代簡單的鏈表結構來維護空閑塊,其中按照中序遍歷得到的空閑塊序列的物理地址恰好按照從小到大排序;每個二叉樹節點上維護該節點為根的子樹上的最大的空閑塊的大小;通過二叉樹的查詢算法可以查找到物理地址最小的能夠滿足條件的空閑地址塊,然后進行刪除以及新的分裂出來的空閑塊的插入等操作;
    平衡二叉樹每次查詢符合條件的第一塊物理空閑塊的時間復雜度為O(log N),對比原先的O(N)有很大進步,但是這里實現較為復雜;
  • (三) 練習2:實現尋找虛擬地址對應的頁表項

  • get_pte函數
    本練習的要求為補全pmm.c中的get_pte函數,該函數的主要功能為根據給定的page directory以及線性地址,查詢出該linear address對應的page table entry,并且根據輸入參數要求判斷是否創建不存在的頁表;
    實現的過程:
    ①此函數的作用是向上提供一個幾乎透明的操作,返回指定 linear address 對應的 page table entry.注意這個函數是單純的獲取其地址,得到 page dir 的 index是 PDX(la),于是對應的 pde 是 pgdir[PDX(la)];
    ②考察 pde 具體的結構,高 20 位是 page table 地址.因此pgdir[PSX(la)]& ~0xFFF即可得到 page table 的物理地址,在取值之前,首先要判斷存在位PTE_P, 如果存在,說明之前已經初始化過了 pd,只需計算la對應的頁表項即可,如果不存在,說明當前頁目錄項除了 PTE_P 外都是空的。此時需要新申請一塊物理內存,作為新的二級頁表,但如果 create=0 的話就直接返回 NULL 就行了。
  • pde_t *pdep = pgdir + PDX(la); // 獲取到頁目錄表中給定線性地址對應到的頁目錄項 pte_t *ptep = ((pte_t *) (KADDR(*pdep & ~0XFFF)) + PTX(la)); // 從找到的頁目錄項中查詢到對應到的頁表中的頁表項,即頁表基址加上線性地址的中的offset if (*pdep & PTE_P) return ptep; // 檢查查找到的頁目錄項是否存在,如果存在直接放回 找到的頁表項即可 if (!create) return NULL; // 如果該頁目錄項是不存在的,并且參數要求不創建新的頁表, 則直接返回 struct Page* pt = alloc_page(); // 如果需要按需創建新的頁表,則請求一個物理頁來存儲 新創建的頁表 if (pt == NULL) return NULL; // 如果物理空間不足,直接返回set_page_ref(pt, 1); // 更新 該物理頁的引用計數 ptep = KADDR(page2pa(pt)); // 獲取到該物理頁的虛擬地址 memset(ptep, 0, PGSIZE); // 新創建的頁表進行初始化 *pdep = (page2pa(pt) & ~0XFFF) | PTE_U | PTE_W | PTE_P; // 對原先的頁目錄項進行設 置,包括設置其對應的頁表的物理地址,以及標志位 return ptep + PTX(la); // 返回線性地址對應的頁目錄項
  • 回答以下問題:
    2.1. 請描述頁目錄項(Pag Director Entry)和頁表(Page Table Entry)中每個組成部分的含義和以及對ucore而言的潛在用處。


    2.1.1. PDE(頁目錄項)的具體組成如圖所示;描述每一個組成部分的含義如下:
    前20位表示4K對齊的該PDE對應的頁表起始位置(物理地址,該物理地址的高20位即PDE中的高20位,低12位為0);
    第9-11位未被CPU使用,可保留給OS使用;
    接下來的第8位可忽略;
    第7位用于設置Page大小,0表示4KB;
    第6位恒為0;
    第5位用于表示該頁是否被使用過;
    第4位設置為1則表示不對該頁進行緩存;
    第3位設置是否使用write through緩存寫策略;
    第2位表示該頁的訪問需要的特權級;
    第1位表示是否允許讀寫;
    第0位為該PDE的存在位;
    2.1.2. 接下來描述頁表項(PTE)中的每個組成部分的含義,具體組成如圖所示:
    高20位與PDE相似的,用于表示該PTE指向的物理頁的物理地址;
    9-11位保留給OS使用;
    7-8位恒為0;
    第6位表示該頁是否為dirty,即是否需要在swap out的時候寫回外存;
    第5位表示是否被訪問;
    3-4位恒為0;
    0-2位分別表示存在位、是否允許讀寫、訪問該頁需要的特權級;
    2.1.3. 潛在用處:
    可以發現無論是PTE還是TDE,都具有著一些保留的位供操作系統使用,也就是說ucore可以利用這些位來完成一些其他的內存管理相關的算法;比如可以在這些位里保存最近一段時間內該頁的被訪問的次數,用于輔助近似地實現虛擬內存管理中的換出策略的LRU之類的算法;也就是說這些保留位有利于OS進行功能的拓展;
  • 2.2. 如果ucore執行過程中訪問內存,出現了頁訪問異常,請問硬件要做哪些事情?

    當ucore執行過程中出現了頁訪問異常,硬件需要完成的事情分別如下:
    - 將發生錯誤的線性地址保存在cr2寄存器中;
    - 在中斷棧中依次壓入EFLAGS,CS, EIP,以及頁訪問異常碼error code,如果page fault是發生在用戶態,則還需要先壓入ss和esp,并且切換到內核棧;
    - 根據中斷描述符表查詢到對應page fault的ISR,跳轉到對應的ISR處執行,接下 來將由軟件進行page fault處理;

    對于大多數操作系統來說,處理頁故障的方法入下:

    (四) 練習3:釋放某虛地址所在的頁并取消對應二級頁表項的映射

    當釋放一個包含某虛地址的物理內存頁時,需要讓對應此物理內存頁的管理數據結構Page做相關的清除處理,使得此物理內存頁成為空閑;另外還需把表示虛地址與物理地址對應關系的二級頁表項清除。

  • page_remove_pte函數
    接下來具體代碼實現來說明釋放某虛地址所在的頁并且取消PTE表項的映射的具體實現;
    ①檢查頁表項pte的PTE_P的值,若為0,則說明物理頁不存在,此時直接返回
    ②首先將頁表項的低12位清零得到物理頁的起始地址,并據此得到對應的Page結構,將Page的ref字段減1,表明取消當前邏輯地址到此物理地址的映射。
    ③然后,判斷Page的ref的值是否為0,若為0,則說明此時沒有任何邏輯地址被映射到此物理地址,當前物理頁已沒有程序使用,因此調用free_page函數回收此物理頁;若不為0,則說明此時仍有至少一個邏輯地址被映射到此物理地址,因此不需回收此物理頁。
    ④將對應的頁表項pte清零,表明此邏輯地址無對應的物理地址。
    ⑤調用tlb_invalidate函數去使能TLB中當前邏輯地址對應的條目。
  • assert(*ptep & PTE_P); // 確保傳入的二級頁表項是存在的 struct Page *page = pte2page(*ptep); // 獲取該頁表項對應的物理頁對應的Page結構 page->ref --; // 減少該物理頁的引用計數 if (!page->ref) free_page(page); // 如果該物理頁的引用計數變成0,即不存在任何虛擬頁指 向該物理頁,釋放該物理頁 *ptep &= (~PTE_P); // 將PTE的存在位設置為0,表示該映射關系無效 tlb_invalidate(pgdir, la); // 刷新TLB,保證TLB中的緩存不會有錯誤的映射關系
  • 回答如下問題:
    2.1. 數據結構Page的全局變量(其實是一個數組)的每一項與頁表中的頁目錄項和頁表項有無對應關系?如果有,其對應關系是啥?
    存在對應關系;
    由于頁表項中存放著對應的物理頁的物理地址,因此可以通過這個物理地址來獲取到對應到的Page數組的對應項,具體做法為將物理地址除以一個頁的大小,然后乘上一個Page結構的大小獲得偏移量,使用偏移量加上Page數組的基地址皆可以或得到對應Page項的地址;

    可通過該函數從頁表項中得到物理page結構;

    2.2. 如果希望虛擬地址與物理地址相等,則需要如何修改lab2,完成此事? 鼓勵通過編程來具體完成這個問題。
    由于在完全啟動了ucore之后,虛擬地址和線性地址相等,都等于物理地址加上0xc0000000,如果需要虛擬地址和物理地址相等,可以考慮更新gdt,更新段映射,使得virtual address = linear address - 0xc0000000,這樣的話就可以實現virtual address = physical address;
    通過ld工具生成的ucore的其實虛擬地址為0xC01000000開始,而bootloader把ucore放在了起始地址為0x001000000的物理內存空間,那么首先將KERNBASE從0xC000000改為0x00000000,原因在于沒有開啟頁地址轉換前,內核邏輯地址經過一次段地址轉換直接得到物理地址。

  • #define KERNBASE 0xC0000000
    phy addr + KERNBASE = virtual addr
    所以,KERNBASE = 0時,phy addr = virtual addr。

    (五) 擴展練習1:在ucore中實現buddy system(未能完全完成)

    Buddy System算法把系統中的可用存儲空間劃分為存儲塊(Block)來進行管理, 每個存儲塊的大小必須是2的n次冪(Pow(2, n)), 即1, 2, 4, 8, 16, 32, 64, 128…
    參考伙伴分配器的一個極簡實現, 在ucore中實現buddy system分配算法;具體的代碼見附錄!
    5.1. 整體思想
    分配器的整體思想是,通過一個數組形式的完全二叉樹來監控管理內存,二叉樹的節點用于標記相應內存塊的使用狀態,高層節點對應大的塊,低層節點對應小的塊,在分配和釋放中我們就通過這些節點的標記屬性來進行塊的分離合并。如圖所示,假設總大小為16單位的內存,我們就建立一個深度為5的滿二叉樹,根節點從數組下標[0]開始,監控大小16的塊;它的左右孩子節點下標[12],監控大小8的塊;第三層節點下標[36]監控大小4的塊……依此類推。

    5.2. 數據結構

    這里的成員size表明管理內存的總單元數目(測試用例中是32),成員longest就是二叉樹的節點標記,表明所對應的內存塊的空閑單位。

    5.3. 分配內存alloc
    ①尋找大小合適的內存塊(大于等于并且最接近2的冪,比如需要27,實際分配32)
    ②如果找到了,分配給應用程序。
    ③如果沒找到,分出合適的內存塊。

    Ⅰ對半分離出高于所需大小的空閑內存塊
    Ⅱ如果分到最低限度,分配這個大小。
    Ⅲ回溯到步驟①(尋找合適大小的塊)
    Ⅳ重復該步驟直到一個合適的塊

    整個分配器的大小就是滿二叉樹節點數目,即所需管理內存單元數目的2倍。一個節點對應4個字節,longest記錄了節點所對應的的內存塊大小。
    內存分配的alloc中,入參是分配器指針和需要分配的大小,返回值是內存塊索引。alloc函數首先將size調整到2的冪大小,并檢查是否超過最大限度。然后進行適配搜索,深度優先遍歷,當找到對應節點后,將其longest標記為0,即分離適配的塊出來,并轉換為內存塊索引offset返回,依據二叉樹排列序號,比如內存總體大小32,我們找到節點下標[8],內存塊對應大小是4,則offset = (8+1)*4-32 = 4,那么分配內存塊就從索引4開始往后4個單位。
    在函數返回之前需要回溯,因為小塊內存被占用,大塊就不能分配了,比如下標[8]標記為0分離出來,那么其父節點下標[0]、[1]、[3]也需要相應大小的分離。將它們的longest進行折扣計算,取左右子樹較大值,下標[3]取4,下標[1]取8,下標[0]取16,表明其對應的最大空閑值。

    5.4. 釋放內存free

    上圖中,首先我們假設我們一個內存塊有1024K,當我們需要給A分配70K內存的時候,
    ①我們發現1024K的一半大于70K,然后我們就把1024K的內存分成兩半,一半512K。
    ②然后我們發現512K的一半仍然大于70K,于是我們再把512K的內存再分成兩半,一半是128K。
    ③此時,我們發現128K的一半小于70K,于是我們就分配為A分配128K的內存。
    ④后面的,B,C,D都這樣,而釋放內存時,則會把相鄰的塊一步一步地合并起來(合并也必需按分裂的逆操作進行合并)。
    我們可以看見,這樣的算法,用二叉樹這個數據結構來實現再合適不過了。
    在內存釋放的free接口,我們只要傳入之前分配的內存地址索引,并確保它是有效值。之后就跟alloc做反向回溯,從最后的節點開始一直往上找到longest為0的節點,即當初分配塊所適配的大小和位置。
    將longest恢復到原來滿狀態的值。繼續向上回溯,檢查是否存在合并的塊,依據就是左右子樹longest的值相加是否等于原空閑塊滿狀態的大小,如果能夠合并,就將父節點longest標記為相加的和。

    5.5. 在ucore中測試
    首先,我們分析ucore的執行過程;
    從練習1中可知,內存的分配函數是在default_pmm.c中實現的,default_pmm.c中各個函數的定義:

    該實現manager是在pmm.c中調用的:

    所以實現buddy system時,要完成buddy.c和buddy.h;
    buddy.h中的內容參考了default_pmm.h實現:

    并且將pmm.c中的調用改為:

    即調用buddy.h中的buddy_pmm_manager;
    而buddy_pmm_manager是在buddy,c中實現的:

    最后通過make qemu來測試結果:

    測試正確;

    (六) 測試

    最終完成所有練習之后,可以通過make grade的所有測試,最終實驗結果如下所示:
    make grade:

    make qemu:

    可以看出上述補充代碼部分正確。

    五、 總結

    本實驗是關于物理內存管理,主要從物理內存和建立頁表兩個方面設計實驗,首先了解了如何發現物理內存,如何建立物理內存的初步管理等等內容;了解頁表的相關操作總體來說有些難,因為涉及到了很多的新數據結構,我們需要很好的理解掌握各個文件中的相關函數,才能理解實驗的內涵。
    通過練習1、2、3,了解了基于段頁式內存地址的轉換機制,頁表的建立和使用方法和物理內存的管理方法。比如在練習1中直觀地看到first fit算法的實現過程,盡管在理論課上學過,而且感覺理論上比較簡單,但實際實現起來還是有點難度的。總體上來說,三個練習的工作量不小,而且也并不是很簡單就能完成的,不過好在注釋十分詳細,跟著注釋一步一步走,然后查閱一些相關的資料后還是能夠完成的。
    通過這個實驗能夠深入的理解段頁式內存管理機制,對課本中的知識點有了深入的理解體會。總的來說,lab2的收獲還是很大,而且正如實驗指導書最開始說的,lab1和lab2比較困難,但通過lab1和lab2后,對計算機原理中的中斷、段頁表機制、特權級等的理解會更深入。對后面的學習有很大的幫助。

    六、 附錄

    主要是buddy.c中的代碼:
    #include <pmm.h>
    #include <list.h>
    #include <string.h>
    #include <default_pmm.h>
    #include <buddy.h>
    //來自參考資料的一些宏定義
    #define LEFT_LEAF(index) ((index) * 2 + 1)
    #define RIGHT_LEAF(index) ((index) * 2 + 2)
    #define PARENT(index) ( ((index) + 1) / 2 - 1)

    #define IS_POWER_OF_2(x) (!((x)&((x)-1)))
    #define MAX(a, b) ((a) > (b) ? (a) : (b))
    #define UINT32_SHR_OR(a,n) ((a)|((a)>>(n)))//右移n位

    #define UINT32_MASK(a) (UINT32_SHR_OR(UINT32_SHR_OR(UINT32_SHR_OR(UINT32_SHR_OR(UINT32_SHR_OR(a,1),2),4),8),16))
    //大于a的一個最小的2^k
    #define UINT32_REMAINDER(a) ((a)&(UINT32_MASK(a)>>1))
    #define UINT32_ROUND_DOWN(a) (UINT32_REMAINDER(a)?((a)-UINT32_REMAINDER(a)):(a))//小于a的最大的2^k

    static unsigned fixsize(unsigned size) {
    size |= size >> 1;
    size |= size >> 2;
    size |= size >> 4;
    size |= size >> 8;
    size |= size >> 16;
    return size+1;
    }

    struct buddy2 {
    unsigned size;//表明管理內存
    unsigned longest;
    };
    struct buddy2 root[80000];//存放二叉樹的數組,用于內存分配

    free_area_t free_area;

    #define free_list (free_area.free_list)
    #define nr_free (free_area.nr_free)

    struct allocRecord//記錄分配塊的信息
    {
    struct Page* base;
    int offset;
    size_t nr;//塊大小
    };

    struct allocRecord rec[80000];//存放偏移量的數組
    int nr_block;//已分配的塊數

    static void buddy_init()
    {
    list_init(&free_list);
    nr_free=0;
    }

    //初始化二叉樹上的節點
    void buddy2_new( int size ) {
    unsigned node_size;
    int i;
    nr_block=0;
    if (size < 1 || !IS_POWER_OF_2(size))
    return;

    root[0].size = size;
    node_size = size * 2;

    for (i = 0; i < 2 * size - 1; ++i) {
    if (IS_POWER_OF_2(i+1))
    node_size /= 2;
    root[i].longest = node_size;
    }
    return;
    }

    //初始化內存映射關系
    static void
    buddy_init_memmap(struct Page base, size_t n)
    {
    assert(n>0);
    struct Page p=base;
    for(;p!=base + n;p++)
    {
    assert(PageReserved§);
    p->flags = 0;
    p->property = 1;
    set_page_ref(p, 0);
    SetPageProperty§;
    list_add_before(&free_list,&(p->page_link));
    }
    nr_free += n;
    int allocpages=UINT32_ROUND_DOWN(n);
    buddy2_new(allocpages);
    }
    //內存分配
    int buddy2_alloc(struct buddy2* self, int size) {
    unsigned index = 0;//節點的標號
    unsigned node_size;
    unsigned offset = 0;

    if (self==NULL)//無法分配
    return -1;

    if (size <= 0)//分配不合理
    size = 1;
    else if (!IS_POWER_OF_2(size))//不為2的冪時,取比size更大的2的n次冪
    size = fixsize(size);

    if (self[index].longest < size)//可分配內存不足
    return -1;

    for(node_size = self->size; node_size != size; node_size /= 2 ) {
    if (self[LEFT_LEAF(index)].longest >= size)
    {
    if(self[RIGHT_LEAF(index)].longest>=size)
    {
    index=self[LEFT_LEAF(index)].longest <= self[RIGHT_LEAF(index)].longest? LEFT_LEAF(index):RIGHT_LEAF(index);
    //找到兩個相符合的節點中內存較小的結點
    }
    else
    {
    index=LEFT_LEAF(index);
    }
    }
    else
    index = RIGHT_LEAF(index);
    }

    self[index].longest = 0;//標記節點為已使用
    offset = (index + 1) * node_size - self->size;
    while (index) {
    index = PARENT(index);
    self[index].longest =
    MAX(self[LEFT_LEAF(index)].longest, self[RIGHT_LEAF(index)].longest);
    }
    //向上刷新,修改先祖結點的數值
    return offset;
    }

    static struct Page*
    buddy_alloc_pages(size_t n){
    assert(n>0);
    if(n>nr_free)
    return NULL;
    struct Page* page=NULL;
    struct Page* p;
    list_entry_t *le=&free_list,*len;
    rec[nr_block].offset=buddy2_alloc(root,n);//記錄偏移量
    int i;
    for(i=0;i<rec[nr_block].offset+1;i++)
    le=list_next(le);
    page=le2page(le,page_link);
    int allocpages;
    if(!IS_POWER_OF_2(n))
    allocpages=fixsize(n);
    else
    {
    allocpages=n;
    }
    //根據需求n得到塊大小
    rec[nr_block].base=page;//記錄分配塊首頁
    rec[nr_block].nr=allocpages;//記錄分配的頁數
    nr_block++;
    for(i=0;i<allocpages;i++)
    {
    len=list_next(le);
    p=le2page(le,page_link);
    ClearPageProperty§;
    le=len;
    }//修改每一頁的狀態
    nr_free-=allocpages;//減去已被分配的頁數
    page->property=n;
    return page;
    }

    void buddy_free_pages(struct Page* base, size_t n) {
    unsigned node_size, index = 0;
    unsigned left_longest, right_longest;
    struct buddy2* self=root;

    list_entry_t le=list_next(&free_list);
    int i=0;
    for(i=0;i<nr_block;i++)//找到塊
    {
    if(rec[i].base==base)
    break;
    }
    int offset=rec[i].offset;
    int pos=i;//暫存i
    i=0;
    while(i<offset)
    {
    le=list_next(le);
    i++;
    }
    int allocpages;
    if(!IS_POWER_OF_2(n))
    allocpages=fixsize(n);
    else
    {
    allocpages=n;
    }
    assert(self && offset >= 0 && offset < self->size);//是否合法
    node_size = 1;
    index = offset + self->size - 1;
    nr_free+=allocpages;//更新空閑頁的數量
    struct Page p;
    self[index].longest = allocpages;
    for(i=0;i<allocpages;i++)//回收已分配的頁
    {
    p=le2page(le,page_link);
    p->flags=0;
    p->property=1;
    SetPageProperty§;
    le=list_next(le);
    }
    while (index) {//向上合并,修改先祖節點的記錄值
    index = PARENT(index);
    node_size *= 2;

    left_longest = self[LEFT_LEAF(index)].longest; right_longest = self[RIGHT_LEAF(index)].longest;if (left_longest + right_longest == node_size) self[index].longest = node_size; elseself[index].longest = MAX(left_longest, right_longest);

    }
    for(i=pos;i<nr_block-1;i++)//清除此次的分配記錄
    {
    rec[i]=rec[i+1];
    }
    nr_block–;//更新分配塊數的值
    }

    static size_t
    buddy_nr_free_pages(void) {
    return nr_free;
    }

    //以下是一個測試函數
    static void

    buddy_check(void) {
    struct Page *p0, *A, *B,*C,*D;
    p0 = A = B = C = D =NULL;

    assert((p0 = alloc_page()) != NULL); assert((A = alloc_page()) != NULL); assert((B = alloc_page()) != NULL);assert(p0 != A && p0 != B && A != B); assert(page_ref(p0) == 0 && page_ref(A) == 0 && page_ref(B) == 0); free_page(p0); free_page(A); free_page(B);A=alloc_pages(500); B=alloc_pages(500); cprintf("A %p\n",A); cprintf("B %p\n",B); free_pages(A,250); free_pages(B,500); free_pages(A+250,250);p0=alloc_pages(1024); cprintf("p0 %p\n",p0); assert(p0 == A); //以下是根據鏈接中的樣例測試編寫的 A=alloc_pages(70); B=alloc_pages(35); assert(A+128==B);//檢查是否相鄰 cprintf("A %p\n",A); cprintf("B %p\n",B); C=alloc_pages(80); assert(A+256==C);//檢查C有沒有和A重疊 cprintf("C %p\n",C); free_pages(A,70);//釋放A cprintf("B %p\n",B); D=alloc_pages(60); cprintf("D %p\n",D); assert(B+64==D);//檢查B,D是否相鄰 free_pages(B,35); cprintf("D %p\n",D); free_pages(D,60); cprintf("C %p\n",C); free_pages(C,80); free_pages(p0,1000);//全部釋放

    }

    const struct pmm_manager buddy_pmm_manager = {
    .name = “buddy_pmm_manager”,
    .init = buddy_init,
    .init_memmap = buddy_init_memmap,
    .alloc_pages = buddy_alloc_pages,
    .free_pages = buddy_free_pages,
    .nr_free_pages = buddy_nr_free_pages,
    .check = buddy_check,
    };

    總結

    以上是生活随笔為你收集整理的操作系统实验二:物理内存管理系统的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    精品中文字幕在线观看 | 亚洲精品一区二区在线观看 | 欧美在线日韩在线 | 人人超碰在线 | 国产人成一区二区三区影院 | 国产高清一 | 欧美天堂视频在线 | 波多野结衣综合网 | www.com.黄| av超碰在线 | 欧美日韩精品综合 | 五月天精品视频 | 国内成人精品视频 | 亚洲无人区小视频 | 91九色网站| 免费观看完整版无人区 | 国产精品成人一区二区三区 | 久久爱资源网 | 人人干人人做 | wwwwww黄 | 五月综合久久 | 欧美日性视频 | 伊人热 | 国产99久久久精品 | 亚洲高清av | 国产成人精品av久久 | 久久国产精品视频观看 | 麻豆视频国产 | 亚洲精品国产精品乱码在线观看 | 久久综合之合合综合久久 | 九色视频自拍 | 在线激情影院一区 | 欧美少妇xxxxxx | 久久精品人人做人人综合老师 | 最近中文字幕免费视频 | 欧美成人h版在线观看 | 久久五月精品 | 日韩精选在线观看 | 亚洲精品欧美视频 | 国产小视频免费观看 | 黄色毛片电影 | 日韩一级电影在线观看 | 久久久久久久久久久成人 | 狠狠操欧美 | 亚洲免费高清视频 | 91麻豆精品国产91久久久久 | 午夜精品久久久久久久久久久 | 精品久久久久久国产91 | 欧洲视频一区 | 色婷丁香 | 69国产精品视频免费观看 | 丁香综合 | 国产精品入口传媒 | 国产偷v国产偷∨精品视频 在线草 | 又色又爽又黄 | 中文字幕在线免费看 | 国语自产偷拍精品视频偷 | 日韩精品中文字幕在线观看 | 精品久久久久一区二区国产 | 国产中文字幕在线视频 | 亚洲成人精品在线观看 | 日韩欧三级 | 激情网色 | 福利av在线| 久久免费的精品国产v∧ | 91香蕉亚洲精品 | 啪啪免费试看 | 免费观看视频黄 | 国产在线专区 | 色在线最新 | 精品久久久久亚洲 | 91麻豆视频| 国产视频一区二区三区在线 | 国产97在线视频 | 区一区二在线 | 国外成人在线视频网站 | 亚洲国产剧情av | 日日夜夜精品视频 | 深爱激情av | 日韩影视精品 | 国产精品麻豆果冻传媒在线播放 | 亚洲男模gay裸体gay | 四虎免费在线观看 | 欧美日韩一区二区三区在线观看视频 | 婷婷色网 | 国产精品免费在线观看视频 | 精品国产亚洲一区二区麻豆 | 欧美99久久| 337p日本大胆噜噜噜噜 | 999成人网 | 黄色av免费电影 | 国内丰满少妇猛烈精品播 | 国产精品乱码一区二三区 | 久久久久久久久久久高潮一区二区 | 精品产品国产在线不卡 | 欧美另类高潮 | 丁香六月欧美 | 国产精品第10页 | 草久中文字幕 | 午夜视频99 | av网站在线观看免费 | 欧美精品久久久久性色 | 粉嫩一二三区 | 91精品网站在线观看 | 最新在线你懂的 | 日韩免费二区 | 免费视频91蜜桃 | 久久综合国产伦精品免费 | 在线播放视频一区 | 五月天综合激情网 | 射久久久 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 日韩精品一区二区三区在线视频 | 久久99精品国产91久久来源 | 久久无码精品一区二区三区 | 国产大片黄色 | 夜夜嗨av色一区二区不卡 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 亚洲黄色在线播放 | 九七视频在线观看 | 国产在线a免费观看 | 麻豆成人在线观看 | 狠狠狠色丁香婷婷综合激情 | 日韩女同一区二区三区在线观看 | 成人免费毛片aaaaaa片 | 天天综合网国产 | 9992tv成人免费看片 | 日韩夜夜爽 | 99爱在线观看 | 黄av免费在线观看 | 日本久久精品视频 | 中文字幕免费观看 | 日韩黄色免费在线观看 | 最新日韩视频在线观看 | 成人va在线观看 | 国产精品av久久久久久无 | 亚洲精品午夜久久久久久久久久久 | 一区二区三区福利 | 国产亚州精品视频 | 97国产超碰 | 日韩免费播放 | 狠狠色婷婷丁香六月 | 一区二区三区高清不卡 | 粉嫩av一区二区三区四区五区 | 日韩大片在线 | 9草在线 | 91亚洲夫妻 | 免费男女羞羞的视频网站中文字幕 | av一级片网站 | 久久大香线蕉app | 中文字幕亚洲高清 | 久久精品首页 | 在线亚洲精品 | 亚洲高清av在线 | 成人黄色免费观看 | 国产精品24小时在线观看 | 久久爱导航 | 婷婷久久精品 | 天天色 天天 | 精品久久久久久久久中文字幕 | av导航福利 | 免费在线观看av网站 | 国产亚洲视频在线观看 | 国产精品免费一区二区三区 | 综合网成人 | 一级片免费观看视频 | 91三级在线观看 | 色婷婷激情综合 | 久久免费视频观看 | 91成人亚洲 | 中文有码在线视频 | 日韩在线网 | 国产一级性生活 | 色干干| 日韩一区精品 | 久久久伊人网 | 五月婷婷六月综合 | 久久久久久久久久久影视 | 91福利国产在线观看 | 婷婷网站天天婷婷网站 | 一区二区三区四区在线免费观看 | 日韩精品视频在线观看免费 | 婷婷射五月 | 91超碰免费在线 | 人人干网 | 久久久久免费精品视频 | 久久永久免费视频 | av在线直接看 | 午夜视频一区二区三区 | 又黄又爽的免费高潮视频 | av官网| 国产一区在线免费 | 国产一区国产精品 | 久久综合爱 | 日韩精品一区二区三区中文字幕 | 久久精品亚洲一区二区三区观看模式 | 色综合久久中文综合久久牛 | 国产在线a | 亚洲欧美日韩一级 | 国产精品网红直播 | av资源中文字幕 | 国产精品成人自拍 | 亚洲精选国产 | 中文字幕精品三级久久久 | 国产欧美日韩一区 | 免费在线观看成人 | 成人黄色国产 | 新av在线 | 国产高清视频在线 | 九九热精品视频在线观看 | 欧美成人aa | 日韩精品一区二区在线视频 | 国产精品毛片一区二区 | 成片免费观看视频 | 精品电影一区 | 四虎永久免费网站 | 日韩专区在线播放 | 国产亚洲一区 | 婷婷精品国产欧美精品亚洲人人爽 | 97在线公开视频 | 24小时日本在线www免费的 | 亚洲成人精品在线观看 | 中文字幕亚洲五码 | 精品一区免费 | 欧美日韩在线视频一区 | 国产精品亚洲人在线观看 | av电影在线不卡 | 国产毛片在线 | 伊人成人精品 | 国产免码va在线观看免费 | 天天插狠狠干 | 亚洲国产精品电影在线观看 | 国产精品成人自产拍在线观看 | 日日操网站 | 丁香午夜婷婷 | 久草男人天堂 | 亚洲精品国产成人av在线 | 91热在线| 久久精品一区八戒影视 | 美女视频黄,久久 | 久久久久国产精品免费网站 | 女人18毛片a级毛片一区二区 | 国产视频久久久 | 91精品久久久久久久久久入口 | av永久网址 | 国内精品久久久久久久久 | 久久精品99久久久久久2456 | 999在线视频 | 最近2019中文免费高清视频观看www99 | 成人av.com| 国产 日韩 在线 亚洲 字幕 中文 | 久久久久免费视频 | 国产视频手机在线 | 日韩中文在线播放 | 在线一二区 | 69久久99精品久久久久婷婷 | 国产亚洲精品久久 | 国产v在线播放 | 欧美精品三级在线观看 | 久久人人97超碰精品888 | 米奇狠狠狠888 | 欧美天堂视频在线 | 免费精品国产va自在自线 | 一区二区三区四区五区在线视频 | 91高清完整版在线观看 | 手机版av在线 | ,午夜性刺激免费看视频 | av官网在线| 香蕉网在线播放 | 午夜婷婷在线观看 | 狠狠地操| 国产一级片网站 | 国色天香在线 | 久草在线久草在线2 | 亚洲国内精品在线 | 色婷婷丁香 | 国产乱对白刺激视频在线观看女王 | 国产另类av| 久黄色 | 亚洲午夜激情网 | 蜜桃视频精品 | 国产黄色av影视 | 最新极品jizzhd欧美 | 四虎国产精品免费观看视频优播 | 国产免费xvideos视频入口 | 亚洲 欧美 变态 国产 另类 | 免费亚洲一区二区 | 人人爱天天操 | 亚洲深爱激情 | 久久6精品 | 国产成人av综合色 | 午夜精品一区二区三区可下载 | 狠狠综合久久av | 91久久精品日日躁夜夜躁国产 | 91中文字幕在线观看 | 99九九热只有国产精品 | 精品国产视频一区 | 国产精品系列在线 | 97超碰人人干| 国产一级在线观看 | 国产情侣一区 | 日韩精品久久久久久 | 亚洲 欧洲av| 国产精品亚洲成人 | 国产美女永久免费 | 欧美极品xxxx | 久久精品亚洲综合专区 | 久久久国产一区 | 91九色国产蝌蚪 | 碰碰影院| 99在线看 | 国内99视频 | 91成人免费观看视频 | 97夜夜澡人人爽人人免费 | 亚洲综合网站在线观看 | 久久久久高清 | 国产电影黄色av | www.狠狠 | 精品国产理论 | 久草观看视频 | 91av原创 | 在线电影 一区 | 日日久视频 | 美女视频黄免费 | 精品一区二区在线看 | .国产精品成人自产拍在线观看6 | 亚洲成a人片在线www | 国产黄在线 | 久久99免费| 日本大尺码专区mv | 99精品视频在线 | 欧美一区二区三区不卡 | 久久不射网站 | 91理论片午午伦夜理片久久 | 午夜少妇av| 精品视频在线免费 | 国产一区福利 | 精品视频资源站 | 久草在线免费看视频 | 五月婷婷黄色网 | 日本精品一 | 日韩三级一区 | 久久特级毛片 | 色婷婷激情电影 | 国产在线视频不卡 | 视频1区2区 | 在线中文字幕av观看 | 亚洲国内精品视频 | 最近中文国产在线视频 | 亚洲老妇xxxxxx | 日躁夜躁狠狠躁2001 | 国产精品igao视频网入口 | 日日操日日插 | 亚洲视频h | 久久婷婷精品视频 | 观看免费av| 日本一区二区不卡高清 | 日本黄色免费在线 | 亚洲欧美成人综合 | 国产视频精品免费 | 丁香狠狠 | 日韩精品一区二区三区免费观看视频 | 黄色免费网站下载 | 手机看片| 开心综合网 | 蜜臀精品久久久久久蜜臀 | 久久视频免费 | 处女av在线 | 成人av免费电影 | 黄色电影网站在线观看 | 91精品国产欧美一区二区 | 91九色自拍 | 精品国产伦一区二区三区 | 成人黄色在线观看视频 | 中文在线亚洲 | 99国产精品久久久久久久久久 | 波多野结衣在线观看视频 | 激情五月婷婷 | 91精品入口 | 最新超碰在线 | 91亚洲精品国产 | 国产专区一 | 亚洲 欧美 国产 va在线影院 | 精品国产一区二区三区久久久久久 | 国产综合精品一区二区三区 | 国产黄色免费看 | 毛片网站免费在线观看 | 97成人精品区在线播放 | 久久美女精品 | 国产成年免费视频 | 免费网站色 | 国产成人av网站 | 日本精品一区二区三区在线播放视频 | 欧美日韩二三区 | 免费看片色 | 96视频免费在线观看 | 亚一亚二国产专区 | 亚洲精品网址在线观看 | 在线之家免费在线观看电影 | 国产综合视频在线观看 | 四月婷婷在线观看 | 九九三级毛片 | 三级av网站 | 国产精品一区二区在线观看免费 | 国产精品18久久久久久vr | 国产精品免费久久久久久 | 日韩欧美在线高清 | 免费影视大全推荐 | 91成人精品一区在线播放 | 99热九九这里只有精品10 | 99999精品 | 国产精品www | 久草电影在线观看 | 久久精品一区二区国产 | 免费三级黄色 | 超碰97免费在线 | 国产中文字幕av | 久久免费a | 激情小说久久 | 中文字幕资源网 国产 | 免费男女羞羞的视频网站中文字幕 | 91免费的视频在线播放 | 高清免费在线视频 | 五月婷婷综合久久 | 免费av黄色 | 亚欧日韩成人h片 | 日韩精品一区二区三区高清免费 | 亚洲精品午夜一区人人爽 | 久久精品视频网 | 激情视频二区 | 奇米先锋 | 男女啪啪网站 | 亚洲黄色在线 | 国产亚洲精品久久久久久电影 | 91在线精品观看 | 精品主播网红福利资源观看 | 欧美一区二区三区激情视频 | 成人网中文字幕 | 视频三区在线 | 国产毛片在线 | 久久久久久久网 | 精品一区三区 | 精品av在线播放 | 国产综合在线观看视频 | 久久久久久久久久久久国产精品 | 91黄色成人| 免费中文字幕 | 日日操操 | 超碰午夜 | 五月导航 | 涩涩成人在线 | 人人舔人人爽 | 欧美精品一区在线 | 亚洲免费一级电影 | 91福利在线导航 | 国产一区免费看 | 色视频网站在线观看一=区 a视频免费在线观看 | 国产精品午夜久久久久久99热 | 精壮的侍卫呻吟h | 91精品国产九九九久久久亚洲 | 国产精品久久久99 | 人人dvd| 亚洲精品国产综合99久久夜夜嗨 | 亚洲精品在线网站 | 国产精品2区| 激情丁香月 | 久久久网 | 综合网在线视频 | 日本中文字幕系列 | www.色com | 香蕉视频免费看 | 国产色小视频 | 欧美一级淫片videoshd | 中文字幕在线观看免费高清完整版 | 91麻豆精品国产 | 99久久9 | 美女视频黄网站 | 69视频网站 | 久久av在线播放 | 成人av一区二区兰花在线播放 | 国产资源在线免费观看 | 丁香六月激情 | 国产一级片免费播放 | 99热这里只有精品1 av中文字幕日韩 | 国产91精品一区二区麻豆网站 | 国产精品久久久久影视 | 国产69精品久久久久久久久久 | 国产精品免费一区二区三区在线观看 | 午夜视频99 | 波多野结衣在线视频一区 | 综合久久精品 | 亚洲精品999 | av大全在线观看 | 91av视频在线免费观看 | 成年人黄色大片在线 | 国产91精品高清一区二区三区 | 中文字幕在线观看日本 | 久久综合五月 | 激情五月六月婷婷 | 97精品国产97久久久久久春色 | 亚洲精品久久久久www | 手机av网站| 国产精品高清免费在线观看 | 黄网站免费看 | 亚洲成人中文在线 | 精品国产免费一区二区三区五区 | 天天插天天色 | 欧美a级在线免费观看 | 性色xxxxhd| 日本三级全黄少妇三2023 | 国产精品久久久久久久久久久久午夜 | 日韩中文字幕视频在线 | 少妇性bbb搡bbb爽爽爽欧美 | 日韩亚洲欧美中文字幕 | 亚洲精品在线免费播放 | 中文字幕在线观看的网站 | 欧美日韩99| 日韩精品欧美精品 | 午夜电影av | 99精品小视频 | 婷婷精品国产欧美精品亚洲人人爽 | 91成年视频| 亚洲最大的av网站 | 美女视频一区 | 毛片视频电影 | 日韩在线观看影院 | 国产精品九色 | 色婷婷亚洲 | 激情导航 | 香蕉视频亚洲 | 综合色亚洲 | 91丨九色丨高潮丰满 | av福利免费| 久草视频在线看 | 亚洲夜夜综合 | 国产精品毛片一区视频 | 久草在线一免费新视频 | 五月激情在线 | 国产精品1区 | 日本中文字幕影院 | 日韩成人av在线 | 日韩免费区| 国产精品原创在线 | 干干干操操操 | 九九热在线精品 | 久草视频免费观 | 一二三精品视频 | 国产精品日韩在线播放 | 粉嫩av一区二区三区四区在线观看 | 久久精品韩国 | 中文字幕一区二区三区久久 | 日韩中文字幕视频在线观看 | 色99视频 | aaa日本高清在线播放免费观看 | 在线视频一区观看 | 四虎影视成人精品 | 亚州免费视频 | 伊人www22综合色 | 在线视频手机国产 | 综合久久精品 | 久久精品视频在线免费观看 | 欧美精品在线观看免费 | 久久久久久久久久网站 | 免费精品国产 | 丁香在线观看完整电影视频 | 免费又黄又爽 | 国产一区成人在线 | 日韩电影在线一区 | 欧美日韩中文字幕视频 | 国产视频18 | 久久五月情影视 | 精品久久久久久亚洲综合网站 | 黄色三级视频片 | 色综合久久精品 | 久久高清| 午夜久久 | 色综合色综合久久综合频道88 | 精品国产一区二区三区免费 | 国产免费一区二区三区最新 | 中午字幕在线观看 | av东方在线 | 欧美国产91 | 五月天视频网 | 欧美激情在线网站 | 亚洲最大色| 99久久综合国产精品二区 | 国产一区二区在线免费播放 | 久久国产日韩 | 欧美日韩免费网站 | 精品视频国产 | 综合色在线 | 国产精品久久久久久久午夜片 | 亚洲国产经典视频 | 91精品国产91久久久久福利 | 亚洲视频资源在线 | 久草com| 久久爱资源网 | 热久精品| 国产又粗又猛又爽又黄的视频先 | 久草在线观看视频免费 | 九九热精品视频在线播放 | 超碰免费在线公开 | 六月婷婷久香在线视频 | 91九色视频 | 九九免费在线观看视频 | 亚洲电影久久 | 在线免费色视频 | 免费观看一级视频 | 中文字幕大全 | 91大神电影| 久久精品视频在线 | 在线观看aa | 91禁在线观看 | 国产精品婷婷午夜在线观看 | 久久精品亚洲精品国产欧美 | 久久久精品午夜 | 91成人免费看 | 亚洲精品午夜久久久久久久久久久 | 欧美网址在线观看 | 2019中文最近的2019中文在线 | 黄网站免费久久 | 国产精品igao视频网网址 | 成人作爱视频 | 亚洲精品乱码久久久久v最新版 | 日韩av男人的天堂 | 久久久久一区二区三区四区 | a黄色一级片 | 亚洲国产精品传媒在线观看 | 久久综合久久久 | 国产精品成久久久久 | 成人在线视频免费看 | 97在线免费 | 2019中文最近的2019中文在线 | 国产精品亚洲综合久久 | 99riav1国产精品视频 | 国产乱码精品一区二区蜜臀 | 夜夜爽夜夜操 | 插综合网 | 久久免费激情视频 | 香蕉免费在线 | 婷婷精品在线视频 | 亚洲天堂免费视频 | 亚洲精品综合一区二区 | 欧美精品亚洲精品日韩精品 | 日韩av视屏在线观看 | 欧美一级欧美一级 | 在线导航av | 高清免费在线视频 | 久久综合射| 欧美91精品| 国产高清久久久 | 久久黄色影视 | 青青草国产精品 | 丁五月婷婷 | 国产中文字幕大全 | www.在线观看av | 激情婷婷网 | 91免费高清在线观看 | 精品福利在线观看 | 天天躁日日躁狠狠躁 | 91高清免费看 | 99视频精品免费视频 | 亚洲永久精品视频 | 精品一区91 | 黄色av电影网 | 98超碰在线 | 91大神免费在线观看 | 国产成人高清在线 | 国产精品国产亚洲精品看不卡15 | 亚州国产视频 | 国产精品久久久久永久免费看 | 日韩电影在线观看一区二区三区 | av日韩国产| 一级性生活片 | 色中色综合 | 插插插色综合 | 国产成人免费网站 | 国产精品原创av片国产免费 | 久久精品永久免费 | 毛片网站在线观看 | 久久综合九色九九 | 国产成人精品av | 久久久国产精品网站 | 91精选在线观看 | 久久久在线免费观看 | 日韩欧美aaa | 天天天天天操 | 97在线观看免费观看高清 | 国产成人在线网站 | 粉嫩高清一区二区三区 | 视频一区在线播放 | 99精品久久久久久久 | 国产精品一区二区你懂的 | 亚州欧美视频 | 91精品国产欧美一区二区 | 国产九九九视频 | 91精品推荐 | 天天综合亚洲 | 日韩av男人的天堂 | 久久国产欧美日韩精品 | 少妇bbw搡bbbb搡bbbb | 免费av福利 | 久久精品视频播放 | 有码一区二区三区 | 美女网站黄在线观看 | 91自拍成人 | 天天色图 | 国产日本在线观看 | 91丨九色丨国产丨porny精品 | 国产日韩欧美在线一区 | 久草在线手机视频 | 免费在线黄色av | 亚洲日本一区二区在线 | 久精品视频在线观看 | 麻豆91精品 | 91综合久久一区二区 | 特级片免费看 | 国产精品毛片一区二区在线看 | 午夜视频99 | 女人18片毛片90分钟 | 91精品啪在线观看国产线免费 | 一区二区视频电影在线观看 | 在线成人小视频 | 亚洲国产日韩欧美 | 久草视频在线资源 | 91精品国产网站 | 亚洲网久久 | 国产一级片在线播放 | 六月丁香激情综合色啪小说 | 亚洲一区黄色 | 成人黄色电影免费观看 | 在线观看色网站 | 国产中文字幕亚洲 | 国产女人18毛片水真多18精品 | 日本特黄一级片 | 成 人 黄 色 免费播放 | 黄色最新网址 | 美女露久久 | 久久久国产一区二区 | 99免费在线视频观看 | 国产精品免费久久久 | 国产一区二区视频在线播放 | 99视频播放 | 高清日韩一区二区 | 国产精品久久久久久久久久白浆 | 成年人在线免费看视频 | 国产玖玖精品视频 | 精品国产一区二区三区久久 | 三级av免费看 | 一本一本久久aa综合精品 | 精品久久久久_ | 欧美日韩国产一区二区三区在线观看 | 99在线视频播放 | 欧美a√大片| 亚洲成aⅴ人片久久青草影院 | 国产精品国产毛片 | 天天操天天舔天天爽 | 永久免费毛片在线观看 | 五月天综合在线 | 久久激情视频免费观看 | 国产精品国产三级国产不产一地 | 国产成人a亚洲精品 | 在线播放国产精品 | 狠狠干我 | 天天草视频 | 91爱在线| 久久99精品久久久久久秒播蜜臀 | 久久精品观看 | 国产精品久久亚洲 | 成人香蕉视频 | 狠狠撸电影| 最新久久免费视频 | 久久久久久久毛片 | 久久人人97超碰com | 在线免费黄网站 | 午夜123 | 久久久久区 | 在线a亚洲视频播放在线观看 | 91视视频在线直接观看在线看网页在线看 | 狠狠色综合网站久久久久久久 | 欧美一级电影在线观看 | 美女在线黄 | 亚洲精品在线视频 | 91亚洲网站| 免费视频一二三 | 深爱开心激情网 | 91福利视频一区 | 九九九在线观看视频 | 国产视频日韩视频欧美视频 | 久久国产成人午夜av影院宅 | 日韩欧美网址 | 黄色三级免费观看 | 国产一级二级在线观看 | 中国一级片在线 | 婷婷在线观看视频 | 免费大片av| 国产在线观 | 国产69精品久久久久久 | 久久综合久色欧美综合狠狠 | 日本黄区免费视频观看 | 99久久日韩精品免费热麻豆美女 | 成人h在线观看 | 高清免费在线视频 | 欧美一性一交一乱 | 久久免费在线观看视频 | 91精品在线播放 | 99精品国产一区二区三区麻豆 | 五月天最新网址 | 一区二区三区中文字幕在线观看 | 五月婷婷影院 | 热久久最新地址 | 在线观看成人网 | 91亚色在线观看 | 精品亚洲午夜久久久久91 | 久久久久人人 | 人人搞人人爽 | 国产精品成人自产拍在线观看 | 久久国产精品99精国产 | 精品国内 | 国产在线一区二区三区播放 | 一级a毛片高清视频 | 久久视频一区二区 | 日韩欧美视频在线播放 | 美女网站视频免费都是黄 | 久久久在线观看 | 亚洲视频1区2区 | 狠狠躁日日躁狂躁夜夜躁 | 久久久久国产一区二区三区四区 | www日韩精品 | 五月天婷婷狠狠 | 日韩欧美在线综合网 | 91精品网站在线观看 | 99精品色| 久久成人一区二区 | 狠狠操天天操 | 一区二区视频在线播放 | 91精品国产一区 | 国产精品麻豆果冻传媒在线播放 | 蜜臀av性久久久久av蜜臀妖精 | 在线中文字幕一区二区 | 国产精品va视频 | 国产私拍在线 | 欧美一区二区三区四区夜夜大片 | av在线一二三区 | 日本久久成人中文字幕电影 | 中文字幕免费观看 | 欧美极品xxxxx | 在线播放你懂 | 久久狠狠亚洲综合 | 三级黄色a | 爱爱一区 | 正在播放国产91 | 久久免费电影网 | 久久久久久免费 | 久久99久久99精品中文字幕 | 国产香蕉视频在线观看 | 少妇按摩av | 欧美精品中文字幕亚洲专区 | 97电院网手机版 | 九精品| 波多野结衣电影一区二区 | 最新极品jizzhd欧美 | 亚洲精选在线 | 久久久久亚洲国产精品 | 综合网伊人 | 在线天堂v | 精品国产福利在线 | 三级黄色大片在线观看 | 成人av在线直播 | 精品91视频 | 日韩精品久久久久久久电影99爱 | 久艹在线观看视频 | 亚洲视频综合在线 | 久久久精品午夜 | 久久久九九 | 日韩在线观看中文字幕 | 亚洲每日更新 | 亚洲精品一区二区三区高潮 | 91亚·色| 奇米网在线观看 | 最近中文字幕国语免费av | 在线视频日韩一区 | 热久久免费视频精品 | www.五月婷婷 | 99视频在线观看视频 | 欧美日韩中 | 亚洲精品久久久久中文字幕二区 | 亚洲精品免费在线视频 | 久久久久人人 | 精品高清美女精品国产区 | 中文字幕视频播放 | 国产高清在线不卡 | 超碰99人人 | 国产成人精品久久亚洲高清不卡 | 国产女人18毛片水真多18精品 | 一区二区三区高清不卡 | 免费看wwwwwwwwwww的视频 久久久久久99精品 91中文字幕视频 | 伊人五月婷| 精品久久久久久综合日本 | 日韩电影一区二区在线 | 色综合天天综合在线视频 | 国产999在线观看 | 激情综合网五月婷婷 | 91香蕉亚洲精品 | 夜夜看av | 欧洲精品二区 | 中文在线字幕免费观看 | av电影不卡| 国产黄大片在线观看 | 欧美一级黄色视屏 | 久久久久免费精品国产 | av在线之家电影网站 | 婷婷综合久久 | 国产日韩欧美视频在线观看 | 九九热视频在线免费观看 | 久久精品国产成人精品 | 午夜私人影院 | 国产精品国产三级国产 | 成年人国产精品 | 丁香六月久久综合狠狠色 | 日本中文在线播放 | 成人性生爱a∨ | 激情网在线视频 | 日韩欧美在线综合网 | 亚洲91精品在线观看 | 最近最新中文字幕视频 | 日日躁你夜夜躁你av蜜 | 最近最新中文字幕 | 狠狠色噜噜狠狠狠狠 | av在线一级 | 久久综合免费视频影院 | 丁香婷婷久久久综合精品国产 | 一区国产精品 | 粉嫩av一区二区三区四区在线观看 | 国产在线欧美 | 欧美在线视频一区二区 | 国产高清久久久久 | 亚洲精品成人av在线 | 日韩电影中文,亚洲精品乱码 | 国产精品久久久久久妇 | 精品一区二区在线免费观看 | 在线观看的a站 | 国产中文视频 | 久久九九影院 | 日韩精品免费 | 国产69精品久久99的直播节目 | 在线v片免费观看视频 | 国产剧情久久 | 亚洲在线视频免费 | 狠狠色丁香婷婷综合视频 | 日韩欧美第二页 | 国产免费二区 | 一区二区三区日韩精品 | 波多野结衣电影久久 | 97久久精品午夜一区二区 | 欧美精品久久久久久久免费 | 国产破处精品 | 久久久久电影网站 | 日日夜夜精品免费观看 | 三级av小说| 欧美日韩高清一区二区 国产亚洲免费看 | 91视频高清 | 91精品在线观看入口 | 国产免费小视频 | 韩日电影在线观看 | www.五月天激情 | 国产精品免费在线播放 | 国产精品第54页 | 亚洲女同videos | 亚洲国产色一区 | 欧美男女爱爱视频 | 黄色三级免费看 | 91完整版观看 | 婷婷色在线 | 欧美精品你懂的 | 激情五月综合 | 国产精品久久久久久久av电影 | 成人久久18免费网站 | 97精品国产aⅴ | 亚洲劲爆av| 五月在线视频 | 婷婷亚洲最大 | 亚洲精品欧美精品 | 玖玖爱在线观看 | 久久久久这里只有精品 | 国产精品久久久亚洲 | 亚洲人片在线观看 | 婷婷色综| 中文字幕在线观看第三页 | 久久精品综合一区 | 久久免费99精品久久久久久 | 97超碰免费在线观看 | 在线天堂8√ | 成年人在线免费看片 | 免费观看国产精品 | av电影不卡 | 欧美色图亚洲图片 | 国产玖玖在线 |