multiboot2.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "multiboot2.h"
  2. #include "assert.h"
  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. bool multiboot2_init(void)
  9. {
  10. uintptr_t *addr = (uintptr_t *)multiboot2_boot_info_addr;
  11. if (multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
  12. ;
  13. return false;
  14. // addr+0 处保存了大小
  15. multiboot2_boot_info_size = *(unsigned int *)addr;
  16. return true;
  17. }
  18. void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
  19. void *data, unsigned int *count)
  20. {
  21. uintptr_t addr = multiboot2_boot_info_addr;
  22. // 接下来的第8字节开始,为 tag 信息
  23. struct iter_data_t *tag = (struct iter_data_t *)((void*)addr + 8);
  24. for (; tag->type != MULTIBOOT_TAG_TYPE_END;
  25. tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
  26. {
  27. if (_fun(tag, data, count) == true)
  28. {
  29. return;
  30. }
  31. }
  32. return;
  33. }
  34. // 读取 grub2 传递的物理内存信息,保存到 e820map_t 结构体中
  35. // 一般而言是这样的
  36. // 地址(长度) 类型
  37. // 0x00(0x9F000) 0x1
  38. // 0x9F000(0x1000) 0x2
  39. // 0xE8000(0x18000) 0x2
  40. // 0x100000(0x7EF0000) 0x1
  41. // 0x7FF0000(0x10000) 0x3
  42. // 0xFFFC0000(0x40000) 0x2
  43. /**
  44. * @brief 获取multiboot2协议提供的内存区域信息
  45. *
  46. * @param _iter_data 要被迭代的信息的结构体
  47. * @param _data 返回信息的结构体指针
  48. * @param count 返回数组的长度
  49. * @return true
  50. * @return false
  51. */
  52. bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *data, unsigned int *count)
  53. {
  54. if (_iter_data->type != MULTIBOOT_TAG_TYPE_MMAP)
  55. return false;
  56. struct multiboot_mmap_entry_t *resource = (struct multiboot_mmap_entry_t *)data;
  57. struct multiboot_mmap_entry_t *mmap = ((struct multiboot_tag_mmap_t *)_iter_data)->entries;
  58. *count = 0;
  59. for (; (uint8_t *)mmap < (uint8_t *)_iter_data + _iter_data->size;
  60. mmap = (struct multiboot_mmap_entry_t *)((uint8_t *)mmap + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size))
  61. {
  62. *resource = *mmap;
  63. // 将指针进行增加
  64. resource = (struct multiboot_mmap_entry_t *)((uint8_t *)resource + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size);
  65. ++(*count);
  66. }
  67. return true;
  68. }
  69. /**
  70. * @brief 获取VBE信息
  71. *
  72. * @param _iter_data 要被迭代的信息的结构体
  73. * @param _data 返回信息的结构体指针
  74. */
  75. bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
  76. {
  77. if (_iter_data->type != MULTIBOOT_TAG_TYPE_VBE)
  78. return false;
  79. *(struct multiboot_tag_vbe_t *)data = *(struct multiboot_tag_vbe_t *)_iter_data;
  80. return true;
  81. }
  82. /**
  83. * @brief 获取帧缓冲区信息
  84. *
  85. * @param _iter_data 要被迭代的信息的结构体
  86. * @param _data 返回信息的结构体指针
  87. */
  88. bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
  89. {
  90. if (_iter_data->type != MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
  91. return false;
  92. *(struct multiboot_tag_framebuffer_info_t *)data = *(struct multiboot_tag_framebuffer_info_t *)_iter_data;
  93. return true;
  94. }
  95. /**
  96. * @brief 获取acpi旧版RSDP
  97. *
  98. * @param _iter_data 要被迭代的信息的结构体
  99. * @param _data old RSDP的结构体指针
  100. * @param reserved
  101. * @return uint8_t* struct multiboot_tag_old_acpi_t
  102. */
  103. bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
  104. {
  105. if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_OLD)
  106. return false;
  107. *(struct multiboot_tag_old_acpi_t *)data = *(struct multiboot_tag_old_acpi_t *)_iter_data;
  108. return true;
  109. }
  110. /**
  111. * @brief 获取acpi新版RSDP
  112. *
  113. * @param _iter_data 要被迭代的信息的结构体
  114. * @param _data old RSDP的结构体指针
  115. * @param reserved
  116. * @return uint8_t* struct multiboot_tag_old_acpi_t
  117. */
  118. bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
  119. {
  120. if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_NEW)
  121. return false;
  122. *(struct multiboot_tag_new_acpi_t *)data = *(struct multiboot_tag_new_acpi_t *)_iter_data;
  123. return true;
  124. }