У меня есть приложение пользовательского пространства, которое я использую для записи в регистры устройства pci. В качестве аргумента он принимает базовый адрес памяти устройства. Вместо того, чтобы искать это через lspci
на каждой платформе я хотел написать сценарий bash, чтобы использовать идентификаторы поставщика / устройства для поиска базового адреса и вместо этого вызова приложения.
В качестве примера возьмем сетевой контроллер Intel с идентификатором устройства «0891». Это на коробке Ubuntu, но мне нужно, чтобы она работала в разных дистрибутивах Linux.
Я подумал о том, чтобы просто разобрать вывод lspci
примерно так:
lspci -vn | grep -A 3 0891 | grep Memory | awk '{print $3}'
который производит:
f0500000
Но мне интересно получить базовый адрес откуда-нибудь в файловой системе, а не полагаться на другое приложение, поэтому я попробовал:
cat /proc/bus/pci/devices | grep 0891 | awk '{print $4}'
Это производит:
f0500004
Почему второе значение смещено на 4 байта?
Дополнительный вопрос: где я могу получить адреса базовой памяти устройства PCI, которые будут работать в разных дистрибутивах, не полагаясь на другие приложения, такие как lspci?
Из того, что я могу определить, формат 0x ???? 0004 передает некоторую дополнительную информацию. Бит 2 указывает, что BAR - это 1 = 64-битный, 0 = 32-битный адрес, бит 3 указывает, что область памяти 1 = с возможностью предварительной выборки, 0 = без предварительной выборки.