wok rev 3918

syslinux/ifmem: use int15h / 0xe820h
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Aug 18 18:45:48 2009 +0200 (2009-08-18)
parents 8c5c15fc1a40
children a64e9d9bbe8c
files syslinux/stuff/extra/ifmem.c
line diff
     1.1 --- a/syslinux/stuff/extra/ifmem.c	Tue Aug 18 18:21:24 2009 +0200
     1.2 +++ b/syslinux/stuff/extra/ifmem.c	Tue Aug 18 18:45:48 2009 +0200
     1.3 @@ -39,24 +39,55 @@
     1.4  #include <stdlib.h>
     1.5  #include <syslinux/boot.h>
     1.6  
     1.7 +struct e820_data {
     1.8 +  uint64_t base;
     1.9 +  uint64_t len;
    1.10 +  uint32_t type;
    1.11 +  uint32_t extattr;
    1.12 +} __attribute__((packed));
    1.13 +
    1.14 +// Get memory size in Kb
    1.15  static unsigned long memory_size(void)
    1.16  {
    1.17 -  unsigned long res;
    1.18 +  unsigned long bytes = 0;
    1.19    com32sys_t ireg, oreg;
    1.20 +  struct e820_data ed;
    1.21  
    1.22    memset(&ireg, 0, sizeof ireg);
    1.23  
    1.24 -  ireg.eax.w[0] = 0xe801;
    1.25 -  __intcall(0x15, &ireg, &oreg);
    1.26 +  ireg.eax.w[0] = 0xe820;
    1.27 +  ireg.edx.l    = 0x534d4150;
    1.28 +  ireg.ecx.l    = sizeof(struct e820_data);
    1.29 +  ireg.edi.w[0] = OFFS(__com32.cs_bounce);
    1.30 +  ireg.es       = SEG(__com32.cs_bounce);
    1.31  
    1.32 -  res = oreg.ecx.w[0] + ( oreg.edx.w[0] << 6);
    1.33 -  if (!res) {
    1.34 -  	memset(&ireg, 0, sizeof ireg);
    1.35 -  	ireg.eax.w[0] = 0x8800;
    1.36 -  	__intcall(0x15, &ireg, &oreg);
    1.37 -	res = ireg.eax.w[0];
    1.38 +  memset(&ed, 0, sizeof ed);
    1.39 +  ed.extattr = 1;
    1.40 +
    1.41 +  do {
    1.42 +    memcpy(__com32.cs_bounce, &ed, sizeof ed);
    1.43 +
    1.44 +    __intcall(0x15, &ireg, &oreg);
    1.45 +    if (oreg.eflags.l & EFLAGS_CF ||
    1.46 +	oreg.eax.l != 0x534d4150 ||
    1.47 +	oreg.ecx.l < 20)
    1.48 +      break;
    1.49 +
    1.50 +    memcpy(&ed, __com32.cs_bounce, sizeof ed);
    1.51 +
    1.52 +    if (ed.type == 1)
    1.53 +       bytes += ed.len;
    1.54 +
    1.55 +    ireg.ebx.l = oreg.ebx.l;
    1.56 +  } while (ireg.ebx.l);
    1.57 +
    1.58 +  if (!bytes) {
    1.59 +     memset(&ireg, 0, sizeof ireg);
    1.60 +     ireg.eax.w[0] = 0x8800;
    1.61 +     __intcall(0x15, &ireg, &oreg);
    1.62 +     return ireg.eax.w[0];
    1.63    }
    1.64 -  return res;
    1.65 +  return bytes / 1024;
    1.66  }
    1.67  
    1.68  int main(int argc, char *argv[])