1 使用的是bios 中断, 每次进行检测都会返回一块 内容。并且标志上,这块内存是否可用。
接下来是代码:
首先是构建 一个文件夹, 两个文件。
types.h 的内容。
#ifndef TYPES_H
#define TYPES_H// 基本整数类型,下面的写法和视频中的不同,加了一些宏处理
// 主要是因为将要使用newlib库,newlib有同样使用typedef定义uint8_t类型
// 为了避免冲突,加上_UINT8_T_DECLARED的配置//这里定义的是一些数据类型
#ifndef _UINT8_T_DECLARED
#define _UINT8_T_DECLARED
typedef unsigned char uint8_t;
#endif#ifndef _UINT16_T_DECLARED
#define _UINT16_T_DECLARED
typedef unsigned short uint16_t;
#endif#ifndef _UINT32_T_DECLARED
#define _UINT32_T_DECLARED
typedef unsigned long uint32_t;
#endif#endif
boot_info.h 的内容
#ifndef BOOT_INFO_H
#define BOOT_INFO_H#include "types.h"#define BOOT_RAM_REGION_MAX 10 // RAM区最大数量//检测内存时用到的结构体
typedef struct _boot_info_t {// RAM区信息struct {uint32_t start;uint32_t size;}ram_region_cfg[BOOT_RAM_REGION_MAX];int ram_region_count;
}boot_info_t;#endif // BOOT_INFO_H
然后是对于 头文件的包含。 loader.h
#include "comm/types.h"
#include "comm/boot_info.h"
loader_16.c 中包含头文件,并且定义结构体。
#include "loader.h"static boot_info_t boot_info; // 启动参数信息
接下来是对 顶层 cmake 的修改。
这里不用修改, 已经添加了 顶层source 目录。
2 一些基本的知识。
网上的截图:
命令的格式是这样的。
举例子。
就了解到这种程度就可以了。
3 什么是 ES:DI
什么是DI 寄存器呢? 在熟悉一遍。
------------------------------------------------------------------------------------------------------------------------------------
接下来是 代码部分。
这里我遇到了一个问题, 就是 头文件一直报错。
报错位置是 typedef unsigned int uint32_t 部分。
我觉得 跟 cmake 有关。
最后的解决方案是 ,自己写了个头文件, 但是 课程的头文件依然保留着, 只是 里面没有内容。
boot_info.h 设置一个结构体用于存放探测到的 内存容量。
#ifndef BOOT_INFO_H
#define BOOT_INFO_H#include "types.h"#define BOOT_RAM_REGION_MAX 10 // RAM区最大数量//检测内存时用到的结构体
typedef struct _boot_info_t {// RAM区信息struct {uint32_t start;uint32_t size;}ram_region_cfg[BOOT_RAM_REGION_MAX];int ram_region_count;
}boot_info_t;#endif // BOOT_INFO_H
types.h 是 一些宏定义。
#ifndef TYPES_H
#define TYPES_Htypedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;#endif
loader.h 什么也不写, 就是这个头文件出问题的。
myloader.h 是自己写的头文件。 这个结构体是 int15 中断需要的。
#ifndef __MYHEADER_H
#define __MYHEADER_H#include "comm/boot_info.h"
#include "comm/types.h"typedef struct SMAP_entry {uint32_t BaseL; // base address uint64_tuint32_t BaseH;uint32_t LengthL; // length uint64_tuint32_t LengthH;uint32_t Type; // entry Typeuint32_t ACPI; // extended
}__attribute__((packed)) SMAP_entry_t;#endif
探测函数 再 loarder_16.c 中。
static void detect_memory(void) {uint32_t contID = 0;SMAP_entry_t smap_entry;int signature, bytes;show_msg("try to detect memory:\r\n");// 初次:EDX=0x534D4150,EAX=0xE820,ECX=24,INT 0x15, EBX=0(初次)// 后续:EAX=0xE820,ECX=24,// 结束判断:EBX=0boot_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.\r\n");return;}// todo: 20字节if (bytes > 20 && (entry->ACPI & 0x0001) == 0){continue;}// 保存RAM信息,只取32位,空间有限无需考虑更大容量的情况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("detect ok.\r\n");
}