Xv6——物理内存分配器

阅读材料

  • Xv6代码:kalloc.c、memlayout.h
  • 教材 3.4 - 3.5 节

物理内存布局

在Xv6中,物理内存大小是固定的,为128MB。物理内存起止也是固定的,由宏 KERNVASE 和 宏 PHYSTOP 定义。这两个宏在 memlayout.h 文件中声明。系统启动时,会把内核的代码加载到物理内存当中去;因此,可用的物理内存起始由符号 end 声明。这里需要注意的是,Xv6为了保证Free Memory 是页大小的整数倍(这样可以保证分配到最后不会出现最后一点物理内存不够一页的情况),会对 end 进行按页对齐操作,因此 end 和 Kernel data 之间会有少许的内存空隙不被使用。

物理内存管理

物理内存数据结构

struct
{
	struct spinlock lock;
	struct run *freelist;
} kmem;

kmem 定义了一个指向链表头部的指针,外加一个保护的锁 

struct run
{
	struct run *next;
};

struct run 结构体变量位于每个页的最低地址处,占8字节, 指向下一个物理页。

如果这样物理页被分配给进程了,struct run 所占的8字节内存进程也是可以正常使用的。

物理内存分配

物理内存分配相当于链表的删除操作,即从物理内存链表头部删除一个页

void* kalloc(void)
{
	struct run *r;

	acquire(&kmem.lock);
	r = kmem.freelist;
	if (r)
		kmem.freelist = r->next;
	release(&kmem.lock);

	if (r)
		memset((char *)r, 5, PGSIZE); // fill with junk
	return (void *)r;
}

物理内存释放

物理内存释放相当于链表的插入操作,在物理内存链表头部插入一个页

void kfree(void *pa)
{
	struct run *r;

	if (((uint64)pa % PGSIZE) != 0 || (char *)pa < end || (uint64)pa >= PHYSTOP)
		panic("kfree");

	// Fill with junk to catch dangling refs.
	memset(pa, 1, PGSIZE);

	r = (struct run *)pa;

	acquire(&kmem.lock);
	r->next = kmem.freelist;
	kmem.freelist = r;
	release(&kmem.lock);
}

参考文献

6. 物理内存管理 | XV6 源代码阅读指南 (gitbook.io)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值