New new enhanced memory detection patch; testers wanted

david parsons (o.r.c@p.e.l.l.p.o.r.t.l.a.n.d.o.r.u.s)
20 Feb 1999 01:46:33 -0800


The memory detect scheme I wrote for Linux 1.2.13 and 2.0.x has become
obsolete. Since I wrote it, many many bioses have stopped supporting
int 15h, 0e801h for extended memory detection and instead gone over to
int 15h, 0e820h. So, I've tweaked my memory detect patch to use 0e820
as well as 0e801 and 088

However, I no longer have access to quite as many machines as I used to
have, so I can't exhaustively test this patch. Does anyone want to try
this out and see if it lets the smoke out of their system? (no, I don't
have a 2.2 patch yet; I'll produce them on demand, but I'm still running
2.0.28 so I won't be able to verify that they actually work.)

____
david parsons \bi/ I sure hope nobody is using 1e4->1eb in the transfer
\/ block.

*** linux-2.0.28-orig/arch/i386/boot/setup.S Sat Mar 30 10:58:57 1996
--- linux-2.0.28+logo/arch/i386/boot/setup.S Sat Feb 20 01:16:49 1999
***************
*** 26,31 ****
--- 26,35 ----
!
! Video handling moved to video.S by Martin Mares, March 1996
! <mj@k332.feld.cvut.cz>
+ !
+ ! Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
+ ! parsons) to avoid loadlin confusion, July 1997
+ !

! NOTE! These had better be the same as in bootsect.s!
#define __ASSEMBLY__
***************
*** 232,237 ****
--- 236,319 ----
loader_ok:
! Get memory size (extended mem, kB)

+ #ifndef STANDARD_MEMORY_BIOS_CALL
+ xor ecx,ecx ! use `configured memory', and pre-zero
+ xor edx,edx ! the registers in case the bios lies
+ mov [0x1e0], ecx ! to us about the call being supported.
+ mov [0x1e4], ecx
+ mov [0x1e8], ecx
+
+ ! Try three different memory detection schemes. First, try
+ ! e820h, which lets us assemble a memory map, then try e801h,
+ ! which returns a 32-bit memory size, and finally 88h, which
+ ! returns 0-64m
+
+ ! method E820H:
+ ! the memory map from hell. e820h returns memory classified into
+ ! a whole bunch of different types, and allows memory holes and
+ ! everything. Currently, I don't care; I just add up all the
+ ! memory and hope that no memory holes will materialize to spoil
+ ! our fun.
+ !
+ ! BUGS: If there's a memory hole, this method will cheerfully ignore
+ ! it and keep adding up memory. It also doesn't truncate at 1mb,
+ ! but adds all memory between 0k and 0xfffK in.
+
+ meme820:
+ mov edx, #0x534d4150 ! ascii `SMAP'
+ xor ebx, ebx ! continuation counter
+ lea di, e820rec ! es:di points at the
+ ! data record.
+
+ jmpe820:
+ mov eax, #0x0000e820 ! e820, upper word zeroed
+ mov ecx, #20 ! size of the e820rec
+
+ int 0x15 ! make the call
+ jc meme801 ! fall to e801 if it fails
+
+ cmp eax, #0x534d4150 ! check the return is `SMAP'
+ jne meme801 ! fall to e801 if it fails
+
+ cmp ebx, #0 ! check to see if ebx is
+ je meme801 ! set to EOF
+
+ cmp e820rec+0x10, #1 ! is this usable memory?
+ jne jmpe820 ! no, grab the next chunk.
+
+ mov eax, e820rec+8+4 ! get low dword and high
+ mov ecx, e820rec+8+0 ! dword of memory size
+ add [0x1e4], ecx ! and add it into our
+ adc [0x1e8], eax ! long long accumulator
+
+ br jmpe820 ! then go back for more.
+
+ ! method E801H:
+ ! memory size is in 1k chunksizes, to avoid confusing loadlin.
+ ! we store the 0xe801 memory size in a completely different place,
+ ! because it will most likely be longer than 16 bits.
+ ! (use 1e0 because that's what Larry Augustine uses in his
+ ! alternative new memory detection scheme, and it's sensible
+ ! to write everything into the same place.)
+
+ meme801:
+
+ mov ax,#0xe801
+ int 0x15
+ jc mem88
+
+ and edx, #0xffff ! clear sign extend
+ shl edx, 6 ! and go from 64k to 1k chunks
+ mov [0x1e0],edx ! store extended memory size
+
+ and ecx, #0xffff ! clear sign extend
+ add [0x1e0],ecx ! and add lower memory into total size.
+
+ ! Ye Olde Traditional Methode. Returns the memory size (up to 16mb or
+ ! 64mb, depending on the bios) in ax.
+ mem88:
+
+ #endif
mov ah,#0x88
int 0x15
mov [2],ax
***************
*** 700,705 ****
--- 782,794 ----
gdt_48:
.word 0x800 ! gdt limit=2048, 256 GDT entries
.word 512+gdt,0x9 ! gdt base = 0X9xxxx
+
+ ! 0xe820 memory map block
+ !
+ e820rec:
+ .word 0,0,0,0 ! base address
+ .word 0,0,0,0 ! length in bytes
+ .word 0,0 ! type of address range

!
! Include video setup & detection code
*** linux-2.0.28-orig/arch/i386/kernel/setup.c Fri Sep 20 07:00:34 1996
--- linux-2.0.28+logo/arch/i386/kernel/setup.c Sat Feb 20 01:15:31 1999
***************
*** 82,87 ****
--- 82,91 ----
*/
#define PARAM empty_zero_page
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
+ #ifndef STANDARD_MEMORY_BIOS_CALL
+ #define E801_MEM_K (*(unsigned long *) (PARAM+0x1e0))
+ #define E820_MEM (*(unsigned long *) (PARAM+0x1e4))
+ #endif
#ifdef CONFIG_APM
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64))
#endif
***************
*** 109,114 ****
--- 113,119 ----
unsigned long * memory_start_p, unsigned long * memory_end_p)
{
unsigned long memory_start, memory_end;
+ unsigned long memory_e801_end, memory_e820_end;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
int len = 0;
static unsigned char smptrap=0;
***************
*** 127,132 ****
--- 132,157 ----
#endif
aux_device_present = AUX_DEVICE_INFO;
memory_end = (1<<20) + (EXT_MEM_K<<10);
+ #ifndef STANDARD_MEMORY_BIOS_CALL
+ memory_e801_end = (1<<20) + (E801_MEM_K<<10);
+
+ printk("Memory: 088: %12ld\n", memory_end);
+ printk("Memory: e801: %12ld\n", memory_e801_end);
+ printk("Memory: e820: %12ld\n", E820_MEM);
+
+ if ((memory_e801_end > memory_end) || (E820_MEM > memory_end)) {
+ if (memory_e801_end > E820_MEM) {
+ memory_end = memory_e801_end;
+ printk("Memory: %ld bytes, sized by 0e801h\n", memory_end);
+ }
+ else {
+ memory_end = E820_MEM;
+ printk("Memory: %ld bytes, sized by 0e820h\n", memory_end);
+ }
+ }
+ else
+ printk("Memory: %ld bytes, sized by 088h\n", memory_end);
+ #endif
memory_end &= PAGE_MASK;
#ifdef CONFIG_BLK_DEV_RAM
rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/