From 576a14c26ee476021099910685e74f7ed9a461f7 Mon Sep 17 00:00:00 2001 From: Maria Pana Date: Tue, 9 Jul 2024 21:36:48 +0300 Subject: [PATCH] blog: Add second GSoC blog post about Multiboot2 Add the second GSoC blog post about Multiboot2 showcasing the progress made during the second set of 3 weeks. Signed-off-by: Maria Pana --- content/blog/2024-07-10-gsoc-multiboot2.mdx | 128 ++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 content/blog/2024-07-10-gsoc-multiboot2.mdx diff --git a/content/blog/2024-07-10-gsoc-multiboot2.mdx b/content/blog/2024-07-10-gsoc-multiboot2.mdx new file mode 100644 index 00000000..4284064f --- /dev/null +++ b/content/blog/2024-07-10-gsoc-multiboot2.mdx @@ -0,0 +1,128 @@ +--- +title: "Multiboot2 Support in Unikraft" +description: | + In my previous blog post, I focused on the first steps of the project: understanding the Multiboot2 protocol and preparing the development environment. Over the following three weeks, I progressed to implementing the necessary changes/additions and then testing the code. +publishedDate: 2024-07-10 +tags: +- gsoc +- gsoc24 +- multiboot2 +- booting +authors: +- Maria Pana +--- + + + +In my [previous blog post](https://unikraft.org/blog/2024-06-17-gsoc-multiboot2), I outlined a general strategy for software enhancement, focusing on the first steps of the project: understanding the Multiboot2 protocol and preparing the development environment. +Naturally, over the following three weeks, I progressed to the next stages: implementing the necessary changes/additions and then testing the code. + +## Structuring for Seamless Integration + +In order to have Multiboot2 integrated in Unikraft, I mirrored the existing file organization established for Multiboot and extended it to accommodate the new protocol. +Three core files handle the protocol itself, while the rest of the codebase is updated around them to ensure proper integration and functionality. +Let's take a closer look: + +### `multiboot.S` + +This assembly file plays a pivotal role in preparing a standardized operating environment. +It verifies the system is booted through a compliant Multiboot/Multiboot2 bootloader and manages essential memory relocations. +In this context, the only modifications required were replacing `multiboot.h` and `MULTIBOOT_BOOTLOADER_MAGIC` with their Multiboot2 counterparts, featured depending on the chosen configurations. + +### `multiboot2.py` + +The Python script generates and adds the Multiboot2 and updated ELF headers to the original ELF file. +This ensures that the bootloader information is strategically positioned at the start, facilitating correct system initialization. +Since the Multiboot protocol is limited to 32-bit systems, the `multiboot.py` script also required transforming 64-bit ELFs into 32-bit ones. +This is no longer the case when it comes to Multiboot2, only needing to incorporate the Multiboot2 and updated ELF headers into the file, without any other alterations. + +### `multiboot2.c` + +This C program is responsible for processing boot information from a Multiboot2-compliant bootloader. +It meticulously manages memory regions, integrates boot parameters, and prepares the system for kernel execution by consolidating memory configurations and allocating essential resources. + +Alongside these core files, I made adjustments to adjacent files to seamlessly link everything together and ensure successful booting under Multiboot2 (e.g. duplicating the `mkukimg` script's menuentry to use `multiboot2` instead of `multiboot` etc.). + +## Testing the Waters: Progress and Challenges + +My initial focus was to lay the groundwork by creating the `multiboot.S` and `multiboot2.py` files and testing them with the simple `helloworld` application. +This allowed me to verify that the Multiboot2 header was inserted correctly and the system could boot without major hiccups. + +Of course, debugging became my constant companion during this process. +Tools like `hexdump` and attaching `gdb` to my custom GRUB build proved invaluable. + +I encountered an initial hurdle regarding the ELF file. +After playing around with GRUB error messages and making a "comparative study" of the binaries with Multiboot, Multiboot2, or no additional header, I realized the ELF was lacking the Multiboot2 header altogether. +Some detective work later, I traced the issue to an unlinked `multiboot2.py` script. + +## Multiboot2 Header: A Deep Dive + +So far, I really emphasized the need of the Multiboot2 header. +But what is its role? + +The Multiboot2 header is a structured data block embedded within the bootable system image. +Its purpose is to facilitate the transition of control and information from the bootloader to the kernel during the boot process. +This header acts as a standardized communication channel, ensuring the kernel can access essential details about the system's hardware, memory layout, and other boot-related parameters. + +### Format and Contents + +The Multiboot2 header follows a specific format, starting with a fixed-size header followed by a series of variable-length tags. + +The fixed-size header includes: + +- The magic number `0xE85250D6` indicating a Multiboot2-compliant image +- The target architecture (e.g. `i386`, `x86_64`) +- The header length, including all tags +- The checksum of the header, used for error detection + +I talked a little about the tags in my previous blog post, but to recap, they provide detailed information about the system's memory layout, boot command line, and other essential parameters. +Commonly, each tag has a type, size and payload. +There is a multitude of tags to choose from, depending on the specific requirements of the system, adding to the flexibility of Multiboot2. + +In the context of this project, it may be valuable to note that simply adding the Multiboot2 header to the ELF file is not sufficient. +On top of that, both `multiboot.py` and `multiboot2.py` scripts add an extra ELF header with updated offsets, "sandwiching" the Multiboot2 header between it and the original ELF. +To better visualize this, we can refer to the following diagram: + +```text + ┌────────────────────┐ + ┌───────│ Updated EHDR |─────────────┐ + | ├────────────────────┤ | + └──────>| Updated PHDR | | + ├────────────────────┤ | + | MB2HDR | | + ├────────────────────┤ | + ┌───────| Original EHDR |────────┐ | + | ├────────────────────┤ | | + └──────>| Original PHDR | | | + ├────────────────────┤ | | + | Original SHDR |<───────┘ | + ├────────────────────┤ | + | ... | | + ├────────────────────┤ | + | Updated SHDR |<────────────┘ + └────────────────────┘ +``` + +This ensures that GRUB identifies the overall file as an ELF and avoids any potential complications along the way. + +### Interaction between Bootloader and Kernel + +The bootloader locates the Multiboot2 header within the ELF file. +After verifying the magic number and architecture compatibility, it parses the header and tags. +Next, the information requested by the tags is placed into the kernel memory and the bootloader passes control to the kernel. + +The kernel, in turn, accesses the Multiboot2 header using the information provided by the bootloader. +It iterates through the tags to extract the necessary data, such as memory regions, boot command line, and other parameters. +This information is used to initialize its own data structures, set up memory management, and configure the system for execution. + +## Next Steps + +With the Multiboot2 header issue resolved, the ELF file is now generated correctly. +However, the system still encounters a roadblock, getting stuck in what appears to be an infinite loop. +More debugging using `gdb` for me it is! + +After I pinpoint and fix the problem, I will move on to: + +- Refactoring `multiboot2.py` to handle tag inclusion more generically +- Implementing the `multiboot2.c` file +- Testing the new modifications once again