我正在尝试移植 raspberrypi's userspace 的位从 C 到 golang 的代码,我遇到了一个涉及 ioctl()
的程序。
我在执行 C 代码时遇到了问题
#define MAJOR_NUM 100
#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *)
static int mbox_property(int file_desc, void *buf){
int ret_val = ioctl(file_desc, IOCTL_MBOX_PROPERTY, buf);
return ret_val;
}
我的 go 等价物是
func mBoxProperty(f *os.File, buf [256]int64) {
err := Ioctl(f.Fd(), IOWR(100, 0, 8), uintptr(unsafe.Pointer(&buf[0])))
if err != nil {
log.Fatalln("mBoxProperty() : ", err)
}
}
func Ioctl(fd, op, arg uintptr) error {
_, _, ep := syscall.Syscall(syscall.SYS_IOCTL, fd, op, arg)
if ep != 0 {
return syscall.Errno(ep)
}
return nil
}
func IOWR(t, nr, size uintptr) uintptr {
return IOC(IocRead|IocWrite, t, nr, size)
}
func IOC(dir, t, nr, size uintptr) uintptr {
return (dir << IocDirshift) | (t << IocTypeshift) | (nr << IocNrshift) | (size << IocSizeshift)
}
但每当我运行它时,我都会收到 invalid argument
错误,我认为这可能是由于我如何调用 IOCTL()
但我不确定,如何我可以解决这个问题吗?
最佳答案
"golang.org/x/sys/unix"
中有ioctl(2) 个包装器. unix.IoctlSetInt
机械上可能会满足您的需求。
看起来您正在将对小内存缓冲区的控制权交给内核。你需要小心这样做:Go 垃圾收集器释放它认为没有被使用的内存对象,即使某些东西正在使用,它也可以移动它。内核不会知道这一点并将继续使用旧指针。 unsafe.Pointer
文档在这个主题上有很多话要说,即使是关于不那么奇特的系统调用。我不知道有什么可以将 Go 对象“锁定”在内存中以防止它被移动或释放(例如,runtime
包中没有任何内容跳出)。
您可以考虑使用 cgo 编写一个非常小的扩展malloc()
编辑了一个适当的缓冲区并将其交给 ioctl。 malloc 的内存不是垃圾收集的,因此它不会移动或从您的下方释放;一些低级工具可能认为这看起来像是内存泄漏(保留指针的旧值以便以后能够释放它并避免这种情况并不是一个坏主意)。
关于c - 如何从 golang 正确地 IOCTL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54388088/