1 #include "multiboot2.h"
2
3
4 #include <common/glib.h>
5 #include <common/kprint.h>
6 uintptr_t multiboot2_boot_info_addr;
7 unsigned int multiboot2_magic;
8 unsigned int multiboot2_boot_info_size;
9
multiboot2_init(void)10 bool multiboot2_init(void)
11 {
12 uintptr_t *addr = (uintptr_t *)multiboot2_boot_info_addr;
13 if (multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
14 ;
15 return false;
16 // addr+0 处保存了大小
17 multiboot2_boot_info_size = *(unsigned int *)addr;
18 return true;
19 }
20
multiboot2_iter(bool (* _fun)(const struct iter_data_t *,void *,unsigned int *),void * data,unsigned int * count)21 void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
22 void *data, unsigned int *count)
23 {
24
25 uintptr_t addr = multiboot2_boot_info_addr;
26 // 接下来的第8字节开始,为 tag 信息
27 struct iter_data_t *tag = (struct iter_data_t *)((void*)addr + 8);
28 for (; tag->type != MULTIBOOT_TAG_TYPE_END;
29 tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
30 {
31
32 if (_fun(tag, data, count) == true)
33 {
34 return;
35 }
36 }
37 return;
38 }
39
40 // 读取 grub2 传递的物理内存信息,保存到 e820map_t 结构体中
41 // 一般而言是这样的
42 // 地址(长度) 类型
43 // 0x00(0x9F000) 0x1
44 // 0x9F000(0x1000) 0x2
45 // 0xE8000(0x18000) 0x2
46 // 0x100000(0x7EF0000) 0x1
47 // 0x7FF0000(0x10000) 0x3
48 // 0xFFFC0000(0x40000) 0x2
49 /**
50 * @brief 获取multiboot2协议提供的内存区域信息
51 *
52 * @param _iter_data 要被迭代的信息的结构体
53 * @param _data 返回信息的结构体指针
54 * @param count 返回数组的长度
55 * @return true
56 * @return false
57 */
multiboot2_get_memory(const struct iter_data_t * _iter_data,void * data,unsigned int * count)58 bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *data, unsigned int *count)
59 {
60 if (_iter_data->type != MULTIBOOT_TAG_TYPE_MMAP)
61 return false;
62
63 struct multiboot_mmap_entry_t *resource = (struct multiboot_mmap_entry_t *)data;
64 struct multiboot_mmap_entry_t *mmap = ((struct multiboot_tag_mmap_t *)_iter_data)->entries;
65 *count = 0;
66 for (; (uint8_t *)mmap < (uint8_t *)_iter_data + _iter_data->size;
67 mmap = (struct multiboot_mmap_entry_t *)((uint8_t *)mmap + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size))
68 {
69 *resource = *mmap;
70 // 将指针进行增加
71 resource = (struct multiboot_mmap_entry_t *)((uint8_t *)resource + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size);
72 ++(*count);
73 }
74 return true;
75 }
76
77 /**
78 * @brief 获取VBE信息
79 *
80 * @param _iter_data 要被迭代的信息的结构体
81 * @param _data 返回信息的结构体指针
82 */
multiboot2_get_VBE_info(const struct iter_data_t * _iter_data,void * data,unsigned int * reserved)83 bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
84 {
85
86 if (_iter_data->type != MULTIBOOT_TAG_TYPE_VBE)
87 return false;
88 *(struct multiboot_tag_vbe_t *)data = *(struct multiboot_tag_vbe_t *)_iter_data;
89 return true;
90 }
91
92 /**
93 * @brief 获取帧缓冲区信息
94 *
95 * @param _iter_data 要被迭代的信息的结构体
96 * @param _data 返回信息的结构体指针
97 */
multiboot2_get_Framebuffer_info(const struct iter_data_t * _iter_data,void * data,unsigned int * reserved)98 bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
99 {
100 if (_iter_data->type != MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
101 return false;
102 *(struct multiboot_tag_framebuffer_info_t *)data = *(struct multiboot_tag_framebuffer_info_t *)_iter_data;
103 return true;
104 }
105
106 /**
107 * @brief 获取acpi旧版RSDP
108 *
109 * @param _iter_data 要被迭代的信息的结构体
110 * @param _data old RSDP的结构体指针
111 * @param reserved
112 * @return uint8_t* struct multiboot_tag_old_acpi_t
113 */
multiboot2_get_acpi_old_RSDP(const struct iter_data_t * _iter_data,void * data,unsigned int * reserved)114 bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
115 {
116 if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_OLD)
117 return false;
118
119 *(struct multiboot_tag_old_acpi_t *)data = *(struct multiboot_tag_old_acpi_t *)_iter_data;
120
121 return true;
122 }
123
124 /**
125 * @brief 获取acpi新版RSDP
126 *
127 * @param _iter_data 要被迭代的信息的结构体
128 * @param _data old RSDP的结构体指针
129 * @param reserved
130 * @return uint8_t* struct multiboot_tag_old_acpi_t
131 */
multiboot2_get_acpi_new_RSDP(const struct iter_data_t * _iter_data,void * data,unsigned int * reserved)132 bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
133 {
134 if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_NEW)
135 return false;
136 *(struct multiboot_tag_new_acpi_t *)data = *(struct multiboot_tag_new_acpi_t *)_iter_data;
137 return true;
138 }