C 操作系统开发中的内存管理

C 操作系统开发中的内存管理,c,memory-management,operating-system,C,Memory Management,Operating System,我不确定这个问题是否与主题有关(如果不是,我很抱歉),但我想知道在创建操作系统时如何实现内存管理。我的理解是: 操作系统提供内存管理 任何编程语言(高于汇编语言,例如C)都需要已管理的内存(用于堆栈帧和堆分配) 这听起来有点矛盾。如果编写内存管理器的工具首先需要内存管理器,那么如何编写内存管理器呢?必须在程序集中完成吗?C不需要托管内存。您可能正在考虑malloc库函数,但这只是一个函数(尽管已标准化,可供用户程序使用) 易于实现的内存分配方案如下所示: char * free_space;

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

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

这听起来有点矛盾。如果编写内存管理器的工具首先需要内存管理器,那么如何编写内存管理器呢?必须在程序集中完成吗?

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

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

char * free_space;
void * kmalloc(size_t s) {
  char * block = free_space;
  free_space += s;
  return block;
}
// free not possible
在初始化到已知内存空闲区的开始时,必须设置指针
空闲空间
。这可能由引导加载程序通过multiboot信息给出

一个更复杂的例子是我很久以前写的

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

在初始化过程中,像上面这样的简单方案有助于设置像我写的那样更复杂的分配器

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

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

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

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


对于以后的进程,您可以使用内核内分配器分配一个或多个帧,并将堆栈设置为指向其末端(在堆栈递减的情况下)。来自的这个示例显示了如何为新进程设置堆栈(这在很大程度上取决于实际的内核/任务切换代码)。(在这种情况下,没有在嵌入式场景中使用的动态分配内存)。

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

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


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

我明白了!但是仍然-为了调用您的kmalloc函数,必须为函数的堆栈帧提供一个调用堆栈,对吗?编译后的函数是否使用(并管理)堆栈寄存器,以便操作系统基本上只需初始化堆栈段/指针寄存器?