OS开发中的内存管理

时间:2015-06-25 08:43:23

标签: c memory-management operating-system

我不确定这个问题是否是主题(如果不是,我道歉),但我想知道在创建操作系统时如何完成内存管理。我的理解是:

  • 操作系统提供内存管理。
  • 任何编程语言(在汇编之上,例如C)都需要已管理的内存(用于堆栈帧和堆分配)。

这听起来像是矛盾的。如果编写内存管理器的工具首先需要内存管理器,那么如何编写内存管理器?必须在组装中完成吗?

2 个答案:

答案 0 :(得分:2)

C不需要托管内存。您可能正在考虑malloc库函数,但这只是一个函数(虽然标准化可用于用户程序)。

易于实现的内存分配方案如下:

char * free_space;
void * kmalloc(size_t s) {
  char * block = free_space;
  free_space += s;
  return block;
}
// free not possible

必须在初始化期间将指针free_space设置为已知空闲内存区域的开头。这可以由引导加载程序通过多重引导信息给出。

在我很久以前写过的this code for a kernel中可以找到一个更复杂的例子。

通常,内存管理分为多个阶段:

在初始化期间,像上面那样的简单方案有助于建立一个比我写的更复杂的分配器。

此分配器仅提供固定大小的块(通常为4Kb,有时也是此大小的倍数)。

当内存池被填满时,从更高级别的分配器请求这些块。此分配器是您通常通过malloc呼叫的分配器。一个突出的例子是Doug Lea的dlmalloc。

关于堆栈:编译的代码执行堆栈指针的递增和递减。但显然它必须先设置为一些可用的空间。对于内核,在初始化期间,您通常将其设置为您知道的空闲内存,例如二进制文件的一部分。这是在汇编中完成的:

lea esp, kstack
; ...
call startup_kernel
; ...
[SECTION .bss]
resb 32768
kstack:

Startup code in assembly from the aforementioned kernel

对于稍后的进程,使用内核分配器分配一个或多个帧,并将堆栈设置为指向它的结束(如果堆栈递减)。来自another kernel的这个示例显示了为新进程设置堆栈所做的工作(这高度依赖于实际的内核/任务切换代码)。 (在这种情况下,没有动态分配的内存,因为它在嵌入式场景中使用)。

答案 1 :(得分:0)

操作系统需要为自身(内核)和用户管理内存。

您似乎在询问用户内存管理。这是通过管理分配给流程的页面来完成的。通过分配页面进程来管理堆栈。

堆内存管理(如malloc)分两部分完成。对于操作系统,内核提供系统服务以将页面映射到进程。其次,库管理在这些页面中创建的一个或多个内存池。