10

I hope the question is phrased well enough for someone to understand.

I understand that main memory (RAM) and for Port I/O driven I/O, it has it's own Address Space that Instructions like IN, OUT use.

If one were to write a real-mode assembler program, would it be up to the developer to have the necessary documentation showing what address ranges specific slots on the motherboard are in what address range? Say the PCIe slot is address X, Printer Y.

Are the addresses a standard address range depending on the Bus type?

What can I read to understand this better? Hope someone can help. Thanks.

~ edit

Referring to PC systems.

3
  • 1
    Do you have any particular platform in mind?
    – Jim Rhodes
    Commented Feb 10, 2012 at 3:26
  • 2
    The answer is completely different for a commodity PC where the software is expected to work in numerous different configurations compared to the answer for an embedded PC where the software only has to support a fixed configuration. You need to narrow down your question. Commented Feb 10, 2012 at 3:39
  • Sorry. I'm referring to a PC. Commented Feb 10, 2012 at 6:54

2 Answers 2

14

On an x86 pc the bios normally manages allocation of the flat/physical address space, and everything uses some place in that space. So the BIOS will "enumerate" the pcie devices by going out on each pcie slot to see if anyone is there. There are standard configuration registers that a pcie device must have some of which indicate how much address space and what kind (I/O based or Memory mapped). the bios attempts to make everyone happy and give them what they want. Windows or linux will not remap these devices or addresses, they take what is given to them by the bios. not every pcie system works that way but unfortunately this is how PC's work.

So if you want to get into the nuts and bolts, get this book http://www.mindshare.com/shop/?c=b&section=0A6B150A I think there is a download link for it if you google "pci system architecture"

if you run linux then find the sources for lspci, there are some libraries and examples that you can rip apart and make your own to examine what devices are in your system and what their base address and memory range are. Most likely you are going to want to just do what other operating systems do and read the pcie host controllers to see what has been allocated where, and provide that information to the software running on that system. You might boot one time and the printer gets address 0xE0000000 and the next time 0xDB000000, provide a mechanism to your environment to give those addresses, or abstract those to some fixed address within your environments address space and have your code manage the translation to the physical/real address for the device.

I assume by using the term real mode you are talking about some flavor of x86 system, and that is probably a PC of some flavor. Maybe a mac. Not sure exactly how a mac does it, dont know enough about their enumeration. the hardware is likely still an intel processor with a north and south bridge followed by a number of pcie bridges or other intel pcie chips that ultimately end up in a number of pcie devices either soldered onto the board (video chips, etc) or pcie slots for plug in cards. If you run linux and use lspci and look at the vendor and part numbers you can find most of the manuals/datasheets for the intel (vendor ID 8086) devices at intels website, and you can use lspci and its sibling programs to examine the control and status registers in those pcie controllers, again if you are interested in digging deeper into this, I am not sure what your real interest is.

The addresses are not a standard, nor fixed, each bios is semi-custom to that motherboard model, the address range for the pcie space is typically one gig or less of the whole processor space, but that window is changing with the move to 64 bit and the need for more space (a slow move). the location of that pcie window is dependent on the hardware (See the datasheets I mentioned for those various intel devices, or via or nvidia or whoever if it is an amd system) if the bios is configured to run in 32 bit mode that pcie window for all pcie devices might be somewhere between the 2 gig but of course below the 4 gig mark, but that doesnt mean all of those systems use the 3 gig mark. for 64 bit I think they tend to be near the top as well but from motherboard to mother board it changes. Then when it comes to enumerating the bus it is both motherboard specific and individuals computer specific, some devices are bolted/soldered onto the motherboard and get enumerated in the same order every time, but cards you plug into the slots, have to respond to the host and sometimes get enumerated based on who answers first, you might boot 20 times and see the same layout, boot one more time and two cards might swap locations because the order they were enumerated changed. So even if it appears that your video card is always at the same place, dont hardcode that number anywhere, always scan the pcie bus or tables or make library calls to find out what is where. it is probably not going to move once you find something until you reboot and try again so you dont have to keep rescanning to find where something is every time you want to access it.

yes, if you upgrade or downgrade your bios, the bios is just software, sometimes the bios changes have to do with pcie enumeration (not that uncommon, say a popular video card doesnt work well on a motherboard they put a mod into the bios software to change the reset or whatever to give that card a better chance at working) and that may change the enumeration for the whole system.

1
  • 1
    This answer is good, but it doesn't include one key detail: how exactly does the BIOS communicate I/O port mapping to the CPU?
    – Alex D
    Commented Oct 21, 2014 at 18:47
0

If one were to write a real-mode assembler program

ISRs are what you may be after (Interrupt Service Routines).
;

This is a list of interrupt handler addresses stored in the first segment of memory. (segment 0000). Each interrupt number has a 4-byte handler address, segment and offset, to which a program will branch when that interrupt is called.

The address can be found by multiplying the interrupt number by 4, that being the offset at which the handler's address is stored.

The ISRs location can be defined as 0000:ax*4, DOS interrupts have the generic number 21h. So just load ax with that (or al)

There's a list of DOS interrupts here... it's moderately large...

http://www.ctyme.com/intr/int-21.htm

Not the answer you're looking for? Browse other questions tagged or ask your own question.