Browse Source

:new: 转换为grub2引导(尚未更正mm模块,且目前无法将内核链接到线性地址0xffffx处)

fslongjin 3 years ago
parent
commit
d9d83335af

+ 1 - 1
.gitignore

@@ -1,3 +1,3 @@
 /cmake-build-debug/
 /bin/
-./DragonOS.iso
+DragonOS.iso

+ 2 - 1
.vscode/settings.json

@@ -13,6 +13,7 @@
         "glib.h": "c",
         "asm.h": "c",
         "memory.h": "c",
-        "irq.h": "c"
+        "irq.h": "c",
+        "multiboot2.h": "c"
     }
 }

+ 3 - 2
kernel/Makefile

@@ -7,8 +7,8 @@ DIR_LIB=lib
 lib_patterns := *.a
 LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
 all: kernel
-#objcopy -I elf64-x86-64 -S -R ".comment" -O elf64-x86-64 kernel ../bin/kernel/kernel.elf
-	cp kernel ../bin/kernel/kernel.elf
+	objcopy -I elf64-x86-64 -S -R ".comment" -O elf64-x86-64 kernel ../bin/kernel/kernel.elf
+# cp kernel ../bin/kernel/kernel.elf
 
 
 kernel: head.o entry.o main.o printk.o trap.o mm.o irq.o 8259A.o process.o syscall.o multiboot2.o
@@ -18,6 +18,7 @@ kernel: head.o entry.o main.o printk.o trap.o mm.o irq.o 8259A.o process.o sysca
 head.o: head.S
 	gcc -E head.S > head.s # 预处理
 	as --64 -o head.o head.s
+#gcc -mcmodel=large -fno-builtin -m64 -c head.S -o head.o
 
 entry.o: exception/entry.S
 	gcc -E exception/entry.S > exception/entry.s

+ 9 - 25
kernel/common/boot_info.h

@@ -2,64 +2,48 @@
 /**
  * @file boot_info.h
  * @brief 启动信息接口
- * @author Zone.N ([email protected])
- * @version 1.0
- * @date 2021-09-18
- * @copyright MIT LICENSE
- * https://github.com/Simple-XX/SimpleKernel
- * @par change log:
- * <table>
- * <tr><th>Date<th>Author<th>Description
- * <tr><td>2021-09-18<td>digmouse233<td>迁移到 doxygen
- * </table>
  */
 
-#ifndef _BOOT_INFO_H_
-#define _BOOT_INFO_H_
-
-#include "stdint.h"
-//#include "resource.h"
+#pragma once
+#include "glib.h"
 
 /**
  * @brief 启动信息接口
  * 由引导传递的机器信息处理
  * 如 grub2 传递的 multiboot2 结构
- * opensbi 传递的 dtb 结构
  * 注意这部分是通过内存传递的,在重新保存之前不能被覆盖
  * 架构专有的数据在 dtb.h 或 multiboot2.h
  * 实现在 dtb.cpp 或 multiboot2.cpp
  */
-namespace BOOT_INFO {
     /// 声明,定义在具体的实现中
     /// 地址
-    extern "C" uintptr_t boot_info_addr;
+    extern uintptr_t  boot_info_addr;
     /// 长度
-    extern size_t boot_info_size;
+    extern unsigned int boot_info_size;
 
     /**
      * @brief 初始化,定义在具体实现中
      * @return true            成功
      * @return false           成功
      */
-    extern bool init(void);
+    extern int init(void);
 
     /**
      * @brief 获取物理内存信息
      * @return resource_t      物理内存资源信息
      */
-    extern resource_t get_memory(void);
+    //extern resource_t get_memory(void);
 
     /**
      * @brief 获取 clint 信息
      * @return resource_t       clint 资源信息
      */
-    extern resource_t get_clint(void);
+    //extern resource_t get_clint(void);
     
     /**
      * @brief 获取 plic 信息
      * @return resource_t       plic 资源信息
      */
-    extern resource_t get_plic(void);
-};
+    //extern resource_t get_plic(void);
+
 
-#endif /* _BOOT_INFO_H_ */

+ 13 - 0
kernel/common/glib.h

@@ -23,6 +23,7 @@
                                              : "memory") // 在sfence指令前的写操作必须在sfence指令后的写操作前完成
 #define io_lfence() __asm__ __volatile__("lfence\n\t" :: \
                                              : "memory") // 在lfence指令前的读操作必须在lfence指令后的读操作前完成。
+
 /**
  * @brief 根据结构体变量内某个成员变量member的基地址,计算出该结构体变量的基地址
  * @param ptr 指向结构体变量内的成员变量member的指针
@@ -50,6 +51,18 @@ ul round(double x)
     return (ul)(x + 0.5);
 }
 
+/**
+ * @brief 地址按照align进行对齐
+ * 
+ * @param addr 
+ * @param _align 
+ * @return ul 对齐后的地址
+ */
+ul ALIGN(const ul addr, const ul _align)
+{
+    return (ul)((addr+_align-1)&(~(_align-1)));
+}
+
 //链表数据结构
 struct List
 {

+ 27 - 22
kernel/common/printk.c

@@ -2,6 +2,8 @@
 // Created by longjin on 2022/1/22.
 //
 #include "printk.h"
+#include "../driver/multiboot2/multiboot2.h"
+#include "../mm/mm.h"
 //#include "linkage.h"
 
 struct screen_info pos;
@@ -34,22 +36,25 @@ int calculate_max_charNum(int len, int size)
     return len / size;
 }
 
-int init_printk(const int width, const int height, unsigned int *FB_address, const int FB_length, const int char_size_x, const int char_size_y)
+int init_printk(const int char_size_x, const int char_size_y)
 {
-
-    pos.width = width;
-    pos.height = height;
+    struct multiboot_tag_framebuffer_info_t info;
+    int reserved;
+    multiboot2_iter(multiboot2_get_Framebuffer_info, &info, &reserved);
+    
+    pos.width = info.framebuffer_width;
+    pos.height = info.framebuffer_height;
     pos.char_size_x = char_size_x;
     pos.char_size_y = char_size_y;
-    pos.max_x = calculate_max_charNum(width, char_size_x);
-    pos.max_y = calculate_max_charNum(height, char_size_y);
-
-    pos.FB_address = FB_address;
-    pos.FB_length = FB_length;
+    pos.max_x = calculate_max_charNum(pos.width, char_size_x);
+    pos.max_y = calculate_max_charNum(pos.height, char_size_y);
+    
+    // @todo:将来需要将帧缓冲区物理地址填写到这个地址的页表项中
+    pos.FB_address = 0xa00000;  
+    pos.FB_length = info.framebuffer_pitch - info.framebuffer_addr;
 
     pos.x = 0;
     pos.y = 0;
-
     return 0;
 }
 
