Page 1 of 2
Physical Memory Layout
Posted: Fri Aug 22, 2003 3:08 pm
by Therx
from what I've gathered you can't use memory from C0000 to FFFFF because its either ROM or non-existant.
But what about from 0 to 4FF and 9FC00 to 9FFFF.
Can I write over the real mode IVT from 0 to 3FF and if so is 0 an addressable piece of memory? I'd always thought not.
Then there's the BDA and EBDA can I write over these once I've got all the relevant data from them.
Also I don't understand how a 32bit processor can address 2^32 bytes of RAM and have addressable IO ports. I'd always thought that the IO ports were mapped to the memory address space but where?
I'm trying to decide on the memory layout for my OS and these points keep bugging me, any help would be very much appeciated.
Cheers
Pete
Re:Physical Memory Layout
Posted: Fri Aug 22, 2003 3:49 pm
by bkilgore
But what about from 0 to 4FF and 9FC00 to 9FFFF.
Can I write over the real mode IVT from 0 to 3FF and if so is 0 an addressable piece of memory? I'd always thought not.
Yes, as long as you don't plan on calling the real-mode interrupts (i.e. with v86 tasks), you're allowed to use this memory for yourself. And yes, this means address 0 is a valid memory address. The reason that it is usually not a valid memory address when programming for existing operating systems is that that virtual address is left unmapped (usually...to make sure to NULL pointers are unintentionally dereferenced, i.e. classic windows "page fault"). However, you're allowed to use it however you want if you don't care about the IVT.
Also I don't understand how a 32bit processor can address 2^32 bytes of RAM and have addressable IO ports. I'd always thought that the IO ports were mapped to the memory address space but where?
There are two different types of I/O, memory-mapped I/O and port I/O, and they use different adressing. The memory-mapped I/O, like you thought, uses the 32-bit address space and limits the virtual address space you can use. port I/O, on the other hand, is addressed using separate pins and does not go through the memory addressing lines at all. For more info read the
IA-32 Intel Architecture Software Developer?s Manual Volume 1: Basic Architecture
Re:Physical Memory Layout
Posted: Fri Aug 22, 2003 4:44 pm
by Schol-R-LEA
A0000-FFFFF is the Reserved Memory Area, and generally isn't available for use even by the OS; however, the actual configuration is more complicated, and highly dependent on the particular system. A0000-BFFFFF is the video memory, as you are probably aware; E0000-FFFFF is the System BIOS. The area between them, C0000-DFFFF, is reserved for add-on BIOS, such as that on the sound card or the video adapter (the area C0000-C8000 in particular is used for the video BIOS). Many newer systems also have extended BIOSes which are larger than the default 64K, and those are also mapped to the reserved areas. In the past, this was also used to access EMS memory, using 64K 'window' which re-mapped to expanded memory. At times some of this reserved memory may in fact be unmapped, but even then it may not be available for the system to use. See
this tutorial for more details.
It is possible to write over the IVT in real mode, but it is extraordinarily inadvisable, except when you actually are changing the interrupt mappings. Writing general data to it with interupts set is a sure way to crash you system. In p-mode, the IVT no longer has any specific importance, and can be in pricniple be overwritten; however, if you return to real mode, or use a v86 task, you'll need the IVT for any real-mode interrupts that occur.
Like with the IVT, it is possible but inadvisable to overwrite the
BIOS Data Area; given that between them, the IVT and the EBDA are a total of less than 5K, it is hardly worth fighting over.
Unlike most newer processor designs, the IA-32 has a separate 64K I/O address space. This special I/O memory is accessed using the [tt]IN[
][/tt] and [tt]OUT[][/tt] instructions. Video memory is an exception to this; because it requires such a large amount of memory, it is mapped into the main address space instead. Some other devices that need wide address spaces use the Reserved Memory Area for it, but this is rare. This I/O arrangement is usually considered one of the flaws in the IA-32 design, as it means that most devices cannot be accessed easily from a HLL like C; however, at the time the 8086 was designed, memory was extremely expensive, and most programming was done in assembly, so it was seen as a reasonable tradeoff.
In real mode, memory from 00500-9FFFF is more or less freely available to the system. Interestingly enough, on the 80286 and later, the area from 100000-1000EF is also available, due to a quirk of the segment:offset addressing scheme; this is referred to as the High Memory Area. However, in order to use the HMA, the A20 address line has to be activated - thanks to another 'good idea' that IBM's designers had when the PC/AT was released in 1985. Do What Thou Wilt with these memory areas (once A20 is set), though you 'll want to avoid silly mistakes like setting your stack 16 bytes above the start of your code.
While I've used linear addresses throughout this discussion, doing so is rather misleading. If your going to work in real mode to any great degree - including writing a boot loader - you'd better make sure you have a solid understanding of segmented memory addressing. Without a good grasp on this tricky issue, you'll onmly drive yourself nuts trying to work in real mode - and you also need to understand it for the more complex aspects of p-mode, as well, but it works differently in p-mode. Of all the design flaws in the IA-32 archtecture, the use of memory segmentation is the most serious, yet again, when it came out, it seemed like a Clever Idea; when the design was settled on in 1978, no one ever dreamed that people would still be using 80x86 CPUs twenty-five years later.
Re:Physical Memory Layout
Posted: Tue Sep 02, 2003 1:32 pm
by Candy
To be exact, the "high memory area" is from 0x100000 to 0x10FFEF (segment == 0xFFFF, offset = 0x0 -> 0xFFFF so total = 0xFFFF + 0xFFFF0 = 0x10FFEF)
Re:Physical Memory Layout
Posted: Tue Sep 02, 2003 3:42 pm
by Schol-R-LEA
Damn, I can't believe I made that mistake. Thanks for the correction.
Re:Physical Memory Layout
Posted: Sun Sep 07, 2003 12:50 pm
by one
Could any of you tell me where i can get information about the layout of memory in a PC? and also about accessing memory in real and protected modes? I',m just a beginner in this area and dont know much. Please help. Thanks
Re:Physical Memory Layout
Posted: Mon Sep 08, 2003 3:32 am
by Pype.Clicker
i guess there should be interresting info for you in
Perica Senjak's tutorial about real mode addressing.
Beyond this, you should ask the BIOS (using the 'SMAP' function -- something like ah=0x8e , int 0x15 iirc) what differences exists between the 'usual' layout and the effective layout (the BIOS knows about Bios extension areas, PCI/VLB memory-mapped devices, physical memory holes and all these kind of nightmares...
Re:Physical Memory Layout
Posted: Mon Sep 08, 2003 4:24 am
by Solar
Pete (aka Therx) wrote:
...is 0 an addressable piece of memory?
0 is not a valid pointer in either C or C++.
Re:Physical Memory Layout
Posted: Mon Sep 08, 2003 4:37 am
by Candy
Solar wrote:
0 is not a valid pointer in either C or C++.
Afaik, 0 is a valid pointer, but it's only the operating system that defines it to be not good. The OS faults on that point (nothing mapped) and gives a null pointer exception.
Re:Physical Memory Layout
Posted: Mon Sep 08, 2003 5:37 am
by Pype.Clicker
to sum things up, C-derivated languages will *assume* dereferencing 0 is a bad thing. In order to implement these language, your OS need to set up an environment that makes this assumption true (either making the page that maps 0 absent, or using expand-down segment that exclude the lowest 4K of memory).
However, you could still access the IVT table by some alternate ways like creating another unprotected segment (which would map the whole memory) that you would use for this special purpose, or by using any non-0 virtual address and force it to map physical address 0.
Note however that in a VM-86 process, the virtual addresses 0..FFF will *have* to be mapped to a valid page frame, so only segment-assisted memory protection will work there.
Re:Physical Memory Layout
Posted: Mon Sep 08, 2003 6:13 am
by Solar
Candy wrote:
0 is a valid pointer, but it's only the operating system that defines it to be not good.
If you initialize a pointer with 0, it is guaranteed that this pointer never points to a valid data "object". (Both C and C++.)
free()ing or delete()ing a pointer to 0 is always a legal no-op.
(From here onward, credit to D. Kuehl for knowing the standard almost by heart.)
The standard
does allow that, upon initializing a pointer with 0 / NULL, the pointer actually holds a
different value than 0, but it still must not point to a valid object. Note that this would have to be done by the
compiler, and would require tweaks to debugger etc. too, since C/C++ coders set "0" <=> "invalid".
Re:Physical Memory Layout
Posted: Tue Sep 09, 2003 1:57 am
by mystran
Solar wrote:
If you initialize a pointer with 0, it is guaranteed that this pointer never points to a valid data "object". (Both C and C++.)
Indeed. AFAIK:
Code: Select all
int main() {
int * foo = 0;
/* This is always printed */
if(foo == 0) printf("Hello");
/* This is printed by modern computers
but not required by C or C++ specification */
if((int) foo == 0) print(" world!");
print("\n");
}
So the point is to say, pointer to 0 need not actually have address of 0. Null pointer is a special pointer and historically, in some cases where hardware supported a null-pointer which did not have address of 0, the correct thing to do was to use that non-zero address for the null pointer.
No C standard to date requires null-pointer to be a pointer with zero address. Actually it does not need to be a "valid" pointer at all and could just as well be something else, as long as that doesn't break anything else specified.
Actually conversion between a pointer and a value type are not even required. Nor are conversion between (char *) and (int *) since you might have completely different represetations for those (old machines again).
Re:Physical Memory Layout
Posted: Tue Sep 09, 2003 2:25 am
by Solar
mystran wrote:
Actually conversion between a pointer and a value type are not even required.
You would be surprised at what a really pedantic compiler could reject... basically, there is no standard compliant, portable, legal way of setting a pointer to an arbitrary address (like the famous 0xb8000)... ;D
Re:Physical Memory Layout
Posted: Tue Sep 09, 2003 3:01 am
by Pype.Clicker
maybe i'm just a wild geek ignoring all ANSI good practice of programming, but having a C environment that doens't let me write
Code: Select all
void *ptr=malloc(size);
if (!ptr) error("no memory);
would just make me throw the compiler away.
And so far, even enabling -wall didn't throw me any warning at that kind of construct.
Re:Physical Memory Layout
Posted: Tue Sep 09, 2003 3:12 am
by Solar
Because that construct
is correct. But try to come up with a char* to 0xb8000 that doesn't throw a warning with -pedantic. The solution is
and potentially non-portable because pointer arithmetics are only defined within the same array (and there is no char* array starting at 0 because 0 must not point to a valid object). Add to this that ptr is not required by the standard to actually
point to address 0 (as we discussed in this thread)... you could, theoretically, end up just about anywhere.
Welcome in the realm of language lawyers. In real life, above code should work perfectly just about everywhere.