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