访问硬件寄存器

时间:2015-07-06 23:57:54

标签: linux linux-kernel driver linux-device-driver sata

我正在努力增强Linux中提供的库存ahci驱动程序,以便执行一些所需的任务。我正试图向AHCI HBA发出命令以便硬盘处理。但是,每当我这样做时,我的系统会锁定并重新启动。试图解释向AHCI驱动器发出命令的过程对于这个问题来说是非常重要的。如果需要,reference this link for the full discussion(该过程相当定义,因为有几个部分,但是,ch 4具有必要的数据结构)。

基本上,将适当的结构写入由BIOS或OS定义的内存区域。我应该写入的第一个存储区是寄存器PxCLB中包含的命令列表基址(如果适用64位寻址,则为PxCLBU)。我的系统是64位,所以我试图获得两个32位寄存器。我的代码基本上是这样的:

void __iomem * pbase = ahci_port_base(ap);
u32 __iomem *temp = (u32*)(pbase + PORT_LST_ADDR);
struct ahci_cmd_hdr *cmd_hdr = NULL;

cmd_hdr = (struct ahci_cmd_hdr*)(u64)
    ((u64)(*(temp + PORT_LST_ADDR_HI)) << 32 | *temp);

pr_info("%s:%d cmd_list is %p\n", __func__, __LINE__, cmd_hdr);
// problems with this next line, makes the system reboot
//pr_info("%s:%d cl[0]:0x%08x\n", __func__, __LINE__, cmd_hdr->opts);

在ahci驱动程序中找到函数 ahci_port_base()(至少是CentOS 6.x)。基本上,它返回AHCI内存区域中该端口的正确地址。 PORT_LST_ADDR和PORT_LST_ADDR_HI都是该驱动程序中定义的宏。获取高地址和低地址后得到的地址通常是0x0000000037900000。这个内存地址是否在我不能简单地取消引用的空间中?

此时我正撞在墙上,因为以这种方式访问​​它的this link shows基本上就是这样做的。

1 个答案:

答案 0 :(得分:2)

  

获取高地址和低地址后获得的地址   通常是0x0000000037900000。这个内存地址   在一个我不能简单地取消引用它的空间?

是的,你是对的 - 这是一个总线地址,你不能解除引用它,因为启用了分页。 (你不应该只是取消引用iomapped地址 - 你应该使用readl() / writel(),但这里的破损更加微妙。

看起来访问该驱动程序中ahci_cmd_hdr的正确方法是:

struct ahci_port_priv *pp = ap->private_data;
cmd_hdr = pp->cmd_slot;