我试图向 I/O 端口写入一个字节,但在arm64 aarch64架构的指令集中找不到正确的指令。
要在 i386 中做同样的事情,我会做类似的事情:
void dbg_io_write_8(uint16_t port, uint8_t val)
{
asm volatile (
"outb %%al, %%dx;"
/* Outputs */ : /* None */
/* Inputs */ : "a" (val), "d" (port)
/* Clobbers */ : /* None */
);
}
并且,供阅读:
uint8_t dbg_io_read_8(uint16_t port)
{
uint8_t val;
asm volatile (
"inb %%dx, %%al;"
/* Outputs */ : "=a" (val)
/* Inputs */ : "d" (port)
/* Clobbers */ : /* None */
);
return val;
}
此代码指的是
NS16550
串口。
arm64没有I/O端口的概念。
如果您既是 CPU 供应商又是 SoC 设计师,并且有充分的理由,您可能会选择将外设映射到(一组)自定义系统寄存器。在这种情况下,您可以通过
mrs
/msr
与外围设备对话。
在所有其他情况下,您将其内存映射到某个物理地址。因此,您可以通过简单的加载和存储来访问它。
看一下 outb(): https://elixir.bootlin.com/linux/latest/source/arch/arm/include/asm/io.h#L235
最终使用 += PCI_IO_VIRT_BASE (=0xfee00000) 将 outb() 访问转换为内存访问