5.1获取物理内存容量

简介: 5.1获取物理内存容量

5.1获取物理内存容量

5.1.1学习Linux获取内存的方法

在 Linux 2.6 内核中, 是用 detect_memory 函数来获取内存容量的 其函数在本质上是通过调用 BIOS 中断 0x15 实现的, 分别是BIOS 中断 0x15 的3个子功能, 子功能号要存放到寄存器EAx或Ax中, 如下:

1.EAx=0xE820 遍历主机上全部内存。

2.Ax=0xE801分别检测低 15MB 和 16MB~4GB 的内存, 最大支持 4GB。

3.AH=0x88 最多检测出 64MB 内存, 实际内存超过此容量也按照 64MB 返回。

利用BIOS中断0x15子功能0xe820获取内存

BIOS 中断 0x15 的子功能 0xE820 能够获取系统的内存布局, 由于系统内存各部分的类型属性不同,BIOS 就按照类型属性来划分这片系统内存, 所以这种查询呈迭代式, 每次 BIOS 只返回一种类型的内存信息 直到将所有内存类型返回完毕。子功能 0xE820 的强大之处是返回的内存信息较丰宫, 包括多个属性字段, 所以需要一种格式结构来组织这些数据。内存信息的内容是用地址范围描述符来描述的, 用于存储这种描述符的结构称之为地址范围描述符。

40057880245b43ff87fbca2c0a87fefd.png

此结构中的字段大小都是4字节, 共5个字段, 所以此结构大小为20字节。 每次 int0x15 之后, BIOS就返回这样一个结构的数据。 注意, ARDS 结构中用 64位宽度的属性来描述这段内存基地址 (起始地址)及其长度, 所以表中的基地址和长度都分为低 32位和高 32 位两部分。

Type 字段用来描述这段内存的类型, 这里所谓的类型是说明这段内存的用途, 即其是可以被操作系统使用, 还是保留起来不能用。 Type字段的具体意义见下表:

92cdf64385ed4e1f831e34fd59a08ac1.png


BIOS 中断只是一段函数例程, 调用它就要为其提供参数现在介绍下 BIOS 中断 0x15 的 0xe820子功能需要哪些参数。先介绍下此中断例程的调用方法。 表5-3 所示是使用此中断的方法, 分输入和输出两部分。


50283b5e496b43d883f849a836ff6483.png

ECX 寄存器和 ES: DI 寄存器, 是典型的 “值-结果” 型参数, 即调用方提供了两个变量作为被调用函数的参数, 一个变量是缓冲区指针, 另一个变量是缓冲区大小。 被调用函数在缓冲区中写入数据后, 将实际所写入的字节数记录到缓冲区大小变量中。

根据表 5-3 中的说明, 此中断的调用步骤如下。

(1) 填写好 “调用前输入” 中列出的寄存器。

(2)执行中断调用 int 0x15。

(3) 在CF位为0的情况下, “返回后输出″ 中对应的寄存器便会有对应的结果。


利用BIOS中断0x15子功能0xe801获取内存

另一个获取内存容量的方法是BIOS 0xl5 中断的子功能 0xE801。

此方法虽然简单,但功能不强大, 最大只能识别4GB 内存, 不过这对咱们32位地址总线足够了。 稍微有点不便的是该方法检测到的内存是分别放置在两组寄存器中的。

a8432309580f4d02b99b1da2ceeda80f.png

此中断的调用步骤如下。

(1) 将AX寄存器写入0xE801。

(2) 执行中断调用 int 0x15。

(3) 在CF 位为0的情况下, “返回后输出” 中对应的寄存器便会有对应的结果。


利用BIOS中断的0x15子功能0x88获取内存

最后一个获取内存的方法也同样是 BIOS 0x15 中断, 子功能号是 0x88。 该方法使用最简单, 但功能也最简单, 简单到只能识别最大 64MB 的内存。 即使内存容量大于 64MB, 也只会显示 63MB, 大家可以自己在bochs中试验下。为什么只显示到63M呢? 因为此中断只会显示 1MB之上的内存,不包括这 1MB

ecf8e36d8089404c84d63ebdbc25d7a0.png


中断返回后, Ax寄存器中的值, 其单位是 1KB。 此中断的调用步骤如下。

(1)将 AX 寄存器写入 0x88

