[英]How to get linux kernel page size programmatically
I am working on a Linux module for IA64. 我正在为IA64开发Linux模块。 My current problem is that the driver uses the PAGE_SIZE and PAGE_SHIFT macros for dma page allocation.
我目前的问题是驱动程序使用PAGE_SIZE和PAGE_SHIFT宏进行dma页面分配。 The problem I am having is that the machine compiling the driver is not the ones that needed to run the driver.
我遇到的问题是编译驱动程序的机器不是需要运行驱动程序的机器。 So, if the PAGE_SIZE on the compiling machine is 2^14K and the destination machine is 2^16K then the driver fails.
因此,如果编译机器上的PAGE_SIZE为2 ^ 14K且目标机器为2 ^ 16K,则驱动程序将失败。
I don't want to turn this question into a 'best practice' issue about compiling modules on machines which are not the ones running the modules. 我不想把这个问题变成关于在不运行模块的机器上编译模块的“最佳实践”问题。 I understand the issues about that.
我理解这个问题。 What I found is that people mostly uses getpagesize() or sysconf(_SC_PAGE_SIZE).
我发现人们大多使用getpagesize()或sysconf(_SC_PAGE_SIZE)。 These two options are out of the ia64 kernel headers so I can't use them.
这两个选项不在ia64内核头文件中,因此我无法使用它们。 Is there another way that I could get the runtime PAGE_SIZE?
还有另一种方法可以获得运行时PAGE_SIZE吗?
Options I am looking at: 我正在看的选项:
尝试使用getconf
实用程序,它可以让您轻松检索页面大小。
getconf PAGESIZE
One approximate method is to read /proc/meminfo
and check Mapped
size ( on mine its 52544 kB as of now ) and then check nr_mapped
in /proc/vmstat
( on mine its 131136 as of now ). 一种近似方法是读取
/proc/meminfo
并检查Mapped
大小(目前我的52544 kB),然后检查/proc/vmstat
nr_mapped
(截至目前我的131136)。 Finally PAGE_SIZE = Mapped/nr_mapped
. 最后
PAGE_SIZE = Mapped/nr_mapped
。 Sometimes this gives you an accurate value ( as in the current example I've quoted ) and sometimes its approximate but very close. 有时候这会给你一个准确的值(就像我引用的当前例子中的那样),有时它的近似但非常接近。 Hope this helps!
希望这可以帮助!
If you are trying to build a kernel module, you will need to have at least the kernel headers that are configured for the kernel the module will run on. 如果您正在尝试构建内核模块,则至少需要具有为模块运行的内核配置的内核头文件。 Those will define the page size macros you need.
这些将定义您需要的页面大小宏。 If you don't have the correctly configured headers, the kernel will refuse to load your module.
如果您没有正确配置的标头,内核将拒绝加载您的模块。
And there is nothing wrong with compiling a module on one machine to run on another, even if it's a different architecture. 编译一台机器上的模块在另一台机器上运行没有任何问题,即使它是一个不同的架构。 You just need to build against the correct kernel source.
您只需要构建正确的内核源代码。
One way to find the page size is to obtain it from smaps for a process. 找到页面大小的一种方法是从一个进程的smaps中获取它。
For example: 例如:
cd /proc/1
grep -i pagesize smaps
KernelPageSize: 4 kB
MMUPageSize: 4 kB
This is what I finally did: 这就是我最终做的:
PAGE_SIZE (PAGE_SIZE = 1 << PAGE_SHIFT)
PAGE_SIZE (PAGE_SIZE = 1 << PAGE_SHIFT)
PAGE_SHIFT
using getconf
API from libc. getconf
API获取当前系统PAGE_SHIFT
。 This wrapper gets the current system page shift and pass it as a module parameter. Right now the module is being loaded on different architectures with different PAGE_SIZE without any problems. 现在,模块正在使用不同的PAGE_SIZE加载到不同的体系结构上而没有任何问题。
You could just run a test, just mmap a file with different offsets and see which fail. 你可以运行一个测试,只需mmap一个具有不同偏移的文件,看看哪个失败了。 Might be annoying in a kernel module though, but maybe there is some other test like that you could use.
可能在内核模块中很烦人,但也许还有其他一些你可以使用的测试。
I fear that it is impossible to do as page size is something defined as part of the kernel. 我担心这是不可能的,因为页面大小被定义为内核的一部分。 page size knowledge is required in case of toolchain also which you use to compile the kernel module.
如果还有用于编译内核模块的工具链,则需要页面大小知识。
So atleast with current kernel architecture, it is impossible to do so. 因此,至少使用当前的内核架构,这是不可能的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.