树莓派4 ARM64架构下访问/dev/mem触发Segmentation Fault问题求助
问题:打开/dev/mem触发Segmentation Fault(Raspbian系统)
我开发这个汇编程序已数月,修复了对齐错误、其他Segmentation Fault等诸多问题,目前卡在打开/dev/mem时触发Segmentation Fault。能看到ELF文件中自定义的“Failed to obtain file descriptor for /dev/mem”错误,但参数看似均正确,当前运行在Raspbian系统。
执行文件代码
.text .include "gpioLedMacros.s" .global _start .align 4 _start: mmapdevmem adds x9, xzr, x0 nanosleep gpiodirectionout pin17 loop: gpioturnon pin17 nanosleep gpioturnoff pin17 nanosleep b loop .data pin17: .word 4 /* pin offset value in select */ .word 21 .word 17 .align 4 pin22: .word 8 /* pin offset value in select */ .word 6 .word 22 .align 4 //Execution File
GPIO宏文件代码
.include "fileMacros.s" .equ prot_read, 1 .equ prot_write, 2 .equ map_shared, 1 .equ pageLength, 4096 .equ setregoffset, 28 .equ clrregoffset, 40 /* mmap creates a virtual page of memory in a specified, or non specified directory, with a varible page size/length for the page created, then returns a virtual address for the virtual page created */ .macro mmapdevmem openat devmem, readwrite+execute, stdin b1: adds x4, xzr, x0 /* mov devmem file descriptor into x4 */ /* Error handling code */ bpl 1f mov x1, #1 ldr x2, =devmemerrmessage ldr w2, [x2] mov x8, #0x40 svc 0 mov x0, #2 mov x8, #0x5d svc 0 1: ldr x5, =gpioBaseAddress/* Load the base gpio address into x5 */ ldr x5, [x5] /* Load the value from the base gpio address */ mov x0, #0 /* move 0 into x0 for stdin */ mov x1, #pageLength /* move 4096 which is the page length into x1 */ mov x2, #3 /* move protect read, and protect write permissions into x2 */ mov x3, #map_shared /* move the map shared value into x3, which is 1 */ mov x8, #0xde /* load the value for the mmap syscall into x8 */ svc 0 /* call mmap */ adds x9, xzr, x0 /* Obtain file descriptor returned from mmap */ bpl 2f mov x1, #1 write x1, errmessage, len 2: /* x0 = 0 x1 = 4096 x2 = 3 x3 = 1 x4 = fd for /dev/mem x5 = value in baseGpioAddress x8 = 0xde / mmap x9 = mmap returned file descriptor */ .endm .macro nanosleep ldr x0, =timeamount ldr x1, =timeamount mov x8, #0x65 svc 0 .endm .macro gpiodirectionout pin ldr x2, =\pin /* Load the pin number into x2 */ ldr w2, [x2] /* Load the value of that pin number into x2 */ ldr w1, [x9, x2]/* Load into x1 the value of the file descriptor of mmap offset by the value of the pin that you're trying to set */ ldr x3, =\pin /* Load the pin number into x3 */ add x3, x3, #4 /* add the amount to shift to the pin number */ ldr x3, [x3] /* Load the value of the shift amount of the pin into x3 */ mov x0, #0b111 /* Load 3 1 bits (which is the clear value) into x0 */ lsl x0, x0, x3 /* Shift the 3 1 bits by the pin shift amount */ bic x1, x1, x0 /* Use the 3 bits to clear the mmap offset file descriptor value */ mov x0, #1 /* Move 1 into x0 for the out value */ lsl x0, x0, x3 /* Shift the out bit by the pin shift amount */ orr x1, x1, x0 /* orr the out bit with the mmap file descriptor pin offset value */ str w1, [x9, x2]/* store the out bit into the mmap file descriptor pin offset */ .endm .macro gpioturnon pin mov x2, x9 add x2, x2, #setregoffset mov x0, #1 ldr x3, =\pin add x3, x3, #8 ldr x3, [x3] lsl x0, x0, x3 str w0, [x2] .endm .macro gpioturnoff pin mov x2, x9 add x2, x2, #clrregoffset mov x0, #1 ldr x3, =\pin add x3, x3, #8 ldr w3, [x3] lsl x0, x0, x3 str w0, [x2] .endm .data devmem: .asciz "/dev/mem" timeamount: .dword 0 timeremaining: .dword 10000000 gpioBaseAddress: .dword 0xfe200000 errmessage: .asciz "Couldn't obtain file descriptor for /dev/mem\n" len = .-errmessage devmemerrmessage: .asciz "Couldn't obtain devmem file descriptor\n" len2 = .-devmemerrmessage //gpio macro file
文件宏文件代码
equ dfd, -100 equ stdin, 0 equ readwrite, 0666 equ execute, 0200 .macro openat filename, flags, permissions ldr x0, =dfd ldr x1, =\filename mov x2, #\flags mov x3, #\permissions mov x8, #0x38 svc 0 .endm .macro fchmod fd, permissions mov x0, \fd ldr x1, =\permissions mov x8, #0x34 svc 0 .endm .macro read fd, fillblock, length mov x0, \fd ldr x1, =\fillblock mov x2, #\length mov x8, #0x3f svc 0 .endm .macro write fd, string, length mov x0, \fd ldr x1, =\string mov x2, \length mov x8, #0x40 svc 0 .endm .macro fsync fd mov x0, \fd mov x8, #0x52 svc 0 .endm .macro close fd mov x0, \fd mov x8, #0x39 svc 0 .endm // File macro file
用gdb调试后发现Segmentation Fault发生在地址0x0000000000410100,objdump查看该位置的指令为000a0058 210a0058 c24680d2 030080d2,目前仅排查至此,恳请提供解决思路。
内容的提问来源于stack exchange,提问作者Virtual Wizard
相关产品推荐
相关产品推荐

