在尝试使用 UIO 而不是直接映射后,我在 Xilinx Zynq 上映射物理内存时遇到问题/dev/mem
。虽然计划是以普通用户身份运行应用程序,而不是root
这仍在运行root
.
显然,第一个映射成功,其余映射到同一个文件描述符12
(/dev/uio/ps2pl
) 失败。虽然明显的区别是偏移量,但它在范围内(请参阅设备树)并且正确进行页面对齐。该应用程序运行良好/dev/mem
.
通过运行观察到的错误strace
is:
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