---
 i386/i386at/model_dep.c | 44 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
index 6c2d1883..b28a3b5f 100644
--- a/i386/i386at/model_dep.c
+++ b/i386/i386at/model_dep.c
@@ -384,8 +384,48 @@ register_mb1_boot_data(const struct multiboot_raw_info 
*mbi)
 static void
 register_mb2_boot_data(const struct multiboot2_raw_info *mb2_info)
 {
-  /* To be implemented. */
-  (void)mb2_info;
+  uint32_t tags_len = mb2_info->total_size;
+  uint32_t offset = 0;
+
+  /* Temporarily preserve the multiboot2 information structure. */
+  const phys_addr_t mb2_phys = _kvtophys(mb2_info);
+  biosmem_register_boot_data(mb2_phys, mb2_phys + tags_len, TRUE);
+
+  tags_len -= offsetof(struct multiboot2_raw_info, content);
+
+  while (offset < tags_len)
+    {
+      const struct multiboot2_tag *tag =
+       (const struct multiboot2_tag *)(&mb2_info->content[offset]);
+
+      switch (tag->type)
+       {
+       case MULTIBOOT2_TAG_TYPE_ELF_SECTIONS:
+         {
+           const struct multiboot2_tag_elf_sections *elf_tag =
+             (const struct multiboot2_tag_elf_sections *)tag;
+
+           register_elf_shdrs_boot_data(&elf_tag->sections,
+                                        elf_tag->num,
+                                        elf_tag->entsize);
+         }
+         break;
+
+       case MULTIBOOT2_TAG_TYPE_MODULE:
+         {
+           const struct multiboot2_tag_module *mod_tag =
+             (const struct multiboot2_tag_module *)tag;
+
+           biosmem_register_boot_data(mod_tag->mod_start, mod_tag->mod_end, 
TRUE);
+         }
+         break;
+
+       default:
+         break;
+       }
+
+      offset += MULTIBOOT2_NEXT_TAG_OFFSET(tag->size);
+    }
 }
 
 /* Register the boot data for whichever of multiboot1 or multiboot2 is
-- 
2.47.3


Reply via email to