Physical Memory Layout
Physical Memory Layout
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
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
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.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.
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 ArchitectureAlso 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?
Re:Physical Memory Layout
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.
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
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
Damn, I can't believe I made that mistake. Thanks for the correction.
Re:Physical Memory Layout
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
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Physical Memory Layout
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...
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
0 is not a valid pointer in either C or C++.Pete (aka Therx) wrote: ...is 0 an addressable piece of memory?
Every good solution is obvious once you've found it.
Re:Physical Memory Layout
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.Solar wrote: 0 is not a valid pointer in either C or C++.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Physical Memory Layout
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.
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
If you initialize a pointer with 0, it is guaranteed that this pointer never points to a valid data "object". (Both C and C++.)Candy wrote: 0 is a valid pointer, but it's only the operating system that defines it to be not good.
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".
Every good solution is obvious once you've found it.
Re:Physical Memory Layout
Indeed. AFAIK: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++.)
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");
}
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
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)... ;Dmystran wrote: Actually conversion between a pointer and a value type are not even required.
Every good solution is obvious once you've found it.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Physical Memory Layout
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
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.
Code: Select all
void *ptr=malloc(size);
if (!ptr) error("no memory);
And so far, even enabling -wall didn't throw me any warning at that kind of construct.
Re:Physical Memory Layout
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.
Code: Select all
char* ptr = 0;
ptr += 0xb8000;
Welcome in the realm of language lawyers. In real life, above code should work perfectly just about everywhere.
Every good solution is obvious once you've found it.