wok-current 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[])