简体   繁体   English

如何以编程方式获取Linux内核页面大小

[英]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: 我正在看的选项:

  • Reading some file in /proc? 在/ proc中读取一些文件?
  • syscall? 系统调用?
  • Other function that let me calculate the PAGE_SIZE by inference (eg ORDER, getpageshift, etc)? 让我通过推理计算PAGE_SIZE的其他函数(例如ORDER,getpageshift等)?
  • Other? 其他?

尝试使用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: 这就是我最终做的:

  • Re-work my current module to take a new module parameter called page_shift and used that to calculate the PAGE_SIZE (PAGE_SIZE = 1 << PAGE_SHIFT) 重新处理我当前的模块以获取一个名为page_shift的新模块参数,并使用它来计算PAGE_SIZE (PAGE_SIZE = 1 << PAGE_SHIFT)
  • Created a module loader wrapper which gets the current system PAGE_SHIFT using getconf API from libc. 创建了一个模块加载器包装器,它使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM