Addressing peripheral memory locations

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
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.
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
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:

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
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:

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
> 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.
 

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
> 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.
 

Cogman

Lifer
Sep 19, 2000
10,284
138
106
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).
 

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
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:

TheELF

Diamond Member
Dec 22, 2012
4,027
753
126
Go to windows device manager right click on the devcice->properties and go to the resources tab
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
So, for example, how do I find out what memory addresses have been assigned to my NIC card's registers?

In code? That's probably going to be OS-specific. And the OS might not let you do any reads or writes to it outside of a device driver.
 

sm625

Diamond Member
May 6, 2011
8,172
137
106
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.