Как можно использовать параметр ядра memmap?

Для новичков как вообще в Linux, так и в конкретной теме, к которой относится вопрос.

Модератор: Bizdelnick

Ответить
MiK13
Сообщения: 1164
ОС: Linux Debian

Как можно использовать параметр ядра memmap?

Сообщение MiK13 »

Компьютер типа Zynq-7000. Процессор Cortex-a9, архитектура ARMv7.
Так как пока не разобрался, как сделать модуль, через который можно было бы принимать данные по DMA (модуль загружается, но /dev/axidma не появляется. Как отладить, не знаю. Может быть надо что-то ещё указать?), решил попробовать запустить прямой доступ напрямую, обращаясь к регистрам контроллера через /dev/mem. Но для этого надо знать физический адрес памяти.
Нашёл в Справочнике по параметрам ядра параметр memmap
memmap=nn[KMG]$ss[KMG] [KNL,ACPI]
Помечает определенную память как зарезервированную. Регион памяти помечается от ss до ss+nn. Пример: исключить память 0x18690000-0x1869ffff
memmap=64K$0x18690000
или
memmap=0x10000$0x18690000
Некоторые загрузчики (bootloaders) могут нуждаться в escape-символе перед '$', наподобие Grub2, иначе '$' и последующее число будет съедено.
Предположил, что Linux после загрузки не будет использовать указанную память.
Установил (точнее, модифицировал) строку параметров ядра:
console=ttyPS0,115200 earlyprintk memmap=0x80M$0x20000000 root=/dev/mmcblk0p2 rw rootwait
думая, что линукс не будет распределять 128 МиБ памяти через malloc.
Но с помощью тестов убедился, что это не так. Память, распределяемая через malloc, выделяется и в этой части.
Поэтому и возник вопрос. Для каких целей может быть использован этот параметр?
Может быть можно как-то иначе создать зарезервированный участок с известным физическим адресом?
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2600
ОС: Gentoo

Re: Как можно использовать параметр ядра memmap?

Сообщение ormorph »

MiK13 писал:
19.01.2022 19:06
Для каких целей может быть использован этот параметр?
Ну так по моему очевидно, оно относится к файлу /dev/mem, в данном случае нельзя будет добраться к зарезервированной памяти через файл /dev/mem.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как можно использовать параметр ядра memmap?

Сообщение Bizdelnick »

MiK13 писал:
19.01.2022 19:06
думая, что линукс не будет распределять 128 МиБ памяти через malloc
Какое отношение malloc имеет к linux?
MiK13 писал:
19.01.2022 19:06
Но с помощью тестов убедился, что это не так. Память, распределяемая через malloc, выделяется и в этой части.
Каких тестов?

Я ничего не понял.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2600
ОС: Gentoo

Re: Как можно использовать параметр ядра memmap?

Сообщение ormorph »

Мне больше интересно как можно обратиться к регистрам контроллера через /dev/mem.
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как можно использовать параметр ядра memmap?

Сообщение MiK13 »

ormorph писал(а):
19.01.2022 21:14
Мне больше интересно как можно обратиться к регистрам контроллера через /dev/mem.
Как обратиться к регистрам контроллера DMA пока не знаю. Так как пока не знаю ни их адресов, ни их состава.
Но вот пример работы с GPIO
tgpio3.tgz
(1.29 КБ) 13 скачиваний
Сначала проверил работу с выводами GPIO через файлы в каталоге /sys, но это оказалось очень медленно.
В этом примере файл /dev/mem отображается в память через mmap и выдача значений на выводы GPIO выполняется путём записи в соответствующие элементы отображённого массива.
В man mem написано
Byte addresses in /dev/mem are interpreted as physical memory addresses. References to nonexistent locations cause errors to be returned.
Значит если регистры контроллера DMA будут иметь аналогичные адреса, то к ним должен быть доступ через /dev/mem.
Ну, а если они будут как порты ввода-вывода, то к ним доступ должен быть через /dev/port
ormorph писал(а):
19.01.2022 19:48
MiK13 писал:
19.01.2022 19:06
Для каких целей может быть использован этот параметр?
Ну так по моему очевидно, оно относится к файлу /dev/mem, в данном случае нельзя будет добраться к зарезервированной памяти через файл /dev/mem.
Для меня это не очевидно.
Так как в man mem написано, что
Адреса байтов в /dev/mem интерпретируются как адреса физической памяти.
я предполагаю, что параметр memmap никак не должен влиять на файл /dev/mem. Он должен влиять на то, как ядро будет распределять память.
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2600
ОС: Gentoo

Re: Как можно использовать параметр ядра memmap?

Сообщение ormorph »

MiK13 писал:
20.01.2022 12:25
Для меня это не очевидно.
Ну это можно проверить, просто зарезервировать адреса и после этого попробовать их считать или записать на них через /dev/mem, если ошибка будет отсутствовать, то это не влияет на /dev/mem.
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как можно использовать параметр ядра memmap?

Сообщение MiK13 »

