Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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:

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

I am curious about what exactly the right operand is doing here - (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". 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? The other thing I am curious about is that 0xFF00 is only 16-bits. I would be expecting 32/64-bits if it were casting a memory address.

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.

like image 655
Bryce Thomas Avatar asked Aug 01 '12 09:08

Bryce Thomas


1 Answers

0xFF00 is an address in the IO address space of the system. If you look in the code, the address is never directly dereferenced but accessed through IO functions.

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.

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. The dereference is further achieved withtin the internal low level functions called inside rtl818x_iowrite8.

like image 101
ouah Avatar answered Oct 04 '22 06:10

ouah