Messages in this thread | | | From | (david parsons) | Subject | A reworked memory detection scheme. | Date | 18 Jul 1997 17:51:47 -0700 |
| |
I've been modifying the memory detection code that I put into the development kernels a few generations ago, and I've got a version that may work a little bit more politely with LOADLIN and its ilk. While the earlier one passed memory back in 64k chunks, this one passes the memory in 1k chunks and uses a different location for the memory sizes returned by int13 0e801h. (Larry Augustine has a new memory scheme that he's planning to post here as well; I've readjusted my memory detect scheme so it uses the same different location as his (inferior, in my unbiased opinion ;-) solution.)
This works on modern motherboards with 64mb and less; I have yet to pull the farm of ancient and obsolete equipment out for backward compatability tests, but am confident that I have not fatally broken anything; but if anyone would like to test it, please do.
----(patch against 2.1.45)---- *** linux/arch/i386/boot/setup.S~ Fri Jul 18 16:13:12 1997 --- linux/arch/i386/boot/setup.S Fri Jul 18 16:31:35 1997 *************** *** 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 + ! #define __ASSEMBLY__ #include <linux/config.h> *************** *** 241,289 **** loader_ok: ! Get memory size (extended mem, kB) ! #ifdef STANDARD_MEMORY_BIOS_CALL ! mov ah,#0x88 ! int 0x15 ! mov [2],ax ! #else push ax push cx push dx ! which bootloader ? ! seg cs ! mov al,byte ptr type_of_loader ! and al,#0xf0 ! cmp al,#0x10 ! jne try_xe801 ! not Loadlin ! seg cs ! cmp byte ptr type_of_loader,#0x16 ! jbe oldstylemem ! Loadlin <= 1.6 don't like that ! try_xe801: mov ax,#0xe801 int 0x15 jc oldstylemem ! ! memory size is (ax+(64*bx)) * 1024; we store bx+(ax/64) ! mov [2],bx ! store extended memory size ! xor dx,dx ! mov cx,#64 ! convert lower memory size from K into ! div cx ! 64k chunks. ! add [2],ax ! add lower memory into total size. ! jmp gotmem oldstylemem: mov ah,#0x88 int 0x15 - or ax,ax ! some BIOSes report ZERO for 64meg - mov word ptr [2],#0x400 - jz gotmem - mov cx,#64 ! got memory size in kbytes, so we need to - xor dx,dx ! adjust to 64k chunks for the system. - div cx mov [2],ax ! gotmem: pop dx pop cx pop ax --- 245,293 ---- loader_ok: ! Get memory size (extended mem, kB) ! #ifndef STANDARD_MEMORY_BIOS_CALL push ax push cx push dx ! which bootloader ? ! ! needed anymore ? ! ! seg cs ! ! mov al,byte ptr type_of_loader ! ! and al,#0xf0 ! ! cmp al,#0x10 ! ! jne try_xe801 ! not Loadlin ! ! seg cs ! ! cmp byte ptr type_of_loader,#0x16 ! ! jbe oldstylemem ! Loadlin <= 1.6 don't like that ! !try_xe801: mov ax,#0xe801 int 0x15 jc oldstylemem ! ! 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.) ! ! and ebx, #0xffff ! clear sign extend ! shl ebx, 6 ! and go from 64k to 1k chunks ! mov [0x1e0],ebx ! store extended memory size ! and eax, #0xffff ! clear sign extend ! add [0x1e0],eax ! and add lower memory into total size. ! ! and fall into the old memory detection code to populate the ! ! compatability slot. oldstylemem: + #endif mov ah,#0x88 int 0x15 mov [2],ax ! ! #ifndef STANDARD_MEMORY_BIOS_CALL pop dx pop cx pop ax *** linux/arch/i386/kernel/setup.c~ Fri Jul 18 16:24:56 1997 --- linux/arch/i386/kernel/setup.c Fri Jul 18 16:28:18 1997 *************** *** 92,97 **** --- 92,100 ---- */ #define PARAM empty_zero_page #define EXT_MEM_K (*(unsigned short *) (PARAM+2)) + #ifndef STANDARD_MEMORY_BIOS_CALL + #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0)) + #endif #ifdef CONFIG_APM #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64)) #endif *************** *** 120,125 **** --- 123,129 ---- unsigned long * memory_start_p, unsigned long * memory_end_p)) { unsigned long memory_start, memory_end; + unsigned long memory_alt_end; char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; static unsigned char smptrap=0; *************** *** 143,152 **** BIOS_revision = SYS_DESC_TABLE.table[2]; } aux_device_present = AUX_DEVICE_INFO; - #ifdef STANDARD_MEMORY_BIOS_CALL memory_end = (1<<20) + (EXT_MEM_K<<10); ! #else ! memory_end = (1<<20) + (EXT_MEM_K*64L*1024L); /* 64kb chunks */ #endif memory_end &= PAGE_MASK; #ifdef CONFIG_BLK_DEV_RAM --- 147,161 ---- BIOS_revision = SYS_DESC_TABLE.table[2]; } aux_device_present = AUX_DEVICE_INFO; memory_end = (1<<20) + (EXT_MEM_K<<10); ! #ifndef STANDARD_MEMORY_BIOS_CALL ! memory_alt_end = (1<<20) + (ALT_MEM_K<<10); ! if (memory_alt_end > memory_end) { ! printk("memory sized by int13 0e801h\n"); ! memory_end = memory_alt_end; ! } ! else ! printk("memory sized by int13 088h\n"); #endif memory_end &= PAGE_MASK; #ifdef CONFIG_BLK_DEV_RAM ----(end patch)----
____ david parsons \bi/ fine hackery since 1960. \/
| |