2011-02-03 3 views
30

Я работаю над модулем Linux для IA64. Моя текущая проблема заключается в том, что драйвер использует макросы PAGE_SIZE и PAGE_SHIFT для распределения страниц dma. Проблема, с которой я столкнулась, заключается в том, что машина, компилирующая драйвер, не те, которые необходимы для запуска драйвера. Итак, если PAGE_SIZE на компиляторе составляет 2^14K, а машина назначения - 2^16K, тогда драйвер не работает.Как получить размер страницы ядра linux программно

Я не хочу превращать этот вопрос в вопрос «лучшей практики» о компиляции модулей на машинах, которые не являются модулями. Я понимаю вопросы об этом. Я обнаружил, что люди в основном используют getpagesize() или sysconf (_SC_PAGE_SIZE). Эти два варианта находятся вне заголовков ядра iia64, поэтому я не могу их использовать. Есть ли другой способ, которым я мог бы получить время выполнения PAGE_SIZE?

Варианты Я смотрю на:

  • Чтение какой-либо файл в/Proc?
  • syscall?
  • Другие функции, которые позволяют мне рассчитать PAGE_SIZE путем вывода (например, ORDER, getpageshift и т. Д.)?
  • Другое?
+0

ты говоришь о 'PAGE_SIZE' настраивается для архитектуры IA64, а не фиксировано? Я думал, что PAGE_SIZE был исправлен для данной архитектуры (например, всегда '4096' для x86). –

+0

IA64 действительно поддерживает несколько размеров страниц: http://www.informit.com/articles/article.aspx?p=29961&seqNum=3 – mdiener

ответ

5

Это то, что я наконец-то:

  • переделывает мой текущий модуль, чтобы принять новый параметр, называемый PAGE_SHIFT и используется, что для вычисления PAGE_SIZE (PAGE_SIZE = 1 << PAGE_SHIFT)
  • Создан модуль загрузчика обертку, который получает ток система PAGE_SHIFT с использованием getconf API от libc. Эта оболочка получает текущий сдвиг системной страницы и передает ее в качестве параметра модуля.

В настоящее время модуль загружается на разные архитектуры с различными PAGE_SIZE без каких-либо проблем.

+0

Noob вопрос. Не могли бы вы объяснить немного больше об обертке, которая использует API getconf? Я имею в виду, вы вызвали команду getconf внутри функции popen() или что-то в этом роде. Немного больше света над ним будет оценено по достоинству. –

6

Если вы пытаетесь создать модуль ядра, вам понадобятся, по крайней мере, заголовки ядра, которые настроены для ядра, в котором будет работать модуль. Они будут определять макросы размера страницы, которые вам нужны. Если у вас нет правильно настроенных заголовков, ядро ​​откажется загружать ваш модуль.

И нет ничего плохого в том, чтобы скомпилировать модуль на одной машине для запуска на другом, даже если это другая архитектура. Вам просто нужно построить против правильного источника ядра.

+0

Это не проблема с источниками ядра. Речь идет о загрузке модуля, скомпилированного на машине, для запуска на другом компьютере (оба имеют одну и ту же версию ядра, но настроены по-разному). Я не хочу перекомпилировать новую конфигурацию, потому что PAGE_SIZE изменился. Я хочу получить этот параметр из ядра как API, а не как MACRO (который решается во время компиляции). – Freddy

+0

<< И нет ничего плохого в том, чтобы скомпилировать модуль на одной машине для запуска на другом, даже если это другая архитектура. Вам просто нужно построить против правильного источника ядра. ........... ТОЧНО ТОЧКА – kumar

+0

PAGE_SIZE является очень фундаментальным и требуется для модуля при построении самого модуля. – kumar

0

Я боюсь, что невозможно сделать, поскольку размер страницы - это что-то определенное как часть ядра. знание размера страницы требуется в случае инструментальной цепочки, которую вы используете для компиляции модуля ядра.

Так что, по крайней мере, с текущей архитектурой ядра, это невозможно сделать.

17

Один приближенный метод должен прочитать /proc/meminfo и проверить Mapped размер (на шахте его 52544 кБ как сейчас), а затем проверить nr_mapped в /proc/vmstat (на шахте его 131136, как сейчас). Наконец PAGE_SIZE = Mapped/nr_mapped. Иногда это дает вам точное значение (как в текущем примере, которое я цитировал), а иногда и приблизительное, но очень близкое. Надеюсь, это поможет!

42

Попробуйте использовать утилиту getconf, что позволит легко получить размер страницы.

getconf PAGESIZE 
+1

Я не думаю, что это отвечает на вопрос OP, но это полезно, так как sysconf (_SC_PAGESIZE) появляется, чтобы возвращать 4K на linuxia64 (пока mprotect не удается на странице, не выровненной на границе 16K). –

0

Вы можете просто запустить тест, просто mmap файл с различными смещениями и посмотрите, сбой. Может быть, раздражает в модуле ядра, хотя, возможно, есть и другие тесты, которые вы могли бы использовать.

1

Один из способов найти размер страницы - получить ее от smaps для процесса.

Например:

cd /proc/1 
cat smaps | grep -i pagesize 

KernelPageSize:  4 kB 
MMUPageSize:   4 kB 
Смежные вопросы