1 #include "multiboot2.h"
2
3 #include <common/glib.h>
4 #include <common/kprint.h>
5 // uintptr_t multiboot2_boot_info_addr;
6 // unsigned int multiboot2_magic;
7 unsigned int multiboot2_boot_info_size;
8
9 #define MBI_RAW_MAX_SIZE 409600
10 // 由于启动时传递的mb2 info所在的地址,在内存管理初始化之后会被覆盖,所以需要将其拷贝到一个固定的位置
11 static uint8_t mbi_raw[MBI_RAW_MAX_SIZE] = {0};
multiboot2_init(uint64_t mb2_info_paddr,uint32_t mb2_magic)12 bool multiboot2_init(uint64_t mb2_info_paddr, uint32_t mb2_magic)
13 {
14 uint64_t vaddr = (uint64_t)phys_2_virt(mb2_info_paddr);
15 if (mb2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
16 return false;
17 // vaddr+0 处保存了大小
18 multiboot2_boot_info_size = *(uint32_t *)vaddr;
19 if (multiboot2_boot_info_size > MBI_RAW_MAX_SIZE)
20 return false;
21
22 memcpy((void *)mbi_raw, (void *)vaddr, multiboot2_boot_info_size);
23
24 return true;
25 }
26
multiboot2_iter(bool (* _fun)(const struct iter_data_t *,void *,unsigned int *),void * data,unsigned int * count)27 void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
28 void *data, unsigned int *count)
29 {
30 // kdebug("multiboot2_boot_info_addr=%#018lx", multiboot2_boot_info_addr);
31
32 // uintptr_t addr = multiboot2_boot_info_addr;
33
34 // for(int i=0;i<8192;i++)
35 // {
36 // mbi_raw[i] = ((uint8_t *)multiboot2_boot_info_addr)[i];
37 // }
38 uint8_t * addr = mbi_raw;
39 // 接下来的第8字节开始,为 tag 信息
40 struct iter_data_t *tag = (struct iter_data_t *)((void *)addr + 8);
41 for (; tag->type != MULTIBOOT_TAG_TYPE_END;
42 tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
43 {
44
45 if (_fun(tag, data, count) == true)
46 {
47 return;
48 }
49 }
50 return;
51 }
52
53 // 读取 grub2 传递的物理内存信息,保存到 e820map_t 结构体中
54 // 一般而言是这样的
55 // 地址(长度) 类型
56 // 0x00(0x9F000) 0x1
57 // 0x9F000(0x1000) 0x2
58 // 0xE8000(0x18000) 0x2
59 // 0x100000(0x7EF0000) 0x1
60 // 0x7FF0000(0x10000) 0x3
61 // 0xFFFC0000(0x40000) 0x2
62 /**
63 * @brief 获取multiboot2协议提供的内存区域信息
64 *
65 * @param _iter_data 要被迭代的信息的结构体
66 * @param _data 返回信息的结构体指针
67 * @param count 返回数组的长度
68 * @return true
69 * @return false
70 */
multiboot2_get_memory(const struct iter_data_t * _iter_data,void * data,unsigned int * count)71 bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *data, unsigned int *count)
72 {
73 if (_iter_data->type != MULTIBOOT_TAG_TYPE_MMAP)
74 return false;
75
76 struct multiboot_mmap_entry_t *resource = (struct multiboot_mmap_entry_t *)data;
77 struct multiboot_mmap_entry_t *mmap = ((struct multiboot_tag_mmap_t *)_iter_data)->entries;
78 *count = 0;
79 for (; (uint8_t *)mmap < (uint8_t *)_iter_data + _iter_data->size;
80 mmap = (struct multiboot_mmap_entry_t *)((uint8_t *)mmap + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size))
81 {
82 *resource = *mmap;
83 // 将指针进行增加
84 resource = (struct multiboot_mmap_entry_t *)((uint8_t *)resource + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size);
85 ++(*count);
86 }
87 return true;
88 }
89
90 /**
91 * @brief 获取VBE信息
92 *
93 * @param _iter_data 要被迭代的信息的结构体
94 * @param _data 返回信息的结构体指针
95 */
multiboot2_get_VBE_info(const struct iter_data_t * _iter_data,void * data,unsigned int * reserved)96 bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
97 {
98
99 if (_iter_data->type != MULTIBOOT_TAG_TYPE_VBE)
100 return false;
101 *(struct multiboot_tag_vbe_t *)data = *(struct multiboot_tag_vbe_t *)_iter_data;
102 return true;
103 }
104
105 /// @brief 获取加载基地址
106 /// @param _iter_data
107 /// @param data
108 /// @param reserved
109 /// @return
multiboot2_get_load_base(const struct iter_data_t * _iter_data,void * data,unsigned int * reserved)110 bool multiboot2_get_load_base(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
111 {
112
113 if (_iter_data->type != MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR)
114 return false;
115 *(struct multiboot_tag_load_base_addr_t *)data = *(struct multiboot_tag_load_base_addr_t *)_iter_data;
116 return true;
117 }
118
119 /**
120 * @brief 获取帧缓冲区信息
121 *
122 * @param _iter_data 要被迭代的信息的结构体
123 * @param _data 返回信息的结构体指针
124 */
multiboot2_get_Framebuffer_info(const struct iter_data_t * _iter_data,void * data,unsigned int * reserved)125 bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
126 {
127 if (_iter_data->type != MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
128 return false;
129 *(struct multiboot_tag_framebuffer_info_t *)data = *(struct multiboot_tag_framebuffer_info_t *)_iter_data;
130 return true;
131 }
132
133 /**
134 * @brief 获取acpi旧版RSDP
135 *
136 * @param _iter_data 要被迭代的信息的结构体
137 * @param _data old RSDP的结构体指针
138 * @param reserved
139 * @return uint8_t* struct multiboot_tag_old_acpi_t
140 */
multiboot2_get_acpi_old_RSDP(const struct iter_data_t * _iter_data,void * data,unsigned int * reserved)141 bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
142 {
143 if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_OLD)
144 return false;
145
146 *(struct multiboot_tag_old_acpi_t *)data = *(struct multiboot_tag_old_acpi_t *)_iter_data;
147
148 return true;
149 }
150
151 /**
152 * @brief 获取acpi新版RSDP
153 *
154 * @param _iter_data 要被迭代的信息的结构体
155 * @param _data old RSDP的结构体指针
156 * @param reserved
157 * @return uint8_t* struct multiboot_tag_old_acpi_t
158 */
multiboot2_get_acpi_new_RSDP(const struct iter_data_t * _iter_data,void * data,unsigned int * reserved)159 bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
160 {
161 if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_NEW)
162 return false;
163 *(struct multiboot_tag_new_acpi_t *)data = *(struct multiboot_tag_new_acpi_t *)_iter_data;
164 return true;
165 }