47

我正在为 IA64 开发一个 Linux 模块。我当前的问题是驱动程序使用 PAGE_SIZE 和 PAGE_SHIFT 宏进行 dma 页面分配。我遇到的问题是编译驱动程序的机器不是运行驱动程序所需的机器。因此,如果编译机器上的 PAGE_SIZE 为 2^14K,而目标机器为 2^16K,则驱动程序失败。

我不想把这个问题变成关于在不是运行模块的机器上编译模块的“最佳实践”问题。我理解这方面的问题。我发现人们大多使用 getpagesize() 或 sysconf(_SC_PAGE_SIZE)。这两个选项不在 ia64 内核头文件中,所以我不能使用它们。有没有另一种方法可以让我获得运行时 PAGE_SIZE?

我正在查看的选项:

  • 在 /proc 中读取一些文件?
  • 系统调用?
  • 让我通过推理计算 PAGE_SIZE 的其他函数(例如 ORDER、getpageshift 等)?
  • 其他?
4

7 回答 7

69

尝试使用该getconf实用程序,它可以让您轻松检索页面大小。

getconf PAGESIZE
于 2012-10-01T11:02:16.137 回答
19

一种近似的方法是读取/proc/meminfo并检查Mapped大小(截至目前我的 52544 kB)然后签nr_mapped/proc/vmstat(截至目前我的 131136)。最后PAGE_SIZE = Mapped/nr_mapped。有时这会给你一个准确的值(如我引用的当前示例),有时它是近似值但非常接近。希望这可以帮助!

于 2011-06-07T07:12:01.540 回答
10

查找页面大小的一种方法是从进程的 smap 中获取它。

例如:

cd /proc/1
grep -i pagesize smaps

KernelPageSize:        4 kB
MMUPageSize:           4 kB
于 2018-02-28T12:52:33.003 回答
7

如果您正在尝试构建内核模块,则至少需要为该模块将在其上运行的内核配置的内核头文件。这些将定义您需要的页面大小宏。如果您没有正确配置的头文件,内核将拒绝加载您的模块。

在一台机器上编译模块以在另一台机器上运行并没有错,即使它是不同的架构。您只需要针对正确的内核源代码进行构建。

于 2011-02-09T22:41:01.847 回答
5

这就是我最终所做的:

  • 重新设计我当前的模块以获取一个名为 page_shift 的新模块参数,并使用它来计算PAGE_SIZE (PAGE_SIZE = 1 << PAGE_SHIFT)
  • PAGE_SHIFT创建了一个模块加载器包装器,它使用getconf来自 libc 的 API获取当前系统。此包装器获取当前系统页面移位并将其作为模块参数传递。

现在,该模块正在以不同的 PAGE_SIZE 加载到不同的架构上,没有任何问题。

于 2011-08-03T19:44:01.797 回答
0

我担心这是不可能的,因为页面大小是内核的一部分。如果您还使用工具链来编译内核模块,则需要了解页面大小。

所以至少在当前的内核架构下,这是不可能的。

于 2011-05-10T05:15:42.930 回答
0

您可以只运行一个测试,只需 mmap 具有不同偏移量的文件并查看哪个失败。虽然在内核模块中可能很烦人,但也许还有其他类似的测试可以使用。

于 2014-02-03T12:32:07.903 回答