简体   繁体   English

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

[英]C code, why is address 0xFF00 being cast to a struct?

I am trying to understand some Linux kernel driver code written in C for a USB Wi-Fi adapter. 我试图了解一些用C编写的USB Wi-Fi适配器的Linux内核驱动程序代码。 Line 1456 in file /drivers/net/wireless/rtl818x/rtl8187/dev.c (just in case anyone wanted to refer to the kernel code for context) reads: 文件/drivers/net/wireless/rtl818x/rtl8187/dev.c 1456 /drivers/net/wireless/rtl818x/rtl8187/dev.c (以防万一有人想参考内核代码获取上下文信息)读取:

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

I am curious about what exactly the right operand is doing here - (struct rtl818x_csr *)0xFF00; 我很好奇这里正确的操作数在做什么- (struct rtl818x_csr *)0xFF00; . I have been interpreting this as saying "cast memory address 0xFF00 to be of type rtl818x_csr and then assign it to priv->map ". 我一直将此解释为说“将广播内存地址0xFF00设置为rtl818x_csr类型,然后将其分配给priv->map ”。 If my interpretation is correct, what is so special about memory address 0xFF00 that the driver can reliably tell that what it is after will always be at this address? 如果我的解释是正确的,那么内存地址0xFF00有什么特别之处,以至于驱动程序可以可靠地告知其后的内容将始终位于该地址? The other thing I am curious about is that 0xFF00 is only 16-bits. 我很好奇的另一件事是0xFF00只有16位。 I would be expecting 32/64-bits if it were casting a memory address. 如果它正在转换内存地址,我期望32/64位。

Can anyone clarify exactly what is going on in this line of code? 任何人都可以弄清楚这行代码中到底发生了什么吗? I imagine there's a flaw in my understanding of the C syntax. 我想我对C语法的理解存在缺陷。

Casting an absolute address to a pointer to a structure is a common way in drivers to access the (memory mapped) registers of a device as a normal C structure. 在驱动程序中,将绝对地址强制转换为指向结构的指针是将设备的(内存映射)寄存器作为普通C结构访问的常见方法。

Using 0xff00 works because C doesn't do sign extension of numbers. 使用0xff00因为C不会对数字进行符号扩展。

0xFF00 is an address in the IO address space of the system. 0xFF00是系统IO地址空间中的地址。 If you look in the code, the address is never directly dereferenced but accessed through IO functions. 如果您查看代码,则永远不会直接取消引用地址,而是通过IO功能访问该地址。

For example, in the call 例如在通话中

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

which then calls Linux kernel low level IO functions. 然后调用Linux内核底层IO功能。

The address is cast to a pointer to a struct to give access to offsets from the adress, example here: 地址被强制转换为指向结构的指针,以访问地址的偏移量,例如:

0xFF00 + offsetof(struct rtl818x_csr, EEPROM_CMD)

Note that in the rtl818x_iowrite8 call above, no dereference occurs when passing the &priv->map->EEPROM_CMD argument because of the & operator, only the address + offset is computed. 请注意,在上面的rtl818x_iowrite8调用中,由于&运算符,在传递&priv->map->EEPROM_CMD参数时,不会发生取消引用,只会计算地址+偏移量。 The dereference is further achieved withtin the internal low level functions called inside rtl818x_iowrite8 . 所述非关联化withtin称为内的内部低级别功能进一步实现rtl818x_iowrite8

You have to consider this from the device point of view. 您必须从设备角度考虑这一点。

Starting at address 0xFF00 inside the address space mapped for the rtl8187 device is a memory range that holds information structured the same way as the rtl818x_csr struct defined here . 从rtl8187器件映射的地址空间内的地址0xFF00开始是一个存储器范围,该存储器范围包含信息的结构与此处定义的rtl818x_csr结构相同。

So after you logically map that region you can start doing bus reads and writes on it to control the device. 因此,在逻辑上映射该区域之后,您就可以开始在其上进行总线读写操作来控制设备。 Like here (had to cut two more hyperlinks because I don't have the reputation necessary to post more than 3, but you get the point). 就像这里 (由于我没有足够的名声来发布三个以上的链接,还不得不削减两个超链接,但是你明白了)。 These are just a couple of examples. 这些只是几个例子。 If you read the entire file you'll see reads and writes are sprinkled everywhere. 如果您阅读了整个文件,则随处可见读写。

In order to understand why that structure looks that way and why 0xFF00 is used instead of 0xBEEF or 0xDEAD you'll have to consult the datasheet for that device. 为了理解该结构的外观以及为什么使用0xFF00代替0xBEEF或0xDEAD,您必须查阅该器件的数据表。

So if you want to start looking at kernel code, and specially device drivers, you'll have to have more than just the code. 因此,如果您要开始查看内核代码,特别是设备驱动程序,则不仅需要代码。 You'll need the datasheet or specifications as well. 您还将需要数据表或规格。 This can be rather difficult to find (see the gazillions of email threads and articles soliciting open documentation from the vendors). 这可能很难找到(请参阅大量的电子邮件主题和文章,向供应商索取开放文档)。

Anyway, I hope I answered your question. 无论如何,我希望我回答了你的问题。 Happy hacking! 骇客入侵!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM