Fancy memory detection patch (2.2.10/ 2.3.6)

david parsons (orc@pell.chi.il.us)
18 Jun 1999 03:35:23 -0700


I've tweaked my memory detection patch to deal with memory holes
(if they're returned to the system by the e820 memory call), but
the 2.2.x and 2.3.x patches suffer from the big problem that I
don't use those kernels in production yet. I've tried the boot
test, and both of these kernels will either (a) boot up to the
point where they can't find the root filesystem (boot floppy)
or Mastodon fails because these new kernels took out the old
flock methods and I've not patch them back in. This same patch
on 2.0.28+logo works well enough for me to put it on a workstation,
enable a memory hole, and do things without it either losing 96mb
of memory or crashing horribly.

So, if you are bold, here are my fancy memory detection patches.
If they don't make systems explode, turn purple, or some similar
antisocial behavior, I'll submit them for inclusion in the main
kernel.

There's one little unrelated makefile patch in here; it's part
of my "not everything is a GNU" patches I've had to apply to
get kernels to actually compile on Mastodon (which uses BSD
programs, not GNU ones.)

To put additional room into the empty_zero_block, I've dropped
a little trampoline into setup.S -- the initial jump now jumps
to a CALL instruction, which then pushes junk onto the stack
and leaps over a 1k scratch area I've put before setup.S starts
up. I don't think this will cause any problems, but will it
make the branch predictor in modern ia32 processors get horribly
confused?

____
david parsons \bi/ Oh, yeah, and the commenting sucks.
\/

---[ cut here for 2.2.10]----
diff -Naur linux-2.2.10-orig/Makefile linux-2.2.10/Makefile
--- linux-2.2.10-orig/Makefile Fri May 28 18:10:19 1999
+++ linux-2.2.10/Makefile Fri Jun 18 02:59:17 1999
@@ -343,8 +343,8 @@

clean: archclean
rm -f kernel/ksyms.lst include/linux/compile.h
- rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' \
- ! -regex '.*ksymoops/.*' -print`
+ find . -name '*.[oas]' -print | grep -v lxdialog/ \
+ | grep -v ksymoops/ | xargs rm -f
rm -f core `find . -type f -name 'core' -print`
rm -f core `find . -name '.*.flags' -print`
rm -f vmlinux System.map
diff -Naur linux-2.2.10-orig/arch/i386/boot/setup.S linux-2.2.10/arch/i386/boot/setup.S
--- linux-2.2.10-orig/arch/i386/boot/setup.S Mon Jun 7 16:13:07 1999
+++ linux-2.2.10/arch/i386/boot/setup.S Fri Jun 18 02:14:22 1999
@@ -37,6 +37,7 @@
#include <linux/version.h>
#include <linux/compile.h>
#include <asm/boot.h>
+#include <asm/e820.h>

! Signature words to ensure LILO loaded us right
#define SIG1 0xAA55
@@ -59,7 +60,7 @@

entry start
start:
- jmp start_of_setup
+ jmp trampoline
! ------------------------ start of header --------------------------------
!
! SETUP-header, must start at CS:2 (old 0x9020:2)
@@ -119,6 +120,8 @@
heap_end_ptr: .word modelist+1024 ! space from here (exclusive) down to
! end of setup code can be used by setup
! for local heap purposes.
+trampoline: call start_of_setup
+ .space 1024
! ------------------------ end of header ----------------------------------

start_of_setup:
@@ -245,37 +248,100 @@
loader_ok:
! Get memory size (extended mem, kB)

+ xor eax, eax
+ mov dword ptr [0x1e0], eax
#ifndef STANDARD_MEMORY_BIOS_CALL
- push ebx

- xor ebx,ebx ! preload new memory slot with 0k
- mov [0x1e0], ebx
+ mov dword ptr [E820MEM], eax
+ mov dword ptr [E820NR], eax
+
+! 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. We scan through this memory map and build a list
+! of the first 32 available memory areas, which we return at [0xC20].
+! We also make a stab at the memory size by the somewhat gross approach
+! of setting memsize to the address+size of the LAST available memory
+! we picked up. This assumes that e820 returns memory regions in strictly
+! increasing order; if a bios returns those memory regions in any other
+! order, we will be in for a world of pain.
+!
+
+meme820:
+ mov edx, #0x534d4150 ! ascii `SMAP'
+ xor ebx, ebx ! continuation counter
+
+jmpe820:
+ mov eax, #0x0000e820 ! e820, upper word zeroed
+ mov ecx, #20 ! size of the e820rec
+
+ mov dword ptr [E820+16], #42
+ mov di, #E820 ! es:di points at the
+ push ds ! data record.
+ pop es
+ 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 dword ptr [E820+16], #1 ! is this usable memory?
+ jne again820
+
+ ! usable memory: add it to the whitelist
+ !
+good820:
+ mov al, byte ptr [E820NR]
+ cmp al, #E820MAX
+ jnl again820
+ inc byte ptr [E820NR]
+ and ax, #0xff ! clear sign extend
+ shl ax, 3 ! double dword alignment
+ mov si, ax
+ mov ecx, dword ptr [E820+8] ! pick up low dword of memsize
+ mov eax, dword ptr [E820+0] ! pick up low dword of address
+ mov E820MAP(si), eax ! store address in whitelist
+ mov E820MAP+4(si), ecx ! store size in whitelist
+
+ add eax, ecx ! set end_mem to address + memsize
+ mov [E820MEM], eax
+
+again820:
+ cmp ebx, #0 ! check to see if ebx is
+ jne jmpe820 ! set to EOF

- mov ax,#0xe801
- int 0x15
- jc oldstylemem

-! Memory size is in 1 k chunksizes, to avoid confusing loadlin.
-! We store the 0xe801 memory size in a completely different place,
+
+! 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.)

