perhaps fix the bug that Linux cannot get a correct memory size.

This commit is contained in:
okuji 2000-05-04 22:15:20 +00:00
parent d08bfbd094
commit 5aef9e78a5
4 changed files with 60 additions and 21 deletions

View file

@ -1,3 +1,23 @@
2000-05-05 OKUJI Yoshinori <okuji@gnu.org>
Ignore any memory holes when passing the maximum memory address
to non-Multiboot kernels (i.e. Linux and *BSD).
* stage2/common.c [!STAGE1_5] (extended_memory): New global
variable.
(init_bios_info) [!STAGE1_5]: Change the type of CONT, MEMTMP
and ADDR to unsigned long from int.
Set EXTENDED_MEMORY to MBI.MEM_UPPER by default.
If MBI.MMAP_LENGTH is not zero, set EXTENDED_MEMORY to the
maximum available address, ignoring any memory holes.
If MBI.MMAP_LENGTH is zero but get_eisamemsize returns other
than -1, set EXTENDED_MEMORY to (CONT >> 10) + 0x3c00 if CONT is
non-zero, otherwise, set it to MEMTMP.
* stage2/shared.h [!STAGE1_5] (extended_memory): Declared.
* stage2/boot.c (load_image): Always pass the "mem=" option to a
Linux kernel, using EXTENDED_MEMORY instead of MBI.MEM_UPPER.
(bsd_boot): Use EXTENDED_MEMORY instead of MBI.MEM_UPPER.
2000-04-30 OKUJI Yoshinori <okuji@gnu.org> 2000-04-30 OKUJI Yoshinori <okuji@gnu.org>
* stage1/stage1.S (message): Use lodsb instead of incw and movb. * stage1/stage1.S (message): Use lodsb instead of incw and movb.

View file

@ -276,19 +276,12 @@ load_image (char *kernel, char *arg, kernel_t suggested_type)
*((unsigned short *) CL_OFFSET) = CL_MY_LOCATION - CL_BASE_ADDR; *((unsigned short *) CL_OFFSET) = CL_MY_LOCATION - CL_BASE_ADDR;
*((unsigned short *) CL_MAGIC_ADDR) = CL_MAGIC; *((unsigned short *) CL_MAGIC_ADDR) = CL_MAGIC;
/* Help Linux to find memory only if more than 64MB are present. grub_memmove (dest, "mem=", 4);
Up to that amount it is fairly capable to find by itself, dest += 4;
and at least newer Phoenix BIOSes are known to put a
10k hole just before 64MB, but report a proper total. */ dest = convert_to_ascii (dest, 'u', (extended_memory + 0x400));
if (mbi.mem_upper + 0x400 > 0x10000) *(dest++) = 'K';
{ *(dest++) = ' ';
grub_memmove ((char *) CL_MY_LOCATION, "mem=", 4);
dest = (char *) (CL_MY_LOCATION + 4);
dest = convert_to_ascii (dest, 'u', (mbi.mem_upper + 0x400));
*(dest++) = 'K';
*(dest++) = ' ';
}
while (*src && *src != ' ') while (*src && *src != ' ')
src++; src++;
@ -696,7 +689,7 @@ bsd_boot (kernel_t type, int bootdev, char *arg)
bi.bi_memsizes_valid = 1; bi.bi_memsizes_valid = 1;
bi.bi_bios_dev = saved_drive; bi.bi_bios_dev = saved_drive;
bi.bi_basemem = mbi.mem_lower; bi.bi_basemem = mbi.mem_lower;
bi.bi_extmem = mbi.mem_upper; bi.bi_extmem = extended_memory;
if (mbi.flags & MB_INFO_AOUT_SYMS) if (mbi.flags & MB_INFO_AOUT_SYMS)
{ {
@ -752,6 +745,6 @@ bsd_boot (kernel_t type, int bootdev, char *arg)
end_mark = 0; end_mark = 0;
(*entry_addr) (clval, bootdev, 0, end_mark, (*entry_addr) (clval, bootdev, 0, end_mark,
mbi.mem_upper, mbi.mem_lower); extended_memory, mbi.mem_lower);
} }
} }

View file

