Xv6学习之kinit1

位置:进入主函数执行的第一个函数

kinit1(end, P2V(4*1024*1024)); // phys page allocator


void
kinit1(void *vstart, void *vend)
{
  initlock(&kmem.lock, "kmem");
  kmem.use_lock = 0;
  freerange(vstart, vend);
}


void
initlock(struct spinlock *lk, char *name)
{
  lk->name = name;
  lk->locked = 0;
  lk->cpu = 0;
}


void
kfree(char *v)
{
  struct run *r;


  if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP)
    panic("kfree");


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


  if(kmem.use_lock)
    acquire(&kmem.lock);
  r = (struct run*)v;
  r->next = kmem.freelist;
  kmem.freelist = r;
  if(kmem.use_lock)
    release(&kmem.lock);
}



####:物理内存分配器
分配器中的数据构是⼀个由可分配物理内存构成的*空 表*个空闲页表的元素是构体
`struct run`2764)。那么分配器从哪⾥得内存来存放些数据构呢?实际上,分配器将每个空
闲页`run` 构体保存在闲页本身中,因闲页中没有其他数据。分配器⽤⼀个spin lock
2764-2766)来保闲链表。表和都封装在⼀个构体中,这样逻辑就比明晰:
该结构体中的域。不过现先忽略,以及`acquire` `release`⽤;我会在
4 章了解其细节
`main` 函数⽤了`kinit1` `kinit2`两个函数分配器⾏初始化(2780)。这样做是由于
`main` 中的⼤部分代都不能使⽤以及4MB 以上的内存。`kinit1`在前 4MB ⾏了不需要的内
存分配。⽽ `kinit2` 的使⽤,并使得更多的内存可⽤于分配。原本应该`main` 决定有多
少物理内存可⽤于分配,但在 x86 上很难实现所以它假机器中有240MB`PHYSTOP`)物理内存,
并将内核末尾和 `PHYSTOP` 的内存都作⼀个初始的空内存池。`kinit1``kinit2`
`freerange`将内存加入空闲链表中,`freerange`是通过对每⼀页调`kfree` 实现该功能。⼀
PTE 只能指向⼀个 4096 节对齐的物理地址(即是4096 的倍数),因此 `freerange`
`PGROUNDUP`来保分配器只会对齐的物理地址。分配器原本⼀开始没有内存可⽤,正是
`kfree` ⽤将可⽤内存交了分配器来管理。
分配器⽤映射到⾼内存区域的虚地址找到对应的物理,⽽⾮物理地址。所以`kinit` 会使⽤ `p2v
(PHYSTOP)`来将`PHYSTOP`(⼀个物理地址)翻译为地址。分配器有将地址看作是整型,
⾏运算(譬如在`kinit` 中遍所有);⽽有将地址看作写内存⽤的指(譬如操作每
中的`run` 构体);地址的双重使⽤




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值