2016-12-24 1 views
0

У меня возникли проблемы с отображением физической памяти на Xilinx Zynq после попытки использовать UIO вместо прямого отображения /dev/mem. Хотя план заключается в том, чтобы запустить приложение как обычный пользователь, а не root, это все еще выполняется как root.mmap Ошибка EINVAL на устройстве UIO

По-видимому, первое сопоставление является успешным, а остальное делается для того же дескриптора файла 12 (/dev/uio/ps2pl). Хотя очевидным отличием является смещение, оно находится в пределах диапазона (см. Дерево устройств), и оно правильно выравнивается по странице. Это приложение хорошо работает с /dev/mem.

Ошибка наблюдали бег с strace является:

open("/dev/uio/ps2pl", O_RDWR|O_SYNC) = 12 
open("/sys/bus/i2c/devices/0-0050/eeprom", O_RDONLY) = 13 
fstat64(13, {st_mode=S_IFREG|0600, st_size=8192, ...}) = 0 
_llseek(13, 0, [0], SEEK_SET)   = 0 
read(13, "\1\1\0\0\0\0\0\0", 8)   = 8 
read(13, "(\\\217\2(\\\217\00233333333\0\0\0\0\0\0\0\0(\\\217\2(\\\217\2"..., 4096) = 4096 
close(13)        = 0 
mmap2(NULL, 48, PROT_READ|PROT_WRITE, MAP_SHARED, 12, 0) = 0xb6f93000 
mmap2(NULL, 48, PROT_READ|PROT_WRITE, MAP_SHARED, 12, 0x400000) = -1 EINVAL (Invalid argument) 
mmap2(NULL, 196608, PROT_READ|PROT_WRITE, MAP_SHARED, 12, 0x200000) = -1 EINVAL (Invalid argument) 
mmap2(NULL, 196608, PROT_READ|PROT_WRITE, MAP_SHARED, 12, 0x100000) = -1 EINVAL (Invalid argument) 
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x1f} --- 
+++ killed by SIGSEGV +++ 
Segmentation fault 

Дерево Устройство загружается в ядро:

# /root/dtc/dtc -f -I fs /sys/firmware/devicetree/base/amba_pl/ps2pl\@40000000/ 
ERROR (name_properties): "name" property in/is incorrect ("ps2pl" instead of base node name) 
Warning: Input tree has errors, output forced 
/dts-v1/; 

/{ 
    reg = <0x40000000 0x40000000>; 
    name = "ps2pl"; 
    interrupts = <0x0 0x44 0x4>; 
    compatible = "generic-uio"; 
    interrupt-parent = <0x3>; 
}; 

Размер отображения UIO является достаточно большим, чтобы вместить выше mmap размеры и смещения:

# cat /sys/devices/soc0/amba_pl/40000000.ps2pl/uio/uio0/maps/map0/size 
0x40000000 

ответ

0

Смещениеобрабатывается по-разному для /dev/mem, затем для устройств UIO. Невозможно использовать произвольное смещение, вместо этого можно отобразить начало каждого региона. В приведенном выше примере имеет только один регион определен в дереве устройств, но можно определить несколько областей:

reg = <0x40000000 0x10000>, 
     <0x40010000 0x10000>, 
     <0x40020000 0x10000>, 
     <0x40030000 0x10000>; 
reg-names = "region0", "id", "region2", "gpio"; 

Доступ к каждому региону/отображение не является очевидным, как описано здесь: https://lwn.net/Articles/232575/

Смещение для доступа к n -й регионам должны быть:

n * sysconf(_SC_PAGESIZE) 

на руке размера страницы является 12 битым окном 0x1000.

Еще несколько общих документов. http://elinux.org/images/b/b0/Uio080417celfelc08.pdf

Смежные вопросы