Skip to content

Commit fc31880

Browse files
authored
Replace stivale2 protocol with limine (#101)
* overview: update from stivale to limine protocol * Replace stivale 2 protocol (cont) * Stivale2 replacement, cont... * replace stivale2 cont. * replace stivale2 cont. * stivale replacement (cont) * stivale replacement cont... * Update updates * Fix typo * Changes requested * Changes requested * Minor changes * Minor fix
1 parent b7869de commit fc31880

File tree

7 files changed

+117
-109
lines changed

7 files changed

+117
-109
lines changed

01_Build_Process/01_Overview.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@ In this part we are going to explore all the tools and steps that are needed in
66

77
In this chapter we will have a global overview of the build process, touching briefly what are the steps involved, and the tools that are going to be used.
88

9-
Then in the [Boots Protocols and Bootloaders](02_Boot_Protocols.md) chapter we will explore in detail how to boot a kernel, and describe two options that can be used for the boot process: Multiboot and Stivale.
9+
Then in the [Boots Protocols and Bootloaders](02_Boot_Protocols.md) chapter we will explore in detail how to boot a kernel, and describe two options that can be used for the boot process: Multiboot and Limine.
1010

1111
The [Makefiles](04_Gnu_Makefiles.md) chapter will explain how to build a process, even if initially is just a bunch of file and it can be done manually, it soon grow more complex, and having the process automated will be more than useful, we will use _Makefile_ for our build script.
1212

1313
One of the most _obscure_, that is always present while building any software, but is hidden to us until we start to roll up our own kernel is the _linking process_. The [Linker Scripts](05_Linker_Scripts.md) chapter will introduce us to the world of _linking_ files and explain how to write a linker script.
1414

1515
Finally the kernel is built but not ready to run yet, we need to copy it into a bootable media, the [Generating A Bootable Iso](06_Generating_Iso.md) chapter will show how to create a bootable iso of our kernel, and finally being able to launch it and see the results of our hard work.
1616

17-
1817
For the rest of this part a basic knowledge of compiling these languages is assumed.
1918

2019
## Freestanding Environment
@@ -49,15 +48,17 @@ However, each GCC toolchain will use the platform-specific headers by default, w
4948
Compiling GCC from source doesn't take too long on a modern CPU (~10 minutes for a complete build on a 7th gen intel mobile cpu, 4 cores), however there are also prebuilt binaries online from places like bootlin, see the useful links appendix for .
5049

5150
## Setting up a build environment
51+
5252
Setting up a proper build environment can be broken down into a few steps:
5353

54-
- Setup a cross compilation toolchain.
54+
- Setup a cross compilation toolchain (refer to the [Appendix E: Cross Platform Building](../99_Appendices/E_Cross_Compilers.md).
5555
- Install an emulator.
5656
- Install any additional tools.
5757
- Setup the bootloader of choice.
5858
- Run a hello world to check everything works.
5959

6060
### Getting a Cross Compiler
61+
6162
The easiest approach here is to simply use clang. Clang is designed to be a cross compiler, and so any install of clang can compile to any supported platform.
6263
To compile for another platform simply invoke clang as normally would, additionally passing `--target=xyz`, where xyz is the target triplet for the target platform.
6364

@@ -80,6 +81,7 @@ The following sections will use the common shorthands to keep things simple:
8081
If using clang be sure to remember to pass `--target=xyz` with each command. This is not necessary with GCC.
8182

8283
### Building C Source Files
84+
8385
Now that we have a toolchain setup we can test it all works by compiling a C file.
8486
Create a C source file, its contents don't matter here as we wont be running it, just telling it compiles.
8587

@@ -212,9 +214,9 @@ Getting access to these debug symbols is dependent on the boot protocol used:
212214

213215
Multiboot 2 provides the Elf-Symbols (section 3.6.7 of the spec) tag to the kernel which provides the elf section headers and the location of the string table. Using these is described below in the stivale section.
214216

215-
### Stivale 2
217+
### Limine Protocol
216218

217-
Stivale2 uses a similar and slightly more complex (but more powerful) mechanism of providing the entire kernel file in memory. This means we're not limited to just using elf files, and can access debug symbols from a kernel in any format. This is because we have the file base address and length and have to do the parsing by ourselves.
219+
Limine uses a similar and slightly more complex (but more powerful) mechanism of providing the entire kernel file in memory.
218220

219221
### ELFs Ahead, Beware!
220222

@@ -239,18 +241,19 @@ Languages built around the C model will usually perform some kind of name mangli
239241

240242
### Locating The Symbol Table
241243

242-
We'll need to access the data stored in the string table quite frequently for looking up symbols, so let's calculate that and store it in the variable `char* strtab_data`. For both protocols it's assumed that we have found the tag returned by the bootloader that contains the location of the elf file/elf symbols.
244+
We'll need to access the data stored in the string table quite frequently for looking up symbols, so let's calculate that and store it in the variable `char* strtab_data`. For both protocols it's assumed that we have found the tag returned by the bootloader that contains the location of the elf file/elf symbols (for more details, see the [Boot Protocols](./02_Boot_Protocols.md) chapter.
243245

244246
```c
245247
//multiboot 2
246248
multiboot_tag_elf_sections* sym_tag;
247249
const char* strtab_data = sym_tag->sections[sym_tag->shndx].sh_offset;
248250

249-
//stivale 2
250-
stivale2_struct_tag_kernel_file* file_tag;
251-
Elf64_Ehdr* hdr = (Elf64_Ehdr*)file_tag->kernel_file;
252-
Elf64_Shdr* shdrs = (Elf64_Shdr*)(file_tag->kernel_file + hdr->shoff);
253-
const char* strtab_data = shdrs[hdr->e_shstrndx].sh_offset;
251+
//Limine Protocol
252+
struct limine_kernel_file_response file_response;
253+
struct limine_file kernel_file = file_response->kernel_file;
254+
Elf64_Ehdr* hdr = (Elf64_Ehdr*) kernel_file->address;
255+
Elf64_Shdr* shdrs = (Elf64_Shdr*) (kernel_file->address + hdr->shoff);
256+
const char* strtab_data = shdrs[hdr->e_shstrndx].sh_offset + kernel_file->address
254257
```
255258

256259
To find the symbol table, iterate through the section headers until one with the name `.symtab` is found.
@@ -288,4 +291,4 @@ void print_symbol(uint64_t addr)
288291
}
289292
```
290293
291-
A quick note about getting the symbol table data address: On multiboot `sym_tab->sh_offset` will be the physical address of the data, while stivale2 will return the original value, which is an offset from the beginning of the file. This means for stivale 2 we would add `file_tag->kernel_base` to this address to get its location in memory.
294+
A quick note about getting the symbol table data address: On multiboot `sym_tab->sh_offset` will be the physical address of the data, while limine protocol will return the original value, which is an offset from the beginning of the file. This means for limine protocol we need to add `kernel_file->address` to this address to get its location in memory.

0 commit comments

Comments
 (0)