xv6-simplified 0.1
简化版xv6
|
虚拟内存管理的实现,包括创建和管理页表,以及将虚拟地址映射到物理地址 More...
#include "include/param.h"
#include "include/types.h"
#include "include/memlayout.h"
#include "include/elf.h"
#include "include/riscv.h"
#include "include/defs.h"
Functions | |
pagetable_t | kvmmake (void) |
创建一个内核页表,其中包含了一些内核需要的映射关系,是内核能够访问到这些区域的内容 | |
void | kvminit (void) |
初始化内核页表kernel_pagetable | |
void | kvminithart () |
将硬件页表寄存器切换到内核页表,并启用分页 | |
pte_t * | walk (pagetable_t pagetable, uint64 va, int alloc) |
在页表中查找虚拟地址va对应的页表项,如果页表项不存在则根据alloc参数决定是否分配新的页表 | |
uint64 | walkaddr (pagetable_t pagetable, uint64 va) |
查找虚拟地址对应的物理地址,如果没有映射则返回0,它只能用于查找用户页 | |
void | kvmmap (pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm) |
将虚拟地址范围映射到物理地址,并将相应的PTE添加到页表中 | |
int | mappages (pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm) |
从va开始的虚拟地址创建PTE,这些PTE指向从pa开始的物理地址 | |
void | uvmunmap (pagetable_t pagetable, uint64 va, uint64 npages, int do_free) |
从虚拟地址va开始,移除npages页的映射,va必须是页对齐的,映射必须存在 | |
pagetable_t | uvmcreate () |
创建一个空的用户页表 | |
void | uvmfirst (pagetable_t pagetable, uchar *src, uint sz) |
将用户的initcode加载到进程的地址0处,用于第一个进程 | |
uint64 | uvmalloc (pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm) |
为进程从oldsz到newsz分配PTE和物理内存 | |
uint64 | uvmdealloc (pagetable_t pagetable, uint64 oldsz, uint64 newsz) |
释放用户进程的内存页,以将进程大小从oldsz缩小到newsz | |
void | freewalk (pagetable_t pagetable) |
递归地释放页表页,所有映射必须已经被删除 | |
void | uvmfree (pagetable_t pagetable, uint64 sz) |
释放用户进程的内存页和页表页 | |
int | uvmcopy (pagetable_t old, pagetable_t new, uint64 sz) |
将一个进程的虚拟地址空间复制到另一个进程的虚拟地址空间,包括页表和物理内存 | |
void | uvmclear (pagetable_t pagetable, uint64 va) |
将一个页表项标记为无效,使得用户无法访问该页。它通常被用于为用户栈设置保护页 | |
int | copyout (pagetable_t pagetable, uint64 dstva, char *src, uint64 len) |
从内核空间复制数据到用户空间 | |
int | copyin (pagetable_t pagetable, char *dst, uint64 srcva, uint64 len) |
从用户空间复制数据到内核空间 | |
int | copyinstr (pagetable_t pagetable, char *dst, uint64 srcva, uint64 max) |
从用户空间复制一个以'\0'结尾的字符串到内核空间 | |
Variables | |
pagetable_t | kernel_pagetable |
char | etext [] |
char | trampoline [] |
虚拟内存管理的实现,包括创建和管理页表,以及将虚拟地址映射到物理地址
int copyin | ( | pagetable_t | pagetable, |
char * | dst, | ||
uint64 | srcva, | ||
uint64 | len | ||
) |
从用户空间复制数据到内核空间
pagetable | 页表 |
dst | 目标内存地址 |
srcva | 源内存地址 |
len | 要复制的数据长度 |
int copyinstr | ( | pagetable_t | pagetable, |
char * | dst, | ||
uint64 | srcva, | ||
uint64 | max | ||
) |
从用户空间复制一个以'\0'结尾的字符串到内核空间
pagetable | 页表 |
dst | 目标内存地址 |
srcva | 源内存地址 |
max | 最大复制字节数 |
int copyout | ( | pagetable_t | pagetable, |
uint64 | dstva, | ||
char * | src, | ||
uint64 | len | ||
) |
从内核空间复制数据到用户空间
pagetable | 用户进程的页表 |
dstva | 目标虚拟地址 |
src | 源数据的指针 |
len | 要复制的数据长度 |
void freewalk | ( | pagetable_t | pagetable | ) |
递归地释放页表页,所有映射必须已经被删除
pagetable | 页表 |
void kvminit | ( | void | ) |
初始化内核页表kernel_pagetable
void kvminithart | ( | void | ) |
将硬件页表寄存器切换到内核页表,并启用分页
pagetable_t kvmmake | ( | void | ) |
创建一个内核页表,其中包含了一些内核需要的映射关系,是内核能够访问到这些区域的内容
void kvmmap | ( | pagetable_t | kpgtbl, |
uint64 | va, | ||
uint64 | pa, | ||
uint64 | sz, | ||
int | perm | ||
) |
将虚拟地址范围映射到物理地址,并将相应的PTE添加到页表中
kpgtbl | 内核页表的起始地址 |
va | 起始虚拟地址 |
pa | 起始物理地址 |
sz | 映射的大小 |
perm | 相应的权限 |
int mappages | ( | pagetable_t | pagetable, |
uint64 | va, | ||
uint64 | size, | ||
uint64 | pa, | ||
int | perm | ||
) |
从va开始的虚拟地址创建PTE,这些PTE指向从pa开始的物理地址
pagetable | 页表的起始地址 |
va | 起始虚拟地址 |
size | 映射的大小 |
pa | 起始物理地址 |
perm | 相应的权限 |
uint64 uvmalloc | ( | pagetable_t | pagetable, |
uint64 | oldsz, | ||
uint64 | newsz, | ||
int | xperm | ||
) |
为进程从oldsz到newsz分配PTE和物理内存
pagetable | 进程的页表 |
oldsz | 进程的旧大小 |
newsz | 进程的新大小 |
xperm | 权限 |
void uvmclear | ( | pagetable_t | pagetable, |
uint64 | va | ||
) |
将一个页表项标记为无效,使得用户无法访问该页。它通常被用于为用户栈设置保护页
pagetable | 用户进程的页表 |
va | 虚拟地址 |
int uvmcopy | ( | pagetable_t | old, |
pagetable_t | new, | ||
uint64 | sz | ||
) |
将一个进程的虚拟地址空间复制到另一个进程的虚拟地址空间,包括页表和物理内存
old | 源进程的页表 |
new | 目标进程的页表 |
sz | 源进程的大小 |
pagetable_t uvmcreate | ( | ) |
创建一个空的用户页表
uint64 uvmdealloc | ( | pagetable_t | pagetable, |
uint64 | oldsz, | ||
uint64 | newsz | ||
) |
释放用户进程的内存页,以将进程大小从oldsz缩小到newsz
pagetable | 进程的页表 |
oldsz | 进程的旧大小 |
newsz | 进程的新大小 |
void uvmfirst | ( | pagetable_t | pagetable, |
uchar * | src, | ||
uint | sz | ||
) |
将用户的initcode加载到进程的地址0处,用于第一个进程
pagetable | 进程的页表 |
src | 指向用户initcode的指针 |
sz | 用户initcode的大小,必须小于一页 |
void uvmfree | ( | pagetable_t | pagetable, |
uint64 | sz | ||
) |
释放用户进程的内存页和页表页
pagetable | 用户进程的页表 |
sz | 用户进程的大小 |
void uvmunmap | ( | pagetable_t | pagetable, |
uint64 | va, | ||
uint64 | npages, | ||
int | do_free | ||
) |
从虚拟地址va开始,移除npages页的映射,va必须是页对齐的,映射必须存在
pagetable | 页表 |
va | 虚拟地址 |
npages | 要移除的页数 |
do_free | 是否释放物理内存 |
pte_t * walk | ( | pagetable_t | pagetable, |
uint64 | va, | ||
int | alloc | ||
) |
在页表中查找虚拟地址va对应的页表项,如果页表项不存在则根据alloc参数决定是否分配新的页表
pagetable | 页表的起始地址 |
va | 所需查找的虚拟地址 |
alloc | 是否需要分配新的页表项 |
uint64 walkaddr | ( | pagetable_t | pagetable, |
uint64 | va | ||
) |
查找虚拟地址对应的物理地址,如果没有映射则返回0,它只能用于查找用户页
pagetable | 页表 |
va | 虚拟地址 |
|
extern |
pagetable_t kernel_pagetable |
|
extern |