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 }