From 0f8b422b34ee2fbb2cebd1eff257955fc6e65d45 Mon Sep 17 00:00:00 2001 From: Ivan Gualandri Date: Tue, 5 Nov 2024 19:41:00 +0000 Subject: [PATCH 1/2] Add a complete example of how to create an executable for our kernel --- 09_Loading_Elf/02_Loading_And_Running.md | 33 +++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/09_Loading_Elf/02_Loading_And_Running.md b/09_Loading_Elf/02_Loading_And_Running.md index 114047a..237698e 100644 --- a/09_Loading_Elf/02_Loading_And_Running.md +++ b/09_Loading_Elf/02_Loading_And_Running.md @@ -47,7 +47,7 @@ Then from the other fields that need validation (that area not in the `e_ident` Be aware that most of the variables and their values have a specific naming convention, for more information refer to the ELF specs. -Beware that some compilers when generating a simple executable are not using the `ET_EXEC` value, but it could be of the type `ET_REL` (value 1), to obtain an executable we need to link it using a linker. For example if we generated the executable: `example.elf` with `ET_REL` type, we can use `ld` (or another equivalent linker): +Another thing to be aware is that some compilers when generating a simple executable are not using the `ET_EXEC` value, but it could be of the type `ET_REL` (value 1), to obtain an executable we need to link it using a linker. For example if we generated the executable: `example.elf` with `ET_REL` type, we can use `ld` (or another equivalent linker): ```sh ld -o example.o example.elf @@ -62,6 +62,37 @@ readelf -e example.elf Will print out all the executable information, including the type. +### Example: Creating a simple program for our kernel + +For this example, let's create a very basic assembly program, that is a simple infinite loop: + +``` +extern loop +[bits 64] +loop: + jmp loop + +``` + +The code, as we can expect is pretty simple, and self-explanatory, it declares a `loop` function, and mark it as global using the `extern` keyword.. + +The above code now can be compiled with nasm: + +```sh +nasm -g -F dwarf example_file.s -o example_file.o +``` + +Where: `-g -F dwarf` are used to add debug symbols to the assembly output. + +The last step is to use a linker to link the file, in this example we are going to use `ld`: + +```sh +ld -g example_file.o -o example_file.elf -e loop +``` + +Where `-g` is a parameter that instructs the linker to include the debugging symbols, and `-e loop` instructs the linker to look for the symbol called `loop` as entry point of the program. + +Now the program is ready to be loaded by our kernel, either as a bootloader module or a file on a filesystem (or any other way that allow the kernel to reach this executable). ## Caveats From ddc7d45fd67abeec2f36274724fb636f7e248263 Mon Sep 17 00:00:00 2001 From: "Ivan G." <59960116+dreamos82@users.noreply.github.com> Date: Sun, 10 Nov 2024 12:18:15 +0000 Subject: [PATCH 2/2] Update 02_Loading_And_Running.md --- 09_Loading_Elf/02_Loading_And_Running.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/09_Loading_Elf/02_Loading_And_Running.md b/09_Loading_Elf/02_Loading_And_Running.md index 237698e..75a825f 100644 --- a/09_Loading_Elf/02_Loading_And_Running.md +++ b/09_Loading_Elf/02_Loading_And_Running.md @@ -79,10 +79,14 @@ The code, as we can expect is pretty simple, and self-explanatory, it declares a The above code now can be compiled with nasm: ```sh -nasm -g -F dwarf example_file.s -o example_file.o +nasm -g -f elf64 -F dwarf example_file.s -o example_file.o ``` -Where: `-g -F dwarf` are used to add debug symbols to the assembly output. +Where: +* `-f elf64` is the output format (in our case we use elf64, but this depend on the target architecture). +* `-g` enable debug symbols +* `-F dwarf` is the debug symbols format (for elf64 we use dwarf, but again it can depends on the target architecture). + The last step is to use a linker to link the file, in this example we are going to use `ld`: