英文:
golang: 32-bit access to mmap'd "/dev/mem" region
问题
由于Go语言是一种系统语言,它应该能够执行一些用户空间硬件驱动程序的工作。
我想要映射"/dev/mem"并对一些内存映射的PCI寄存器进行读写操作。
由于Go语言的syscall.Mmap返回一个字节数组,我应该如何对寄存器进行32位(例如)的读写操作?
逐字节访问是不合适的,因为某些寄存器只支持32位访问。
英文:
Since golang is a systems language, it should be capable of doing some user space hardware driver job then.
I want to mmap "/dev/mem" and do some read or writes to some memory mapped pci registers.
Since golang's syscall.Mmap return a byte array. How could I possibly do a 32-bit(for example) read or writes to the registers?
byte by byte access is not approperiate since some registers only support 32 bit access.
答案1
得分: 4
你可以通过使用unsafe
包,并在正确的偏移处获取一个*uint32
指针来实现这一点。下面是一个针对普通字节数组的示例,但对于mmap映射的数组也应该适用。
package main
import (
"fmt"
"unsafe"
)
func main() {
a := make([]byte, 30)
p := (*uint32)(unsafe.Pointer(&a[8]))
*p = 0xabcd0123
fmt.Println(a)
}
这段代码将在字节数组a
的偏移量为8的位置处设置一个uint32
类型的值,并打印整个数组a
的内容。
英文:
You can do this by using unsafe
and getting a *uint32
pointer into the block at the right offset. Here's an example for a regular byte array, but an mmap'ed one should work the same.
package main
import (
"fmt"
"unsafe"
)
func main() {
a := make([]byte, 30)
p := (*uint32)(unsafe.Pointer(&a[8]))
*p = 0xabcd0123
fmt.Println(a)
}
答案2
得分: 0
这是一个示例。欢迎你。;)
func Readu32(baseAddress int64, offset int64) uint32 {
var value uint32 = 0xFFFFFFFF
const bufferSize int = 4096
file, err := os.Open("/dev/mem")
if err != nil {
log.Fatal(err)
}
defer file.Close()
mmap, err := syscall.Mmap(int(file.Fd()), baseAddress, bufferSize, syscall.PROT_READ, syscall.MAP_SHARED)
if err != nil {
log.Fatal(err)
}
value = *(*uint32)(unsafe.Pointer(&mmap[offset]))
err = syscall.Munmap(mmap)
if err != nil {
log.Fatal(err)
}
return value
}
英文:
Here is an example. You are welcome.
func Readu32(baseAddress int64, offset int64) uint32 {
var value uint32 = 0xFFFFFFFF
const bufferSize int = 4096
file, err := os.Open("/dev/mem")
if err != nil {
log.Fatal(err)
}
defer file.Close()
mmap, err := syscall.Mmap(int(file.Fd()), baseAddress, bufferSize, syscall.PROT_READ, syscall.MAP_SHARED)
if err != nil {
log.Fatal(err)
}
value = *(*uint32)(unsafe.Pointer(&mmap[offset]))
err = syscall.Munmap(mmap)
if err != nil {
log.Fatal(err)
}
return value
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论