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/