Int 15/AX=E820h ,Int 15/AX=E801h

Int 15/AX=E820h 是用来获取系统中的内存映地址描述符的,操作系统常用来获取内存大小.

PS:内存(Memory)可以是我们平时所说的在主板上的内存条,我们称作Base Memory,也可以是毗边
Base Memory 的并作为普通内存扩展的内存.

 

首先来了解一下相关的数据结构:

Format of Phoenix BIOS system memory map address range descriptor
(BIOS系统内存映射地址描述符格式,通常在英文中被称作Entry,一个Entry描述一种系统内存信息):

Offset  Size    Description    
00h    QWORD   base address    #系统内存块基地址
08h    QWORD   length in bytes #系统内存大小
10h    DWORD   type of address range #内存类型,看下面的(Values for System Memory Map address type)

这个结构块的大小为20

格式:

AX = E820h
EAX = 0000E820h
EDX = 534D4150h ('SMAP')
EBX = continuation value or 00000000h to start at beginning of map
持续值 或者 等于00000000h,以便重map的开头开始scan ECX = size of buffer for result, in bytes (should be >= 20 bytes) ES:DI -> buffer for result

Return:
CF clear if successful

EAX = 534D4150h ('SMAP') ES:DI buffer filled EBX = next offset from which to copy or 00000000h if all done ECX = 传送到缓冲区buf的Entry的大小,一般为20个字节,ECX=20 CF set on error AH = error code (86h)
Reference:http://www.ctyme.com/intr/rb-1741.htm
除了Base Memory外,他还返回芯片集定义的系统内存地址空洞,而这些空洞是没有被使用的,是
主板内存映射设备和BIOS所保留的.
Values for System Memory Map address type:
01h    memory, available to OS
02h    reserved, not available (e.g. system ROM, memory-mapped device)
03h    ACPI Reclaim Memory (usable by OS after reading ACPI tables)
04h    ACPI NVS Memory (OS is required to save this memory between NVS
sessions)
other  not defined yet -- treat as Reserved
原理描述:
调用此功能可以从系统某一个地方(这里存放有一个List(列表),这个列表里存放的都是一个个的
Entry)通过设置EBX(20的倍数)的值,然后调用int 0x15就可以讲EBX所指向的Entry拷贝
到ES:DI所指向的内存区)
 
 
 
Linux2.4.10-setup.S中关于内存检测(E820h)注释及流程:
首先了解一下empty_zero_page 都存放些什么东西:
Offset Type  Description
------  ----  -----------
    0 32 bytes struct screen_info, SCREEN_INFO
   ATTENTION, overlaps the following !!!
    2 unsigned short EXT_MEM_K, extended memory size in Kb (from int 0x15)
 0x20 unsigned short CL_MAGIC, commandline magic number (=0xA33F)
 0x22 unsigned short CL_OFFSET, commandline offset
   Address of commandline is calculated:
     0x90000 + contents of CL_OFFSET
   (only taken, when CL_MAGIC = 0xA33F)
 0x40 20 bytes struct apm_bios_info, APM_BIOS_INFO
 0x80 16 bytes hd0-disk-parameter from intvector 0x41
 0x90 16 bytes hd1-disk-parameter from intvector 0x46
 0xa0 16 bytes System description table truncated to 16 bytes.
   ( struct sys_desc_table_struct )
 0xb0 - 0x1df  Free. Add more parameters here if you really need them.
0x1e0 unsigned long ALT_MEM_K, alternative mem check, in Kb
0x1e8 char  number of entries in E820MAP (below)
0x1f1 char  size of setup.S, number of sectors
0x1f2 unsigned short MOUNT_ROOT_RDONLY (if !=0)
0x1f4 unsigned short size of compressed kernel-part in the
   (b)zImage-file (in 16 byte units, rounded up)
0x1f6 unsigned short swap_dev (unused AFAIK)
0x1f8 unsigned short RAMDISK_FLAGS
0x1fa unsigned short VGA-Mode (old one)
0x1fc unsigned short ORIG_ROOT_DEV (high=Major, low=minor)
0x1ff char  AUX_DEVICE_INFO
0x200 short jump to start of setup code aka "reserved" field.
0x202 4 bytes  Signature for SETUP-header, ="HdrS"
0x206 unsigned short Version number of header format
   Current version is 0x0201...
0x208 8 bytes  (used by setup.S for communication with boot loaders,
    look there)
0x210 char  LOADER_TYPE, = 0, old one
   else it is set by the loader:
   0xTV: T=0 for LILO
    1 for Loadlin
    2 for bootsect-loader
    3 for SYSLINUX
    4 for ETHERBOOT
    V = version
