Linux 写入端口0cf8h失败,出现segfault
我有一个e2-2000型号的AMD处理器。这是家庭0fh。 根据0fh BKDG系列,我有此代码读取设备和供应商ID:Linux 写入端口0cf8h失败,出现segfault,linux,assembly,x86-64,pci,Linux,Assembly,X86 64,Pci,我有一个e2-2000型号的AMD处理器。这是家庭0fh。 根据0fh BKDG系列,我有此代码读取设备和供应商ID: ReadPCIConfiguration: movq $0x80000100, %rax movq $0x0cf8, %rdx outl %eax, %dx # sigsegv caught here movq $0x0cfc, %rdx inl %dx, %eax ret 据我所知,读/写PCI配置的算法如下: 将目标总线
ReadPCIConfiguration:
movq $0x80000100, %rax
movq $0x0cf8, %rdx
outl %eax, %dx # sigsegv caught here
movq $0x0cfc, %rdx
inl %dx, %eax
ret
据我所知,读/写PCI配置的算法如下:
- 将目标总线号、设备号、功能号和偏移量或寄存器号写入配置地址端口
- 从/到配置数据端口执行1、2或4字节的r/w操作
- 31-EnReg-启用交易(R/W)
- 24..31-保留(R/O)
- 16..23-总线数(R/W)
- 11..15-德夫努姆(R/W)
- 8..10-函数(R/W)
- 2..7-注册表编号(R/W)
- 0..1-保留(R/O)
(我从用户空间GNU/Debian“Wheezy”Linux 3.11.6运行编译和链接的应用程序)默认情况下,Linux不允许用户代码写入I/O端口。(从安全角度来看,这样做可能非常危险。)如果您希望Linux允许您的进程访问I/O端口,您有两种选择:
ioperm
系统调用。然而,ioperm
已经被弃用了一段时间,Josh Triplett最近允许用户从内核中删除它。如果您希望您的代码为可预见的未来继续工作,请避免使用ioperm
默认情况下,Linux不允许userland代码写入I/O端口。(从安全角度来看,这样做可能非常危险。)如果您希望Linux允许您的进程访问I/O端口,您有两种选择:
ioperm
系统调用。然而,ioperm
已经被弃用了一段时间,Josh Triplett最近允许用户从内核中删除它。如果您希望您的代码为可预见的未来继续工作,请避免使用ioperm
我不是一个硬件爱好者,但可能操作系统不允许您直接写入端口?这肯定有一个系统调用,以确保只有具有正确权限的进程才能这样做。也许你是对的。但问题是,在将来,代码应该在操作系统开始时运行(重新配置系统内存映射),我想至少测试代码的读取访问和读取正确性?在virtualbox中的操作系统之前运行它。因为没有操作系统,所以这肯定不会给出segfault,但我不知道你的代码是做什么的!我明白了。我发现一个解决方案是调用
ioperm
和iopl
。也许我应该删除这个问题?我不是一个硬件专家,但可能操作系统不允许您直接写入端口?这肯定有一个系统调用,以确保只有具有正确权限的进程才能这样做。也许你是对的。但问题是,在将来,代码应该在操作系统开始时运行(重新配置系统内存映射),我想至少测试代码的读取访问和读取正确性?在virtualbox中的操作系统之前运行它。因为没有操作系统,所以这肯定不会给出segfault,但我不知道你的代码是做什么的!我明白了。我发现一个解决方案是调用ioperm
和iopl
。也许我应该删除这个问题?那么,你说ioperm
现在不推荐了。那iopl系统调用呢?看看Josh Triplett的电子邮件。他推出的补丁允许用户编译出iopl
和ioperm
。看起来,我将使用iopl
进行我自己的测试,并在将来使用/dev/port
。但是他们为什么要禁用ioperm
&iopl
?也许是出于安全原因?无论如何,谢谢你的快速回答。所以,你说ioperm
现在不推荐了。那iopl系统调用呢?看看Josh Triplett的电子邮件。他推出的补丁允许用户编译出iopl
和ioperm
。看起来,我将使用iopl
进行我自己的测试,并在将来使用/dev/port
。但是他们为什么要禁用ioperm
&iopl
?也许是出于安全原因?无论如何,谢谢你的快速回答。