xv6 kmem这个全局变量,是在何时通过什么函数初始化的?初始化后,内存中大部分字节存储的数据是什么,是0吗?[10%]
时间: 2024-01-24 16:19:45 浏览: 73
在xv6中,`kmem`是一个指向`struct run`结构体的指针数组,用于管理内核使用的物理内存页。该变量在操作系统启动时通过`kinit`函数进行初始化,具体过程如下:
1. `kinit1`: 将物理内存划分为多个大小相等的页框,将每个页框对应的`struct run`结构体插入到空闲列表中。
2. `kinit2`: 遍历内存中的所有页表,将已经被占用的物理页从空闲列表中删除。
3. `kmeminit`: 将`kmem`指向空闲列表中的第一个`struct run`结构体,表示内核可用内存的起始地址。
在初始化后,`kmem`中存储的是物理内存页的信息,每个`struct run`结构体表示一个空闲的物理页,包含一个指向下一个空闲页的指针。因为`kmem`只是一个指针数组,不是一个真正的内存区域,所以在初始化后,`kmem`数组中存储的数据并不是0。
相关问题
7. [40%] 阅读xv6中的kalloc.c文件,回答以下问题 - xv6中空闲页框是通过什么数据结构组织的(链表?位图?)[5%] - `kmem`全局变量中,为何有一个成员`lock`?如果没有这个成员会有何问题?[5%] - `kmem`这个全局变量,是在何时通过什么函数初始化的?初始化后,内存中大部分字节存储的数据是什么,是0吗?[10%] - 现在需要维护系统中的空闲页框数,你需要 - 在`kalloc.c`文件中定义一个全局变量`freeMemCnt`,记录空闲页框数; - 在分配和回收内存时维护这个全局变量; - 然后实现系统调用`int freemem(void)`查询这个变量的值; - 实现以下用户命令`free`,打印空闲页框数。
1. xv6中空闲页框是通过链表组织的,具体来说是一个单向链表。
2. `kmem`全局变量中,有一个成员`lock`是为了实现对于内存分配的原子性操作而存在的。如果没有这个成员,多个进程同时申请内存时可能会产生竞争条件,导致分配错误或者分配重复的问题。
3. `kmem`这个全局变量是在`kmain()`函数中通过`kinit() `函数初始化的。初始化后,内存中大部分字节存储的是空闲页框的信息,即每个页框对应一个`struct run`结构体,其中包含了指向下一个空闲页框的指针。
4. 在`kalloc.c`文件中定义一个全局变量`freeMemCnt`,并在`kinit()`函数中初始化为可用页框数。在分配和回收内存时,分别修改`freeMemCnt`的值。然后实现系统调用`int freemem(void)`查询这个变量的值,以及用户命令`free`,打印空闲页框数的实现如下:
```c
// kalloc.c
unsigned int freeMemCnt; // 全局变量记录空闲页框数
void kinit(void) {
// ...
freeMemCnt = nfreerange(); // 初始化为可用页框数
// ...
}
void *
kalloc(void)
{
// ...
if(r == 0)
return 0;
freeMemCnt--; // 修改空闲页框数
// ...
}
void
kfree(void *v)
{
// ...
freeMemCnt++; // 修改空闲页框数
// ...
}
// syscall.c
int sys_freemem(void) {
return freeMemCnt;
}
// console.c
void
consoleintr(int (*getc)(void))
{
// ...
if (strncmp(buf, "free", 4) == 0) {
printf("Free memory pages: %d\n", freemem());
continue;
}
// ...
}
```
需要注意的是,用户命令`free`的实现需要在`consoleintr()`函数中添加相应的处理逻辑。另外,需要在`syscall.h`中添加`sys_freemem()`函数的声明。
现在需要维护系统中的空闲页框数,你需要 - 在`kalloc.c`文件中定义一个全局变量`freeMemCnt`,记录空闲页框数; - 在分配和回收内存时维护这个全局变量; - 然后实现系统调用`int freemem(void)`查询这个变量的值; - 实现以下用户命令`free`,打印空闲页框数
好的,这里是实现的步骤:
1. 在`kalloc.c`文件中定义一个全局变量`freeMemCnt`,记录空闲页框数:
```c
// kalloc.c
#include "defs.h"
#include "x86.h"
#include "memlayout.h"
#include "mmu.h"
#include "param.h"
#include "spinlock.h"
// 添加全局变量
int freeMemCnt = 0;
// ...
```
2. 在分配和回收内存时维护这个全局变量:
```c
// kalloc.c
#include "defs.h"
#include "x86.h"
#include "memlayout.h"
#include "mmu.h"
#include "param.h"
#include "spinlock.h"
// 添加全局变量
int freeMemCnt = 0;
// ...
// 分配一页内存
char *
kalloc(void)
{
struct run *r;
acquire(&kmem.lock);
r = kmem.freelist;
if (r)
kmem.freelist = r->next;
// 维护 freeMemCnt
if (r)
freeMemCnt--;
release(&kmem.lock);
return (char*)r;
}
// 释放一页内存
void
kfree(char *v)
{
struct run *r = (struct run*)v;
acquire(&kmem.lock);
r->next = kmem.freelist;
kmem.freelist = r;
// 维护 freeMemCnt
freeMemCnt++;
release(&kmem.lock);
}
// ...
```
3. 实现系统调用`int freemem(void)`查询这个变量的值:
```c
// sysproc.c
#include "defs.h"
#include "param.h"
#include "proc.h"
#include "syscall.h"
extern int freeMemCnt;
// 实现系统调用
int
sys_freemem(void)
{
// 直接返回 freeMemCnt
return freeMemCnt;
}
```
4. 实现以下用户命令`free`,打印空闲页框数:
```c
// user/sh.c
#include "user.h"
int
main(int argc, char *argv[])
{
int freeMemCnt;
if ((freeMemCnt = freemem()) < 0) {
printf("freemem() failed!\n");
exit();
}
printf("%d free page frame(s)\n", freeMemCnt);
exit();
}
```
这样就实现了维护系统中的空闲页框数,并且可以通过`freemem()`系统调用查询空闲页框数,通过`free`命令打印空闲页框数。
阅读全文