kmem中的freelist指针指向空闲物理块链表。空闲物理块链表中的节点为run结构体。但是: 可以看到这个结构体只有指向下一个节点的指针。请解释这个链表中的空闲物理块保存在哪里呢?
时间: 2024-03-26 15:36:40 浏览: 91
在内核启动时,会将物理内存按照一定的大小划分成多个块,每个块称为一页(page)。这些页面会被加入到一个物理页面的链表中,这个链表被称为空闲页面链表。
在Linux中,空闲页面链表的头指针被命名为“free_list”。每个节点是一个run结构体,该结构体只有一个指向下一个节点的指针。在这个链表中,每个节点实际上表示一个空闲页面,因此每个节点所占用的空间大小为一个页面的大小。
当系统需要分配内存时,会从空闲页面链表中取出一个页面,并将它从链表中移除。当系统释放内存时,会将该页面加入到空闲页面链表的头部。
因此,空闲物理块并没有单独保存在链表中,而是以页面的形式存在于物理内存中,并被加入到空闲页面链表中。
相关问题
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()`函数的声明。
[root@server1 ~]# cat /etc/group root:x:0: bin:x:1: daemon:x:2: sys:x:3: adm:x:4: tty:x:5: disk:x:6: lp:x:7: mem:x:8: kmem:x:9: wheel:x:10: cdrom:x:11: mail:x:12:postfix man:x:15: dialout:x:18: floppy:x:19: games:x:20: tape:x:33: video:x:39: ftp:x:50: lock:x:54: audio:x:63: nobody:x:99: users:x:100: utmp:x:22: utempter:x:35: input:x:999: systemd-journal:x:190: systemd-network:x:192: dbus:x:81: polkitd:x:998: ssh_keys:x:997: sshd:x:74: postdrop:x:90: postfix:x:89: chrony:x:996: saslauth:x:76: hue:x:1000: wf:x:1001: zjl:x:1002: mygroup:x:1003:
这是一个/etc/group文件的示例。该文件包含系统中所有组的列表,每行一个。每个组都有一个名称、一个密码(通常为空)、一个GID(组ID)和一个成员列表。
在这个示例中,可以看到root、bin、daemon、sys等系统组,这些组是由系统自动创建的。还有一些其他的组,比如wheel、users、audio等,这些组通常是由管理员创建的,用于组织和管理用户。
从最后几行可以看到,这个文件中还有一些自定义的组,比如hue、wf、zjl和mygroup。这些组是由管理员手动创建的,用于特定的目的。你可以使用`groupadd`命令来创建新组,使用`usermod`命令将用户添加到组中。
阅读全文