(2) 执行中断调用 int0x15

(3)在CF位为0的情况下, “返回后输出” 中对应的寄存器便会有对应的结果。


##实际代码获取物理内存


;-------  int 15h eax = 0000E820h ,edx = 534D4150h ('SMAP') 获取内存布局  -------
   xor ebx, ebx         ;第一次调用时,ebx值要为0
   mov edx, 0x534d4150        ;edx只赋值一次,循环体中不会改变
   mov di, ards_buf       ;ards结构缓冲区
.e820_mem_get_loop:       ;循环获取每个ARDS内存范围描述结构
   mov eax, 0x0000e820        ;执行int 0x15后,eax值变为0x534d4150,所以每次执行int前都要更新为子功能号。
   mov ecx, 20          ;ARDS地址范围描述符结构大小是20字节
   int 0x15
   jc .e820_failed_so_try_e801   ;若cf位为1则有错误发生,尝试0xe801子功能  汇编语言jc指令,当flags寄存器中的CF位为1时触发
   add di, cx         ;使di增加20字节指向缓冲区中新的ARDS结构位置
   inc word [ards_nr]       ;记录ARDS数量  对地址中的内容+1再送回给地址
   cmp ebx, 0         ;若ebx为0且cf不为1,这说明ards全部返回,当前已是最后一个   cmp比较ebx与0是否相等,相等ZF=1,不相等ZF=0
   jnz .e820_mem_get_loop ;flagsZF位不为0/不等于时跳转执行
;在所有ards结构中,找出(base_add_low + length_low)的最大值,即内存的容量。
   mov cx, [ards_nr]        ;遍历每一个ARDS结构体,循环次数是ARDS的数量
   mov ebx, ards_buf 
   xor edx, edx         ;edx为最大的内存容量,在此先清0
.find_max_mem_area:       ;无须判断type是否为1,最大的内存块一定是可被使用
   mov eax, [ebx]       ;base_add_low
   add eax, [ebx+8]       ;length_low
   add ebx, 20          ;指向缓冲区中下一个ARDS结构
   cmp edx, eax         ;冒泡排序,找出最大,edx寄存器始终是最大的内存容量
   jge .next_ards          ;jge大于或者等于转移指令
   mov edx, eax         ;edx为总内存大小
.next_ards:
   loop .find_max_mem_area
   jmp .mem_get_ok
;------  int 15h ax = E801h 获取内存大小,最大支持4G  ------
; 返回后, ax cx 值一样,以KB为单位,bx dx值一样,以64KB为单位
; 在ax和cx寄存器中为低16M,在bx和dx寄存器中为16MB到4G。
.e820_failed_so_try_e801:
   mov ax,0xe801
   int 0x15
   jc .e801_failed_so_try88   ;若当前e801方法失败,就尝试0x88方法
;1 先算出低15M的内存,ax和cx中是以KB为单位的内存数量,将其转换为以byte为单位
   mov cx,0x400      ;cx和ax值一样,cx用做乘数
   mul cx 
   shl edx,16
   and eax,0x0000FFFF
   or edx,eax
   add edx, 0x100000 ;ax只是15MB,故要加1MB
   mov esi,edx       ;先把低15MB的内存容量存入esi寄存器备份
;2 再将16MB以上的内存转换为byte为单位,寄存器bx和dx中是以64KB为单位的内存数量
   xor eax,eax
   mov ax,bx    
   mov ecx, 0x10000 ;0x10000十进制为64KB
   mul ecx    ;32位乘法,默认的被乘数是eax,积为64位,高32位存入edx,低32位存入eax.
   add esi,eax    ;由于此方法只能测出4G以内的内存,故32位eax足够了,edx肯定为0,只加eax便可
   mov edx,esi    ;edx为总内存大小
   jmp .mem_get_ok
;-----------------  int 15h ah = 0x88 获取内存大小,只能获取64M之内  ----------
.e801_failed_so_try88: 
   ;int 15后,ax存入的是以kb为单位的内存容量
   mov  ah, 0x88
   int  0x15
   jc .error_hlt
   and eax,0x0000FFFF
   ;16位乘法,被乘数是ax,积为32位.积的高16位在dx中,积的低16位在ax中
   mov cx, 0x400     ;0x400等于1024,将ax中的内存容量换为以byte为单位
   mul cx
   shl edx, 16       ;把dx移到高16位
   or edx, eax       ;把积的低16位组合到edx,为32位的积
   add edx,0x100000  ;0x88子功能只会返回1MB以上的内存,故实际内存大小要加上1MB
