Why is the memory size returned by E801h BIOS interrupt 15h ignored on linux?

359 Views Asked by At

I'm studying linux-3.9.9 memory detect code. I can't understand the code:

} else if (oreg.ax == 15*1024) {
     boot_params.alt_mem_k = (oreg.bx << 6) + oreg.ax;

Q1 Why memory size is stored to boot_params.alt_mem_k only when the condition (oreg.ax == 15*1024) is satisfied?

 } else {
     boot_params.alt_mem_k = oreg.ax; 
 }

Q2 Why ignore memory above 16MB in the else condition?

Although a comment explains the reason why, I can't understand this, because I can't find any information about "memory hole".

This detect_memory_e801 function is located in < linux-3.9.9/arch/x86/boot/memory.c >.

The whole source is like below:

static int detect_memory_e801(void)
{
      struct biosregs ireg, oreg;
      initregs(&ireg);
      ireg.ax = 0xe801;
      intcall(0x15, &ireg, &oreg); 
      if (oreg.eflags & X86_EFLAGS_CF)
          return -1;

      /* Do we really need to do this? */
      if (oreg.cx || oreg.dx) {
          oreg.ax = oreg.cx;
          oreg.bx = oreg.dx;
      }
      if (oreg.ax > 15*1024) {
          return -1;  /* Bogus! */
      } else if (oreg.ax == 15*1024) {
          boot_params.alt_mem_k = (oreg.bx << 6) + oreg.ax;
      } else {
    /*
     * This ignores memory above 16MB if we have a memory
     * hole there.  If someone actually finds a machine
     * with a memory hole at 16MB and no support for
     * 0E820h they should probably generate a fake e820
     * map.
     */
          boot_params.alt_mem_k = oreg.ax; 
      }
      return 0;
}
1

There are 1 best solutions below

1
On

The idea is that if ax < 15k then you either have <16MB memory in which case bx should be zero and can be ignored, or you have >16MB memory with a hole starting below 16MB and ending somewhere above 16MB. However from this information, the size of the hole can't be determined and the safe choice is to ignore the memory above 16MB in this case because it's not contiguous.