diff --git a/.gitignore b/.gitignore
index 14ce310d..28fb3c93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
/cmake-build-debug/
/bin/
-./DragonOS.iso
\ No newline at end of file
+DragonOS.iso
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 7e4e51ef..d427ee94 100644
--- a/.vscode/settings.json
+++ b/.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"
}
}
\ No newline at end of file
diff --git a/kernel/Makefile b/kernel/Makefile
index f0cfda68..9622b61c 100644
--- a/kernel/Makefile
+++ b/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
diff --git a/kernel/common/boot_info.h b/kernel/common/boot_info.h
index 8e854fab..43ea38ae 100644
--- a/kernel/common/boot_info.h
+++ b/kernel/common/boot_info.h
@@ -2,64 +2,48 @@
/**
* @file boot_info.h
* @brief 启动信息接口
- * @author Zone.N (Zone.Niuzh@hotmail.com)
- * @version 1.0
- * @date 2021-09-18
- * @copyright MIT LICENSE
- * https://github.com/Simple-XX/SimpleKernel
- * @par change log:
- *
- * Date | Author | Description
- * |
---|
2021-09-18 | digmouse233 | 迁移到 doxygen
- * |
*/
-#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_ */
\ No newline at end of file
diff --git a/kernel/common/glib.h b/kernel/common/glib.h
index 478b7e62..a4c014c7 100644
--- a/kernel/common/glib.h
+++ b/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
{
diff --git a/kernel/common/printk.c b/kernel/common/printk.c
index d68b6817..5a65da30 100644
--- a/kernel/common/printk.c
+++ b/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 ... 格式化字符串
diff --git a/kernel/common/printk.h b/kernel/common/printk.h
index 3c13fccc..1e81c0ad 100644
--- a/kernel/common/printk.h
+++ b/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
*
diff --git a/kernel/driver/multiboot2/boot.S b/kernel/driver/multiboot2/boot.S
deleted file mode 100644
index 7941984d..00000000
--- a/kernel/driver/multiboot2/boot.S
+++ /dev/null
@@ -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
diff --git a/kernel/driver/multiboot2/multiboot2.c b/kernel/driver/multiboot2/multiboot2.c
index 2e1bb0f5..a9290a20 100644
--- a/kernel/driver/multiboot2/multiboot2.c
+++ b/kernel/driver/multiboot2/multiboot2.c
@@ -1,3 +1,100 @@
+#include "multiboot2.h"
+#include "assert.h"
-int *boot_info_addr;
-int *multiboot2_magic;
\ No newline at end of file
+#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;
+}
\ No newline at end of file
diff --git a/kernel/driver/multiboot2/multiboot2.cpp b/kernel/driver/multiboot2/multiboot2.cpp
deleted file mode 100644
index b92dcfed..00000000
--- a/kernel/driver/multiboot2/multiboot2.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * @file multiboot2.cpp
- * @brief multiboot2 解析实现
- * @author Zone.N (Zone.Niuzh@hotmail.com)
- * @version 1.0
- * @date 2021-09-18
- * @copyright MIT LICENSE
- * https://github.com/Simple-XX/SimpleKernel
- * @par change log:
- *
- * Date | Author | Description
- * |
---|
2021-09-18 | digmouse233 | 迁移到 doxygen
- * |
- */
-
-#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(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;
- }
-};
\ No newline at end of file
diff --git a/kernel/driver/multiboot2/multiboot2.h b/kernel/driver/multiboot2/multiboot2.h
index 02386184..0b8cf556 100644
--- a/kernel/driver/multiboot2/multiboot2.h
+++ b/kernel/driver/multiboot2/multiboot2.h
@@ -1,24 +1,13 @@
/**
* @file multiboot2.h
* @brief multiboot2 解析
- * @author Zone.N (Zone.Niuzh@hotmail.com)
- * @version 1.0
- * @date 2021-09-18
- * @copyright MIT LICENSE
- * https://github.com/Simple-XX/SimpleKernel
- * @par change log:
- *
- * Date | Author | Description
- * |
---|
2021-09-18 | digmouse233 | 迁移到 doxygen
- * |
*/
-#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;
+extern unsigned int multiboot2_magic;
- /* This should be in %eax. */
- static constexpr const uint32_t MULTIBOOT2_BOOTLOADER_MAGIC = 0x36d76289;
+/* 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;
- /* Alignment of multiboot modules. */
- static constexpr const uint32_t MULTIBOOT_MOD_ALIGN = 0x00001000;
+/* The magic field should contain this. */
+static const unsigned int MULTIBOOT2_HEADER_MAGIC = 0xe85250d6;
- /* Alignment of the multiboot info structure. */
- static constexpr const uint32_t MULTIBOOT_INFO_ALIGN = 0x00000008;
+/* This should be in %eax. */
+static const unsigned int MULTIBOOT2_BOOTLOADER_MAGIC = 0x36d76289;
- /* Flags set in the 'flags' member of the multiboot header. */
+/* Alignment of multiboot modules. */
+static const unsigned int MULTIBOOT_MOD_ALIGN = 0x00001000;
- 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;
+/* Alignment of the multiboot info structure. */
+static const unsigned int MULTIBOOT_INFO_ALIGN = 0x00000008;
- 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;
+/* Flags set in the 'flags' member of the multiboot header. */
- 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 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 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 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 constexpr const uint32_t MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED =
- 1;
- static constexpr const uint32_t MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED =
- 2;
+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;
- 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;
- };
+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;
- struct multiboot_header_tag_t {
- uint16_t type;
- uint16_t flags;
- uint32_t size;
- };
+static const unsigned int MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED =
+ 1;
+static const unsigned int MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED =
+ 2;
- struct multiboot_header_tag_information_request_t : multiboot_header_tag_t {
- uint32_t requests[0];
- };
+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_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);
+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;
};
-namespace BOOT_INFO {
- /// 魔数
- extern "C" uint32_t multiboot2_magic;
+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;
};
-#endif /* _MULTIBOOT2_H_ */
\ No newline at end of file
+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);
\ No newline at end of file
diff --git a/kernel/head.S b/kernel/head.S
index b1f4af66..65fe9d8a 100644
--- a/kernel/head.S
+++ b/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*/
diff --git a/kernel/link.lds b/kernel/link.lds
index b4897f60..694dcc69 100644
--- a/kernel/link.lds
+++ b/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 = .;
}
diff --git a/kernel/main.c b/kernel/main.c
index 102ca4b9..274eac8e 100644
--- a/kernel/main.c
+++ b/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();
diff --git a/kernel/mm/mm.h b/kernel/mm/mm.h
index 18da78a1..a744cccd 100644
--- a/kernel/mm/mm.h
+++ b/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
diff --git a/run.sh b/run.sh
index 2ffd8605..9b54c6fb 100644
--- a/run.sh
+++ b/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"