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>
* 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_MAGIC_ADDR) = CL_MAGIC;
/* Help Linux to find memory only if more than 64MB are present.
Up to that amount it is fairly capable to find by itself,
and at least newer Phoenix BIOSes are known to put a
10k hole just before 64MB, but report a proper total. */
if (mbi.mem_upper + 0x400 > 0x10000)
{
grub_memmove ((char *) CL_MY_LOCATION, "mem=", 4);
dest = (char *) (CL_MY_LOCATION + 4);
grub_memmove (dest, "mem=", 4);
dest += 4;
dest = convert_to_ascii (dest, 'u', (mbi.mem_upper + 0x400));
*(dest++) = 'K';
*(dest++) = ' ';
}
dest = convert_to_ascii (dest, 'u', (extended_memory + 0x400));
*(dest++) = 'K';
*(dest++) = ' ';
while (*src && *src != ' ')
src++;
@ -696,7 +689,7 @@ bsd_boot (kernel_t type, int bootdev, char *arg)
bi.bi_memsizes_valid = 1;
bi.bi_bios_dev = saved_drive;
bi.bi_basemem = mbi.mem_lower;
bi.bi_extmem = mbi.mem_upper;
bi.bi_extmem = extended_memory;
if (mbi.flags & MB_INFO_AOUT_SYMS)
{
@ -752,6 +745,6 @@ bsd_boot (kernel_t type, int bootdev, char *arg)
end_mark = 0;
(*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;
#ifndef STAGE1_5
unsigned long saved_mem_upper;
/* This saves the maximum size of extended memory (in KB). */
unsigned long extended_memory;
#endif
/*
@ -98,7 +101,7 @@ void
init_bios_info (void)
{
#ifndef STAGE1_5
int cont, memtmp, addr;
unsigned long cont, memtmp, addr;
#endif
/*
@ -117,6 +120,10 @@ init_bios_info (void)
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
* first memory region. If there are multiple memory regions,
@ -134,11 +141,11 @@ init_bios_info (void)
cont = get_mmap_entry ((void *) addr, cont);
/* If the returned buffer's base is zero, quit. */
if (!*((int *) addr))
if (! *((unsigned long *) addr))
break;
mbi.mmap_length += *((int *) addr) + 4;
addr += *((int *) addr) + 4;
mbi.mmap_length += *((unsigned long *) addr) + 4;
addr += *((unsigned long *) addr) + 4;
}
while (cont);
@ -160,7 +167,7 @@ init_bios_info (void)
{
for (cont = 0, addr = mbi.mmap_addr;
addr < mbi.mmap_addr + mbi.mmap_length;
addr += *((int *) addr) + 4)
addr += *((unsigned long *) addr) + 4)
{
if (((struct AddrRangeDesc *) addr)->BaseAddrHigh == 0
&& ((struct AddrRangeDesc *) addr)->Type == MB_ARD_MEMORY
@ -177,19 +184,37 @@ init_bios_info (void)
while (cont);
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)
{
cont = memtmp & ~0xFFFF;
memtmp = memtmp & 0xFFFF;
if (cont != 0)
extended_memory = (cont >> 10) + 0x3c00;
else
extended_memory = memtmp;
if (!cont || (memtmp == 0x3c00))
memtmp += (cont >> 10);
else
{
/* XXX should I do this at all ??? */
mbi.mmap_addr = (int) fakemap;
mbi.mmap_addr = (unsigned long) fakemap;
mbi.mmap_length = sizeof (fakemap);
fakemap[0].LengthLow = (mbi.mem_lower << 10);
fakemap[1].LengthLow = (memtmp << 10);

View file

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