- 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
- ! compatibility slot.
+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:

-oldstylemem:
- pop ebx
-#else
- mov dword ptr [0x1e0], #0
#endif
mov ah,#0x88
int 0x15
diff -Naur linux-2.2.10-orig/arch/i386/kernel/setup.c linux-2.2.10/arch/i386/kernel/setup.c
--- linux-2.2.10-orig/arch/i386/kernel/setup.c Tue Jun 8 10:43:21 1999
+++ linux-2.2.10/arch/i386/kernel/setup.c Fri Jun 18 02:53:05 1999
@@ -49,6 +49,7 @@
#include <asm/smp.h>
#include <asm/cobalt.h>
#include <asm/msr.h>
+#include <asm/e820.h>

/*
* Machine setup..
@@ -82,6 +83,8 @@
unsigned char table[0];
};

+struct e820map e820 = { 0 };
+
unsigned char aux_device_present;

#ifdef CONFIG_BLK_DEV_RAM
@@ -101,6 +104,9 @@
#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
#define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
+#define E820_MEM (*(unsigned long *) (PARAM+E820MEM))
+#define E820_MAP_NR (*(char*) (PARAM+E820NR))
+#define E820_MAP ((unsigned long *) (PARAM+E820MAP))
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
@@ -277,9 +283,27 @@
#ifndef STANDARD_MEMORY_BIOS_CALL
{
unsigned long memory_alt_end = (1<<20) + (ALT_MEM_K<<10);
- /* printk(KERN_DEBUG "Memory sizing: %08x %08x\n", memory_end, memory_alt_end); */
+ unsigned long *mem = E820_MAP;
+
if (memory_alt_end > memory_end)
memory_end = memory_alt_end;
+
+ if (E820_MEM > memory_end)
+ memory_end = E820_MEM;
+
+ if ((e820.nr_map = E820_MAP_NR) > 0) {
+ int x;
+
+ if (e820.nr_map > E820MAX)
+ e820.nr_map = 0;
+ else for (x = 0; x < e820.nr_map; x++) {
+ e820.map[x].addr = *(mem++);
+ e820.map[x].size = *(mem++);
+ /*printk("E820: region %d, %lu bytes @ %08lx\n",
+ x, e820.map[x].size, e820.map[x].addr);*/
+ }
+ }
+
}
#endif

diff -Naur linux-2.2.10-orig/arch/i386/mm/init.c linux-2.2.10/arch/i386/mm/init.c
--- linux-2.2.10-orig/arch/i386/mm/init.c Thu Jan 21 11:28:40 1999
+++ linux-2.2.10/arch/i386/mm/init.c Fri Jun 18 02:55:43 1999
@@ -27,6 +27,7 @@
#include <asm/pgtable.h>
#include <asm/dma.h>
#include <asm/fixmap.h>
+#include <asm/e820.h>

