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