@ -30,6 +30,9 @@ unsigned long saved_drive;
unsigned long saved_partition; unsigned long saved_partition;
#ifndef STAGE1_5 #ifndef STAGE1_5
unsigned long saved_mem_upper; unsigned long saved_mem_upper;
/* This saves the maximum size of extended memory (in KB). */
unsigned long extended_memory;
#endif #endif
/* /*
@ -98,7 +101,7 @@ void
init_bios_info (void) init_bios_info (void)
{ {
#ifndef STAGE1_5 #ifndef STAGE1_5
int cont, memtmp, addr; unsigned long cont, memtmp, addr;
#endif #endif
/* /*
@ -117,6 +120,10 @@ init_bios_info (void)
gateA20 (1); gateA20 (1);
/* Store the size of extended memory in EXTENDED_MEMORY, in order to
tell it to non-Multiboot OSes. */
extended_memory = mbi.mem_upper;
/* /*
* The "mbi.mem_upper" variable only recognizes upper memory in the * The "mbi.mem_upper" variable only recognizes upper memory in the
* first memory region. If there are multiple memory regions, * first memory region. If there are multiple memory regions,
@ -134,11 +141,11 @@ init_bios_info (void)
cont = get_mmap_entry ((void *) addr, cont); cont = get_mmap_entry ((void *) addr, cont);
/* If the returned buffer's base is zero, quit. */ /* If the returned buffer's base is zero, quit. */
if (!*((int *) addr)) if (! *((unsigned long *) addr))
break; break;
mbi.mmap_length += *((int *) addr) + 4; mbi.mmap_length += *((unsigned long *) addr) + 4;
addr += *((int *) addr) + 4; addr += *((unsigned long *) addr) + 4;
} }
while (cont); while (cont);
@ -160,7 +167,7 @@ init_bios_info (void)
{ {
for (cont = 0, addr = mbi.mmap_addr; for (cont = 0, addr = mbi.mmap_addr;
addr < mbi.mmap_addr + mbi.mmap_length; addr < mbi.mmap_addr + mbi.mmap_length;
addr += *((int *) addr) + 4) addr += *((unsigned long *) addr) + 4)
{ {
if (((struct AddrRangeDesc *) addr)->BaseAddrHigh == 0 if (((struct AddrRangeDesc *) addr)->BaseAddrHigh == 0
&& ((struct AddrRangeDesc *) addr)->Type == MB_ARD_MEMORY && ((struct AddrRangeDesc *) addr)->Type == MB_ARD_MEMORY
@ -177,19 +184,37 @@ init_bios_info (void)
while (cont); while (cont);
mbi.mem_upper = (memtmp - 0x100000) >> 10; mbi.mem_upper = (memtmp - 0x100000) >> 10;
/* Find the maximum available address. Ignore any memory holes. */
for (addr = mbi.mmap_addr;
addr < mbi.mmap_addr + mbi.mmap_length;
addr += *((unsigned long *) addr) + 4)
{
struct AddrRangeDesc *desc = (struct AddrRangeDesc *) addr;
if (desc->BaseAddrHigh == 0
&& desc->Type == MB_ARD_MEMORY
&& desc->BaseAddrLow + desc->LengthLow > extended_memory)
extended_memory = desc->BaseAddrLow + desc->LengthLow;
}
} }
else if ((memtmp = get_eisamemsize ()) != -1) else if ((memtmp = get_eisamemsize ()) != -1)
{ {
cont = memtmp & ~0xFFFF; cont = memtmp & ~0xFFFF;
memtmp = memtmp & 0xFFFF; memtmp = memtmp & 0xFFFF;
if (cont != 0)
extended_memory = (cont >> 10) + 0x3c00;
else
extended_memory = memtmp;
if (!cont || (memtmp == 0x3c00)) if (!cont || (memtmp == 0x3c00))
memtmp += (cont >> 10); memtmp += (cont >> 10);
else else
{ {
/* XXX should I do this at all ??? */ /* XXX should I do this at all ??? */
mbi.mmap_addr = (int) fakemap; mbi.mmap_addr = (unsigned long) fakemap;
mbi.mmap_length = sizeof (fakemap); mbi.mmap_length = sizeof (fakemap);
fakemap[0].LengthLow = (mbi.mem_lower << 10); fakemap[0].LengthLow = (mbi.mem_lower << 10);
fakemap[1].LengthLow = (memtmp << 10); fakemap[1].LengthLow = (memtmp << 10);

View file

@ -525,6 +525,7 @@ extern unsigned long saved_drive;
extern unsigned long saved_partition; extern unsigned long saved_partition;
#ifndef STAGE1_5 #ifndef STAGE1_5
extern unsigned long saved_mem_upper; extern unsigned long saved_mem_upper;
extern unsigned long extended_memory;
#endif #endif
/* /*