# HG changeset patch # User Pascal Bellard # Date 1250613948 -7200 # Node ID 0cd931b3cd7975dddc088c373f1b84a6a157a694 # Parent 8c5c15fc1a404967d28d56b6d90d359d22e75768 syslinux/ifmem: use int15h / 0xe820h diff -r 8c5c15fc1a40 -r 0cd931b3cd79 syslinux/stuff/extra/ifmem.c --- a/syslinux/stuff/extra/ifmem.c Tue Aug 18 18:21:24 2009 +0200 +++ b/syslinux/stuff/extra/ifmem.c Tue Aug 18 18:45:48 2009 +0200 @@ -39,24 +39,55 @@ #include #include +struct e820_data { + uint64_t base; + uint64_t len; + uint32_t type; + uint32_t extattr; +} __attribute__((packed)); + +// Get memory size in Kb static unsigned long memory_size(void) { - unsigned long res; + unsigned long bytes = 0; com32sys_t ireg, oreg; + struct e820_data ed; memset(&ireg, 0, sizeof ireg); - ireg.eax.w[0] = 0xe801; - __intcall(0x15, &ireg, &oreg); + ireg.eax.w[0] = 0xe820; + ireg.edx.l = 0x534d4150; + ireg.ecx.l = sizeof(struct e820_data); + ireg.edi.w[0] = OFFS(__com32.cs_bounce); + ireg.es = SEG(__com32.cs_bounce); - res = oreg.ecx.w[0] + ( oreg.edx.w[0] << 6); - if (!res) { - memset(&ireg, 0, sizeof ireg); - ireg.eax.w[0] = 0x8800; - __intcall(0x15, &ireg, &oreg); - res = ireg.eax.w[0]; + memset(&ed, 0, sizeof ed); + ed.extattr = 1; + + do { + memcpy(__com32.cs_bounce, &ed, sizeof ed); + + __intcall(0x15, &ireg, &oreg); + if (oreg.eflags.l & EFLAGS_CF || + oreg.eax.l != 0x534d4150 || + oreg.ecx.l < 20) + break; + + memcpy(&ed, __com32.cs_bounce, sizeof ed); + + if (ed.type == 1) + bytes += ed.len; + + ireg.ebx.l = oreg.ebx.l; + } while (ireg.ebx.l); + + if (!bytes) { + memset(&ireg, 0, sizeof ireg); + ireg.eax.w[0] = 0x8800; + __intcall(0x15, &ireg, &oreg); + return ireg.eax.w[0]; } - return res; + return bytes / 1024; } int main(int argc, char *argv[])