• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

Addressing peripheral memory locations

chrstrbrts

Senior member
Hello everyone,

OK, so I have a decent idea of how peripherals are linked and how the CPU sees and communicates with them.

The BIOS firmware is responsible for assigning addresses to peripherals at boot time by writing to the peripherals' base address registers. The option ROMs are assigned addresses as well.

The CPU uses memory mapped I/O to send data to the peripherals by sending addresses to the memory controller just as if the CPU were trying to reach RAM locations. I may be wrong, but I don't think that isolated I/O is used anymore.

OK, so here's my question:

Let's say you write a program, and the program tells the CPU to read from a memory location on a peripheral device and do something with it.

Well, the BIOS has assigned that peripheral device, specifically the memory location on that peripheral device, a memory address mapped into the CPU's address space.

So, when you compile and link your source code, the machine instruction that's generated for that read instruction should just be a simple mov instruction that contains the address of the peripheral's memory location.

But, doesn't the BIOS assign those addresses differently after every boot?

If after the current the boot, peripheral memory location #3 has address 10 but after the next boot, the same peripheral memory location has address 15, how can the same code work successfully from boot to boot?

Thanks.
 
The last time I wrote device drivers was in college, for DOS, but:

I assume the device driver queries the OS for the device address. Or it is not allowed to talk directly to the address and the OS passes the data.

For code in the BIOS like for the keyboard and mouse in its setup screen, the BIOS knows what addresses it has assigned and again the code can look up those addresses from a function call or global pointer.

Back in the DOS days devices had sets of fixed addresses and your program had to have configuration settings for which port address and interrupt to use for hardware like the sound card. When putting the cards into a system you sometimes had to juggle dip switches or use BIOS settings to resolve 2 devices wanting to use the same port or interrupt.
 
Last edited:
I assume the device driver queries the OS for the device address. Or it is not allowed to talk directly to the address and the OS passes the data.

OK, so if either of these is correct, then what must be happening is that after the BIOS assigns addresses, that info is stored in some sort of kernel space data structure for future reference. Right?

For code in the BIOS like for the keyboard and mouse in its setup screen, the BIOS knows what addresses it has assigned and again the code can look up those addresses from a function call or global pointer.

Again, there must exist some sort of data structure created after the BIOS assigns addresses that links hardware with assigned addresses so that the hardware can be found.

But, in this instance where would that data be?

After all, the OS hasn't been booted yet.

Would it still just be in RAM somewhere?

Back in the DOS days devices had sets of fixed addresses and your program had to have configuration settings for which port address and interrupt to use for hardware like the sound card. When putting the cards into a system you sometimes had to juggle dip switches or use BIOS settings to resolve 2 devices wanting to use the same port or interrupt.

I'm familiar with the old paradigm. But, now we have PCIe and plug n play, and all of that is dynamic and automated.

Because the system itself is doing all of these things for the user, it needs to somehow have some self awareness regarding the settings it has configured.
 
Last edited:
> Would it still just be in RAM somewhere?

It could either placed in a RAM table at a known address or available by asking the BIOS, but I have no idea which. The BIOS does have its own API, googling for info on the modern BIOS functions available to an OS might answer this.
 
> Would it still just be in RAM somewhere?

It could either placed in a RAM table at a known address or available by asking the BIOS, but I have no idea which. The BIOS does have its own API, googling for info on the modern BIOS functions available to an OS might answer this.

OK. So, a source code instruction that asks the CPU to grab data from a peripheral device would actually generate a machine instruction to access code on the BIOS chip that acts like some kind of driver that grabs the data required and send it back to the CPU?


Thanks, will look at it.
 
Honestly, You'll probably be best served by reading this guy

https://www-ssl.intel.com/content/d...s-software-developer-vol-3a-part-1-manual.pdf

(Yay datasheets!).

The long and short answer is that the CPU will read memory address FFFFFFF0H. How that eventually translates to the BIOSes memory is going to be dependant on the memory controller. After that, all control is handed over to the BIOS to setup memory mappings and initialize things. Once the bios has done that job, it starts the chain events that lead to the OS booting up. The OS gets full access and control of memory mappings after that and it is in charge of performing a lot of the post initialization driver setup.

IIRC. Most of the initial memory mappings that are done are really just on the order of "I'm here, I'm this, talk to me if you wish". The OS is more in charge of setting up most of the communications/driver handshakes that need to go on. Though I do believe that the BIOS init process gives the device being registered a chance to make changes and set things up in memory. This "feature" is one of the driving reasons for UEFI. UEFI tries to put layers and protections around the device handshake process to prevent rogue devices from taking control of everything.

How memory address translates to activating IO pins is going to depend on how intel interprets their memory mapping setup. That is all contained in the linked document (it will be the same for AMD and similar with how ARM works).
 
Hello,

So, I've been reading about the firmware's initialization of peripheral devices by writing to certain peripheral memory locations, mapping those locations to the CPU's I/O space and memory space, and copying option ROM/expansion ROM code into RAM.

My question is after everything has been initialized, the POST is completed without incident, and the OS is up and running how can one from user space learn what memory chunk in the CPU's memory map has been assigned to a peripheral?

So, for example, how do I find out what memory addresses have been assigned to my NIC card's registers?

Thanks.

I merged this thread on the same topic into this older thread -- Programming Moderator Ken g6
 
Last edited by a moderator:
Go to windows device manager right click on the devcice->properties and go to the resources tab
 
If after the current the boot, peripheral memory location #3 has address 10 but after the next boot, the same peripheral memory location has address 15, how can the same code work successfully from boot to boot?

A program will have one function that gets the base address for the device. It will have another function that uses that address to access the device. There wont be any hardcoded addresses.
 
Back
Top