Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Booting/linux-bootstrap-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ Here we compare the value of the `ss` and `ds` registers. According to the comme
sti # Now we should have a working stack
```

`dx` register stores stack pointer value whish should point to the top of the stack. The value of the stack pointer is `0x9000`. GRUB 2 bootloader sets it during loading of the Linux kernel image and the address is defined by the:
`dx` register stores stack pointer value which should point to the top of the stack. The value of the stack pointer is `0x9000`. GRUB 2 bootloader sets it during loading of the Linux kernel image and the address is defined by the:

<!-- https://raw.githubusercontent.com/rhboot/grub2/refs/heads/master/include/grub/i386/linux.h#L34-L34 -->
```C
Expand Down
2 changes: 1 addition & 1 deletion Booting/linux-bootstrap-3.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Enter a video mode or "scan" to scan for additional modes:

Before proceeding further to investigate what the `set_video` function does, it will be useful to take a look at the API for the management of the kernel's early heap.

After getting the video mode set by the bootloader, we can see reseting the heap value by the `RESET_HEAP` macro. The definition of this macro is in the [arch/x86/boot/boot.h](https://github.com/torvalds/linux/blob/master/arch/x86/boot/boot.h):
After getting the video mode set by the bootloader, we can see resetting the heap value by the `RESET_HEAP` macro. The definition of this macro is in the [arch/x86/boot/boot.h](https://github.com/torvalds/linux/blob/master/arch/x86/boot/boot.h):

<!-- https://raw.githubusercontent.com/torvalds/linux/refs/heads/master/arch/x86/boot/boot.h#L174-L174 -->
```C
Expand Down
2 changes: 1 addition & 1 deletion Booting/linux-bootstrap-4.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ As we mentioned in the beginning of this chapter - on `x86_64`, the processor mu

- `PML4` - top level table, each entry points to `PDPT`
- `PDPT` - 3rd level table, each entry points to `PD`
- `PD` - 2nd level table, each entry poitns to `PT`
- `PD` - 2nd level table, each entry points to `PT`
- `PT` - 1st level table, each entry points to a 4 killobyte physical page

The physical address of the top level table must be stored in the `cr3` register.
Expand Down
6 changes: 3 additions & 3 deletions Booting/linux-bootstrap-5.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ SYM_DATA_START_LOCAL(gdt)
SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
```

After the new `Global Desciptor Table` was loaded, the next step is to load new `Interrupt Descriptor Table`:
After the new `Global Descriptor Table` was loaded, the next step is to load new `Interrupt Descriptor Table`:

<!-- https://raw.githubusercontent.com/torvalds/linux/refs/heads/master/arch/x86/boot/compressed/head_64.S#L369-L376 -->
```assembly
Expand All @@ -122,7 +122,7 @@ After the new `Global Desciptor Table` was loaded, the next step is to load new
call load_stage1_idt
```

The `load_stage1_idt` function is defined in the [arch/x86/boot/compressed/idt_64.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/idt_64.c) and uses the `lidt` instruction to load address of the new `Interrupt Desciptor Table` . For this moment, the `Interrupt Descriptor Table` has `NULL` entries to avoid interrupts. The valid interrupt handlers will be loaded after kernel relocation.
The `load_stage1_idt` function is defined in the [arch/x86/boot/compressed/idt_64.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/idt_64.c) and uses the `lidt` instruction to load address of the new `Interrupt Descriptor Table` . For this moment, the `Interrupt Descriptor Table` has `NULL` entries to avoid interrupts. The valid interrupt handlers will be loaded after kernel relocation.

The next steps after this will be highly related to the setup of `5-level` paging if it is configured using the `CONFIG_PGTABLE_LEVELS=5` kernel configuration option. This feature extends the virtual address space beyond the traditional 4-level paging scheme, but it is still relatively uncommon in practice and not essential for understanding the mainline boot flow. For clarity and focus, we’ll set it aside and continue with the standard 4-level paging case.

Expand Down Expand Up @@ -215,7 +215,7 @@ We can skip the part of the code wrapped with the `CONFIG_AMD_MEM_ENCRYPT` as it
- `PF` - Page fault interrupt
- `NMI` - Non-maskable interrupt

The first interrupt handler is set because the `initialize_identity_maps` function which we will see very soon many need it. It can be used in a case [Address space layout randomization](https://en.wikipedia.org/wiki/Address_space_layout_randomization) is enabled and such random physical and virtual addresses were choosen for which mapping does not exist in the current page tables. The second interrupt handler needed to prevent triple-fault if such interrupt will appear during kernel decompression. So at least dummy NMI is needed.
The first interrupt handler is set because the `initialize_identity_maps` function which we will see very soon many need it. It can be used in a case [Address space layout randomization](https://en.wikipedia.org/wiki/Address_space_layout_randomization) is enabled and such random physical and virtual addresses were chosen for which mapping does not exist in the current page tables. The second interrupt handler needed to prevent triple-fault if such interrupt will appear during kernel decompression. So at least dummy NMI is needed.

After the `Interrupt Descriptor Table` is re-loaded, the `initialize_identity_maps` function is called:

Expand Down
4 changes: 2 additions & 2 deletions Concepts/linux-cpu-4.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
}
```

and as we may see it just returns result of the `__blocking_notifier_call_chain` function. As we may see, the `blocking_notifer_call_chain` takes three parameters:
and as we may see it just returns result of the `__blocking_notifier_call_chain` function. As we may see, the `blocking_notifier_call_chain` takes three parameters:

* `nh` - head of notification chain list;
* `val` - type of a notification;
Expand All @@ -247,7 +247,7 @@ int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
}
```

Where `nr_to_call` and `nr_calls` are number of notifier functions to be called and number of sent notifications. As you may guess the main goal of the `__blocking_notifer_call_chain` function and other functions for other notification types is to call callback function when an event occurs. Implementation of the `__blocking_notifier_call_chain` is pretty simple, it just calls the `notifier_call_chain` function from the same source code file protected with read/write semaphore:
Where `nr_to_call` and `nr_calls` are number of notifier functions to be called and number of sent notifications. As you may guess the main goal of the `__blocking_notifier_call_chain` function and other functions for other notification types is to call callback function when an event occurs. Implementation of the `__blocking_notifier_call_chain` is pretty simple, it just calls the `notifier_call_chain` function from the same source code file protected with read/write semaphore:

```C
int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
Expand Down
2 changes: 1 addition & 1 deletion DataStructures/linux-datastructures-3.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
}
```

Besides the `bitmap_fill` and `bitmap_zero` functions, the [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/bitmap.h) header file provides `bitmap_copy` which is similar on the `bitmap_zero`, but just uses [memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html) instead of [memset](http://man7.org/linux/man-pages/man3/memset.3.html). Also it provides bitwise operations for bit array like `bitmap_and`, `bitmap_or`, `bitamp_xor` and etc. We will not consider implementation of these functions because it is easy to understand implementations of these functions if you understood all from this part. Anyway if you are interested in how these function are implemented, you may open [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/bitmap.h) header file and start to research.
Besides the `bitmap_fill` and `bitmap_zero` functions, the [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/bitmap.h) header file provides `bitmap_copy` which is similar on the `bitmap_zero`, but just uses [memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html) instead of [memset](http://man7.org/linux/man-pages/man3/memset.3.html). Also it provides bitwise operations for bit array like `bitmap_and`, `bitmap_or`, `bitmap_xor` and etc. We will not consider implementation of these functions because it is easy to understand implementations of these functions if you understood all from this part. Anyway if you are interested in how these function are implemented, you may open [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/bitmap.h) header file and start to research.

That's all.

Expand Down
2 changes: 1 addition & 1 deletion Interrupts/linux-interrupts-3.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ If we will look at these definitions, we may know that compiler will generate tw

But it is not only fake error-code. Moreover the `-1` also represents invalid system call number, so that the system call restart logic will not be triggered.

The last two parameters of the `idtentry` macro `shift_ist` and `paranoid` allow to know do an exception handler runned at stack from `Interrupt Stack Table` or not. You already may know that each kernel thread in the system has its own stack. In addition to these stacks, there are some specialized stacks associated with each processor in the system. One of these stacks is - exception stack. The [x86_64](https://en.wikipedia.org/wiki/X86-64) architecture provides special feature which is called - `Interrupt Stack Table`. This feature allows to switch to a new stack for designated events such as an atomic exceptions like `double fault`, etc. So the `shift_ist` parameter allows us to know do we need to switch on `IST` stack for an exception handler or not.
The last two parameters of the `idtentry` macro `shift_ist` and `paranoid` allow to know do an exception handler ran at stack from `Interrupt Stack Table` or not. You already may know that each kernel thread in the system has its own stack. In addition to these stacks, there are some specialized stacks associated with each processor in the system. One of these stacks is - exception stack. The [x86_64](https://en.wikipedia.org/wiki/X86-64) architecture provides special feature which is called - `Interrupt Stack Table`. This feature allows to switch to a new stack for designated events such as an atomic exceptions like `double fault`, etc. So the `shift_ist` parameter allows us to know do we need to switch on `IST` stack for an exception handler or not.

The second parameter - `paranoid` defines the method which helps us to know did we come from userspace or not to an exception handler. The easiest way to determine this is to via `CPL` or `Current Privilege Level` in `CS` segment register. If it is equal to `3`, we came from userspace, if zero we came from kernel space:

Expand Down
2 changes: 1 addition & 1 deletion Interrupts/linux-interrupts-4.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ Links
* [Linux kernel memory management](https://0xax.gitbook.io/linux-insides/summary/mm)
* [Fix-Mapped Addresses and ioremap](https://0xax.gitbook.io/linux-insides/summary/mm/linux-mm-2)
* [Extended Industry Standard Architecture](https://en.wikipedia.org/wiki/Extended_Industry_Standard_Architecture)
* [INT isntruction](https://en.wikipedia.org/wiki/INT_%28x86_instruction%29)
* [INT instruction](https://en.wikipedia.org/wiki/INT_%28x86_instruction%29)
* [INTO](http://x86.renejeschke.de/html/file_module_x86_id_142.html)
* [BOUND](http://pdos.csail.mit.edu/6.828/2005/readings/i386/BOUND.htm)
* [opcode](https://en.wikipedia.org/?title=Opcode)
Expand Down
2 changes: 1 addition & 1 deletion SyncPrim/linux-sync-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ Notice that we did not touch `queue` yet. We do not need it, because for two thr
queue:
node = this_cpu_ptr(&qnodes[0].mcs);
idx = node->count++;
tail = encode_tail(smp_processer_id(), idx);
tail = encode_tail(smp_processor_id(), idx);

node = grab_mcs_node(node, idx);
```
Expand Down