我正在尝试理解C如何为全局变量分配内存。
我正在研究一个简单的内核。到目前为止,除了打印到屏幕并启用中断之外,它不能做更多的事情。我现在正在研究基本的物理内存管理器。
我的内存管理器是一个位图,如果分配或可用内存,则设置1或0。我需要将我的内核使用的内存添加到位图中作为“已分配”,因此不会覆盖它。
我可以很容易地找到内核的开头,因为它静态加载到0x100000。弄清楚长度也不应该太困难。我不确定的部分是全局变量放在内存中的位置吗?
假设我的内核为12K,我可以将这些3x 4K内存块分配给它进行保护。我是否需要分配更多来覆盖它使用的变量?或者变量是那个12K的一部分?
感谢您的帮助,我希望我有足够的理解。
答案 0 :(得分:2)
答案 1 :(得分:1)
正如前面的回答所说,大多数变量都存储在.bss部分中,但它们也可以存储在.data或.rodata部分中,具体取决于您是将全局变量定义为static还是const。编译完成后,您可以使用readelf -S kernel.bin来确切了解每个部分将使用多少空间。对于.bss部分,仅当二进制文件加载到内存中并且不占用磁盘空间时才占用内存。这意味着您编译的内核二进制文件将小于以后在进入内存时使用的实际大小(通常通过grub)。
除了使用readelf之外,确定内核将使用多少数据的简单方法是将.bss部分放在链接描述文件中的.data部分中。然后内核二进制文件的大小在磁盘上和内存中都是相同的大小(实际上它在内存中会有点小,因为不是所有的部分都被grub复制)但是至少你知道你的最小内存量需要分配。
答案 2 :(得分:0)
我建议使用自定义链接描述文件(假设您使用gcc
):它使内核部分的布局显式且可自定义(要阅读有关链接器脚本的更多信息,请阅读info ld
)。您可以看到我的操作系统链接描述文件here的示例。
要查看默认链接描述文件,请使用-v
的{{1}} / --verbose
选项。
大多数全局变量位于ld
和.data.*
部分,使用0初始化的变量进入.rodata.*
。