То, что вы просите, называется DMA. Вам необходимо написать драйвер, чтобы зарезервировать эту память.
Да, я понимаю, что вы сказали, что не хотите вмешиваться ОС, и драйвер становится частью ОС, но в отсутствие резервирования драйвера ядро считает, что вся память принадлежит ему. (Если вы не скажете ядру игнорировать блок памяти, согласно ответу Аарона, то есть.)
Глава 15 (PDF) « Драйверов устройств Linux, 3 / e » Рубини, Корбета и Кроа-Хартманна посвящена DMA и смежным темам.
Если вам нужна HTML-версия этого, я нашел версию второго издания этой главы в Интернете. Помните, что 2-й редакции уже более десяти лет, она вышла, когда появилось новое ядро 2.4. С тех пор была проделана большая работа над подсистемой управления памятью ядра, поэтому она может не очень хорошо применяться.
Если вы хотите, чтобы ОС полностью игнорировала это, вам нужно сделать дыру в памяти, используя «
memmap
.» Смотрите эту ссылку . Например, если вы хотите 512M на барьере 2 ГБ, вы можете поставить "memmap=512M$2G
" в командной строке вашего ядра.Вам нужно будет проверить,
dmesg
чтобы найти непрерывное отверстие для кражи, чтобы не топать ни на каких устройствах; это зависит от вашей материнской платы + карты.Это не рекомендуемый способ сделать что-то - см. Ответ Уоррена Янга о том, как правильно это сделать (драйверы ядра + DMA). Я отвечаю на тот вопрос, который вы задали. Если вы планируете сделать это для конечных пользователей, они будут ненавидеть вас, если вы сделаете это с ними ... поверьте мне, это единственная причина, по которой я знал этот ответ.
Изменить: Если вы используете grub2 w / grubby (например, CentOS 7), вам необходимо убедиться, что вы не используете $ . Там должно быть сингл
\
раньше$
. Пример:источник
uint8_t *ptr = 0x8000000
" с моим примером? Или это может вызвать ошибку ... Да, я действительно не знаю. Опять же, я знал ответ, потому что я был конечным пользователем плохо спроектированной PCI-карты, где мне приходилось вручную выделять буфер ниже отметки 4G, а затем сообщать драйверу, где находится это пространство; это может быть невозможно из пользовательского пространства.MMAP_FIXED | MMAP_ANON
. Без собственного устройства DMA, с которым я могу играть, я не могу сказать, действительно ли оно выполняет то, что хотел OP, но мой процессор CentOS с радостью дал мне блок 8 МБ при 512 МБ, когда я сказалmemmap=8M$512M
в GRUB. Это даже не требует root-доступа, как я и опасался. Но даже если это делает правильно, я все же думаю, что вам, вероятно, понадобится драйвер для обработки прерываний и тому подобное.mmap()
страницы будут обнулены до того, как код пользователя увидит их. Это сделано для безопасности, чтобы данные не передавались из одного процесса в другой. Еще одна причина использовать драйвер, поскольку вам может потребоваться сохранить содержимое буфера DMA во время загрузки драйвера. И, кстати, произвольно расположенныйmmap()
вызов завершается успешно даже безmemmap
опции загрузки ядра, по крайней мере, до тех пор, пока никто не использует память, расположенную там, где вы просили. Вариант загрузки, несомненно, увеличивает шансы на успех, но это не является строго необходимым.Чтобы зарезервировать блок памяти из ядра в Linux на основе ARM, вы также можете использовать
reserved-memory
узел в файле дерева устройств (dts). В документации ядра (см. Здесь ) есть пример:источник
Сначала введите эту команду, чтобы проверить текущие настройки:
Чтобы изменить установленное значение, отредактируйте
/etc/sysctl.conf
. Ищите строку:Если он не существует, создайте его (вместе с желаемым значением). Допустимы следующие значения:
8М чрезвычайно консервативен; это может сидеть в 16M удобно. Как только вы измените значение, запустите это, и перезагрузка не требуется:
источник