ormorph писал(а):
20.01.2022 14:13
MiK13 писал:
20.01.2022 12:25
Для меня это не очевидно.
Ну это можно проверить, просто зарезервировать адреса и после этого попробовать их считать или записать на них через /dev/mem, если ошибка будет отсутствовать, то это не влияет на /dev/mem.
Так вот и возникает вопрос как зарезервировать адреса, чтобы Linux их не трогал.
Я в строку для ядра добавил параметр memmap=0x80M$0x20000000, который, по идее, должен был зарезервировать место в 0x80M байт (128 МиБ) начиная с адреса 0x20000000. То есть половина общей памяти в 1 ГБ
Правда, free такого уменьшения не показал.
Я написал три простые программы.
1. Через /dev/mem записывает, начиная с адреса 0x20000000, последовательность из 32M int чисел.
2. Проверяет, также через /dev/mem, не изменились ли в ней данные
3. while(malloc(1024*1024*32)) выделяет области памяти и записывает другие данные
Программой 2 проверяю содержимое памяти, записанное программой 1. После определённого числа записей содержимое "зарезервированной" области искажается.
Сейчас попробую посмотреть, что в файле /proc/meminfo и /proc/iomem
Может быть имеет смысл попытаться ограничить общую память через параметр mem=768M и попробовать использовать старшие 256 МиБ.
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как можно использовать параметр ядра memmap?

Сообщение MiK13 »

MiK13 писал:
20.01.2022 15:44
Может быть имеет смысл попытаться ограничить общую память через параметр mem=768M и попробовать использовать старшие 256 МиБ.
Попробовал. И обнаружил интересный эффект.

Shell

root@Zynq:/proc# head -n3 iomem
00000000-2fffffff : System RAM
00008000-008fffff : Kernel code
00a00000-00a62243 : Kernel data
Первая строчка была 00000000-3fffffff : System RAM
То есть параметр сработал. Но.
Программа, которая заполняет память 32M интов с адреса 0x20000000

Shell

root@Zynq:/run/media/mmcblk1p1/T# time ./fillmem_w
page_size = 4096 1000

real 0m0.832s
user 0m0.761s
sys 0m0.071s
Программа, которая заполняет память 32M интов с адреса 0x30000000 (за пределами, выделенными ядру)

Shell

root@Zynq:/dev/shm# time ./fillmem_w
page_size = 4096 1000

real 0m3.028s
user 0m2.988s
sys 0m0.040s
Время работы программы почему-то увеличилось почти в 4 раза
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2600
ОС: Gentoo

Re: Как можно использовать параметр ядра memmap?

Сообщение ormorph »

Если читать описание, то некоторым загрузчикам ещё требуется escape символ:

Код: Выделить всё

memmap=80M\$0x20000000
так как загрузчик может использовать символ $ для переменных или ещё чего.
Спасибо сказали:
MiK13
Сообщения: 1164
ОС: Linux Debian

Re: Как можно использовать параметр ядра memmap?

Сообщение MiK13 »

ormorph писал(а):
20.01.2022 16:24
Если читать описание, то некоторым загрузчикам ещё требуется escape символ:

Код: Выделить всё

memmap=80M\$0x20000000
так как загрузчик может использовать символ $ для переменных или ещё чего.
Да, я думал об этом. Правда, не был уверен, что в качестве escape знака подходит именно обратная черта.
Сейчас собрал систему с этим знаков. Проверил. Но ничего не изменилось

Shell

root@Zynq:/proc# cat cmdline iomem
console=ttyPS0,115200 earlyprintk memmap=0x80M\$0x20000000 root=/dev/mmcblk0p2 rw rootwait
00000000-3fffffff : System RAM
00008000-008fffff : Kernel code
00a00000-00a62243 : Kernel data
40400000-4040ffff : /amba_pl/dma@40400000
e0000000-e0000fff : xuartps
e0001000-e0001fff : xuartps
e0002000-e0002fff : /amba/usb@e0002000
e0004000-e0004fff : /amba/i2c@e0004000
e0005000-e0005fff : /amba/i2c@e0005000
e0006000-e0006fff : /amba/spi@e0006000
e000a000-e000afff : /amba/gpio@e000a000
e000b000-e000bfff : /amba/ethernet@e000b000
e000d000-e000dfff : /amba/spi@e000d000
e0100000-e0100fff : /amba/sdhci@e0100000
e0101000-e0101fff : /amba/sdhci@e0101000
f8003000-f8003fff : /amba/dmac@f8003000
f8003000-f8003fff : /amba/dmac@f8003000
f8005000-f8005fff : /amba/watchdog@f8005000
f8007000-f80070ff : /amba/devcfg@f8007000
f8007100-f800711f : /amba/adc@f8007100
f800c000-f800cfff : /amba/ocmc@f800c000
fffc0000-ffffffff : f800c000.ocmc
Конечно оптимальным было бы разораться как работать с DMA.
Может быть и получится...
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2600
ОС: Gentoo

Re: Как можно использовать параметр ядра memmap?

Сообщение ormorph »

MiK13 писал:
20.01.2022 18:25
Конечно оптимальным было бы разораться как работать с DMA.
Было бы не плохо. Ну а метод доступа к GPIO через /dev/mem, меня заинтересовал. Потом дорвусь до своей rpi4 и попробую это использовать.
У вас надо смотреть спецификации на Zynq-7000, производитель это должен предоставлять, у меня на RPI4 их полно. Нужно смотреть что у вас за микроконтроллер(процессор) используется, по нему и смотреть документацию. Например в RPI4 используется BCM2711.
На ваш нашёл это, но там смотрю написано под их среду разработки, по этому с адресами не очень то хорошо. Смотрю там используется DMA контроллер PL330, можно по нему посмотреть документацию, может поможет.
Спасибо сказали:
Ответить