C代码,为什么要将地址0xFF00转换为结构体?

7

我正在尝试理解一些用C语言编写的Linux内核驱动程序代码,该代码是为了一个USB Wi-Fi适配器而编写的。文件/drivers/net/wireless/rtl818x/rtl8187/dev.c中的第1456行(以防有人想要参考内核代码进行上下文)如下:

    priv->map = (struct rtl818x_csr *)0xFF00;

我对这里的右操作数-(struct rtl818x_csr *)0xFF00;很好奇。我的理解是将内存地址0xFF00转换为类型rtl818x_csr,并将其分配给priv->map。如果我的理解是正确的,那么有什么特别之处使得驱动程序可以可靠地知道它要查找的东西总在这个地址上?另一件让我好奇的事情是0xFF00只有16位。如果它正在转换内存地址,我会期望是32/64位。

有人能够澄清这行代码的确切含义吗?我想C语法中存在缺陷。


看起来RTL818x芯片组的控制/状态寄存器是内存映射到地址0xFF00。 - Paul R
3个回答

2

0xFF00是系统IO地址空间中的一个地址。如果您查看代码,该地址永远不会被直接引用,而是通过IO函数进行访问。

例如,在以下调用中:

rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
                 RTL818X_EEPROM_CMD_CONFIG);

然后调用Linux内核的低级IO函数。

将地址转换为指向结构体的指针,以便访问该地址的偏移量,例如:

0xFF00 + offsetof(struct rtl818x_csr, EEPROM_CMD)

请注意,在上面的rtl818x_iowrite8调用中,传递&priv->map->EEPROM_CMD参数时没有进行解引用,因为有&运算符,只计算地址+偏移量。解引用是在rtl818x_iowrite8内部调用的低级函数中进一步实现的。

2
将绝对地址转换为指向结构体的指针是驱动程序中访问设备(内存映射)寄存器的常见方式,就像访问普通的C结构体一样。
使用0xff00是可行的,因为C不会对数字进行符号扩展。

2
你需要从设备的角度考虑这个问题。
在为rtl8187设备映射的地址空间内,从地址0xFF00开始有一个存储信息的内存范围,其结构与此处定义的rtl818x_csr结构相同。
因此,在逻辑上映射该区域后,您可以开始对其进行总线读写以控制设备。例如此处(我必须切断两个超链接,因为我没有足够的声望来发布超过3个以上的超链接,但您明白我的意思)。这些只是一些例子。如果您阅读整个文件,您会发现读取和写入遍布其中。
为了理解为什么该结构看起来是那样的,以及为什么使用0xFF00而不是0xBEEF或0xDEAD,您需要查阅该设备的数据手册。
因此,如果您想开始查看内核代码,特别是设备驱动程序,您需要不仅有代码,还需要数据手册或规格说明。这可能相当难以找到(请参见数以亿计的电子邮件线程和文章,请求供应商提供开放文档)。
无论如何,希望我回答了你的问题。 祝您愉快地黑客!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接