extern void show_net_buffers(void);
extern unsigned long init_smp_mappings(unsigned long);
@@ -390,6 +391,18 @@
int datapages = 0;
int initpages = 0;
unsigned long tmp;
+ unsigned long start_seg = 0;
+ unsigned long size_seg = ~0;
+ int nr_map = 0;
+
+ if (nr_map < e820.nr_map) {
+ start_seg = e820.map[nr_map].addr + PAGE_OFFSET;
+ size_seg = e820.map[nr_map].size;
+ printk("region %d: %lu bytes @ %08lx\n",
+ nr_map, size_seg, start_seg - PAGE_OFFSET);
+ nr_map++;
+ }
+

end_mem &= PAGE_MASK;
high_memory = (void *) end_mem;
@@ -424,7 +437,23 @@
}

while (start_mem < end_mem) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
+ if (start_mem > start_seg) {
+ if (start_mem < start_seg + size_seg)
+ clear_bit(PG_reserved,
+ &mem_map[MAP_NR(start_mem)].flags);
+ else if (nr_map < e820.nr_map) {
+ start_seg = e820.map[nr_map].addr + PAGE_OFFSET;
+ size_seg = e820.map[nr_map].size;
+ printk("region %d: %lu bytes @ %08lx\n",
+ nr_map, size_seg, start_seg - PAGE_OFFSET);
+ nr_map++;
+ continue; /* be paranoid in case the */
+ /* e820 code hasn't collapsed */
+ /* adjacent usable memory */
+ }
+ else
+ break; /* no more valid memory */
+ }
start_mem += PAGE_SIZE;
}
for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
diff -Naur linux-2.2.10-orig/include/asm-i386/e820.h linux-2.2.10/include/asm-i386/e820.h
--- linux-2.2.10-orig/include/asm-i386/e820.h Wed Dec 31 16:00:00 1969
+++ linux-2.2.10/include/asm-i386/e820.h Fri Jun 18 02:12:12 1999
@@ -0,0 +1,34 @@
+/*
+ * structures and definitions for the int 15, ax=e820 memory map
+ * scheme.
+ *
+ * In a nutshell, arch/i386/boot/setup.S populates a scratch table
+ * in the empty_zero_block that contains a list of usable address/size
+ * duples. In arch/i386/kernel/setup.c, this information is
+ * transferred into the e820map, and in arch/i386/mm/init.c, that
+ * new information is used to mark pages reserved or not.
+ *
+ */
+#ifndef __E820_HEADER
+#define __E820_HEADER
+
+#define E820 0x2d0 /* scratch area */
+#define E820MAP 0x300 /* our map */
+#define E820MAX 32 /* number of entries in E820MAP */
+#define E820MEM 0x1e4 /* memtop from e820 calls */
+#define E820NR 0x1e8 /* # entries in E820MAP */
+
+#ifndef __ASSEMBLY__
+
+struct e820map {
+ int nr_map;
+ struct {
+ unsigned long addr;
+ unsigned long size;
+ } map[E820MAX];
+};
+
+extern struct e820map e820;
+#endif/*!__ASSEMBLY__*/
+
+#endif/*__E820_HEADER*/

----[ cut here for 2.3.6]----

diff -Naur linux-2.3.6-orig/Makefile linux-2.3.6/Makefile
--- linux-2.3.6-orig/Makefile Wed Jun 2 14:40:19 1999
+++ linux-2.3.6/Makefile Fri Jun 18 03:03:06 1999
@@ -343,8 +343,8 @@

clean: archclean
rm -f kernel/ksyms.lst include/linux/compile.h
- rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' \
- ! -regex '.*ksymoops/.*' -print`
+ find . -name '*.[oas]' -print | grep -v lxdialog/ \
+ | grep -v ksymoops/ | xargs rm -f
rm -f core `find . -type f -name 'core' -print`
rm -f core `find . -name '.*.flags' -print`
rm -f vmlinux System.map
diff -Naur linux-2.3.6-orig/arch/i386/boot/setup.S linux-2.3.6/arch/i386/boot/setup.S
--- linux-2.3.6-orig/arch/i386/boot/setup.S Sat Nov 28 17:18:54 1998
+++ linux-2.3.6/arch/i386/boot/setup.S Fri Jun 18 03:03:06 1999
@@ -37,6 +37,7 @@
#include <linux/version.h>
#include <linux/compile.h>
#include <asm/boot.h>
+#include <asm/e820.h>

! Signature words to ensure LILO loaded us right
#define SIG1 0xAA55
@@ -59,7 +60,7 @@

