Skip to content

Commit

Permalink
Fix: typos (#99)
Browse files Browse the repository at this point in the history
* fix: typo

* fix: remove trailing spaces

* fix: Even more typos

* fix: revise typos according to feedback

* fix: typo limine.cfg + heading
  • Loading branch information
kouosi authored Oct 7, 2024
1 parent 68726ca commit 8f58715
Show file tree
Hide file tree
Showing 48 changed files with 175 additions and 189 deletions.
10 changes: 5 additions & 5 deletions 00_Introduction/01_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ We hope you enjoy, and find something interesting here!

The book is divided in parts and every part is composed by one or more chapter. Each numbered chapter adds a new layer to the kernel, expanding its capabilities. While it's not strictly necessary to read them in order, it is encouraged as some later chapters may reference earlier ones.

There is also a series of appendices at the end of the book, covering some extra topics that may be useful along the way. The appendices are intended to be used as a reference, and can be read at any time.
There is also a series of appendices at the end of the book, covering some extra topics that may be useful along the way. The appendices are intended to be used as a reference, and can be read at any time.

### Topics covered

As we've already mentioned, our main purpose here is to guide the reader through the general process of building a kernel (and surrounding operating system). We're using `x86_64` as our reference architecture, but most of the concepts should transfer to other architectures, with the exception of the very early stages of booting.

Below the list of parts that compose the book:
Below the list of parts that compose the book:

* *Build Process* - The first part is all about setting up a suitable environment for operating systems development, explaining what tools are needed and the steps required to build and test a kernel.
* *Architecture/Drivers* - This part contains most of the architecture specific components, as well as most of the data structures and underlying mechanisms of the hardware we'll need. It also includes some early drivers that are very useful during further development (like the keyboard and timer).
* *Video Output* - This part looks at working with linear framebuffers, and how we can display text on them to aid with early debugging.
* *Memory Management* - This part looks at the memory management stack of a kernel. We cover all the layers from the physical memory manager, to the virtual memory manager and the heap.
* *Scheduling* - A modern operating system should support running multiple programs at once. In this part we're going to look at how processes and threads are implemented, write a simple scheduler and have a look at some of the typical concurrency issues that arise.
* *Scheduling* - A modern operating system should support running multiple programs at once. In this part we're going to look at how processes and threads are implemented, write a simple scheduler and have a look at some of the typical concurrency issues that arise.
* *Userspace* - Many modern architectures support different level of privileges, that means programs that are running on lower levels can't access resources/data reserved for higher levels.
* *Inter-Process Communication (IPC)* - This part looks at how we might implement IPC for our kernel, allowing isolated programs to communicate with each other in a controlled way.
* *Virtual File System (VFS)* - This part will cover how a kernel presents different file systems to the rest of the system. We'll also take a look at implementing a 'tempfs' that is loaded from a tape archive (tar), similar to initrd.
* *Inter-Process Communication (IPC)* - This part looks at how we might implement IPC for our kernel, allowing isolated programs to communicate with each other in a controlled way.
* *Virtual File System (VFS)* - This part will cover how a kernel presents different file systems to the rest of the system. We'll also take a look at implementing a 'tempfs' that is loaded from a tape archive (tar), similar to initrd.
* *The ELF format* - Once we have a file system we can load files from it, why not load a program? This part looks at writing a simple program loader for ELF64 binaries, and why you would want to use this format.
* *Going Beyond* - The final part (for now). We have implemented all the core components of a kernel, and we are free to go from here. This final chapter contains some ideas for new components that we might want to add, or at least begin thinking about.

Expand Down
4 changes: 2 additions & 2 deletions 01_Build_Process/01_Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Telling the compiler to not use these features can be done by passing some extra
- `-mno-mmx`: Disables using the FPU registers for 64-bit integer calculations.
- `-mno-3dnow`: Disables 3dnow! extensions, similar to MMX.
- `-mno-sse -mno-sse2`: Disables SSE and SSE2, which use the 128-bit xmm registers, and require setup before use.
- `-mcmodel=kernel`: The compiler uses 'code models' to help optimize code generation depending on where in memory the code might run. The `medium` cmodel runs in the lower 2GiB, while the `large` runs anywhere in the 64-bit address space. We could use `large` for our kernel, but if the kernel is being loaded loading in the top-most 2GiB `kernel` valuie can be used which allows similar optimizations to `medium`.
- `-mcmodel=kernel`: The compiler uses 'code models' to help optimize code generation depending on where in memory the code might run. The `medium` code model runs in the lower 2GiB, while the `large` runs anywhere in the 64-bit address space. We could use `large` for our kernel, but if the kernel is being loaded loading in the top-most 2GiB `kernel` value can be used which allows similar optimizations to `medium`.

There are also a few other compiler flags that are useful, but not necessary:

Expand All @@ -118,7 +118,7 @@ This section should be seen as an extension to the section above on compiling C

When compiling C++ for a freestanding environment, there are a few extra flags that are required:

- `-fno-rtti`: Tells the compiler not to generate runtime type information. This requires runtime support from the compiler libaries, and the os. Neither of which we have in a freestanding environment.
- `-fno-rtti`: Tells the compiler not to generate runtime type information. This requires runtime support from the compiler libraries, and the os. Neither of which we have in a freestanding environment.
- `-fno-exceptions`: Requires the compiler libraries to work, again which we don't have. Means we can't use C++ exceptions in your code. Some standard functions (like the `delete` operator) still require you to declare them `noexcept` so the correct symbols are generated.

And a few flags that are not required, but can be nice to have:
Expand Down
2 changes: 1 addition & 1 deletion 01_Build_Process/03_Gnu_Makefiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Next up is an important line: `.PHONY: `. Make targets are presumed to output a

The `all` and `clean` targets work as we'd expect, building the final output or cleaning the build files. It's worth noting the '@' symbol in front of echo. When at the start of a line, it tells make not to echo the rest of the line to the shell. In this case we're using echo because we want to output text without the shell trying to run it. Therefore we tell make not to output the echo line itself, since echo will already write the following text to the shell.

The line `-rm -r build/` begins with a minus/hyphen. Normally if a command fails (returns a non-zero exit code), make will abort the sequence of commands and display an error. Beginning a line with a hyphen tells make to ignore the error code. Make will still tell if an error ocurred, but it won't stop the executing the make file. In this case this is what we want.
The line `-rm -r build/` begins with a minus/hyphen. Normally if a command fails (returns a non-zero exit code), make will abort the sequence of commands and display an error. Beginning a line with a hyphen tells make to ignore the error code. Make will still tell if an error occurred, but it won't stop the executing the make file. In this case this is what we want.

The last two rules tell make how it should create a `*.c.o` or `*.S.o` file if it needs them. They have a dependency on a file of the same name, but with a different extension (`*.c` or `*.S`). This means make will fail with an error if the source file does not exist, or if we forget to add it to the `SRCS` variables above. We do a protective mkdir, to ensure that the filepath used for output actually exists.

Expand Down
4 changes: 2 additions & 2 deletions 01_Build_Process/04_Linker_Scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ Let's consider the following example:
} :text
```

First we give this output section a name, in this case its `.text`. To the right of the colon is where we would place any extra attributes for this section or override the LMA. By default the LMA will be the same as the VMA, but if required it can be overriden here using the `AT()` syntax. Two examples are provided below: the first sets the LMA of a section to an absolute address, and the second shows the use of another operator (`ADDR()`) in combination with `AT()` to get the VMA of a section, and then use it for calculating where to place the LMA. This results in a section with an LMA relative to it's VMA.
First we give this output section a name, in this case its `.text`. To the right of the colon is where we would place any extra attributes for this section or override the LMA. By default the LMA will be the same as the VMA, but if required it can be overridden here using the `AT()` syntax. Two examples are provided below: the first sets the LMA of a section to an absolute address, and the second shows the use of another operator (`ADDR()`) in combination with `AT()` to get the VMA of a section, and then use it for calculating where to place the LMA. This results in a section with an LMA relative to it's VMA.

```
/* absolute LMA, set to 0x1234 */
Expand All @@ -149,7 +149,7 @@ Next up we have a number of lines describing the input sections, with the format

