You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:24:53