*** 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 ! + ! + ! Extended memory detection scheme retwiddled by orc@pell.chi.il.us (jessica l. + ! 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;