02-2 【编写loader工程内容】检测内存容量



方法:利用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使用的内存块:





posted @   卡卡发  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示