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 }