【xv6】03 page table

文章讲述了在Linux等操作系统中,通过在用户空间和内核间共享只读区域来加速getpid系统调用的方法,介绍了如何映射用户空间的USYSCALL区域、trapframe结构以及sys_pgaccess系统调用的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Speed up system calls (easy)

一些操作系统(比如 Linux)会通过在用户空间和内核之间共享只读区域来加速特定的系统调用。这可以消除系统调用的消耗。这里只要求对getpid()加速。
当每个进程被创建时,可以在USYSCALL上映射一个只读页。USYSCALL是定义在memlayout.h中定义的虚拟内存。在这一页的开始,保存一个struct usyscall(这个结构体也定义在 memlayout.h),并且初始化它来保存当前进程的PID。 对于这个实验,ugetpid()已经在用户空间提供了,并且会自动使用USYSCALL映射。
一些提示:

  • 可以在 kernel/proc.c里的 proc_pagetable()里执行这个映射。
  • 选择合适的权限位,允许用户空间可以访问这个页
  • mappages()很有用
  • 不要忘了使用allocproc()初始化页
  • 确保使用freeproc()释放页

分析

ugetpid()

int
ugetpid(void)
{
   
  struct usyscall *u = (struct usyscall *)USYSCALL;
  return u->pid;
}

这里直接拿了一个地址转换成 struct ussycall.

映射到页

结构体proc

struct proc {
   
...

  // these are private to the process, so p->lock need not be held.
  uint64 kstack;               // Virtual address of kernel stack
  uint64 sz;                   // Size of process memory (bytes)
  pagetable_t pagetable;       // User page table
  struct trapframe *trapframe; // data page for trampoline.S
  struct context context;      // swtch() here to run process
  struct file *ofile[NOFILE];  // Open files
  struct inode *cwd;           // Current directory
  char name[16];               // Process name (debugging)
};

这里发现一个trapframe,现在就照着这个变量写。

// kernel/proc.c
struct proc {
   
  // these are private to the process, so p->lock need not be held.
  uint64 kstack;               // Virtual address of kernel stack
  uint64 sz;                   // Size of process memory (bytes)
  pagetable_t pagetable;       // User page table
  struct trapframe *trapframe; // data page for trampoline.S
  struct usyscall *usyscall_frame;   // Add a data page for usyscall
  struct context context;      // swtch() here to run process
  struct file *ofile[NOFILE];  // Open files
  struct inode *cwd;           // Current directory
  char name[16];               // Process name (debugging)
};

初始化 usyscall_frame

// kernel/proc.c : allocproc
/ Look in the process table for an UNUSED proc.
// If found, initialize state required to run in the kernel,
// and return with p->lock held.
// If there are no free procs, or a memory allocation fails, return 0.
static struct proc*
allocproc(void)
{
   
  struct proc *p;

  for(p = proc; p < &proc[NPROC]; p++) {
   
    acquire(&p->lock)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值