0x211 char  loadflags:
   bit0 = 1: kernel is loaded high (bzImage)
   bit7 = 1: Heap and pointer (see below) set by boot
      loader.
0x212 unsigned short (setup.S)
0x214 unsigned long KERNEL_START, where the loader started the kernel
0x218 unsigned long INITRD_START, address of loaded ramdisk image
0x21c unsigned long INITRD_SIZE, size in bytes of ramdisk image
0x220 4 bytes  (setup.S)
0x224 unsigned short setup.S heap end pointer
0x2d0 - 0x600  E820MAP
0x800 string, 2K max COMMAND_LINE, the kernel commandline as
   copied using CL_OFFSET.
   Note: this will be copied once more by setup.c
   into a local buffer which is only 256 bytes long.
   ( #define COMMAND_LINE_SIZE 256 )
 
 
loader_ok:
# Get memory size (extended mem, kB)
 xorl %eax, %eax
 movl %eax, (0x1e0)
#ifndef STANDARD_MEMORY_BIOS_CALL
 movb %al, (E820NR)  # E820NR=0x1e8 number of entries in E820MAP
# 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 memory areas, which we return at [E820MAP].
# This is documented at http://www.teleport.com/~acpi/acpihtml/topic245.htm
#define SMAP  0x534d4150
meme820:
 xorl %ebx, %ebx   # continuation counter
 movw $E820MAP, %di   # point into the whitelist
      # so we can have the bios
      # directly write into it.
jmpe820:
 movl $0x0000e820, %eax  # e820, upper word zeroed
 movl $SMAP, %edx   # ascii 'SMAP'
 movl $20, %ecx   # size of the e820rec
 pushw %ds    # data record.
 popw %es
 int $0x15    # make the call
 jc bail820    # fall to e801 if it fails
 cmpl $SMAP, %eax   # check the return is `SMAP'
 jne bail820    # fall to e801 if it fails
# cmpl $1, 16(%di)   # is this usable memory?
# jne again820
 # If this is usable memory, we save it by simply advancing %di by
 # sizeof(e820rec).
 #
good820:
 movb (E820NR), %al   # up to 32 entries
 cmpb $E820MAX, %al
 jnl bail820
 incb (E820NR)
 movw %di, %ax
 addw $20, %ax
 movw %ax, %di
again820:
 cmpl $0, %ebx   # check to see if
 jne jmpe820    # %ebx is set to EOF
bail820:
 
 
通过上面的汇编指令,就把可用内存的Entry描述块顺序放到了empty_zero_page的
0x2d0 - 0x600  E820MAP处.那么计算内存大小也就不困难了.
 
 
 
Int 15/AX=E801h 
reference:http://www.ctyme.com/intr/rb-1739.htm

Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS

AX = E801h

Return:
CF clear if successful AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB) BX = extended memory above 16M, in 64K blocks CX = configured memory 1M to 16M, in K DX = configured memory above 16M, in 64K blocks CF set on error

Notes: Supported by the A03 level (6/14/94) and later XPS P90 BIOSes, as well as
the Compaq Contura, 3/8/93 DESKPRO/i, and 7/26/93 LTE Lite 386 ROM BIOS.
Supported by AMI BIOSes dated 8/23/94 or later. On some systems, the BIOS returns
AX=BX=0000h; in this case, use CX and DX instead of AX and BX. This interface is
used by Windows NT 3.1, OS/2 v2.11/2.20, and is used as a fall-back by newer
versions if AX=E820h is not supported. This function is not used by MS-DOS 6.0
HIMEM.SYS when an EISA machine (for example with parameter /EISA)
(see also MEM F000h:FFD9h), or no Compaq machine was detected, or parameter
/NOABOVE16 was given.
 
 
 
 
 
 
meme801:
 stc     # fix to work around buggy
 xorw %cx,%cx    # BIOSes which dont clear/set
 xorw %dx,%dx    # carry on pass/error of
      # e801h memory size call
      # or merely pass cx,dx though
      # without changing them.
 movw $0xe801, %ax
 int $0x15
 jc mem88
 cmpw $0x0, %cx   # Kludge to handle BIOSes
 jne e801usecxdx   # which report their extended
 cmpw $0x0, %dx   # memory in AX/BX rather than
 jne e801usecxdx   # CX/DX.  The spec I have read
 movw %ax, %cx   # seems to indicate AX/BX
 movw %bx, %dx   # are more reasonable anyway...
e801usecxdx:
 andl $0xffff, %edx   # clear sign extend
 shll $6, %edx   # and go from 64k to 1k chunks
 movl %edx, (0x1e0)   # store extended memory size
 andl $0xffff, %ecx   # clear sign extend
  addl %ecx, (0x1e0)   # and add lower memory into
      # total size.
 
 
 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值