Есть ли ограничение размера для модуля ядра в Linux?
У меня проблема с загрузкой модуля ядра, существует большая структура данных, размером около 2 ГБ памяти - могу ли я предварительно выделить таблицу (чтобы она отображалась в.bss, когда я делаю size -A module.ko
или попытаться vmalloc()
во время загрузки загрузка модуля завершается с insmod: error inserting 'module.ko': -1 Cannot allocate memory
,
Я попытался отладить проблему в Linux пользовательского режима, но я получаю кучу ошибок (это может быть продолжено в GDB, но в итоге появляется сообщение консоли overflow in relocation type 10 val <value in the ball park of 6G>
а также 'module' likely not compiled with -mcmodel=kernel
, Я предполагаю, что с Kbuild
-mcmodel
должно быть правильно, верно?
Итак, вопросы:
- Существует ли общий предел 2G для размера модуля ядра Linux?
- Существует ли определенный предел 2G для модулей ядра в usernode linux (я думаю, что в прошлом я замечал, что большому модулю ядра нужен чистый, непрерывный блок памяти...)
- Могу ли я указать
-mcmodel=large
для модуля ядра и ожидать, что он будет работать?
Я пробовал это на Debian Squeeze, 64-битной, 2.6.32-5-amd64 (хост) с 8Gb памяти и 2.6.32 в uml с 4G памятью, так что это не должно быть обычной проблемой нехватки памяти.
Дополнительный кредит для работы вокруг лимита, если такой лимит существует:)
3 ответа
Если я определю таблицу как static
- загрузка модуля действительно не удастся - это, вероятно, из-за лимита 1,5G, упомянутого в ответе Andrew Aylett
Тем не менее, если я делаю динамический vmalloc()
звонки, я смог получить до 7680 МБ на хосте с 8 ГБ памяти (пока ядро не убило какой-то важный процесс, и мой X не завис).
Итак, чтобы ответить на мои вопросы:
- Да, но только для данных, которые компилируются как
static
- Не похоже на это.
- Там нет необходимости делать это.
Дополнительный кредит: просто сделай vmalloc()
Это работает только в ядрах Linux, более новых, чем 2.6.10 - до этого vmalloc()
Лимит был 64 Мб.
Что касается вашего первого вопроса - ограничение на сам модуль составляет 64 мегабайта. Загрузчик модулей отклонит загрузку модуля, который превышает этот размер. Из ядра / module.c:
if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
return ERR_PTR(-ENOMEM);
Это верно как для 2.6.32, так и для более новых ядер, вплоть до 3.3.
РЕДАКТИРОВАТЬ: В версии ядра 3.4 ограничение 64 МБ было удалено. Теперь фактический лимит зависит только от того, сколько памяти vmalloc()
можно выделить.
Помните, что память пространства ядра отличается от памяти пространства пользователя - в 32-битном Linux ядро имеет только адресное пространство 1 Гб. В 64-битном Linux ядро содержит больше адресного пространства для ядра, но в документации по ядру говорится, что для модулей доступно только 1536 МБ.