0

我正在努力增强 Linux 中提供的股票 ahci 驱动程序,以执行一些需要的任务。我正试图向 AHCI HBA 发出命令以供硬盘驱动器处理。但是,每当我这样做时,我的系统都会锁定并重新启动。试图解释向 AHCI 驱动器发出命令的过程对于这个问题来说意义重大。如果需要,请参考此链接以进行完整讨论(该过程已完全定义,因为有几个部分,但是,第 4 章具有必要的数据结构)。

本质上,将适当的结构写入由 BIOS 或操作系统定义的内存区域。我应该写入的第一个内存区域是寄存器 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_port_base()函数可以在 ahci 驱动程序中找到(至少它适用于 CentOS 6.x)。基本上,它会返回 AHCI 内存区域中该端口的正确地址。PORT_LST_ADDR 和 PORT_LST_ADDR_HI 都是该驱动程序中定义的宏。我得到高地址和低地址后得到的地址通常是0x0000000037900000。这个内存地址是否在我不能简单地取消引用它的空间中?

在这一点上,我的头撞到了墙上,因为这个链接表明以这种方式访问​​它本质上就是它的完成方式。

4

1 回答 1

2

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

是的,你是对的——那是一个总线地址,你不能仅仅因为启用了分页而取消引用它。(您也不应该只是取消引用 iomapped 地址 - 您应该使用readl()/writel()来处理这些地址,但这里的破坏更加微妙)。

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

struct ahci_port_priv *pp = ap->private_data;
cmd_hdr = pp->cmd_slot;
于 2015-07-07T07:01:36.993 回答