Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Aug 1997 12:43:00 -0400 (EDT)
From:      Gary Kendall <gdk@ccomp.inode.COM>
To:        freebsd-hackers@freebsd.ORG
Subject:   Sizing mem > 64MB at boot-time
Message-ID:  <199708231643.MAA00831@ccomp.inode.com>

next in thread | raw e-mail | index | archive | help
Hi, all.  I've been trying to hack enough "smarts" into the memsize() function
from sys/i386/boot/biosboot/bios.S to get the actual number of installed 1KB
pages of memory from the BIOS, so it can be passed on the the kernel in hopes
of eliminating (in most cases) the need for the MAXMEM option in the kernel
config file (an ugly hack, IMHO).

However, I'm having more than a little difficulty in getting the code right,
since this is my first time out with assembler on an Intel chip.  I think
what I have is close, but I don't seem to be getting pointers to local bss
storage in the right segment/register format.  The code compiles and runs,
but, in the case of xm_e820 (Int 15H, AX=E820), always returns a value of
4096 1KB pages (eg, 4MB).  I've been testing it on a floppy, and I suggest
anyone who plays with it do the same. ;-)

The xm_e801 code seems to work, but I had to test it on a friend's box with
an AMI BIOS.  The xm_e820 code is what's needed for my BIOS (MR BIOS.. also
works on newer Award BIOS's), and that's where the problem lives.

I've included a shar file containing just the (revised) memsize() function,
and the specs for BIOS calls Int 15H, AX=E820 and AX=E801.  I got the specs
from the www.ctyme.com web site as part of Ralf's interrupt list.  (A very
nicely organized serachable database of interrupts!)

Any help anyone can give me in sorting out segments and/or operand sizes
in real-mode would be greatly appreciated.

Regards,
Gary Kendall <gdk@inode.com>

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  The difficult is done immediately, the impossible takes a little longer.  %
%----------------------------------------------------------------------------%
%              gdk@ccomp.inode.com  or  gkendall@eddie.mit.edu               %
%----------------------------------------------------------------------------%
%  Creative Computing * 96 Forest Street * Danvers, MA 01923 * 508-777-3784  %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