After the closing brace is where we tell the linker what program header this section should be in, in this case its the `text` phdr. The program header name is prefixed with a colon in this case.

Similarly to the program headers we should specify ithe following sections in in our script:
Similarly to the program headers we should specify the following sections in in our script:

* _.text_
* _.rodata_
Expand Down
4 changes: 2 additions & 2 deletions 01_Build_Process/05_Generating_Iso.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ This file contains some global config options for grub (setting boot timeouts, e

Global options can be changed using the `set option=value` syntax, and a list is available from the grub documentation.

For each boot option, a menu entry needs to be created within grub.cfg. A menu entry consists of a header, and then a body containing a series of grub commands to boot the operating system. This allows grub to provide a flexible interface for more complex setups.
For each boot option, a menu entry needs to be created within `grub.cfg`. A menu entry consists of a header, and then a body containing a series of grub commands to boot the operating system. This allows grub to provide a flexible interface for more complex setups.

However in our case, we just want to boot our kernel using the standard multiboot2 protocol. Fortunately grub has a built in command (`multiboot2`) for doing just that:

Expand Down Expand Up @@ -73,7 +73,7 @@ That took a little more work than grub, but this can (and should) be automated a
### Limine.cfg
Similar to grub, limine also uses a config file. This config file has its own documentation, which is available in the limine repository.

Limine.cfg lists each boot entry as a title, followed by a series of key-value pairs. To boot our example from above using stivale 2, our config might look like the following:
The `limine.cfg` file lists each boot entry as a title, followed by a series of key-value pairs. To boot our example from above using stivale 2, our config might look like the following:

```
:My Operating System
Expand Down
2 changes: 1 addition & 1 deletion 01_Build_Process/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This part is going to cover all the tools and steps that are needed in order to

Below the list of chapters for this part:

- [General Overview](01_Overview.md): This chapter will serve as a high level overview of the overall building process, explaining why some steps are needed, and what is thier purpose. It also give an introduction to many of the concepts that will be developed in the in the following chapters.
- [General Overview](01_Overview.md): This chapter will serve as a high level overview of the overall building process, explaining why some steps are needed, and what is their purpose. It also give an introduction to many of the concepts that will be developed in the in the following chapters.
- [Boot Protocols & Bootloaders](02_Boot_Protocols.md): This chapter will explore two different solutions for booting our kernel: _Multiboot2_ and _Stivale_, explaining how they should be used and configured in order to boot our kernel, and what are their difference.
- [Makefiles](03_Gnu_Makefiles.md): The building script, we are going to use to build our kernel: Makefile.
- [Linker Scripts](04_Linker_Scripts.md): This chapter will introduce one of the probably most _obscure_ part of the building process, especially for beginners, it will explain what are the linker scripts, why they are important, and how to write one.
Expand Down
1 change: 0 additions & 1 deletion 02_Architecture/01_Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,3 @@ The interrupted code is usually never aware that an interrupt even occurred, and
## Drivers

Not device drivers for graphic cards, network interfaces, and other hardware, but on early stages of development we will need some basic drivers to implement some of the future features, for example we will need to have at least one supported Timer to implement the scheduler, we will most likely want to add a basic support for a keyboard in order to implement a cli, these topics will be covered in this section, along with other architecture specific drivers required by the CPU.

Loading

0 comments on commit 8f58715

Please sign in to comment.