Skip to content

Commit 1a02d1e

Browse files
authored
Debugging minor changes (#88)
* Minor fixes in the appendices section * minor syntax fix to acpi chapter * clarify length field in acpisdt header * Fix file name (issue #86) * minor changes to memory management section * Minor changes to heap chapter * Requested changes
1 parent cd440f3 commit 1a02d1e

7 files changed

Lines changed: 36 additions & 34 deletions

File tree

01_Build_Process/03_Gnu_Makefiles.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ There's a million and one excellent resources on makefiles out there, so this ch
66

77
There's multiple different make-like programs out there, a lot of them share a common base, usually the one specified in posix. GNU make also has a bunch of custom extensions it adds, which can be quite useful. These will render our Makefiles only usable for gnu make, which is the most common version. So this is fine, but if we care about being fully portable between make versions, we'll have to avoid these.
88

9-
If we want to use gnu make extensions, we now have a makefile that wont run under every version of make. Fortunately the folks at gnu allow us to name our makefile `GNUMakefile` instead, and this will run as normal. However other versions of make won't see this file, meaning they wont try to run it.
9+
If we want to use gnu make extensions, we now have a makefile that wont run under every version of make. Fortunately the folks at gnu allow us to name our makefile `GNUmakefile` instead, and this will run as normal. However other versions of make won't see this file, meaning they wont try to run it.
1010

1111
## Simple Makefile Example
1212

02_Architecture/06_ACPITables.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ The newer version is backward compatible with the older.
2020

2121
Accessing the RSDP register depends on the boot system used, if we are using grub, we get a copy of the RSDT/XSDT in one of the multiboot2 header tags. The specs contains two possible tags for the RSDP value, which one is used depend on the version:
2222

23-
* For the version 1 the MULTIBOOT_TAG_TYPE_ACPI_OLD is used (type 14)
24-
* For the version 2 the MULTIBOOT_TAG_TYPE_ACPI_NEW is used (type 15)
23+
* For the version 1 the `MULTIBOOT_TAG_TYPE_ACPI_OLD` is used (type 14)
24+
* For the version 2 the `MULTIBOOT_TAG_TYPE_ACPI_NEW` is used (type 15)
2525

2626
Both headers are identical, with the only difference being in the type value, they are composed of just two fields:
2727

@@ -113,6 +113,8 @@ struct ACPISDTHeader {
113113
```
114114
* The second part is the table itself, every SDT has its own table
115115

116+
It's important to note that hte `Length` field contains the size of the table, header included.
117+
116118
#### RSDT vs XSDT
117119

118120
These 2 tables have the same purpose and are mutually exclusive. If the latter exists, the former is to be ignored, otherwise use the former.
@@ -142,8 +144,8 @@ ACPISDTHeader* header = (ACPISDTHeader*)(use_xsdt ? xsdt->sdtAddresses[n] : (uin
142144

143145
### Some useful infos
144146

145-
* Be aware that the Signature in the RSD* structure is not null terminated. This means that if we try to print it, you will most likely end up in printing garbage in the best case scenario.
146-
* The RSDT Data is an array of uint32_t addresses while the XSDT data is an array of uint64_t addresses. The number of items in the RSDT and XSDT can be computed in the following way:
147+
* Be aware that the `Signature` the signature in any of the ACPI tables are not null-terminated. This means that if we try to print it, you will most likely end up in printing garbage in the best case scenario.
148+
* The RSDT Data is an array of `uint32_t` addresses while the XSDT data is an array of `uint64_t` addresses. The number of items in the RSDT and XSDT can be computed in the following way:
147149

148150
```c
149151
//for the RSDT

04_Memory_Management/01_Overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Each of the layers has a dedicated chapter, however we'll start with a high leve
2828

2929
## A Word of Wisdom
3030

31-
As said at the beginning of this chapter Memory management is one of the most important parts of a kernel, as every other part of the kernel will interact with it in some way. It's worth taking the extra time to consider what features we want our PMM and VMM to have, and the ramifications. A little planning now can save us a lot of heacaches and rewriting code later!
31+
As said at the beginning of this chapter Memory management is one of the most important parts of a kernel, as every other part of the kernel will interact with it in some way. It's worth taking the extra time to consider what features we want our PMM and VMM to have, and the ramifications. A little planning now can save us a lot of headaches and rewriting code later!
3232

3333
## PMM - Physical Memory Manager
3434

04_Memory_Management/03_Paging.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,11 @@ Note about PWT and PCD, the definiton of those bits depends on whether PAT (page
213213
214214
If we are using 2MB pages this is how the address will be handled by the paging mechanism:
215215
216-
| | | | | |
217-
|------------|-----------|---------------|------------|-----------|
218-
| 63 .... 48 | 47 ... 39 | 38 ... 30 | 29 .. 21 | 20 ... 0 |
219-
| 1 ... 1 | 1 ... 1 | 1 ... 0 | 0 ... 0 | 0 ... 0 |
220-
| Sgn. ext | PML4 | PDPR | Page dir | Offset |
216+
| | | | | |
217+
|--------------|-----------|---------------|--------------|------------|
218+
| 63 .... 48 | 47 ... 39 | 38 ... 30 | 29 .. 21 | 20 ... 0 |
219+
| 1 ... 1 | 1 ... 1 | 1 ... 0 | 0 ... 0 | 0 ... 0 |
220+
| **Sgn. ext** | **PML4** | **PDPR** | **Page dir** | **Offset** |
221221
222222
* Bits 63 to 48, not used in address translation.
223223
* Bits 47 ... 39 are the PML4 entry.
@@ -231,11 +231,11 @@ Every table has 512 elements, so we have an address space of $2^{512}*2^{512}*2^
231231
232232
If we are using 4kB pages this is how the address will be handled by the paging mechanism:
233233
234-
| | | | | | |
235-
|-----------|-----------|-----------|-----------|-------------|-----------|
236-
| 63 ... 48 | 47 ... 39 | 38 ... 30 | 29 ... 21 | 20 ... 12 | 11 ... 0 |
237-
| 1 ... 1 | 1 ... 1 | 1 ... 0 | 0 ... 0 | 0 ... 0 | 0 ... 0 |
238-
| Sgn. ext | PML4 | PDPR | Page dir | Page Table | Offset |
234+
| | | | | | |
235+
|--------------|-----------|-----------|--------------|----------------|-------------|
236+
| 63 ... 48 | 47 ... 39 | 38 ... 30 | 29 ... 21 | 20 ... 12 | 11 ... 0 |
237+
| 1 ... 1 | 1 ... 1 | 1 ... 0 | 0 ... 0 | 0 ... 0 | 0 ... 0 |
238+
| **Sgn. ext** | **PML4** | **PDPR** | **Page dir** | **Page Table** | **Offset** |
239239
240240
* Bits 63 to 48, not used in address translation.
241241
* Bits 47 ... 39 are the PML4 entry.
@@ -257,10 +257,10 @@ The idea of the page fault handler is to look at the error code and faulting add
257257
258258
The error code has the following structure:
259259
260-
| | | | | | |
261-
|-----------|-------|--------|------|-------|-----|
262-
| 31 .... 4 | 4 | 3 | 2 | 1 | 0 |
263-
| Reserved | I/D | RSVD | U/S | W/R | P |
260+
| | | | | | |
261+
|------------|---------|----------|---------|---------|-------|
262+
| 31 .... 4 | 4 | 3 | 2 | 1 | 0 |
263+
| _Reserved_ | **I/D** | **RSVD** | **U/S** | **W/R** | **P** |
264264
265265
The meanings of these bits are expanded below:
266266

04_Memory_Management/05_Heap_Allocation.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Well the answer is, as we already know: it allocates memory, specifically in byt
5555

5656
If we are writing an OS, we already know that RAM can be viewed as a very long array, where the index into this array is the memory address. The allocator is returning these indices. So we can already see the first detail we'll need to keep track of: next available address.
5757

58-
Let's start with a simple example, assume that we have an address space of 100 bytes, nothing has allocated yet, and the program makes the following consecutive `alloc()` calls:
58+
Let's start with a simple example, assume that we have an address space of 100 bytes, nothing has been allocated yet, and the program makes the following consecutive `alloc()` calls:
5959

6060
```c
6161
alloc(10);
@@ -94,7 +94,7 @@ uint8_t *cur_heap_position = 0; //Just an example, in the real world you would u
9494
//a virtual address allocated from the VMM.
9595
void *first_alloc(size_t size) {
9696
uint8_t *addr_to_return = cur_heap_position;
97-
cur_heap_position= cur_heap_position + size;
97+
cur_heap_position = cur_heap_position + size;
9898
return (void*) addr_to_return;
9999
}
100100
```
@@ -111,7 +111,7 @@ void first_free(void *ptr) {
111111
112112
Yeah... that's right, it's not an error. A bump allocator does not have `free()`.
113113
114-
Why? Because we are not keeping track of the allocated memory, so we can't just update the `cur_heap_position` variable with the address of ptr, because we don't know who is using the memory after ptr. So we are forced just to do nothing.
114+
Why? Because we are not keeping track of the allocated memory, so we can't just update the `cur_heap_position` variable with the address of ptr, since we don't know who is using the memory after ptr. So we are forced just to do nothing.
115115
116116
Even if probably useless let's see what are the pros and cons of this approach:
117117
@@ -128,9 +128,9 @@ Of course the cons are probably pretty clear and make this algorithm pretty usel
128128
* There is no way to traverse the heap, because we don't keep track of the allocations.
129129
* We will eventually run out of memory (OOM - out of memory).
130130
131-
### Part 2: Adding Free()
131+
### Part 2: Adding free()
132132
133-
The main problem with this algorithm is that we don't keep track of what we have allocated in the past, so we are not able to free that memory in the future, when it's no longer used.
133+
The main problem with the algorithm outlined above is that we don't keep track of what we have allocated in the past, so we are not able to free that memory in the future, when it's no longer used.
134134
135135
Now we're going to build a new allocator based on the one we just implemented. The first thing to do is try to figure out what are the information we need to keep track of from the previous allocations:
136136

99_Appendices/F_Debugging.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ symbol-file path/to/kernel.bin
2424

2525
Below a list of some useful gdb commands
2626

27-
* Show register content: *info register reg* where reg is the register we need
28-
* Set breakpoint to specific address: *break 0xaddress*
29-
* Show memory address content: *x/nfu addr* wher: n is the number of iterations f the format (x = hex) and the addr we want to show
30-
* We can show also the content of pointer stored into a register: *x/h ($rax)* shows the content of memory address pointed by rax
27+
* Show register content: `info register reg` where reg is the register we need
28+
* Set breakpoint to specific address: `break 0xaddress`
29+
* Show memory address content: `x/nfu addr` where: *n* is the number of iterations *f* the format (*x* = hex) and the *addr* we want to show
30+
* We can show also the content of pointer stored into a register: `x/h ($rax)` shows the content of memory address pointed by rax
3131

3232
### Navigation
3333

@@ -223,10 +223,10 @@ QEMU 6.1.0 monitor - type 'help' for more information
223223

224224
From here is possible to send commands directly to the emulator, below a list of useful commands:
225225

226-
* **help** Well this is the first command to get some help on how to use the monitor.
227-
* **info xxxx** It will print several information, depending on xxxx for example: *info lapic* will show the current status of the local apic, *info mem* will print current virtual memory mappings, *info registers* will print the registers content.
228-
* **x/cf address** where c is the number of items we want to display in decimal, f is the format (`x` for hex, `c` for char, etc) display the content of c virtual memory locations starting from address.
229-
* **xp/cf address** same as above, but for physical memory.
226+
* `help` Well this is the first command to get some help on how to use the monitor.
227+
* `info xxxx` It will print several information, depending on xxxx for example: `info lapic` will show the current status of the local apic, `info mem` will print current virtual memory mappings, `info registers` will print the registers content.
228+
* `x /cf address` where c is the number of items we want to display in decimal, f is the format (`x` for hex, `c` for char, etc) display the content of c virtual memory locations starting from address.
229+
* `xp /cf address` same as above, but for physical memory.
230230

231231
#### Info mem & Info tlb
232232

99_Appendices/J_Updates.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Third Book release
4040

4141
### Revision 3
4242

43-
Release date: April 2024
43+
Release date: April 2024.
4444
Fourth book release
4545

4646
* Typo fixes

0 commit comments

Comments
 (0)