--------------------------------- cut here -----------------------------------
# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	/tmp/memsize.S
#	/tmp/xm_e820
#	/tmp/xm_e801
#
echo x - /tmp/memsize.S
sed 's/^X//' >/tmp/memsize.S << 'END-of-/tmp/memsize.S'
X/*
X *
X * memsize(i) :  return the memory size in KB. i == 0 for conventional memory,
X *		i == 1 for extended memory
X *	BIOS call "INT 12H" to get conventional memory size
X *	BIOS call "INT 15H, AH=88H" to get extended memory size
X *		Both have the return value in AX.
X *
X */
X
XENTRY(memsize)
X	pushl	%ebp
X	movl	%esp, %ebp
X	pushl	%ebx
X	pushl	%ecx
X	pushl	%edx
X	pushl	%edi
X
X	movl	8(%ebp), %ebx
X
X	call	EXT(prot_to_real)	/* enter real mode */
X
X	cmpb	$0x1, %bl
X	data32
X	je	xext
X	
X	sti
X	int	$0x12
X	cli
X	data32
X	jmp	xdone
X
Xxext:
Xxm_e820:
X	movl	$0x100000, %ebx		/* start at 1MB */
X1:	cmpl	$0, %ebx
X	data32
X	je	xdone
X	xorl	%eax, %eax
X	movw	$0xE820, %ax
X	movl	$xm_e820_smap, %edx
X	movl	$xm_e820_tbsz, %ecx
X	movl	%es:xm_e820_tab, %edi
X	sti
X	int	$0x15
X	cli
X	data32
X	jc	xm_e801
X
X	cmpl	$xm_e820_avail, %es:16(%edi)
X	data32
X	jne	1b
X	movl	%es:8(%edi), %eax
X	shrl	$10, %eax
X	movl	xm_e820_totk, %edx
X	addl	(%edx), %eax
X	movl	%eax, (%edx)
X	data32
X	jmp	1b
X
Xxm_e801:
X	xorl	%eax, %eax
X	movw	$0xE801, %ax
X	sti
X	int	$0x15
X	cli
X	data32
X	jc	xm_88
X
X	movzwl	%cx, %ecx
X	movzwl	%dx, %edx
X	shll	$6, %edx
X	addl	%edx, %ecx
X	movl	%ecx, %eax
X	data32
X	jmp	xdone
X
Xxm_88:
X	xorl	%eax, %eax
X	movb	$0x88, %ah
X	sti
X	int	$0x15
X	cli
X	movzwl	%ax, %eax
X
Xxdone:
X	movl	%eax, %ebx
X
X	data32
X	call	EXT(real_to_prot)
X
X	popl	%edi
X	popl	%edx
X	popl	%ecx
X	movl	%ebx, %eax
X	popl	%ebx
X	popl	%ebp
X	ret
X
Xxm_e820_tbsz=	20
X	.lcomm xm_e820_tab, xm_e820_tbsz
X	.align 2
X	.lcomm xm_e820_totk, 4
X
Xxm_e820_smap=	0x534D4150	/* "SMAP" */
X
X/* e820 memory types */
Xxm_e820_avail=	0x01
Xxm_e820_resvd=	0x02
Xxm_e820_acpi=	0x03
Xxm_e820_nvs=	0x04
END-of-/tmp/memsize.S
echo x - /tmp/xm_e820
sed 's/^X//' >/tmp/xm_e820 << 'END-of-/tmp/xm_e820'
XFrom gdk Wed Aug 20 10:34:49 1997
XReceived: (from gdk@localhost) by ccomp.inode.com (8.6.9/1.3) id KAA01490; Wed, 20 Aug 1997 10:34:45 -0400
XDate: Wed, 20 Aug 1997 10:34:45 -0400
XFrom: Gary Kendall <gdk@ccomp.inode.com>
XMessage-Id: <199708201434.KAA01490@ccomp.inode.com>
XX-URL: http://www.ctyme.com/intr/RB-1666.HTM
XTo: Gary Kendall <gdk@inode.com>
XSubject: Int 15/AX=E820h
XStatus: O
X
X
X                              Int 15/AX=E820h
X                                      
X   ----------------------
X   
X  Newer BIOSes - GET SYSTEM MEMORY MAP
X  
XAX = E820h
XEAX = 0000E820h
XEDX = 534D4150h ('SMAP')
XEBX = continuation value or 00000000h to start at beginning of map
XECX = size of buffer for result, in bytes (should be >= 20 bytes)
XES:DI -> buffer for result (see #0498)
X
XReturn:
XCF clear if successful
XEAX = 534D4150h ('SMAP')
XES:DI buffer filled
XEBX = next offset from which to copy or 00000000h if all done
XECX = actual length returned in bytes
XCF set on error
XAH = error code (86h) (see #0415 at INT 15/AH=80h)
X
X   Notes: Originally introduced with the Phoenix BIOS v4.0, this function
X   is now supported by most newer BIOSes, since various versions of
X   Windows call it to find out about the system memory. A maximum of 20
X   bytes will be transferred at one time, even if ECX is higher; some
X   BIOSes (e.g. Award Modular BIOS v4.50PG) ignore the value of ECX on
X   entry, and always copy 20 bytes. Some BIOSes expect the high word of
X   EAX to be clear on entry, i.e. EAX=0000E820h. If this function is not
X   supported, an application should fall back to AX=E802h, AX=E801h, and
X   then AH=88h. The BIOS is permitted to return a nonzero continuation
X   value in EBX and indicate that the end of the list has already been
X   reached by returning with CF set on the next iteration. This function
X   will return base memory and ISA/PCI memory contiguous with base memory
X   as normal memory ranges; it will indicate chipset-defined address
X   holes which are not in use and motherboard memory-mapped devices, and
X   all occurrences of the system BIOS as reserved; standard PC address
X   ranges will not be reported
X   
X   See Also: AH=C7h - AX=E801h"Phoenix" - AX=E881h - MEM xxxxh:xxx0h"ACPI"
X
X
XFormat of Phoenix BIOS system memory map address range descriptor:
X
XOffset  Size    Description     (Table 0497)
X00h    QWORD   base address
X08h    QWORD   length in bytes
X10h    DWORD   type of address range (see #0498)
X
X
X(Table 0498)
XValues for System Memory Map address type:
X01h    memory, available to OS
X02h    reserved, not available (e.g. system ROM, memory-mapped device)
X03h    ACPI Reclaim Memory (usable by OS after reading ACPI tables)
X04h    ACPI NVS Memory (OS is required to save this memory between NVS
Xsessions)
Xother  not defined yet -- treat as Reserved
X
X   See Also: #0497
X   
X   Category: Vendor-specific BIOS Extensions - Int 15h - N 
X   
X   ----------------------
X
END-of-/tmp/xm_e820
echo x - /tmp/xm_e801
sed 's/^X//' >/tmp/xm_e801 << 'END-of-/tmp/xm_e801'
XFrom gdk Wed Aug 20 10:37:43 1997
XReceived: (from gdk@localhost) by ccomp.inode.com (8.6.9/1.3) id KAA01499; Wed, 20 Aug 1997 10:37:42 -0400
XDate: Wed, 20 Aug 1997 10:37:42 -0400
XFrom: Gary Kendall <gdk@ccomp.inode.com>
XMessage-Id: <199708201437.KAA01499@ccomp.inode.com>
XX-URL: http://www.ctyme.com/intr/RB-1664.HTM
XTo: Gary Kendall <gdk@inode.com>
XSubject: Int 15/AX=E801h
XStatus: O
X
X
X                              Int 15/AX=E801h
X                                      
X   ----------------------
X   
X  Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
X  
XAX = E801h
X
XReturn:
XCF clear if successful
XAX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
XBX = extended memory above 16M, in 64K blocks
XCX = configured memory 1M to 16M, in K
XDX = configured memory above 16M, in 64K blocks
XCF set on error
X
X   Notes: Supported by the A03 level (6/14/94) and later XPS P90 BIOSes,
X   as well as the Compaq Contura, 3/8/93 DESKPRO/i, and 7/26/93 LTE Lite
X   386 ROM BIOS. Supported by AMI BIOSes dated 8/23/94 or later. This
X   interface is used by Windows NT 3.1, OS/2 v2.11/2.20, and is used as a
X   fall-back by newer versions if AX=E820h is not supported
X   
X   See Also: AH=8Ah"Phoenix" - AX=E802h - AX=E820h - AX=E881h"Phoenix"
X   
X   Category: Vendor-specific BIOS Extensions - Int 15h - P 
X   
X   ----------------------
X
END-of-/tmp/xm_e801
exit
--------------------------------- cut here -----------------------------------



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199708231643.MAA00831>