entry start
start:
- jmp start_of_setup
+ jmp trampoline
! ------------------------ start of header --------------------------------
!
! SETUP-header, must start at CS:2 (old 0x9020:2)
@@ -119,6 +120,8 @@
heap_end_ptr: .word modelist+1024 ! space from here (exclusive) down to
! end of setup code can be used by setup
! for local heap purposes.
+trampoline: call start_of_setup
+ .space 1024
! ------------------------ end of header ----------------------------------

start_of_setup:
@@ -245,37 +248,100 @@
loader_ok:
! Get memory size (extended mem, kB)

+ xor eax, eax
+ mov dword ptr [0x1e0], eax
#ifndef STANDARD_MEMORY_BIOS_CALL
- push ebx

- xor ebx,ebx ! preload new memory slot with 0k
- mov [0x1e0], ebx
+ mov dword ptr [E820MEM], eax
+ mov dword ptr [E820NR], eax
+
+! 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. We scan through this memory map and build a list
+! of the first 32 available memory areas, which we return at [0xC20].
+! We also make a stab at the memory size by the somewhat gross approach
+! of setting memsize to the address+size of the LAST available memory
+! we picked up. This assumes that e820 returns memory regions in strictly
+! increasing order; if a bios returns those memory regions in any other
+! order, we will be in for a world of pain.
+!
+
+meme820:
+ mov edx, #0x534d4150 ! ascii `SMAP'
+ xor ebx, ebx ! continuation counter
+
+jmpe820:
+ mov eax, #0x0000e820 ! e820, upper word zeroed
+ mov ecx, #20 ! size of the e820rec
+
+ mov dword ptr [E820+16], #42
+ mov di, #E820 ! es:di points at the
+ push ds ! data record.
+ pop es
+ 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 dword ptr [E820+16], #1 ! is this usable memory?
+ jne again820
+
+ ! usable memory: add it to the whitelist
+ !
+good820:
+ mov al, byte ptr [E820NR]
+ cmp al, #E820MAX
+ jnl again820
+ inc byte ptr [E820NR]
+ and ax, #0xff ! clear sign extend
+ shl ax, 3 ! double dword alignment
+ mov si, ax
+ mov ecx, dword ptr [E820+8] ! pick up low dword of memsize
+ mov eax, dword ptr [E820+0] ! pick up low dword of address
+ mov E820MAP(si), eax ! store address in whitelist
+ mov E820MAP+4(si), ecx ! store size in whitelist
+
+ add eax, ecx ! set end_mem to address + memsize
+ mov [E820MEM], eax
+
+again820:
+ cmp ebx, #0 ! check to see if ebx is
+ jne jmpe820 ! set to EOF

- mov ax,#0xe801
- int 0x15
- jc oldstylemem

-! Memory size is in 1 k chunksizes, to avoid confusing loadlin.
-! We store the 0xe801 memory size in a completely different place,
+
+! 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.)

- 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
- ! compatibility slot.
+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:

-oldstylemem:
- pop ebx
-#else
- mov dword ptr [0x1e0], #0
#endif
mov ah,#0x88
int 0x15
diff -Naur linux-2.3.6-orig/arch/i386/kernel/setup.c linux-2.3.6/arch/i386/kernel/setup.c
--- linux-2.3.6-orig/arch/i386/kernel/setup.c Tue Jun 8 10:42:46 1999
+++ linux-2.3.6/arch/i386/kernel/setup.c Fri Jun 18 03:03:06 1999
@@ -49,6 +49,7 @@
#include <asm/smp.h>
#include <asm/cobalt.h>
#include <asm/msr.h>
+#include <asm/e820.h>

/*
* Machine setup..
@@ -82,6 +83,8 @@
unsigned char table[0];
};

+struct e820map e820 = { 0 };
+
unsigned char aux_device_present;

#ifdef CONFIG_BLK_DEV_RAM
@@ -101,6 +104,9 @@
#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
#define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
+#define E820_MEM (*(unsigned long *) (PARAM+E820MEM))
+#define E820_MAP_NR (*(char*) (PARAM+E820NR))
+#define E820_MAP ((unsigned long *) (PARAM+E820MAP))
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
@@ -277,9 +283,27 @@
#ifndef STANDARD_MEMORY_BIOS_CALL
{
unsigned long memory_alt_end = (1<<20) + (ALT_MEM_K<<10);
- /* printk(KERN_DEBUG "Memory sizing: %08x %08x\n", memory_end, memory_alt_end); */
+ unsigned long *mem = E820_MAP;
+
if (memory_alt_end > memory_end)
memory_end = memory_alt_end;
+
+ if (E820_MEM > memory_end)
+ memory_end = E820_MEM;
+
+ if ((e820.nr_map = E820_MAP_NR) > 0) {
+ int x;
+
+ if (e820.nr_map > E820MAX)
+ e820.nr_map = 0;
+ else for (x = 0; x < e820.nr_map; x++) {
+ e820.map[x].addr = *(mem++);
+ e820.map[x].size = *(mem++);
+ /*printk("E820: region %d, %lu bytes @ %08lx\n",
+ x, e820.map[x].size, e820.map[x].addr);*/
+ }
+ }
+
}
#endif

