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 }