@@ -81,7 +86,7 @@ void auto_newline()
 {
     /**
      * @brief 超过每行最大字符数,自动换行
-     * 
+     *
      */
     if (pos.x > pos.max_x)
     {
@@ -314,7 +319,7 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
         case 'x':
             flags |= SMALL;
         case 'X':
-            //flags |= SPECIAL;
+            // flags |= SPECIAL;
             if (qualifier == 'l')
                 str = write_num(str, va_arg(args, ull), 16, field_width, precision, flags);
             else
@@ -352,13 +357,13 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
             break;
         case 'f':
             // 默认精度为3
-            //printk("1111\n");
-            //va_arg(args, double);
-            //printk("222\n");
+            // printk("1111\n");
+            // va_arg(args, double);
+            // printk("222\n");
 
             if (precision < 0)
                 precision = 3;
-            
+
             str = write_float_point_num(str, va_arg(args, double), field_width, precision, flags);
 
             break;
@@ -383,11 +388,11 @@ static char *write_num(char *str, ull num, int base, int field_width, int precis
 {
     /**
      * @brief 将数字按照指定的要求转换成对应的字符串
-     * 
+     *
      * @param str 要返回的字符串
      * @param num 要打印的数值
      * @param base 基数
-     * @param field_width 区域宽度 
+     * @param field_width 区域宽度
      * @param precision 精度
      * @param flags 标志位
      */
@@ -486,10 +491,10 @@ static char *write_float_point_num(char *str, double num, int field_width, int p
 {
     /**
      * @brief 将浮点数按照指定的要求转换成对应的字符串
-     * 
+     *
      * @param str 要返回的字符串
      * @param num 要打印的数值
-     * @param field_width 区域宽度 
+     * @param field_width 区域宽度
      * @param precision 精度
      * @param flags 标志位
      */
@@ -578,7 +583,7 @@ static void putchar(unsigned int *fb, int Xsize, int x, int y, unsigned int FRco
 {
     /**
      * @brief 在屏幕上指定位置打印字符
-     * 
+     *
      * @param fb 帧缓存线性地址
      * @param Xsize 行分辨率
      * @param x 左上角列像素点位置
@@ -617,7 +622,7 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
 {
     /**
      * @brief 格式化打印字符串
-     * 
+     *
      * @param FRcolor 前景色
      * @param BKcolor 背景色
      * @param ... 格式化字符串

+ 1 - 5
kernel/common/printk.h

@@ -57,14 +57,10 @@ char buf[4096]; //vsprintf()的缓冲区
 /**
  * @brief 初始化printk的屏幕信息
  * 
- * @param width 屏幕宽度
- * @param height 屏幕高度
- * @param FB_address 帧缓冲区地址
- * @param FB_length 帧缓冲区长度
  * @param char_size_x 字符的列坐标
  * @param char_size_y 字符的行坐标
  */
-int init_printk(const int width, const int height, unsigned int *FB_address, const int FB_length, const int char_size_x, const int char_size_y);
+int init_printk(const int char_size_x, const int char_size_y);
 /**
  * @brief Set the printk pos object
  * 

+ 0 - 225
kernel/driver/multiboot2/boot.S

@@ -1,225 +0,0 @@
-
-// 以下是来自 multiboot2 规范的定义
-//  How many bytes from the start of the file we search for the header.
-#define MULTIBOOT_SEARCH 32768
-#define MULTIBOOT_HEADER_ALIGN 8
-
-//  The magic field should contain this.
-#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
-
-//  This should be in %eax.
-#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
-
-//  Alignment of multiboot modules.
-#define MULTIBOOT_MOD_ALIGN 0x00001000
-
-//  Alignment of the multiboot info structure.
-#define MULTIBOOT_INFO_ALIGN 0x00000008
-
-//  Flags set in the 'flags' member of the multiboot header.
-
-#define MULTIBOOT_TAG_ALIGN 8
-#define MULTIBOOT_TAG_TYPE_END 0
-#define MULTIBOOT_TAG_TYPE_CMDLINE 1
-#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
-#define MULTIBOOT_TAG_TYPE_MODULE 3
-#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
-#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
-#define MULTIBOOT_TAG_TYPE_MMAP 6
-#define MULTIBOOT_TAG_TYPE_VBE 7
-#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
-#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
-#define MULTIBOOT_TAG_TYPE_APM 10
-#define MULTIBOOT_TAG_TYPE_EFI32 11
-#define MULTIBOOT_TAG_TYPE_EFI64 12
-#define MULTIBOOT_TAG_TYPE_SMBIOS 13
-#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
-#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
-#define MULTIBOOT_TAG_TYPE_NETWORK 16
-#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
-#define MULTIBOOT_TAG_TYPE_EFI_BS 18
-#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
-#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
-#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
-
-#define MULTIBOOT_HEADER_TAG_END 0
-#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
-#define MULTIBOOT_HEADER_TAG_ADDRESS 2
-#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
-#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
-#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
-#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
-#define MULTIBOOT_HEADER_TAG_EFI_BS 7
-#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
-#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
-#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
-
-#define MULTIBOOT_ARCHITECTURE_I386 0
-#define MULTIBOOT_ARCHITECTURE_MIPS32 4
-#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
-
-#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
-#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
-#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
-
-#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
-#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
-
-
-// 直接用 -m64 编译出来的是 64 位代码,
-// 但是启动后的机器是 32 位的,相当于在 32 位机器上跑 64 位程序。
-// 得加一层跳转到 64 位的 -m32 代码,开启 long 模式后再跳转到以 -m64 编译的代码中
-// 对于 x86_64,需要在启动阶段进入长模式(IA32E),这意味着需要一个临时页表
-// See https://wiki.osdev.org/Creating_a_64-bit_kernel: 
-// With a 32-bit bootstrap in your kernel
-
-// 这部分是从保护模式启动 long 模式的代码
-// 工作在 32bit
-// 声明这一段代码以 32 位模式编译
-.code32
-
-// multiboot2 文件头
-// 计算头长度
-.SET HEADER_LENGTH, multiboot_header_end - multiboot_header
-// 计算校验和
-.SET CHECKSUM, -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + HEADER_LENGTH)
-// 8 字节对齐
-.align MULTIBOOT_HEADER_ALIGN
-// 声明所属段
-.section .multiboot_header
-multiboot_header:
-    // 魔数
-    .long MULTIBOOT2_HEADER_MAGIC
-    // 架构
-    .long MULTIBOOT_ARCHITECTURE_I386
-    // 头长度
-    .long HEADER_LENGTH
-    // 校验和
-    .long CHECKSUM
-    // 添加其它内容在此,详细信息见 Multiboot2 Specification version 2.0.pdf
-	.short MULTIBOOT_HEADER_TAG_END
-    // 结束标记
-    .short 0
-    .long 8
-multiboot_header_end:
-
-// 临时页表 4KB/页
-.section .data
-.align 0x1000
-pml4:
-    .skip 0x1000
-pdpt:
-    .skip 0x1000
-pd:
-    .skip 0x1000
-pt:
-    .skip 0x1000
-
-// 临时 GDT
-.align 16
-gdt64:
-null_desc:
-    .short 0xFFFF
-    .short 0
-    .byte 0
-    .byte 0
-    .byte 0
-    .byte 0
-code_desc:
-    .short 0
-    .short 0
-    .byte 0
-    .byte 0x9A
-    .byte 0x20
-    .byte 0
-data_desc:
-    .short 0
-    .short 0
-    .byte 0
-    .byte 0x92
-    .byte 0
-    .byte 0
-user_code_desc:
-    .short 0
-    .short 0
-    .byte 0
-    .byte 0xFA
-    .byte 0x20
-    .byte 0
-user_data_desc:
-    .short 0
-    .short 0
-    .byte 0
-    .byte 0xF2
-    .byte 0
-    .byte 0
-gdt64_pointer:
-    .short gdt64_pointer-gdt64-1
-    .quad gdt64
-gdt64_pointer64:
-    .short gdt64_pointer-gdt64-1
-    .quad gdt64
-
-.section .text
-.global _start
-.type _start, @function
-# 在 multiboot2.cpp 中定义
-.extern boot_info_addr
-.extern multiboot2_magic
-_start:
-    // 关中断
-    cli
-    // multiboot2_info 结构体指针
-    //mov %ebx, boot_info_addr
-    // 魔数
-   // mov %eax, multiboot2_magic
-    // 从保护模式跳转到长模式
-    // 1. 允许 PAE
-    mov %cr4, %eax
-    or $(1<<5), %eax
-    mov %eax, %cr4
-    // 2. 设置临时页表
-    // 最高级
-    mov $pml4, %eax
-    mov $pdpt, %ebx
-    or $0x3, %ebx
-    mov %ebx, 0(%eax)
-    // 次级
-    mov $pdpt, %eax
-    mov $pd, %ebx
-    or $0x3, %ebx
-    mov %ebx, 0(%eax)
-    // 次低级
-    mov $pd, %eax
-    mov $pt, %ebx
-    or $0x3, %ebx
-    mov %ebx, 0(%eax)
-    // 最低级
-    // 循环 512 次,填满一页
-    mov $512, %ecx
-    mov $pt, %eax
-    mov $0x3, %ebx
-.fill_pt:
-    mov %ebx, 0(%eax)
-    add $0x1000, %ebx
-    add $8, %eax
-    loop .fill_pt
-    // 填写 CR3
-    mov $pml4, %eax
-    mov %eax, %cr3
-    // 3. 切换到 long 模式
-    mov $0xC0000080, %ecx
-    rdmsr
-    or $(1<<8), %eax
-    wrmsr
-    // 4. 开启分页
-    mov %cr0, %eax
-    or $(1<<31), %eax
-    mov %eax, %cr0
-    // 5. 重新设置 GDT
-    mov $gdt64_pointer, %eax
-    lgdt 0(%eax)
-    // 6. 跳转到 64 位代码执行
-    jmp $0x8, $_start64
-    hlt
-    ret

+ 99 - 2
kernel/driver/multiboot2/multiboot2.c

@@ -1,3 +1,100 @@
+#include "multiboot2.h"
+#include "assert.h"
 
-int *boot_info_addr;
-int *multiboot2_magic;
+#include "../../common/glib.h"
+
+uintptr_t boot_info_addr;
+unsigned int multiboot2_magic;
+unsigned int boot_info_size;
+
+bool multiboot2_init(void)
+{
+    uintptr_t *addr = (uintptr_t*)boot_info_addr;
+    if(multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC);
+        return false;
+    // addr+0 处保存了大小
+    boot_info_size = *(unsigned int *)addr;
+    return true;
+}
+
+void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, int *),
+                     void *data, int *count)
+{
+    uintptr_t addr = boot_info_addr;
+    // 下一字节开始为 tag 信息
+    struct iter_data_t *tag = (struct iter_data_t *)(addr + 8);
+    for (; tag->type != MULTIBOOT_TAG_TYPE_END;
+         tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
+    {
+        if (_fun(tag, data, count) == true)
+        {
+            return;
+        }
+    }
+    return;
+}
+
+// 读取 grub2 传递的物理内存信息,保存到 e820map_t 结构体中
+// 一般而言是这样的
+// 地址(长度) 类型
+// 0x00(0x9F000) 0x1
+// 0x9F000(0x1000) 0x2
+// 0xE8000(0x18000) 0x2
+// 0x100000(0x7EF0000) 0x1
+// 0x7FF0000(0x10000) 0x3
+// 0xFFFC0000(0x40000) 0x2
+/**
+ * @brief 获取multiboot2协议提供的内存区域信息
+ *
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data 返回信息的结构体指针
+ * @param count 返回数组的长度
+ * @return true
+ * @return false
+ */
+bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *data, int *count)
+{
+    if (_iter_data->type != MULTIBOOT_TAG_TYPE_MMAP)
+        return false;
+
+    struct multiboot_mmap_entry_t *resource = (struct multiboot_mmap_entry_t *)data;
+    struct multiboot_mmap_entry_t *mmap = ((struct multiboot_tag_mmap_t *)_iter_data)->entries;
+    *count = (uint8_t *)_iter_data + _iter_data->size;
+    for (; (uint8_t *)mmap < (uint8_t *)_iter_data + _iter_data->size;
+         mmap = (struct multiboot_mmap_entry_t *)((uint8_t *)mmap + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size))
+    {
+        *resource = *mmap;
+        // 将指针进行增加
+        resource = (struct multiboot_mmap_entry_t *)((uint8_t *)resource + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size);
+    }
+    return true;
+}
+
+/**
+ * @brief 获取VBE信息
+ * 
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data 返回信息的结构体指针
+ */
+bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, int *reserved)
+{
+    
+    if (_iter_data->type != MULTIBOOT_TAG_TYPE_VBE)
+        return false;
+    *(struct multiboot_tag_vbe_t *)data = *(struct multiboot_tag_vbe_t *)_iter_data;
+    return true;
+}
+
+/**
+ * @brief 获取帧缓冲区信息
+ * 
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data 返回信息的结构体指针
+ */
+bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *data, int *reserved)
+{
+    if(_iter_data->type !=MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
+        return false;
+    *(struct multiboot_tag_framebuffer_info_t *)data = *(struct multiboot_tag_framebuffer_info_t*)_iter_data;
+    return true;
+}

+ 0 - 104
kernel/driver/multiboot2/multiboot2.cpp

@@ -1,104 +0,0 @@
-/**
- * @file multiboot2.cpp
- * @brief multiboot2 解析实现
- * @author Zone.N ([email protected])
- * @version 1.0
- * @date 2021-09-18
- * @copyright MIT LICENSE
- * https://github.com/Simple-XX/SimpleKernel
- * @par change log:
- * <table>
- * <tr><th>Date<th>Author<th>Description
- * <tr><td>2021-09-18<td>digmouse233<td>迁移到 doxygen
- * </table>
- */
-
-#include "assert.h"
-#include "stdio.h"
-//#include "common.h"
-#include "multiboot2.h"
-#include "boot_info.h"
-//#include "resource.h"
-//#include "pmm.h"
-
-/// @todo 优化
-void MULTIBOOT2::multiboot2_iter(bool (*_fun)(const iter_data_t *, void *),
-                                 void *_data) {
-    uintptr_t addr = BOOT_INFO::boot_info_addr;
-    // 下一字节开始为 tag 信息
-    iter_data_t *tag = (iter_data_t *)(addr + 8);
-    for (; tag->type != MULTIBOOT_TAG_TYPE_END;
-         tag = (iter_data_t *)((uint8_t *)tag + COMMON::ALIGN(tag->size, 8))) {
-        if (_fun(tag, _data) == true) {
-            return;
-        }
-    }
-    return;
-}
-
-bool MULTIBOOT2::multiboot2_init(void) {
-    uintptr_t addr = BOOT_INFO::boot_info_addr;
-    // 判断魔数是否正确
-    assert(BOOT_INFO::multiboot2_magic == MULTIBOOT2_BOOTLOADER_MAGIC);
-    assert((reinterpret_cast<uintptr_t>(addr) & 7) == 0);
-    // addr+0 保存大小
-    BOOT_INFO::boot_info_size = *(uint32_t *)addr;
-    return true;
-}
-
-// 读取 grub2 传递的物理内存信息,保存到 e820map_t 结构体中
-// 一般而言是这样的
-// 地址(长度) 类型
-// 0x00(0x9F000) 0x1
-// 0x9F000(0x1000) 0x2
-// 0xE8000(0x18000) 0x2
-// 0x100000(0x7EF0000) 0x1
-// 0x7FF0000(0x10000) 0x3
-// 0xFFFC0000(0x40000) 0x2
-bool MULTIBOOT2::get_memory(const iter_data_t *_iter_data, void *_data) {
-    if (_iter_data->type != MULTIBOOT2::MULTIBOOT_TAG_TYPE_MMAP) {
-        return false;
-    }
-    resource_t *resource = (resource_t *)_data;
-    resource->type       = resource_t::MEM;
-    resource->name       = (char *)"available phy memory";
-    resource->mem.addr   = 0x0;
-    resource->mem.len    = 0;
-    MULTIBOOT2::multiboot_mmap_entry_t *mmap =
-        ((MULTIBOOT2::multiboot_tag_mmap_t *)_iter_data)->entries;
-    for (; (uint8_t *)mmap < (uint8_t *)_iter_data + _iter_data->size;
-         mmap = (MULTIBOOT2::multiboot_mmap_entry_t
-                     *)((uint8_t *)mmap +
-                        ((MULTIBOOT2::multiboot_tag_mmap_t *)_iter_data)
-                            ->entry_size)) {
-        // 如果是可用内存或地址小于 1M
-        // 这里将 0~1M 的空间全部算为可用,在 c++ 库可用后进行优化
-        if (mmap->type == MULTIBOOT_MEMORY_AVAILABLE ||
-            mmap->addr < 1 * COMMON::MB) {
-            // 长度+
-            resource->mem.len += mmap->len;
-        }
-    }
-    return true;
-}
-
-namespace BOOT_INFO {
-    // 地址
-    uintptr_t boot_info_addr;
-    // 长度
-    size_t boot_info_size;
-    // 魔数
-    uint32_t multiboot2_magic;
-
-    bool init(void) {
-        auto res = MULTIBOOT2::multiboot2_init();
-        info("BOOT_INFO init.\n");
-        return res;
-    }
-
-    resource_t get_memory(void) {
-        resource_t resource;
-        MULTIBOOT2::multiboot2_iter(MULTIBOOT2::get_memory, &resource);
-        return resource;
-    }
-};

+ 426 - 310
kernel/driver/multiboot2/multiboot2.h

@@ -1,24 +1,13 @@
 /**
  * @file multiboot2.h
  * @brief multiboot2 解析
- * @author Zone.N ([email protected])
- * @version 1.0
- * @date 2021-09-18
- * @copyright MIT LICENSE
- * https://github.com/Simple-XX/SimpleKernel
- * @par change log:
- * <table>
- * <tr><th>Date<th>Author<th>Description
- * <tr><td>2021-09-18<td>digmouse233<td>迁移到 doxygen
- * </table>
  */
 
-#ifndef _MULTIBOOT2_H_
-#define _MULTIBOOT2_H_
+#pragma once
 
 #include "stdint.h"
 #include "stdbool.h"
-#include "boot_info.h"
+#include "../../common/boot_info.h"
 
 /// @see Multiboot2 Specification version 2.0.pdf
 // 启动后,在 32 位内核进入点,机器状态如下:
@@ -35,300 +24,427 @@
 /**
  * @brief MULTIBOOT2 接口抽象
  */
-class MULTIBOOT2 {
-private:
-    /*  How many bytes from the start of the file we search for the header. */
-    static constexpr const uint32_t MULTIBOOT_SEARCH       = 32768;
-    static constexpr const uint32_t MULTIBOOT_HEADER_ALIGN = 8;
-
-    /*  The magic field should contain this. */
-    static constexpr const uint32_t MULTIBOOT2_HEADER_MAGIC = 0xe85250d6;
-
-    /*  This should be in %eax. */
-    static constexpr const uint32_t MULTIBOOT2_BOOTLOADER_MAGIC = 0x36d76289;
-
-    /*  Alignment of multiboot modules. */
-    static constexpr const uint32_t MULTIBOOT_MOD_ALIGN = 0x00001000;
-
-    /*  Alignment of the multiboot info structure. */
-    static constexpr const uint32_t MULTIBOOT_INFO_ALIGN = 0x00000008;
-
-    /*  Flags set in the 'flags' member of the multiboot header. */
-
-    static constexpr const uint32_t MULTIBOOT_TAG_ALIGN                 = 8;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_END              = 0;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_CMDLINE          = 1;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME = 2;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_MODULE           = 3;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_BASIC_MEMINFO    = 4;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_BOOTDEV          = 5;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_MMAP             = 6;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_VBE              = 7;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_FRAMEBUFFER      = 8;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_ELF_SECTIONS     = 9;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_APM              = 10;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_EFI32            = 11;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_EFI64            = 12;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_SMBIOS           = 13;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_ACPI_OLD         = 14;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_ACPI_NEW         = 15;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_NETWORK          = 16;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_EFI_MMAP         = 17;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_EFI_BS           = 18;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_EFI32_IH         = 19;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_EFI64_IH         = 20;
-    static constexpr const uint32_t MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR   = 21;
-
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_END = 0;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST =
-        1;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_ADDRESS       = 2;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS = 3;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS = 4;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_FRAMEBUFFER   = 5;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_MODULE_ALIGN  = 6;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_EFI_BS        = 7;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 =
-        8;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 =
-        9;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_RELOCATABLE = 10;
-
-    static constexpr const uint32_t MULTIBOOT_ARCHITECTURE_I386   = 0;
-    static constexpr const uint32_t MULTIBOOT_ARCHITECTURE_MIPS32 = 4;
-    static constexpr const uint32_t MULTIBOOT_HEADER_TAG_OPTIONAL = 1;
-
-    static constexpr const uint32_t MULTIBOOT_LOAD_PREFERENCE_NONE = 0;
-    static constexpr const uint32_t MULTIBOOT_LOAD_PREFERENCE_LOW  = 1;
-    static constexpr const uint32_t MULTIBOOT_LOAD_PREFERENCE_HIGH = 2;
-
-    static constexpr const uint32_t MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED =
-        1;
-    static constexpr const uint32_t MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED =
-        2;
-
-    struct multiboot_header_t {
-        // Must be MULTIBOOT_MAGIC - see above.
-        uint32_t magic;
-        // ISA
-        uint32_t architecture;
-        // Total header length.
-        uint32_t header_length;
-        // The above fields plus this one must equal 0 mod 2^32.
-        uint32_t checksum;
-    };
-
-    struct multiboot_header_tag_t {
-        uint16_t type;
-        uint16_t flags;
-        uint32_t size;
-    };
-
-    struct multiboot_header_tag_information_request_t : multiboot_header_tag_t {
-        uint32_t requests[0];
-    };
-
-    struct multiboot_header_tag_address_t : multiboot_header_tag_t {
-        uint32_t header_addr;
-        uint32_t load_addr;
-        uint32_t load_end_addr;
-        uint32_t bss_end_addr;
-    };
-
-    struct multiboot_header_tag_entry_address_t : multiboot_header_tag_t {
-        uint32_t entry_addr;
-    };
-
-    struct multiboot_header_tag_console_flags_t : multiboot_header_tag_t {
-        uint32_t console_flags;
-    };
-
-    struct multiboot_header_tag_framebuffer_t : multiboot_header_tag_t {
-        uint32_t width;
-        uint32_t height;
-        uint32_t depth;
-    };
-
-    struct multiboot_header_tag_module_align_t : multiboot_header_tag_t {
-        ;
-    };
-
-    struct multiboot_header_tag_relocatable_t : multiboot_header_tag_t {
-        uint32_t min_addr;
-        uint32_t max_addr;
-        uint32_t align;
-        uint32_t preference;
-    };
-
-    struct multiboot_color_t {
-        uint8_t red;
-        uint8_t green;
-        uint8_t blue;
-    };
-
-    static constexpr const uint32_t MULTIBOOT_MEMORY_AVAILABLE        = 1;
-    static constexpr const uint32_t MULTIBOOT_MEMORY_RESERVED         = 2;
-    static constexpr const uint32_t MULTIBOOT_MEMORY_ACPI_RECLAIMABLE = 3;
-    static constexpr const uint32_t MULTIBOOT_MEMORY_NVS              = 4;
-    static constexpr const uint32_t MULTIBOOT_MEMORY_BADRAM           = 5;
-    struct multiboot_mmap_entry_t {
-        uint64_t addr;
-        uint64_t len;
-        uint32_t type;
-        uint32_t zero;
-    };
-
-    struct multiboot_tag_t {
-        uint32_t type;
-        uint32_t size;
-    };
-
-    struct multiboot_tag_string_t : multiboot_tag_t {
-        char string[0];
-    };
-
-    struct multiboot_tag_module_t : multiboot_tag_t {
-        uint32_t mod_start;
-        uint32_t mod_end;
-        char     cmdline[0];
-    };
-
-    struct multiboot_tag_basic_meminfo_t : multiboot_tag_t {
-        uint32_t mem_lower;
-        uint32_t mem_upper;
-    };
-
-    struct multiboot_tag_bootdev_t : multiboot_tag_t {
-        uint32_t biosdev;
-        uint32_t slice;
-        uint32_t part;
-    };
-
-    struct multiboot_tag_mmap_t : multiboot_tag_t {
-        uint32_t               entry_size;
-        uint32_t               entry_version;
-        multiboot_mmap_entry_t entries[0];
-    };
-
-    struct multiboot_vbe_info_block_t {
-        uint8_t external_specification[512];
-    };
-
-    struct multiboot_vbe_mode_info_block_t {
-        uint8_t external_specification[256];
-    };
-
-    struct multiboot_tag_vbe_t : multiboot_tag_t {
-        uint16_t vbe_mode;
-        uint16_t vbe_interface_seg;
-        uint16_t vbe_interface_off;
-        uint16_t vbe_interface_len;
-
-        multiboot_vbe_info_block_t      vbe_control_info;
-        multiboot_vbe_mode_info_block_t vbe_mode_info;
-    };
-
-    struct multiboot_tag_elf_sections_t : multiboot_tag_t {
-        uint32_t num;
-        uint32_t entsize;
-        // 段字符串表索引
-        uint32_t shndx;
-        char     sections[0];
-    };
-
-    struct multiboot_tag_apm_t : multiboot_tag_t {
-        uint16_t version;
-        uint16_t cseg;
-        uint32_t offset;
-        uint16_t cseg_16;
-        uint16_t dseg;
-        uint16_t flags;
-        uint16_t cseg_len;
-        uint16_t cseg_16_len;
-        uint16_t dseg_len;
-    };
-
-    struct multiboot_tag_efi32_t : multiboot_tag_t {
-        uint32_t pointer;
-    };
-
-    struct multiboot_tag_efi64_t : multiboot_tag_t {
-        uint64_t pointer;
-    };
-
-    struct multiboot_tag_smbios_t : multiboot_tag_t {
-        uint8_t major;
-        uint8_t minor;
-        uint8_t reserved[6];
-        uint8_t tables[0];
-    };
-
-    struct multiboot_tag_old_acpi_t : multiboot_tag_t {
-        uint8_t rsdp[0];
-    };
-
-    struct multiboot_tag_new_acpi_t : multiboot_tag_t {
-        uint8_t rsdp[0];
-    };
-
-    struct multiboot_tag_network_t : multiboot_tag_t {
-        uint8_t dhcpack[0];
-    };
-
-    struct multiboot_tag_efi_mmap_t : multiboot_tag_t {
-        uint32_t descr_size;
-        uint32_t descr_vers;
-        uint8_t  efi_mmap[0];
-    };
-
-    struct multiboot_tag_efi32_ih_t : multiboot_tag_t {
-        uint32_t pointer;
-    };
-
-    struct multiboot_tag_efi64_ih_t : multiboot_tag_t {
-        uint64_t pointer;
-    };
-
-    struct multiboot_tag_load_base_addr_t : multiboot_tag_t {
-        uint32_t load_base_addr;
-    };
-
-    // 迭代变量
-    // 与 multiboot_tag_t 相同
-    struct iter_data_t {
-        uint32_t type;
-        uint32_t size;
-    };
-
-public:
-    /**
-     * @brief 初始化
-     * @return true            成功
-     * @return false           失败
-     */
-    static bool multiboot2_init(void);
-
-    /**
-     * @brief 迭代器
-     * @param  _fun            迭代操作
-     * @param  _data           数据
-     */
-    static void multiboot2_iter(bool (*_fun)(const iter_data_t *, void *),
-                                void *_data);
-
-    /**
-     * @brief 获取内存信息
-     * @param  _iter_data      迭代变量
-     * @param  _data           数据
-     * @return true            成功
-     * @return false           失败
-     */
-    static bool get_memory(const iter_data_t *_iter_data, void *_data);
-};
-
-namespace BOOT_INFO {
-    /// 魔数
-    extern "C" uint32_t multiboot2_magic;
-};
-
-#endif /* _MULTIBOOT2_H_ */
+
+extern unsigned int multiboot2_magic;
+
+/*  How many bytes from the start of the file we search for the header. */
+static const unsigned int MULTIBOOT_SEARCH = 32768;
+static const unsigned int MULTIBOOT_HEADER_ALIGN = 8;
+
+/*  The magic field should contain this. */
+static const unsigned int MULTIBOOT2_HEADER_MAGIC = 0xe85250d6;
+
+/*  This should be in %eax. */
+static const unsigned int MULTIBOOT2_BOOTLOADER_MAGIC = 0x36d76289;
+
+/*  Alignment of multiboot modules. */
+static const unsigned int MULTIBOOT_MOD_ALIGN = 0x00001000;
+
+/*  Alignment of the multiboot info structure. */
+static const unsigned int MULTIBOOT_INFO_ALIGN = 0x00000008;
+
+/*  Flags set in the 'flags' member of the multiboot header. */
+
+static const unsigned int MULTIBOOT_TAG_ALIGN = 8;
+static const unsigned int MULTIBOOT_TAG_TYPE_END = 0;
+static const unsigned int MULTIBOOT_TAG_TYPE_CMDLINE = 1;
+static const unsigned int MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME = 2;
+static const unsigned int MULTIBOOT_TAG_TYPE_MODULE = 3;
+static const unsigned int MULTIBOOT_TAG_TYPE_BASIC_MEMINFO = 4;
+static const unsigned int MULTIBOOT_TAG_TYPE_BOOTDEV = 5;
+static const unsigned int MULTIBOOT_TAG_TYPE_MMAP = 6;
+static const unsigned int MULTIBOOT_TAG_TYPE_VBE = 7;
+static const unsigned int MULTIBOOT_TAG_TYPE_FRAMEBUFFER = 8;
+static const unsigned int MULTIBOOT_TAG_TYPE_ELF_SECTIONS = 9;
+static const unsigned int MULTIBOOT_TAG_TYPE_APM = 10;
+static const unsigned int MULTIBOOT_TAG_TYPE_EFI32 = 11;
+static const unsigned int MULTIBOOT_TAG_TYPE_EFI64 = 12;
+static const unsigned int MULTIBOOT_TAG_TYPE_SMBIOS = 13;
+static const unsigned int MULTIBOOT_TAG_TYPE_ACPI_OLD = 14;
+static const unsigned int MULTIBOOT_TAG_TYPE_ACPI_NEW = 15;
+static const unsigned int MULTIBOOT_TAG_TYPE_NETWORK = 16;
+static const unsigned int MULTIBOOT_TAG_TYPE_EFI_MMAP = 17;
+static const unsigned int MULTIBOOT_TAG_TYPE_EFI_BS = 18;
+static const unsigned int MULTIBOOT_TAG_TYPE_EFI32_IH = 19;
+static const unsigned int MULTIBOOT_TAG_TYPE_EFI64_IH = 20;
+static const unsigned int MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR = 21;
+
+static const unsigned int MULTIBOOT_HEADER_TAG_END = 0;
+static const unsigned int MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST =
+    1;
+static const unsigned int MULTIBOOT_HEADER_TAG_ADDRESS = 2;
+static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS = 3;
+static const unsigned int MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS = 4;
+static const unsigned int MULTIBOOT_HEADER_TAG_FRAMEBUFFER = 5;
+static const unsigned int MULTIBOOT_HEADER_TAG_MODULE_ALIGN = 6;
+static const unsigned int MULTIBOOT_HEADER_TAG_EFI_BS = 7;
+static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 =
+    8;
+static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 =
+    9;
+static const unsigned int MULTIBOOT_HEADER_TAG_RELOCATABLE = 10;
+
+static const unsigned int MULTIBOOT_ARCHITECTURE_I386 = 0;
+static const unsigned int MULTIBOOT_ARCHITECTURE_MIPS32 = 4;
+static const unsigned int MULTIBOOT_HEADER_TAG_OPTIONAL = 1;
+
+static const unsigned int MULTIBOOT_LOAD_PREFERENCE_NONE = 0;
+static const unsigned int MULTIBOOT_LOAD_PREFERENCE_LOW = 1;
+static const unsigned int MULTIBOOT_LOAD_PREFERENCE_HIGH = 2;
+
+static const unsigned int MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED =
+    1;
+static const unsigned int MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED =
+    2;
+
+static const unsigned int MULTIBOOT_MEMORY_AVAILABLE = 1;
+static const unsigned int MULTIBOOT_MEMORY_RESERVED = 2;
+static const unsigned int MULTIBOOT_MEMORY_ACPI_RECLAIMABLE = 3;
+static const unsigned int MULTIBOOT_MEMORY_NVS = 4;
+static const unsigned int MULTIBOOT_MEMORY_BADRAM = 5;
+
+struct multiboot_header_t
+{
+    // Must be MULTIBOOT_MAGIC - see above.
+    unsigned int magic;
+    // ISA
+    unsigned int architecture;
+    // Total header length.
+    unsigned int header_length;
+    // The above fields plus this one must equal 0 mod 2^32.
+    unsigned int checksum;
+};
+
+struct multiboot_header_tag_t
+{
+    uint16_t type;
+    uint16_t flags;
+    unsigned int size;
+};
+struct multiboot_header_tag_information_request_t
+{
+    uint16_t type;
+    uint16_t flags;
+    unsigned int size;
+
+    unsigned int requests[0];
+};
+struct multiboot_header_tag_address_t
+{
+    uint16_t type;
+    uint16_t flags;
+    unsigned int size;
+
+    unsigned int header_addr;
+    unsigned int load_addr;
+    unsigned int load_end_addr;
+    unsigned int bss_end_addr;
+};
+
+struct multiboot_header_tag_entry_address_t
+{
+    uint16_t type;
+    uint16_t flags;
+    unsigned int size;
+
+    unsigned int entry_addr;
+};
+
+struct multiboot_header_tag_console_flags_t
+{
+    uint16_t type;
+    uint16_t flags;
+    unsigned int size;
+
+    unsigned int console_flags;
+};
+
+struct multiboot_header_tag_framebuffer_t
+{
+    uint16_t type;
+    uint16_t flags;
+    unsigned int size;
+
+    unsigned int width;
+    unsigned int height;
+    unsigned int depth;
+};
+
+struct multiboot_header_tag_module_align_t
+{
+    uint16_t type;
+    uint16_t flags;
+    unsigned int size;
+};
+
+struct multiboot_header_tag_relocatable_t
+{
+    uint16_t type;
+    uint16_t flags;
+    unsigned int size;
+
+    unsigned int min_addr;
+    unsigned int max_addr;
+    unsigned int align;
+    unsigned int preference;
+};
+
+struct multiboot_color_t
+{
+    uint8_t red;
+    uint8_t green;
+    uint8_t blue;
+};
+
+// multiboot2协议的内存区域信息
+struct multiboot_mmap_entry_t
+{
+    uint64_t addr;
+    uint64_t len;
+    unsigned int type;
+    unsigned int reserved;
+};
+
+struct multiboot_tag_t
+{
+    unsigned int type;
+    unsigned int size;
+};
+
+struct multiboot_tag_string_t
+{
+    struct multiboot_tag_t tag_t;
+    char string[0];
+};
+
+struct multiboot_tag_module_t
+{
+    struct multiboot_tag_t tag_t;
+    unsigned int mod_start;
+    unsigned int mod_end;
+    char cmdline[0];
+};
+
+struct multiboot_tag_basic_meminfo_t
+{
+    struct multiboot_tag_t tag_t;
+    unsigned int mem_lower;
+    unsigned int mem_upper;
+};
+
+struct multiboot_tag_bootdev_t
+{
+    struct multiboot_tag_t tag_t;
+    unsigned int biosdev;
+    unsigned int slice;
+    unsigned int part;
+};
+
+struct multiboot_tag_mmap_t
+{
+    struct multiboot_tag_t tag_t;
+    unsigned int entry_size;
+    unsigned int entry_version;
+    struct multiboot_mmap_entry_t entries[0];
+};
+
+struct multiboot_vbe_info_block_t
+{
+    uint8_t external_specification[512];
+};
+
+struct multiboot_vbe_mode_info_block_t
+{
+    uint8_t external_specification[256];
+};
+
+// bootloader传递的VBE信息的结构体
+struct multiboot_tag_vbe_t
+{
+    struct multiboot_tag_t tag_t;
+    uint16_t vbe_mode;
+    uint16_t vbe_interface_seg;
+    uint16_t vbe_interface_off;
+    uint16_t vbe_interface_len;
+
+    // The fields ‘vbe_control_info’ and ‘vbe_mode_info’ contain VBE control information returned by the VBE Function 00h and VBE mode information
+    // returned by the VBE Function 01h, respectively.
+    struct multiboot_vbe_info_block_t vbe_control_info;
+    struct multiboot_vbe_mode_info_block_t vbe_mode_info;
+};
+
+struct multiboot_tag_framebuffer_info_t
+{
+    struct multiboot_tag_t tag_t;
+    uint64_t framebuffer_addr;
+    uint32_t framebuffer_pitch; // 帧缓存上界
+    // width and height expressed in pixels except type=2
+    // when type=2, they are expressed in characters
+    uint32_t framebuffer_width;
+    uint32_t framebuffer_height;
+    // number of bits per pixel.
+    uint8_t framebuffer_bpp;
+    // 帧缓存的类型
+    uint8_t framebuffer_type;
+    uint8_t reserved;
+};
+
+// indexed color
+struct multiboot_tag_framebuffer_info_type0_t
+{
+    struct multiboot_tag_framebuffer_info_t;
+    uint32_t framebuffer_palette_num_colors;
+    struct multiboot_color_t color_desc;
+};
+
+// direct RGB color
+struct multiboot_tag_framebuffer_info_type1_t
+{
+    struct multiboot_tag_framebuffer_info_t;
+
+    uint8_t framebuffer_red_field_position;
+    uint8_t framebuffer_red_mask_size;
+    uint8_t framebuffer_green_field_position;
+    uint8_t framebuffer_green_mask_size;
+    uint8_t framebuffer_blue_field_position;
+    uint8_t framebuffer_blue_mask_size;
+};
+
+struct multiboot_tag_elf_sections_t
+{
+    struct multiboot_tag_t tag_t;
+    unsigned int num;
+    unsigned int entsize;
+    // 段字符串表索引
+    unsigned int shndx;
+    char sections[0];
+};
+
+struct multiboot_tag_apm_t
+{
+    struct multiboot_tag_t tag_t;
+    uint16_t version;
+    uint16_t cseg;
+    unsigned int offset;
+    uint16_t cseg_16;
+    uint16_t dseg;
+    uint16_t flags;
+    uint16_t cseg_len;
+    uint16_t cseg_16_len;
+    uint16_t dseg_len;
+};
+
+struct multiboot_tag_efi32_t
+{
+    struct multiboot_tag_t tag_t;
+    unsigned int pointer;
+};
+
+struct multiboot_tag_efi64_t
+{
+    struct multiboot_tag_t tag_t;
+    uint64_t pointer;
+};
+
+struct multiboot_tag_smbios_t
+{
+    struct multiboot_tag_t tag_t;
+    uint8_t major;
+    uint8_t minor;
+    uint8_t reserved[6];
+    uint8_t tables[0];
+};
+
+struct multiboot_tag_old_acpi_t
+{
+    struct multiboot_tag_t tag_t;
+    uint8_t rsdp[0];
+};
+
+struct multiboot_tag_new_acpi_t
+{
+    struct multiboot_tag_t tag_t;
+    uint8_t rsdp[0];
+};
+
+struct multiboot_tag_network_t
+{
+    struct multiboot_tag_t tag_t;
+    uint8_t dhcpack[0];
+};
+
+struct multiboot_tag_efi_mmap_t
+{
+    struct multiboot_tag_t tag_t;
+    unsigned int descr_size;
+    unsigned int descr_vers;
+    uint8_t efi_mmap[0];
+};
+
+struct multiboot_tag_efi32_ih_t
+{
+    struct multiboot_tag_t tag_t;
+    unsigned int pointer;
+};
+
+struct multiboot_tag_efi64_ih_t
+{
+    struct multiboot_tag_t tag_t;
+    uint64_t pointer;
+};
+
+struct multiboot_tag_load_base_addr_t
+{
+    struct multiboot_tag_t tag_t;
+    unsigned int load_base_addr;
+};
+
+// 迭代变量
+// 与 multiboot_tag_t 相同
+struct iter_data_t
+{
+    unsigned int type;
+    unsigned int size;
+};
+
+/**
+ * @brief 初始化
+ * @return true            成功
+ * @return false           失败
+ */
+static bool multiboot2_init(void);
+
+/**
+ * @brief 迭代器
+ * @param  _fun            迭代操作
+ * @param  _data           数据
+ */
+void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, int *),
+                            void *_data, int *count);
+
+/**
+ * @brief 获取multiboot2协议提供的内存区域信息
+ *
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data 返回信息的结构体指针
+ * @param count 返回数组的长度
+ * @return true
+ * @return false
+ */
+bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *_data, int *count);
+
+/**
+ * @brief 获取VBE信息
+ *
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data 返回信息的结构体指针
+ */
+bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *_data, int *reserved);
+
+/**
+ * @brief 获取帧缓冲区信息
+ *
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data 返回信息的结构体指针
+ */
+bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *_data, int *reserved);

+ 88 - 3
kernel/head.S

@@ -72,6 +72,74 @@
 #define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
 
 
+// 以下是来自 multiboot2 规范的定义
+//  How many bytes from the start of the file we search for the header.
+#define MULTIBOOT_SEARCH 32768
+#define MULTIBOOT_HEADER_ALIGN 8
+
+//  The magic field should contain this.
+#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
+
+//  This should be in %eax.
+#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
+
+//  Alignment of multiboot modules.
+#define MULTIBOOT_MOD_ALIGN 0x00001000
+
+//  Alignment of the multiboot info structure.
+#define MULTIBOOT_INFO_ALIGN 0x00000008
+
+//  Flags set in the 'flags' member of the multiboot header.
+
+#define MULTIBOOT_TAG_ALIGN 8
+#define MULTIBOOT_TAG_TYPE_END 0
+#define MULTIBOOT_TAG_TYPE_CMDLINE 1
+#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
+#define MULTIBOOT_TAG_TYPE_MODULE 3
+#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
+#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
+#define MULTIBOOT_TAG_TYPE_MMAP 6
+#define MULTIBOOT_TAG_TYPE_VBE 7
+#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
+#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
+#define MULTIBOOT_TAG_TYPE_APM 10
+#define MULTIBOOT_TAG_TYPE_EFI32 11
+#define MULTIBOOT_TAG_TYPE_EFI64 12
+#define MULTIBOOT_TAG_TYPE_SMBIOS 13
+#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
+#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
+#define MULTIBOOT_TAG_TYPE_NETWORK 16
+#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
+#define MULTIBOOT_TAG_TYPE_EFI_BS 18
+#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
+#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
+#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
+
+#define MULTIBOOT_HEADER_TAG_END 0
+#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
+#define MULTIBOOT_HEADER_TAG_ADDRESS 2
+#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
+#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
+#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
+#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
+#define MULTIBOOT_HEADER_TAG_EFI_BS 7
+#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
+#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
+#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
+
+#define MULTIBOOT_ARCHITECTURE_I386 0
+#define MULTIBOOT_ARCHITECTURE_MIPS32 4
+#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
+
+#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
+#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
+#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
+
+#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
+#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
+
+
+
 // 直接用 -m64 编译出来的是 64 位代码,
 // 但是启动后的机器是 32 位的,相当于在 32 位机器上跑 64 位程序。
 // 得加一层跳转到 64 位的 -m32 代码,开启 long 模式后再跳转到以 -m64 编译的代码中
@@ -103,12 +171,25 @@ multiboot_header:
     // 校验和
     .long CHECKSUM
     // 添加其它内容在此,详细信息见 Multiboot2 Specification version 2.0.pdf
+
+// 设置帧缓冲区
+.align 8
+framebuffer_tag_start:
+    .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
+    .short MULTIBOOT_HEADER_TAG_OPTIONAL
+    .long framebuffer_tag_end - framebuffer_tag_start
+    .long 1440
+    .long 900
+    .long 32
+framebuffer_tag_end:
+.align 8
 	.short MULTIBOOT_HEADER_TAG_END
     // 结束标记
     .short 0
     .long 8
 multiboot_header_end:
 
+
 // 临时页表 4KB/页
 .section .data
 .align 0x1000
@@ -172,13 +253,14 @@ gdt64_pointer64:
 # 在 multiboot2.cpp 中定义
 .extern boot_info_addr
 .extern multiboot2_magic
+.extern _start64
 _start:
     // 关中断
     cli
     // multiboot2_info 结构体指针
-    //mov %ebx, boot_info_addr
+    mov %ebx, boot_info_addr
     // 魔数
-    //mov %eax, multiboot2_magic
+    mov %eax, multiboot2_magic
     / 从保护模式跳转到长模式
     // 1. 允许 PAE
     mov %cr4, %eax
@@ -238,6 +320,7 @@ _start:
     hlt
     ret
 
+
 .section .text
 
 .code64
@@ -279,6 +362,8 @@ ENTRY(_start64)
     mov $__PDE, %ebx
     or $0x7, %ebx
     mov %ebx, 0(%eax)
+
+
 // ==== 加载CR3寄存器
     movq $__PML4E, %rax //设置页目录基地址
     movq %rax, %cr3
@@ -421,7 +506,7 @@ __PDE:
 	.quad	0x400087
 	.quad	0x600087
 	.quad	0x800087
-	.quad	0xe0000087		/*0x a00000*/
+	.quad	0xe0000087		/*虚拟地址0x a00000 帧缓冲区映射到这里*/ 
 	.quad	0xe0200087
 	.quad	0xe0400087
 	.quad	0xe0600087		/*0x1000000*/

+ 10 - 6
kernel/link.lds

@@ -2,15 +2,15 @@
 OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64")
 OUTPUT_ARCH(i386:x86-64)
 ENTRY(_start)
+
 SECTIONS
 {
-
 	. = 0;
-
-
-	. = 1M;
+	. = 0x100000;
+	
 	.text :
 	{
+		
 		_text = .;
 		*(.multiboot_header)
 		*(.text)
@@ -23,10 +23,9 @@ SECTIONS
 		_data = .;
 		*(.data)
 		
-        *(.eh_frame)
 		_edata = .;
 	}
-	.rodata : 
+	.rodata :
 	{
 		_rodata = .;	
 		*(.rodata)
@@ -42,5 +41,10 @@ SECTIONS
 		_ebss = .;
 	}
 
+	.eh_frame :
+	{
+		*(.eh_frame)
+	}
+
 	_end = .;
 }

+ 9 - 8
kernel/main.c

@@ -12,7 +12,7 @@
 #include "process/process.h"
 #include "syscall/syscall.h"
 
-unsigned int *FR_address = (unsigned int *)0xffff800000a00000; //帧缓存区的地址
+unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
                                                                // char fxsave_region[512] __attribute__((aligned(16)));
 
 struct memory_desc memory_management_struct = {{0}, 0};
@@ -62,17 +62,17 @@ void test_mm()
 // 初始化系统各模块
 void system_initialize()
 {
+    
     // 初始化printk
-    init_printk(1024, 768, FR_address, 1024 * 768 * 4, 8, 16);
-    printk("11111\n");
+    
+    init_printk(8, 16);
+    
     load_TR(10); // 加载TR寄存器
-    while(1);
-    // 初始化任务状态段表
-    ul tss_item_addr = 0xffff800000007c00;
+    ul tss_item_addr = 0x7c00;
 
     set_TSS64(_stack_start, _stack_start, _stack_start, tss_item_addr, tss_item_addr,
               tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr);
-
+    
     // 初始化中断描述符表
     init_sys_vector();
 
@@ -84,6 +84,7 @@ void system_initialize()
 
     // 先初始化系统调用模块
     syscall_init();
+
     // 再初始化进程模块。顺序不能调转
     process_init();
 }
@@ -93,7 +94,7 @@ void Start_Kernel(void)
 {
 
     system_initialize();
-
+    
     // show_welcome();
     // test_mm();
 

+ 1 - 1
kernel/mm/mm.h

@@ -7,7 +7,7 @@
 #define PTRS_PER_PGT 512
 
 // 内核层的起始地址
-#define KERNEL_BASE_ADDR ((unsigned long)0xffff800000000000)
+#define KERNEL_BASE_ADDR ((unsigned long)0x100000)
 
 #define PAGE_4K_SHIFT 12
 #define PAGE_2M_SHIFT 21

+ 1 - 1
run.sh

@@ -12,7 +12,7 @@ if [ ! "$1" == "--nobuild" ]; then
     make clean
 fi
 
-IA32_USE_QEMU=1
+IA32_USE_QEMU=0
 bochsrc="./bochsrc"
 ARCH="x86_64"