diff -Naur linux-2.3.6-orig/arch/i386/mm/init.c linux-2.3.6/arch/i386/mm/init.c
--- linux-2.3.6-orig/arch/i386/mm/init.c Tue Jun 8 10:49:48 1999
+++ linux-2.3.6/arch/i386/mm/init.c Fri Jun 18 03:04:46 1999
@@ -27,6 +27,7 @@
#include <asm/pgtable.h>
#include <asm/dma.h>
#include <asm/fixmap.h>
+#include <asm/e820.h>

extern void show_net_buffers(void);
extern unsigned long init_smp_mappings(unsigned long);
@@ -392,6 +393,19 @@
unsigned long tmp;
unsigned long endbase;

+ unsigned long start_seg = 0;
+ unsigned long size_seg = ~0;
+ int nr_map = 0;
+
+ if (nr_map < e820.nr_map) {
+ start_seg = e820.map[nr_map].addr + PAGE_OFFSET;
+ size_seg = e820.map[nr_map].size;
+ printk("region %d: %lu bytes @ %08lx\n",
+ nr_map, size_seg, start_seg - PAGE_OFFSET);
+ nr_map++;
+ }
+
+
end_mem &= PAGE_MASK;
high_memory = (void *) end_mem;
max_mapnr = num_physpages = MAP_NR(end_mem);
@@ -427,7 +441,23 @@
}

while (start_mem < end_mem) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
+ if (start_mem > start_seg) {
+ if (start_mem < start_seg + size_seg)
+ clear_bit(PG_reserved,
+ &mem_map[MAP_NR(start_mem)].flags);
+ else if (nr_map < e820.nr_map) {
+ start_seg = e820.map[nr_map].addr + PAGE_OFFSET;
+ size_seg = e820.map[nr_map].size;
+ printk("region %d: %lu bytes @ %08lx\n",
+ nr_map, size_seg, start_seg - PAGE_OFFSET);
+ nr_map++;
+ continue; /* be paranoid in case the */
+ /* e820 code hasn't collapsed */
+ /* adjacent usable memory */
+ }
+ else
+ break; /* no more valid memory */
+ }
start_mem += PAGE_SIZE;
}
for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
diff -Naur linux-2.3.6-orig/include/asm-i386/e820.h linux-2.3.6/include/asm-i386/e820.h
--- linux-2.3.6-orig/include/asm-i386/e820.h Wed Dec 31 16:00:00 1969
+++ linux-2.3.6/include/asm-i386/e820.h Fri Jun 18 03:03:06 1999
@@ -0,0 +1,34 @@
+/*
+ * structures and definitions for the int 15, ax=e820 memory map
+ * scheme.
+ *
+ * In a nutshell, arch/i386/boot/setup.S populates a scratch table
+ * in the empty_zero_block that contains a list of usable address/size
+ * duples. In arch/i386/kernel/setup.c, this information is
+ * transferred into the e820map, and in arch/i386/mm/init.c, that
+ * new information is used to mark pages reserved or not.
+ *
+ */
+#ifndef __E820_HEADER
+#define __E820_HEADER
+
+#define E820 0x2d0 /* scratch area */
+#define E820MAP 0x300 /* our map */
+#define E820MAX 32 /* number of entries in E820MAP */
+#define E820MEM 0x1e4 /* memtop from e820 calls */
+#define E820NR 0x1e8 /* # entries in E820MAP */
+
+#ifndef __ASSEMBLY__
+
+struct e820map {
+ int nr_map;
+ struct {
+ unsigned long addr;
+ unsigned long size;
+ } map[E820MAX];
+};
+
+extern struct e820map e820;
+#endif/*!__ASSEMBLY__*/
+
+#endif/*__E820_HEADER*/

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/