multiboot2.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "multiboot2.h"
  2. #include "assert.h"
  3. #include "../../common/glib.h"
  4. uintptr_t boot_info_addr;
  5. unsigned int multiboot2_magic;
  6. unsigned int boot_info_size;
  7. bool multiboot2_init(void)
  8. {
  9. uintptr_t *addr = (uintptr_t*)boot_info_addr;
  10. if(multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC);
  11. return false;
  12. // addr+0 处保存了大小
  13. boot_info_size = *(unsigned int *)addr;
  14. return true;
  15. }
  16. void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
  17. void *data, unsigned int *count)
  18. {
  19. uintptr_t addr = boot_info_addr;
  20. // 下一字节开始为 tag 信息
  21. struct iter_data_t *tag = (struct iter_data_t *)(addr + 8);
  22. for (; tag->type != MULTIBOOT_TAG_TYPE_END;
  23. tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
  24. {
  25. if (_fun(tag, data, count) == true)
  26. {
  27. return;
  28. }
  29. }
  30. return;
  31. }
  32. // 读取 grub2 传递的物理内存信息,保存到 e820map_t 结构体中
  33. // 一般而言是这样的
  34. // 地址(长度) 类型
  35. // 0x00(0x9F000) 0x1
  36. // 0x9F000(0x1000) 0x2
  37. // 0xE8000(0x18000) 0x2
  38. // 0x100000(0x7EF0000) 0x1
  39. // 0x7FF0000(0x10000) 0x3
  40. // 0xFFFC0000(0x40000) 0x2
  41. /**
  42. * @brief 获取multiboot2协议提供的内存区域信息
  43. *
  44. * @param _iter_data 要被迭代的信息的结构体
  45. * @param _data 返回信息的结构体指针
  46. * @param count 返回数组的长度
  47. * @return true
  48. * @return false
  49. */
  50. bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *data, unsigned int *count)
  51. {
  52. if (_iter_data->type != MULTIBOOT_TAG_TYPE_MMAP)
  53. return false;
  54. struct multiboot_mmap_entry_t *resource = (struct multiboot_mmap_entry_t *)data;
  55. struct multiboot_mmap_entry_t *mmap = ((struct multiboot_tag_mmap_t *)_iter_data)->entries;
  56. *count = 0;
  57. for (; (uint8_t *)mmap < (uint8_t *)_iter_data + _iter_data->size;
  58. mmap = (struct multiboot_mmap_entry_t *)((uint8_t *)mmap + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size))
  59. {
  60. *resource = *mmap;
  61. // 将指针进行增加
  62. resource = (struct multiboot_mmap_entry_t *)((uint8_t *)resource + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size);
  63. ++(*count);
  64. }
  65. return true;
  66. }
  67. /**
  68. * @brief 获取VBE信息
  69. *
  70. * @param _iter_data 要被迭代的信息的结构体
  71. * @param _data 返回信息的结构体指针
  72. */
  73. bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
  74. {
  75. if (_iter_data->type != MULTIBOOT_TAG_TYPE_VBE)
  76. return false;
  77. *(struct multiboot_tag_vbe_t *)data = *(struct multiboot_tag_vbe_t *)_iter_data;
  78. return true;
  79. }
  80. /**
  81. * @brief 获取帧缓冲区信息
  82. *
  83. * @param _iter_data 要被迭代的信息的结构体
  84. * @param _data 返回信息的结构体指针
  85. */
  86. bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
  87. {
  88. if(_iter_data->type !=MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
  89. return false;
  90. *(struct multiboot_tag_framebuffer_info_t *)data = *(struct multiboot_tag_framebuffer_info_t*)_iter_data;
  91. return true;
  92. }