【问题标题】:Dynamic Memory Allocation in Real Mode Operating System实模式操作系统中的动态内存分配
【发布时间】:2020-01-19 16:15:07
【问题描述】:

我正在构建一个实模式操作系统作为一个爱好项目。作为我的第一个操作系统项目,我想从头开始,因此选择构建实模式操作系统。话虽如此,我并没有特别关注任何操作系统,但有很多来源的想法。我认为更多的实模式是一种暂存模式,在给定硬件的情况下,软件可以是任何东西,几乎不需要处理器的干预。

解决这个问题,我正在构建一个类似alloc() 的系统调用,用户程序可以在他们需要更多内存时调用它。我知道像brk() 这样的系统调用会更容易实现,但无论如何都会有malloc()

此操作系统中的用户程序将是一个简单的 COM 文件,没有头文件,并且静态分配了数据和代码。然而,动态分配的内存将驻留在代码和堆栈段之后。

A、AE、B、BE、C、CE 是内存模型中的地址。请注意,需要这样的内存安排才能符合 SMALL 内存模型(因为大多数编译器都假定这样的模型)。

现在有了一些上下文,我计划通过下面的表格来实现动态内存分配。

偏移量”列是在“C”地址之后分配内存的开始。当请求更多内存时,操作系统将通过任一方式分配内存

  • 从当前空闲的表中找到一个或多个连续的足够大的块或
  • 在表中最后一个条目的“偏移 + 大小”位置分配更多内存。

因此,free() 系统调用将在完成时释放一个或多个 a 块。

我的问题是:

  1. 这样的动态内存分配模型是否可行?为什么不使用这样的模型?
  2. 这样的系统调用 allocfree 是否应该在库中而不是系统调用中更好?

【问题讨论】:

  • "但是动态分配的内存将驻留在代码和堆栈段之后。"请确认我的理解: CCE 之间的 1KB 内存中的分配表吗?这个表有多少条记录? Size 是用什么衡量的?是字节吗?块是什么意思?
  • @SepRoland 分配表将驻留在别处。在“进程”表中说 - 每个进程一个。大小以字节为单位。块是表中的行。如果我们想要 105 个字节,OS 将从 CE+17(第 3 行和第 4 行)开始分配 110 个字节(然后将它们标记为已使用)。这就是为什么我们有 Blocks = 2。在释放时,操作系统会将这两行都标记为 FREE。
  • IMO 您的表格不应包含 2 个或更多标记为 FREE 的相邻行。如果要释放的内存直接高于或低于另一个空闲内存,则 free() 系统调用应立即合并。只需将较低的行向上移动并保持 TotalRowsCount。这样你分配 105 个字节的例子会变得更简单。

标签: x86 x86-16 osdev real-mode


【解决方案1】:

这样的动态内存分配模型是否可行?为什么不使用这样的模型?

谁说这样的内存模型是不是不用呢?我创建的 BASIC 编程语言使用类似的东西来引用字符串和数组。您表中的 rows 对应于我的 BASIC 中的 StringDescriptors。

这样的系统调用allocfree 应该在库中而不是系统调用中更好吗?

个人喜好问题,但由于内存分配是如此基础,它认为它大部分属于内核。然后可能是使用int 指令的系统调用...

偏移量、大小、状态和块。

这些是您选择放入分配表的内容。您放入的所有内容也需要更新。当有冗余信息时,这是很多额外的工作。您可以删除 Size 信息,因为您可以通过减去两个相邻的指针来获得它。
您也可以不使用 Blocks 信息,因为它总是 1 if free() 在免费块聚集在一起时立即合并。

CE+0,   USED     ; Size is 7 == (CE+7) - (CE+0)
CE+7,   USED     ; Size is 10 == (CE+17) - (CE+7)
CE+17,  FREE     ; Size is 110 == (CE+127) - (CE+17)
CE+127, USED     ; Size is 40 == (CE+167) - (CE+127)
CE+167, EOL      ; TotalRowsCount = 5

新分配105字节:

CE+0,   USED     ; Size is 7 == (CE+7) - (CE+0)
CE+7,   USED     ; Size is 10 == (CE+17) - (CE+7)
CE+17,  USED     ; Size is 105 == (CE+122) - (CE+17)
CE+122, FREE     ; Size is 5 == (CE+127) - (CE+122)
CE+127, USED     ; Size is 40 == (CE+167) - (CE+127)
CE+167, EOL      ; TotalRowsCount = 6

释放 40 字节分配:

CE+0,   USED     ; Size is 7 == (CE+7) - (CE+0)
CE+7,   USED     ; Size is 10 == (CE+17) - (CE+7)
CE+17,  USED     ; Size is 105 == (CE+122) - (CE+17)
CE+122, FREE     ; Size is 45 == (CE+167) - (CE+122)
CE+167, EOL      ; TotalRowsCount = 5

【讨论】:

  • 感谢您的回复。我实际上是在使用 Blocks 列合并空闲的连续空间。但是我知道,如果我进行了适当的整合,我可以根据要求分配确切的空间,并将剩余的可用空间保留在另一个新块中。但为了简单起见,我采取了这种方式 - 找到最大的连续空闲块并分配它们(至少在基础上)
猜你喜欢
  • 2016-08-06
  • 1970-01-01
  • 2017-07-11
  • 2021-10-16
  • 2012-10-29
  • 1970-01-01
  • 2016-10-21
  • 2018-08-15
  • 1970-01-01
相关资源
最近更新 更多