.mem_get_ok:
   mov [total_mem_bytes], edx  ;将内存换为byte单位后存入total_mem_bytes处。
目录
相关文章
|
2月前
|
Linux Shell 虚拟化
使用LiME收集主机物理内存的内容时发生宕机
使用LiME收集主机物理内存的内容时发生宕机
|
2月前
crash —— 获取物理内存布局信息
crash —— 获取物理内存布局信息
|
4月前
|
开发者 Java
JVM内存问题之top命令的物理内存信息中,'used'和'free','avail Mem'分别表示什么
JVM内存问题之top命令的物理内存信息中,'used'和'free','avail Mem'分别表示什么
|
4月前
|
运维 DataWorks 安全
DataWorks产品使用合集之如何查看空间资源、CPU、内存和存储空间容量
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
4月前
|
机器学习/深度学习 分布式计算 大数据
MaxCompute产品使用合集之如何查看空间资源、CPU和内存以及存储空间容量
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
6月前
|
算法 内存技术
深入理解操作系统内存管理:从虚拟内存到物理内存的旅程
【5月更文挑战第24天】 在现代计算机系统中,操作系统的内存管理是确保系统高效稳定运行的关键组成部分。本文将探讨操作系统是如何通过虚拟内存到物理内存的映射机制,实现对内存资源的高效管理和保护。我们将剖析分页和分段两种主要的内存管理技术,并讨论它们如何协同工作以提供内存抽象、重定位、共享和保护。文章还将涉及虚拟内存的技术细节,包括页面置换算法和内存分配策略,以及它们对系统性能的影响。
|
6月前
|
存储 缓存 算法
深入理解操作系统内存管理:从虚拟内存到物理内存
【5月更文挑战第30天】操作系统的心脏——内存管理,在系统性能和稳定性中扮演着关键角色。本文将深入探讨操作系统中的内存管理机制,特别是虚拟内存与物理内存之间的映射关系、分页机制以及内存分配策略。通过分析现代操作系统如何处理内存资源,我们可以更好地理解计算机系统的内部工作原理,并掌握提升系统性能的关键因素。
|
6月前
|
存储 算法 内存技术
深入理解操作系统内存管理:从虚拟内存到物理内存的映射
【4月更文挑战第30天】 在现代操作系统中,内存管理是一个复杂而关键的功能。它不仅确保了系统资源的有效利用,还为每个运行的程序提供了独立的地址空间,保障了程序之间的隔离性和安全性。本文将探讨操作系统如何通过分页机制和虚拟内存技术实现内存的抽象化,以及这些技术是如何影响应用程序性能的。我们将详细解析虚拟地址到物理地址的转换过程,并讨论操作系统在此过程中扮演的角色。文章的目的是为读者提供一个清晰的框架,以便更好地理解内存管理的工作原理及其对系统稳定性和效率的影响。
|
6月前
|
人工智能 缓存 算法
深入理解操作系统内存管理:从虚拟内存到物理内存的映射
【4月更文挑战第8天】 在现代操作系统中,内存管理是核心功能之一,它负责协调和管理计算机的内存资源,确保系统稳定高效地运行。本文深入探讨了操作系统内存管理的关键概念——虚拟内存和物理内存的映射机制。通过剖析分页系统、分段机制和虚拟内存地址转换过程,文章旨在为读者提供一个清晰的理解框架,同时讨论了内存管理的优化技术及其对系统性能的影响。此外,还简要介绍了内存碎片问题以及垃圾回收机制的重要性,并展望了未来内存管理技术的发展趋势。
|
6月前
|
存储 算法 内存技术
深入理解操作系统内存管理:从虚拟内存到物理内存
【2月更文挑战第30天】 在现代计算机系统中,操作系统的内存管理是确保系统高效稳定运行的关键组成部分。本文将深入探讨操作系统内存管理的复杂世界,特别是虚拟内存和物理内存之间的关联与转换机制。通过分析分页系统的工作原理、虚拟地址空间的结构以及页面置换算法,文章旨在为读者提供一个清晰的框架,以理解内存管理在操作系统中的重要性和实现细节。