首先是 创建 include 文件夹,
创建了三个文件夹, cpu , include , cpu (include 下)
然后是 修改 cmakelist
接下来 是 创建 cpu.h, 关于 x86 cpu 相关的东西。
#ifndef CPU_H
#define CPU_H
#include "comm/types.h"
#pragma pack(1)
/**
* GDT描述符
*/
// 这是gdt 表的模板
typedef struct _segment_desc_t {
uint16_t limit15_0;
uint16_t base15_0;
uint8_t base23_16;
uint16_t attr; //注意这里面是有 16:19 的 limit 的值的。
uint8_t base31_24;
}segment_desc_t;
#pragma pack()
// 这是c 文件中的两个函数
void cpu_init (void);
void segment_desc_set(int selector, uint32_t base, uint32_t limit, uint16_t attr);
#endif
然后是创建 cpu.c
#include "cpu/cpu.h"
#include "os_cfg.h"
//这里创建了一个GDT 的数组
static segment_desc_t gdt_table[GDT_TABLE_SIZE];
/**
* 设置段描述符
*/
// selector 是选择子, base : 低地址, limit:界限, attr : 属性
// 这是一个 对每个 gdt 进行初始化的函数
void segment_desc_set(int selector, uint32_t base, uint32_t limit, uint16_t attr) {
segment_desc_t * desc = gdt_table + selector / sizeof(segment_desc_t); // 这里 可以不除以 sizeof(segment_desc_t) 的,dgt表是 4个字节,4个字节的往前走的。
desc->limit15_0 = limit & 0xffff;
desc->base15_0 = base & 0xffff;
desc->base23_16 = (base >> 16) & 0xff;
desc->attr = attr | (((limit >> 16) & 0xf) << 8); // 这里 在attr里面设置了 limit 的值。
desc->base31_24 = (base >> 24) & 0xff;
}
/**
* 初始化GDT
*/
//对每个表 进行循环的初始化。
void init_gdt(void) {
// 全部清空
for (int i = 0; i < GDT_TABLE_SIZE; i++) {
segment_desc_set(i * sizeof(segment_desc_t), 0, 0, 0); // 这里是在清空每个表。
}
}
/**
* CPU初始化
*/
void cpu_init (void) {
init_gdt();
}
然后是创建 os_cfg.h , 放的是操作系统配置有关的宏定义 。
#ifndef OS_OS_CFG_H
#define OS_OS_CFG_H
#define GDT_TABLE_SIZE 256 // GDT表项数量
#endif //OS_OS_CFG_H
gdt 表的个数 是有限制的,具体多少限制 不清楚。
然后是将 实现的函数 加到 cpu.h 中,这里已经加过了。
然后是在 init.c 文件中 对 gpt 表进行初始化。
经过编译+ 测试是可以的。