xv6學習筆記 分頁機制 和記憶體管理

2021-09-02 22:57:33 字數 2382 閱讀 4300

mmu.h原始碼中給出了xv6虛擬位址的構成,及所代表的含義

mmu.h中還有頁表的相關資訊,每個頁目錄都與1024條記錄,每乙個頁表中也有1024條記錄,每一頁的大小4096位元組,也就是4kb。

// page directory and page table constants.

#define npdentries     1024    // # directory entries per page directory

#define nptentries     1024    // # ptes per page table核心載入到記憶體後,在main函式中,首先呼叫kinit1(),由於這時候的虛擬位址 [kernbase, kernbase+4mb) 對映到 實體地址[0, 4mb),所以核心實際能用的虛擬位址空間顯然是不足以完成正常工作的,所以初始化過程中需要重新設定頁表。如圖:

xv6在main函式中呼叫kinit1和kinit2來初始化物理記憶體。

kinit1初始化核心末尾到物理記憶體4m的物理記憶體空間為未使用。呼叫freerange將空閒記憶體加入到空閒記憶體鍊錶中

void kinit1(void *vstart, void *vend)

kinit1(end, p2v(4*1024*1024));

在核心構建了新頁表後,能夠完全訪問核心的虛擬位址空間,然後kinit2初始化剩餘核心空間到phystop為未使用,開始了鎖機制保護空閒記憶體鍊錶。

void kinit2(void *vstart, void *vend)

kinit2(p2v(4*1024*1024), p2v(phystop));

之前說呼叫kinit2之前需要構建新的頁表,main函式通過呼叫kvmalloc函式來實現核心新頁表的初始化。通過初始化,最後記憶體布局和位址空間如下:核心末尾實體地址到實體地址phystop的記憶體空間未使用 ;虛擬位址空間kernbase以上部分對映到物理記憶體低位址相應位置

void

kvmalloc(void)

在說一下 walkpgdir,這個函式用來計算pte(頁表條目)的位址,他會根據va的前十位來先找到在頁目錄的條目。如果該條目不存在,說明該頁表不存在;如果alloc引數被設定,walkpgdir會分配頁表頁並將其實體地址放到頁目錄中。最後用虛擬位址的接下來10位來找到其在頁表中的 pte位址。

return 0;}​

#define pdx(va)         (((uint)(va) >> pdxshift) & 0x3ff)

​static pte_t *walkpgdir(pde_t *pgdir, const void *va, int alloc)

else

return &pgtab[ptx(va)];

}另外,在setupkvm中,所有的對映,最後都儲存在kmap這樣乙個結構體中,下面這是kmap的結構

// every process's page table.

static struct kmap kmap = , // i/o space

,     // kern text+rodata

, // kern data+memory

, // more devices

};xv6對上層提供kalloc和kfree介面來管理物理記憶體,上層無需知道具體的細節,kalloc返回虛擬位址空間的位址,kfree以虛擬位址為引數,通過kalloc和kfree能夠有效管理物理記憶體,讓上層只需要考慮虛擬位址空間。

kalloc分配4kb(相當於一頁的大小)的物理記憶體,並返回乙個核心可以使用的指標,如果返回0說明這頁無法被分配。

kfree以虛擬位址為引數,用來釋放一頁的記憶體空間

void kfree(char *v)

​// allocate one 4096-byte page of physical memory.

// returns a pointer that the kernel can use.

// returns 0 if the memory cannot be allocated.

char* kalloc(void)

xv6將未分配的記憶體組成乙個鍊錶,乙個結構體

struct run ;

struct kmem;

xv6實際上通過儲存虛擬位址空間的freelist,然後通過頁表找到實體地址。由此,層呼叫的只需要想著「虛擬位址a對應的一頁釋放為空閒頁」「分配一頁返回虛擬位址給我」即可。

XV6記憶體布局

1 規定系統最大物理記憶體為16mb。2 應用程式使用0 640k虛擬記憶體,640k 1m是對映io空間,1m以上的高位記憶體只有核心可以使用,4064 4096最高32m位址空間對映到不同的裝置。3 每個應用程式都有自己的頁表,頁表的前160項 0 640k 記憶體是自己對映的,從640k到最高...

Xv6 多程序程式設計

參考 xv6 riscv book 1.1 processes and memory 系統呼叫 描述int fork 建立乙個程序 通過複製當前程序 返回子程序 pid int exit int status 終止當前程序,status 會被報告給 wait 無返回值 int wait int st...

安裝並啟動xv6

從github上拉取xv6的原始碼 git clone git sudo apt get install qemu輸入下面的命令 objdump i第二行應該輸出 elf32 i386 輸入下面的命令,gcc m32 print libgcc file name應輸出 usr lib gcc i48...