奇怪的返回类型__get_free_pages

时间:2015-02-24 16:12:27

标签: kernel

为什么它返回unsigned long?为什么不用void *或char *?

unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)

我想它会返回一个地址,还是我完全误解了这个功能?

2 个答案:

答案 0 :(得分:1)

您更正,它返回分配的第一页的第一个字节的内存地址。 page_address()内部使用的__get_free_pages()实际上返回void*的有趣内容。

这样做的原因可以在LDD3, chapter 11 (PDF)中找到:

  

虽然在混合使用不同数据类型时必须小心,但有时候有充分的理由这样做。一种这样的情况是针对内存地址,就内核而言,它们是特殊的。虽然从概念上讲,地址是指针,但通常使用无符号整数类型可以更好地完成内存管理。内核将物理内存视为一个巨大的数组,而内存地址只是数组的索引。此外,指针很容易被解除引用;当直接处理内存地址时,你几乎从不想要取消引用它们   这种方式。使用整数类型可防止此解除引用,从而避免错误。因此,内核中的通用内存地址通常是无符号长的,利用了指针和长整数总是相同的事实,至少在Linux当前支持的所有平台上都是如此。

答案 1 :(得分:1)

“从内存管理的角度来看,系统的RAM可以看作是一个线性的页面数组,因此将地址视为整数类型可以有一定的意义 - 基本上是对数组的索引。整数也可以用于任意算术; C中的指针也可以这样使用,但是很快会进入“未定义的行为”领域,过度热情的编译器可能觉得有权创建各种混乱。所以unsigned long建立为来自get_free_page()的返回类型,通常也就是一个引用可能出现在内存中任何位置的地址的方式。“ - 来自https://lwn.net/Articles/669015/ - 请阅读这篇关于unsigned long与void *的有趣故事: - )