I guess that the BIOS changing 7C00h-7DFFh is enough writing test and it's implicit (it's virtually impossible to have the same memory image there and 1 Megabyte above). The other test would be to test the even/odd Megabyte with interrupts disabled every time we end major tests and assume that the A20 line is enabled as soon as both Megabytes become different and stop trying to enable it (and always test for that before trying to enable it again right after jumping to the binary image).Octocontrabass wrote:If a machine happened to boot with the same data at both locations you check, there is no test more robust than attempting to change one and seeing if the other changes too.~ wrote:If that happens, reading or writing only a few bytes would no longer be a robust test and a best test could probably be comparing two whole contiguous Megabytes in an even-odd Megabyte pair.
Performing tests outside the first two megabytes can falsely report that A20 is enabled on some motherboards. Since the A20 gate only needs to affect the first two megabytes, some motherboards implement it in a way that only affects the first two megabytes, and the rest of the physical address space behaves as if A20 is always enabled.
What would be more important is to compare only user-space memory, not ROM, BIOS or device-mapped memory because that will make the tests fail if any device changes its state.
The right way to do the A20 enabling test would be to always write to the first Megabyte. In this way if you get a different result in the second Megabyte, the only reason could be that the A20 line is enabled (or that there's just 1 Megabyte of memory, but in that case we couldn't boot a big system anyway).Octocontrabass wrote:Your bootloader knows where everything is. It's easy to avoid destroying any data.~ wrote:I say that it would probably be better to avoid writing memory at all, first to prevent data destruction and to have a cleaner and more generic code, and second because writing memory could also give a false positive if CPU cache is involved, or if the hardware memory controller happens to hold data temporarily when there is no RAM present and we write that.
If the cache interferes with detecting the A20 status, DOS will fail. Any PC old enough for caches to be a concern is also old enough that no one would buy a PC that couldn't run DOS.
Nonexistent RAM is not a concern. You only care if writing in the second megabyte affects the first megabyte. It doesn't matter what happens to the data you've written to the second megabyte if it doesn't affect the first megabyte.
The right way is to write to existent RAM.
If you try to test the A20 line based on writing specifically to the second Megabyte, you won't know if it doesn't change the first Megabyte as well because the A20 line is enabled, or because the second Megabyte doesn't exist.
As can be seen, if we write the even Megabyte and then compare against the odd Megabyte, we are always certain that we use the most stable Megabyte as a pinpoint. We get rid of the uncertainty of nonexistent RAM and cache/stray values problems.
If by writing the even Megabyte the odd Megabyte becomes different, then that's the only certain and clean, stable test we are left with, that the A20 line is enabled.