利用BIOS中断获取内存容量
来源:互联网 发布:mac os x 10.10.5下载 编辑:程序博客网 时间:2024/06/10 06:25
- e820h子功能
- 地址范围描述符
- e820h的调用参数
- 案例实现内存探测
- 定义数据存放结构约定探测结果存放于0x8000处
- 调用中断并判断是否发生错误是否探测完所有内存块
- 完整代码
- e820h子功能
机器启动后有2种方式探测物理内存:直接探测、通过BIOS中断探测。
这里我们关注如何通过BIOS的0x15中断探测物理内存。
由于BIOS中断需要在实模式下调用,所以我们在bootloader中探测物理内存比较合适。
BIOS的0x15中断有3个子功能:e820h、e801h、88h。这三个子功能区别是:
- e820h返回内存布局,信息量大
- e801h返回内存容量
- 88h最简单,功能也最弱
e820h子功能
这是功能最强大的子功能,使用也最复杂。
地址范围描述符
系统内存分为很多内存块,这些内存块加起来才构成系统的总内存。而这些内存块有不同的类型:有的OS可以使用、有的OS不能使用。
每次调用这个中断都会得到一块内存的描述,要通过多次调用才能得到系统所有内存块的描述。
e820将物理内存探测的结果以地址范围描述符的格式放在内存中。地址范围描述符共计20字节,格式是:
我们将在内存中开辟一个数组来存放所有地址范围描述符。
在c语言中可以这样定义:
struct { uint64_t addr; uint64_t size; uint32_t type;};
e820h的调用参数
显然在保护模式下用int $0x15
来调用15h中断。
但在这之前我们要将参数放置在寄存器中:
- eax:子功能编号,这里我们填入0xe820
- edx:534D4150h(ascii字符”SMAP”),签名,约定填”SMAP”
- ebx:每调用一次
int $0x15
,ebx会加1。当ebx为0表示所有内存块检测完毕。(重要!看后面的案例会明白如何使用) - ecx:存放地址范围描述符的内存大小,至少要设置为20。
- es:di:告诉BIOS要把地址描述符写到这个地址。
中断的返回值如下:
- CF标志位:若中断执行失败,则置为1。
- eax:值是534D4150h(“SMAP”)
- es:di:中断不改变该值,值与参数传入的值一致
- ebx:下一个中断描述符的计数值(见后面的案例)
- ecx:返回BIOS写到cs:di处的地址描述符的大小(应该就是20吧?)
- ah:若发生错误,表示错误码
案例:实现内存探测
定义数据存放结构,约定探测结果存放于0x8000处
约定在bootloader中将内存探测结果放到0x8000地址处。
数据存放的格式在c中定义了:
struct e820map { int nr_map; // 表示数组元素个数,该字段是为了方便后续OS,不是BIOS访问的 struct { uint64_t addr; uint64_t size; uint32_t type; } map[E820MAX];};
调用中断,并判断是否发生错误、是否探测完所有内存块
通过int $0x15
调用中断。如果发生错误,CF位为1。那么可以尝试使用其它子功能进行探测,或者就直接关机(连内存容量都没探测肯定无法启动OS了)
根据ebx判断是否完成所有内存块的探测,如果没有则继续int $0x15
探测下一个内存块,如此反复直到所有内存块探测完毕。
完整代码
c代码
#define E820MAX 20struct e820map { int nr_map; // 表示元素个数 struct { uint64_t addr; uint64_t size; uint32_t type; } map[E820MAX];};
汇编
probe_memory: movl $0, 0x8000 xorl %ebx, %ebx movw $0x8004, %distart_probe: movl $0xE820, %eax movl $20, %ecx movl $SMAP, %edx int $0x15 jnc cont movw $12345, 0x8000 # 在ucore中表示出错,与BIOS无关 jmp finish_probecont: addw $20, %di # 控制BIOS该将“地址描述符”写到哪里 incl 0x8000 # nr_map成员自增1,该变量与BIOS无关 cmpl $0, %ebx # 如果ebx是0,探测就成功结束 jnz start_probe # 如果ebx不是0,继续探测下一个内存块finish_probe:
0 0
- 利用BIOS中断获取内存容量
- 获取BIOS常规内存容量
- BIOS中断
- BIOS中断
- BIOS中断
- BIOS中断
- BIOS 中断
- bios 中断
- BIOS中断
- BIOS中断
- BIOS中断
- bios中断
- BIOS中断
- BIOS中断
- BIOS中断
- bios 中断
- BIOS中断
- BIOS中断
- 进制完全解析
- UWP C++/CX开荒记 序
- Android Studio进行编译程序时,R文件报红
- MATLAB矩阵生成函数
- 备份与还原
- 利用BIOS中断获取内存容量
- 曾经做过的c练习(11-15)
- 解决TCP延迟应答(Delay ACK)问题的3个小Trick
- JavaScript replace() 方法+字符子集介绍(*)
- Sqoop1.99.7安装、配置和使用(一)
- iOS日期推算星期的方法
- Binary Tree Right Side View
- 关于BinderPool Binder连接池的愚见
- tcp参数详解之tcp_fin_timeout