Skip to content

Commit

Permalink
Add third blog post for Linux x86 boot protocol
Browse files Browse the repository at this point in the history
Signed-off-by: Mihnea Firoiu <[email protected]>
  • Loading branch information
Mihnea0Firoiu committed Aug 2, 2024
1 parent 803e4a1 commit fdd85f2
Showing 1 changed file with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions content/blog/2024-08-02-unikraft-gsoc-lxboot_x86.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: "GSoC'24: Linux x86 Boot Protocol Support"
description: |
The Linux boot protocol plays an important role in the initialization of the Linux operating system, emphasizing the importance of system optimization and scalability.
publishedDate: 2024-08-02
image: /images/unikraft-gsoc24.png
tags:
- gsoc
- gsoc24
- booting
authors:
- Mihnea Firoiu
---

## Setup in Unikraft

First of all, I added the following lines to the `lxboot.S` file from Unikraft:

```diff
diff --git a/plat/kvm/x86/lxboot.S b/plat/kvm/x86/lxboot.S
index 0ebe18a5..8140804f 100644
--- a/plat/kvm/x86/lxboot.S
+++ b/plat/kvm/x86/lxboot.S
@@ -21,6 +21,13 @@ lcpu_boot_startup_args:
.quad 0
.quad 0

+.code32
+.section .text.32.boot
+ENTRY(_lxboot_entry32)
+ cli
+ hlt
+END(_lxboot_entry32)
+
/**
* 64-bit Linux Boot Protocol entry function
*
```

This way, if my header is correct and I do indeed reach Unikraft, the guest should hang.

## Starting to debug

There are 2 binary files that are of interest here: `linuxboot.bin` and `linuxboot_dma.bin`.
The `linuxboot.bin` file is optained by compiling `linuxboot.S` and the `linuxboot_dma.bin` file is optained by compiling `linuxboot_dma.c`.
As you can see, one is written in x86 AT&T assembly and the other is written in C, by using inline assembly.
Naturally, the one written in C would be easier to debug, and luckily, it seems like I do no need the other one.

By adding in `linuxboot.S` the following code, the QEMU instance should stay in a loop:

```diff
diff --git a/pc-bios/optionrom/linuxboot.S b/pc-bios/optionrom/linuxboot.S
index ba821ab922..26df825db8 100644
--- a/pc-bios/optionrom/linuxboot.S
+++ b/pc-bios/optionrom/linuxboot.S
@@ -30,6 +30,8 @@ run_linuxboot:

cli
cld
+0:
+ jmp 0b

jmp copy_kernel
boot_kernel:

```

I observed that nothing changes in its behaviour, so I added the following lines in `linuxboot_dma.bin`:

```diff
diff --git a/pc-bios/optionrom/linuxboot_dma.c b/pc-bios/optionrom/linuxboot_dma.c
index cbcf6679d9..4f12fe359e 100644
--- a/pc-bios/optionrom/linuxboot_dma.c
+++ b/pc-bios/optionrom/linuxboot_dma.c
@@ -55,6 +55,8 @@ asm(
"_bev:\n"
" cli\n"
" cld\n"
+"some_label:\n"
+" jmp some_label\n"
" jmp load_kernel\n"
);
```

This time the QEMU instance stayed in the loop, so everything was fine.
Now, all I had to do was to change the `jmp` with two `nop` instructions in gdb and from there to start debugging.
Sounds easy, right?

## Unexpected challenges

For some (at the time) unknown reason, when compiling the `.bin` files didn't update.
Was it my fault?
Did I have something wrong with my setup?

After a lot of time, I figured out along with my mentors that I needed to have `gcc-multilib` instead of the one that I had previously.
As different versions of gcc clash (installing one uninstalls the other), I had to replace it.

I observed that there are 3 `linuxboot.bin` and 3 `linuxboot_dma.bin` in the filesystem.
Only one of each was updated when compiling, and it wasn't the one that it searched for by default.
Using `strace`, I figured out that QEMU looks for the `.bin` file in the directory from which the command runs.
Because of this, I copied the `linuxboot_dma.bin` that was updated where I needed it.

## Next steps

I am going to look what and where the problem is inside the `linuxboot_dma.bin` file, using gdb.
Everything took much more than I expected, so I have to do this now.

0 comments on commit fdd85f2

Please sign in to comment.