1 /** 2 * @file multiboot2.h 3 * @brief multiboot2 解析 4 */ 5 6 #pragma once 7 8 #include <DragonOS/stdint.h> 9 #include "stdbool.h" 10 #include <common/boot_info.h> 11 #include <driver/acpi/acpi.h> 12 13 /// @see Multiboot2 Specification version 2.0.pdf 14 // 启动后,在 32 位内核进入点,机器状态如下: 15 // 1. CS 指向基地址为 0x00000000,限长为4G – 1的代码段描述符。 16 // 2. DS,SS,ES,FS 和 GS 指向基地址为0x00000000,限长为4G – 17 // 1的数据段描述符。 18 // 3. A20 地址线已经打开。 19 // 4. 页机制被禁止。 20 // 5. 中断被禁止。 21 // 6. EAX = 0x2BADB002 22 // 7. 系统信息和启动信息块的线性地址保存在 EBX中(相当于一个指针)。 23 // 以下即为这个信息块的结构 24 25 /** 26 * @brief MULTIBOOT2 接口抽象 27 */ 28 29 extern unsigned int multiboot2_magic; 30 extern uintptr_t multiboot2_boot_info_addr; 31 32 /* How many bytes from the start of the file we search for the header. */ 33 static const unsigned int MULTIBOOT_SEARCH = 32768; 34 static const unsigned int MULTIBOOT_HEADER_ALIGN = 8; 35 36 /* The magic field should contain this. */ 37 static const unsigned int MULTIBOOT2_HEADER_MAGIC = 0xe85250d6; 38 39 /* This should be in %eax. */ 40 static const unsigned int MULTIBOOT2_BOOTLOADER_MAGIC = 0x36d76289; 41 42 /* Alignment of multiboot modules. */ 43 static const unsigned int MULTIBOOT_MOD_ALIGN = 0x00001000; 44 45 /* Alignment of the multiboot info structure. */ 46 static const unsigned int MULTIBOOT_INFO_ALIGN = 0x00000008; 47 48 /* Flags set in the 'flags' member of the multiboot header. */ 49 50 static const unsigned int MULTIBOOT_TAG_ALIGN = 8; 51 static const unsigned int MULTIBOOT_TAG_TYPE_END = 0; 52 static const unsigned int MULTIBOOT_TAG_TYPE_CMDLINE = 1; 53 static const unsigned int MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME = 2; 54 static const unsigned int MULTIBOOT_TAG_TYPE_MODULE = 3; 55 static const unsigned int MULTIBOOT_TAG_TYPE_BASIC_MEMINFO = 4; 56 static const unsigned int MULTIBOOT_TAG_TYPE_BOOTDEV = 5; 57 static const unsigned int MULTIBOOT_TAG_TYPE_MMAP = 6; 58 static const unsigned int MULTIBOOT_TAG_TYPE_VBE = 7; 59 static const unsigned int MULTIBOOT_TAG_TYPE_FRAMEBUFFER = 8; 60 static const unsigned int MULTIBOOT_TAG_TYPE_ELF_SECTIONS = 9; 61 static const unsigned int MULTIBOOT_TAG_TYPE_APM = 10; 62 static const unsigned int MULTIBOOT_TAG_TYPE_EFI32 = 11; 63 static const unsigned int MULTIBOOT_TAG_TYPE_EFI64 = 12; 64 static const unsigned int MULTIBOOT_TAG_TYPE_SMBIOS = 13; 65 static const unsigned int MULTIBOOT_TAG_TYPE_ACPI_OLD = 14; 66 static const unsigned int MULTIBOOT_TAG_TYPE_ACPI_NEW = 15; 67 static const unsigned int MULTIBOOT_TAG_TYPE_NETWORK = 16; 68 static const unsigned int MULTIBOOT_TAG_TYPE_EFI_MMAP = 17; 69 static const unsigned int MULTIBOOT_TAG_TYPE_EFI_BS = 18; 70 static const unsigned int MULTIBOOT_TAG_TYPE_EFI32_IH = 19; 71 static const unsigned int MULTIBOOT_TAG_TYPE_EFI64_IH = 20; 72 static const unsigned int MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR = 21; 73 74 static const unsigned int MULTIBOOT_HEADER_TAG_END = 0; 75 static const unsigned int MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST = 76 1; 77 static const unsigned int MULTIBOOT_HEADER_TAG_ADDRESS = 2; 78 static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS = 3; 79 static const unsigned int MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS = 4; 80 static const unsigned int MULTIBOOT_HEADER_TAG_FRAMEBUFFER = 5; 81 static const unsigned int MULTIBOOT_HEADER_TAG_MODULE_ALIGN = 6; 82 static const unsigned int MULTIBOOT_HEADER_TAG_EFI_BS = 7; 83 static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 = 84 8; 85 static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 = 86 9; 87 static const unsigned int MULTIBOOT_HEADER_TAG_RELOCATABLE = 10; 88 89 static const unsigned int MULTIBOOT_ARCHITECTURE_I386 = 0; 90 static const unsigned int MULTIBOOT_ARCHITECTURE_MIPS32 = 4; 91 static const unsigned int MULTIBOOT_HEADER_TAG_OPTIONAL = 1; 92 93 static const unsigned int MULTIBOOT_LOAD_PREFERENCE_NONE = 0; 94 static const unsigned int MULTIBOOT_LOAD_PREFERENCE_LOW = 1; 95 static const unsigned int MULTIBOOT_LOAD_PREFERENCE_HIGH = 2; 96 97 static const unsigned int MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED = 98 1; 99 static const unsigned int MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED = 100 2; 101 102 static const unsigned int MULTIBOOT_MEMORY_AVAILABLE = 1; 103 static const unsigned int MULTIBOOT_MEMORY_RESERVED = 2; 104 static const unsigned int MULTIBOOT_MEMORY_ACPI_RECLAIMABLE = 3; 105 static const unsigned int MULTIBOOT_MEMORY_NVS = 4; 106 static const unsigned int MULTIBOOT_MEMORY_BADRAM = 5; 107 108 struct multiboot_header_t 109 { 110 // Must be MULTIBOOT_MAGIC - see above. 111 unsigned int magic; 112 // ISA 113 unsigned int architecture; 114 // Total header length. 115 unsigned int header_length; 116 // The above fields plus this one must equal 0 mod 2^32. 117 unsigned int checksum; 118 }; 119 120 struct multiboot_header_tag_t 121 { 122 uint16_t type; 123 uint16_t flags; 124 unsigned int size; 125 }; 126 struct multiboot_header_tag_information_request_t 127 { 128 uint16_t type; 129 uint16_t flags; 130 unsigned int size; 131 132 unsigned int requests[0]; 133 }; 134 struct multiboot_header_tag_address_t 135 { 136 uint16_t type; 137 uint16_t flags; 138 unsigned int size; 139 140 unsigned int header_addr; 141 unsigned int load_addr; 142 unsigned int load_end_addr; 143 unsigned int bss_end_addr; 144 }; 145 146 struct multiboot_header_tag_entry_address_t 147 { 148 uint16_t type; 149 uint16_t flags; 150 unsigned int size; 151 152 unsigned int entry_addr; 153 }; 154 155 struct multiboot_header_tag_console_flags_t 156 { 157 uint16_t type; 158 uint16_t flags; 159 unsigned int size; 160 161 unsigned int console_flags; 162 }; 163 164 struct multiboot_header_tag_framebuffer_t 165 { 166 uint16_t type; 167 uint16_t flags; 168 unsigned int size; 169 170 unsigned int width; 171 unsigned int height; 172 unsigned int depth; 173 }; 174 175 struct multiboot_header_tag_module_align_t 176 { 177 uint16_t type; 178 uint16_t flags; 179 unsigned int size; 180 }; 181 182 struct multiboot_header_tag_relocatable_t 183 { 184 uint16_t type; 185 uint16_t flags; 186 unsigned int size; 187 188 unsigned int min_addr; 189 unsigned int max_addr; 190 unsigned int align; 191 unsigned int preference; 192 }; 193 194 struct multiboot_color_t 195 { 196 uint8_t red; 197 uint8_t green; 198 uint8_t blue; 199 }; 200 201 // multiboot2协议的内存区域信息 202 struct multiboot_mmap_entry_t 203 { 204 uint64_t addr; 205 uint64_t len; 206 unsigned int type; 207 unsigned int reserved; 208 }; 209 210 struct multiboot_tag_t 211 { 212 unsigned int type; 213 unsigned int size; 214 }; 215 216 struct multiboot_tag_string_t 217 { 218 struct multiboot_tag_t tag_t; 219 char string[0]; 220 }; 221 222 struct multiboot_tag_module_t 223 { 224 struct multiboot_tag_t tag_t; 225 unsigned int mod_start; 226 unsigned int mod_end; 227 char cmdline[0]; 228 }; 229 230 struct multiboot_tag_basic_meminfo_t 231 { 232 struct multiboot_tag_t tag_t; 233 unsigned int mem_lower; 234 unsigned int mem_upper; 235 }; 236 237 struct multiboot_tag_bootdev_t 238 { 239 struct multiboot_tag_t tag_t; 240 unsigned int biosdev; 241 unsigned int slice; 242 unsigned int part; 243 }; 244 245 struct multiboot_tag_mmap_t 246 { 247 struct multiboot_tag_t tag_t; 248 unsigned int entry_size; 249 unsigned int entry_version; 250 struct multiboot_mmap_entry_t entries[0]; 251 }; 252 253 struct multiboot_vbe_info_block_t 254 { 255 uint8_t external_specification[512]; 256 }; 257 258 struct multiboot_vbe_mode_info_block_t 259 { 260 uint8_t external_specification[256]; 261 }; 262 263 // bootloader传递的VBE信息的结构体 264 struct multiboot_tag_vbe_t 265 { 266 struct multiboot_tag_t tag_t; 267 uint16_t vbe_mode; 268 uint16_t vbe_interface_seg; 269 uint16_t vbe_interface_off; 270 uint16_t vbe_interface_len; 271 272 // The fields ‘vbe_control_info’ and ‘vbe_mode_info’ contain VBE control information returned by the VBE Function 00h and VBE mode information 273 // returned by the VBE Function 01h, respectively. 274 struct multiboot_vbe_info_block_t vbe_control_info; 275 struct multiboot_vbe_mode_info_block_t vbe_mode_info; 276 }; 277 278 struct multiboot_tag_framebuffer_info_t 279 { 280 struct multiboot_tag_t tag_t; 281 uint64_t framebuffer_addr; 282 uint32_t framebuffer_pitch; // 帧缓存上界 283 // width and height expressed in pixels except type=2 284 // when type=2, they are expressed in characters 285 uint32_t framebuffer_width; 286 uint32_t framebuffer_height; 287 // number of bits per pixel. 288 uint8_t framebuffer_bpp; 289 // 帧缓存的类型 290 uint8_t framebuffer_type; 291 uint8_t reserved; 292 }; 293 294 // indexed color 295 struct multiboot_tag_framebuffer_info_type0_t 296 { 297 struct multiboot_tag_framebuffer_info_t header; 298 uint32_t framebuffer_palette_num_colors; 299 struct multiboot_color_t color_desc; 300 }; 301 302 // direct RGB color 303 struct multiboot_tag_framebuffer_info_type1_t 304 { 305 struct multiboot_tag_framebuffer_info_t header; 306 307 uint8_t framebuffer_red_field_position; 308 uint8_t framebuffer_red_mask_size; 309 uint8_t framebuffer_green_field_position; 310 uint8_t framebuffer_green_mask_size; 311 uint8_t framebuffer_blue_field_position; 312 uint8_t framebuffer_blue_mask_size; 313 }; 314 315 struct multiboot_tag_elf_sections_t 316 { 317 struct multiboot_tag_t tag_t; 318 unsigned int num; 319 unsigned int entsize; 320 // 段字符串表索引 321 unsigned int shndx; 322 char sections[0]; 323 }; 324 325 struct multiboot_tag_apm_t 326 { 327 struct multiboot_tag_t tag_t; 328 uint16_t version; 329 uint16_t cseg; 330 unsigned int offset; 331 uint16_t cseg_16; 332 uint16_t dseg; 333 uint16_t flags; 334 uint16_t cseg_len; 335 uint16_t cseg_16_len; 336 uint16_t dseg_len; 337 }; 338 339 struct multiboot_tag_efi32_t 340 { 341 struct multiboot_tag_t tag_t; 342 unsigned int pointer; 343 }; 344 345 struct multiboot_tag_efi64_t 346 { 347 struct multiboot_tag_t tag_t; 348 uint64_t pointer; 349 }; 350 351 struct multiboot_tag_smbios_t 352 { 353 struct multiboot_tag_t tag_t; 354 uint8_t major; 355 uint8_t minor; 356 uint8_t reserved[6]; 357 uint8_t tables[0]; 358 }; 359 360 struct multiboot_tag_old_acpi_t 361 { 362 struct multiboot_tag_t tag_t; 363 //uint8_t rsdp[0]; 364 struct acpi_RSDP_t rsdp; 365 }; 366 367 struct multiboot_tag_new_acpi_t 368 { 369 struct multiboot_tag_t tag_t; 370 //uint8_t rsdp[0]; 371 struct acpi_RSDP_2_t rsdp; 372 }; 373 374 struct multiboot_tag_network_t 375 { 376 struct multiboot_tag_t tag_t; 377 uint8_t dhcpack[0]; 378 }; 379 380 struct multiboot_tag_efi_mmap_t 381 { 382 struct multiboot_tag_t tag_t; 383 unsigned int descr_size; 384 unsigned int descr_vers; 385 uint8_t efi_mmap[0]; 386 }; 387 388 struct multiboot_tag_efi32_ih_t 389 { 390 struct multiboot_tag_t tag_t; 391 unsigned int pointer; 392 }; 393 394 struct multiboot_tag_efi64_ih_t 395 { 396 struct multiboot_tag_t tag_t; 397 uint64_t pointer; 398 }; 399 400 struct multiboot_tag_load_base_addr_t 401 { 402 struct multiboot_tag_t tag_t; 403 unsigned int load_base_addr; 404 }; 405 406 // 迭代变量 407 // 与 multiboot_tag_t 相同 408 struct iter_data_t 409 { 410 unsigned int type; 411 unsigned int size; 412 }; 413 414 /** 415 * @brief 初始化 416 * @return true 成功 417 * @return false 失败 418 */ 419 static bool multiboot2_init(void); 420 421 /** 422 * @brief 迭代器 423 * @param _fun 迭代操作 424 * @param _data 数据 425 */ 426 void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *), 427 void *_data, unsigned int *count); 428 429 /** 430 * @brief 获取multiboot2协议提供的内存区域信息 431 * 432 * @param _iter_data 要被迭代的信息的结构体 433 * @param _data 返回信息的结构体指针 434 * @param count 返回数组的长度 435 * @return true 436 * @return false 437 */ 438 bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *_data, unsigned int *count); 439 440 /** 441 * @brief 获取VBE信息 442 * 443 * @param _iter_data 要被迭代的信息的结构体 444 * @param _data 返回信息的结构体指针 445 */ 446 bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *_data, unsigned int *reserved); 447 448 /** 449 * @brief 获取帧缓冲区信息 450 * 451 * @param _iter_data 要被迭代的信息的结构体 452 * @param _data 返回信息的结构体指针 453 */ 454 bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *_data, unsigned int *reserved); 455 456 /** 457 * @brief 获取acpi旧版RSDP 458 * 459 * @param _iter_data 要被迭代的信息的结构体 460 * @param _data old RSDP的结构体指针 461 * @param reserved 462 * @return uint8_t* 463 */ 464 bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved); 465 466 /** 467 * @brief 获取acpi新版RSDP 468 * 469 * @param _iter_data 要被迭代的信息的结构体 470 * @param _data old RSDP的结构体指针 471 * @param reserved 472 * @return uint8_t* struct multiboot_tag_old_acpi_t 473 */ 474 bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved);