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_H
typedef 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_t
uint32_t BaseH;
uint32_t LengthL; // length uint64_t
uint32_t LengthH;
uint32_t Type; // entry Type
uint32_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=0
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.\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");
}