方法:利用BIOS中断来检测内存容量,具体是BIOS INT 0x15(或INT 15H)
具体使用方法:
参考文档链接:https://wiki.osdev.org/Detecting_Memory_(x86)
实操
(1)首先定义一个结构体
因为内存是分成好多块的,有一些是已经被硬件占用了:
因此检测内存返回的结构体应该是个结构体数组
boot_info.h
#ifndef BOOT_INFO_H
#define BOOT_INFO_H
#include "types.h" //是一个包含基础数据类型的头文件
#define BOOT_RAM_REGION_MAX 10
typedef struct _boot_info_t{
struct{
uint32_t start; //起始地址
uint32_t size; //内存块大小
}ran_region_cfg[BOOT_RAM_REGION_MAX]; //"cfg" 是 "configuration" 的缩写,表示配置或配置信息
int ram_region_count;//用于保存这个数组里面有多少个内存块是可使用的内存块
}boot_info_t;
#endif
types.h
#ifndef TYPES_H
#define TYPES_H
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t; //uint32_t定义为一种数据类型,表示32位整型
#endif
再把这两个头文件都加到loader.h里头
(2)编写检测内存容量功能的函数
- 在loader.h里定义一个结构体,用于接收内存块的信息
//定义一个结构体,用于接收内存信息
typedef struct SMAP_entry{
uint32_t BaseL;
uint32_t BaseH;
uint32_t LengthL;
uint32_t LengthH;
uint32_t Type; //值为1时,表示该内存块是可用的有效的
uint32_t ACPI;
}__attribute__((packed)) SMAP_entry_t;
- 在loader_16.c里面编写检测内存的函数
static void detect_memory(){
uint32_t contID=0;
uint32_t signature,bytes;
SMAP_entry_t smap_entry;
show_msg("try to detect memory:\n\r");
boot_info.ram_region_count=0;
for(int i=0;i<BOOT_RAM_REGION_MAX;i++){
SMAP_entry_t *entry=&smap_entry;
__asm__ __volatile__(
"int $0x15"
: "=a"(signature),"=c"(bytes),"=b"(contID)
: "a"(0xE820),"b"(contID),"c"(24),"d"(0x534D4150),"D"(entry)
);
if (signature != 0x534D4150){
show_msg("Failed\n\r");
return;
}
if(bytes>20 &&(entry->ACPI & 0X0001)==0){
continue;
}
if (entry->Type ==1){
boot_info.ram_region_cfg[boot_info.ram_region_count].start=entry->BaseL;
boot_info.ram_region_cfg[boot_info.ram_region_count].size=entry->LengthL;
boot_info.ram_region_count++;
}
if(contID==0){
break;
}
}
show_msg("ok.\n\r");
}
(3)调试运行
结果:
一共有两块可供OS使用的内存块:
标签:02,info,region,boot,loader,内存,entry,uint32,内存容量 From: https://www.cnblogs.com/kakafa/p/18321462