From a87a34141759f90a6facb89b1352ebf90b2107c0 Mon Sep 17 00:00:00 2001 From: okuji Date: Sat, 20 May 2000 21:35:20 +0000 Subject: [PATCH] improve some memory functions. --- ChangeLog | 25 ++++++++++++++++ THANKS | 1 + grub/asmstub.c | 60 ++++++++++++++++++++++++++++--------- stage2/asm.S | 9 +++--- stage2/common.c | 80 ++++++++++++++++++++++++++----------------------- 5 files changed, 118 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index a6e39f7a4..9c3495174 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2000-05-21 OKUJI Yoshinori + + * stage2/asm.S (set_int13_handler): Don't use MBI to get the + lower memory size. Instead, decrease it in the BIOS memory + directly and set %eax to it, since MBI.MEM_LOWER may not be the + same as [0x413] any longer due to the previous change. + + * grub/asmstub.c (CONVENTIONAL_MEMSIZE): Changed to 640 * 1024 + from 640. You didn't like the inconsistency between + EXTENDED_MEMSIZE and CONVENTIONAL_MEMSIZE, did you? + (get_memsize): Return CONVENTIONAL_MEMSIZE >> 10 instead of + CONVENTIONAL_MEMSIZE, if TYPE is zero. + (get_eisamemsize): Return EXTENDED_MEMSIZE >> 10 instead of + EXTENDED_MEMSIZE / 1024. Just a cosmetic change. + (MMAR_DESC_LENGTH): New macro. Defined as 20. + (get_mmap_entry): Define a new variable DESC_TABLE statically, + and copy the CONTth entry to *DESC if CONT is a correct index. + +2000-05-21 Chip Salzenberg + + * stage2/common.c (mmap_avail_at): New function, abstracted out + of init_bios_info, to scan E820 memory map. + (init_bios_info): Use mmap_avail_at for _both_ MBI.MEM_UPPER and + MBI.MEM_LOWER. + 2000-05-17 OKUJI Yoshinori Update the network support to Etherboot-4.6.1. diff --git a/THANKS b/THANKS index f3fa3634c..c7cd75535 100644 --- a/THANKS +++ b/THANKS @@ -11,6 +11,7 @@ Andrew Clausen Bradford Hovinen Brian Brunswick Bryan Ford +Chip Salzenberg Dan J. Walters Edmund GRIMLEY EVANS Edward Killips diff --git a/grub/asmstub.c b/grub/asmstub.c index eae7c4d97..e6180ac88 100644 --- a/grub/asmstub.c +++ b/grub/asmstub.c @@ -73,7 +73,7 @@ int grub_stage2 (void); /* Simulated memory sizes. */ #define EXTENDED_MEMSIZE (3 * 1024 * 1024) /* 3MB */ -#define CONVENTIONAL_MEMSIZE (640) /* 640kB */ +#define CONVENTIONAL_MEMSIZE (640 * 1024) /* 640kB */ /* Simulated disk sizes. */ #define DEFAULT_FD_CYLINDERS 80 @@ -684,10 +684,10 @@ get_code_end (void) int get_memsize (int type) { - if (!type) - return CONVENTIONAL_MEMSIZE; + if (! type) + return CONVENTIONAL_MEMSIZE >> 10; else - return EXTENDED_MEMSIZE; + return EXTENDED_MEMSIZE >> 10; } @@ -698,7 +698,7 @@ get_memsize (int type) int get_eisamemsize (void) { - return (EXTENDED_MEMSIZE / 1024); + return (EXTENDED_MEMSIZE >> 10); } @@ -707,26 +707,58 @@ get_eisamemsize (void) #define MMAR_DESC_TYPE_ACPI_RECLAIM 3 /* usable by OS after reading ACPI */ #define MMAR_DESC_TYPE_ACPI_NVS 4 /* required to save between NVS sessions */ +#define MMAR_DESC_LENGTH 20 + /* Fetch the next entry in the memory map and return the continuation value. DESC is a pointer to the descriptor buffer, and CONT is the previous continuation value (0 to get the first entry in the - map). */ + map). */ int get_mmap_entry (struct mmar_desc *desc, int cont) { - if (! cont) + /* Record the memory map statically. */ + static struct mmar_desc desc_table[] = + { + /* The conventional memory. */ { - /* First entry, located at 1MB. */ - desc->desc_len = sizeof (*desc) - sizeof (desc->desc_len); - desc->addr = 1024 * 1024; - desc->length = EXTENDED_MEMSIZE; - desc->type = MMAR_DESC_TYPE_AVAILABLE; + MMAR_DESC_LENGTH, + 0, + CONVENTIONAL_MEMSIZE, + MMAR_DESC_TYPE_AVAILABLE + }, + /* BIOS RAM and ROM (such as video memory). */ + { + MMAR_DESC_LENGTH, + CONVENTIONAL_MEMSIZE, + 0x100000 - CONVENTIONAL_MEMSIZE, + MMAR_DESC_TYPE_RESERVED + }, + /* The extended memory. */ + { + MMAR_DESC_LENGTH, + 0x100000, + EXTENDED_MEMSIZE, + MMAR_DESC_TYPE_AVAILABLE + } + }; + + int num = sizeof (desc_table) / sizeof (*desc_table); + + if (cont < 0 || cont >= num) + { + /* Should not happen. */ + desc->desc_len = 0; } else { - /* No more entries, so give an error. */ - desc->desc_len = 0; + /* Copy the entry. */ + *desc = desc_table[cont++]; + + /* If the next entry exists, return the index. */ + if (cont < num) + return cont; } + return 0; } diff --git a/stage2/asm.S b/stage2/asm.S index aacd58214..9d1e942e6 100644 --- a/stage2/asm.S +++ b/stage2/asm.S @@ -564,13 +564,12 @@ ENTRY(set_int13_handler) movw 2(%edi), %ax movw %ax, ABS(int13_segment) - /* get the lower memory size */ - movl $EXT_C(mbi), %edi - movl 4(%edi), %eax /* decrease the lower memory size and set it to the BIOS memory */ - decl %eax movl $0x413, %edi - movw %ax, (%edi) + decw (%edi) + xorl %eax, %eax + movw (%edi), %ax + /* compute the segment */ shll $6, %eax diff --git a/stage2/common.c b/stage2/common.c index 54ff004da..1a39c4ad1 100644 --- a/stage2/common.c +++ b/stage2/common.c @@ -90,13 +90,42 @@ static struct AddrRangeDesc fakemap[3] = {20, 0x100000, 0, 0, 0, MB_ARD_MEMORY}, {20, 0x1000000, 0, 0, 0, MB_ARD_MEMORY} }; -#endif /* STAGE1_5 */ +/* A big problem is that the memory areas aren't guaranteed to be: + (1) contiguous, (2) sorted in ascending order, or (3) non-overlapping. + Thus this kludge. */ +static unsigned long +mmap_avail_at (unsigned long bottom) +{ + unsigned long top, addr; + int cont; + + top = bottom; + do + { + for (cont = 0, 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 <= top + && desc->BaseAddrLow + desc->LengthLow > top) + { + top = desc->BaseAddrLow + desc->LengthLow; + cont++; + } + } + } + while (cont); + + return top - bottom; +} +#endif /* ! STAGE1_5 */ -/* - * This queries for BIOS information. - */ - +/* This queries for BIOS information. */ void init_bios_info (void) { @@ -140,7 +169,7 @@ init_bios_info (void) { cont = get_mmap_entry ((void *) addr, cont); - /* If the returned buffer's base is zero, quit. */ + /* If the returned buffer's length is zero, quit. */ if (! *((unsigned long *) addr)) break; @@ -152,41 +181,16 @@ init_bios_info (void) if (mbi.mmap_length) { /* - * This is to get the upper memory up to the first memory - * hole into the "mbi.mem_upper" element, for OS's that - * don't care about the memory map, but might care about - * RAM above 64MB. - * - * A big problem is that the memory areas aren't guaranteed - * to be: (1) contiguous, (2) sorted in ascending order, or - * (3) non-overlapping. + * This is to get the lower memory, and upper memory (up to the + * first memory hole), into the "mbi.mem_{lower,upper}" + * elements. This is for OS's that don't care about the memory + * map, but might care about total RAM available. */ - memtmp = 0x100000; + mbi.mem_lower = mmap_avail_at (0) >> 10; + mbi.mem_upper = mmap_avail_at (0x100000) >> 10; - do - { - for (cont = 0, addr = mbi.mmap_addr; - addr < mbi.mmap_addr + mbi.mmap_length; - addr += *((unsigned long *) addr) + 4) - { - if (((struct AddrRangeDesc *) addr)->BaseAddrHigh == 0 - && ((struct AddrRangeDesc *) addr)->Type == MB_ARD_MEMORY - && ((struct AddrRangeDesc *) addr)->BaseAddrLow <= memtmp - && (((struct AddrRangeDesc *) addr)->BaseAddrLow - + ((struct AddrRangeDesc *) addr)->LengthLow) > memtmp) - { - memtmp = (((struct AddrRangeDesc *) addr)->BaseAddrLow - + ((struct AddrRangeDesc *) addr)->LengthLow); - cont++; - } - } - } - while (cont); - - mbi.mem_upper = (memtmp - 0x100000) >> 10; - /* Find the maximum available address. Ignore any memory holes. */ - for (addr = mbi.mmap_addr; + for (memtmp = 0, addr = mbi.mmap_addr; addr < mbi.mmap_addr + mbi.mmap_length; addr += *((unsigned long *) addr) + 4) {