You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Booting/README.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,6 @@ This chapter describes the Linux kernel boot process. Here you will see a series
7
7
*[Video mode initialization and transition to protected mode](linux-bootstrap-3.md) - describes video mode initialization in the kernel setup code and transition to protected mode.
8
8
*[Transition to 64-bit mode](linux-bootstrap-4.md) - describes preparation for transition into 64-bit mode and details of transition.
9
9
*[Kernel Decompression](linux-bootstrap-5.md) - describes preparation before kernel decompression and details of direct decompression.
10
-
*[Kernel random address randomization](linux-bootstrap-6.md) - describes randomization of the Linux kernel load address.
10
+
*[Kernel load address randomization](linux-bootstrap-6.md) - describes randomization of the Linux kernel load address.
Copy file name to clipboardExpand all lines: Booting/linux-bootstrap-1.md
+2-2
Original file line number
Diff line number
Diff line change
@@ -73,7 +73,7 @@ The starting address is formed by adding the base address to the value in the EI
73
73
'0xfffffff0'
74
74
```
75
75
76
-
We get `0xfffffff0`, which is 16 bytes below 4GB. This point is called the [reset vector](https://en.wikipedia.org/wiki/Reset_vector). It's the memory location at which the CPU expects to find the first instruction to execute after reset. It contains a [jump](https://en.wikipedia.org/wiki/JMP_%28x86_instruction%29) (`jmp`) instruction that usually points to the [BIOS](https://en.wikipedia.org/wiki/BIOS) (Basic Input/Output System) entry point. For example, if we look in the [coreboot](https://www.coreboot.org/) source code (`src/cpu/x86/16bit/reset16.inc`), we see:
76
+
We get `0xfffffff0`, which is 16 bytes below 4GB. This point is called the [reset vector](https://en.wikipedia.org/wiki/Reset_vector). It's the memory location at which the CPU expects to find the first instruction to execute after reset. It contains a [jump](https://en.wikipedia.org/wiki/JMP_%28x86_instruction%29) (`jmp`) instruction that usually points to the [BIOS](https://en.wikipedia.org/wiki/BIOS) (Basic Input/Output System) entry point. For example, if we look in the [coreboot](https://www.coreboot.org/) source code ([src/cpu/x86/16bit/reset16.inc](https://review.coreboot.org/plugins/gitiles/coreboot/+/refs/heads/4.11_branch/src/cpu/x86/16bit/reset16.inc)), we see:
77
77
78
78
```assembly
79
79
.section ".reset", "ax", %progbits
@@ -87,7 +87,7 @@ _start:
87
87
88
88
Here we can see the `jmp` instruction [opcode](http://ref.x86asm.net/coder32.html#xE9), which is `0xe9`, and its destination address at `_start16bit - ( . + 2)`.
89
89
90
-
We also see that the `reset` section is `16` bytes and is compiled to start from the address `0xfffffff0` (`src/cpu/x86/16bit/reset16.ld`):
90
+
We also see that the `reset` section is `16` bytes and is compiled to start from the address `0xfffffff0` ([src/cpu/x86/16bit/reset16.ld](https://review.coreboot.org/plugins/gitiles/coreboot/+/refs/heads/4.11_branch/src/cpu/x86/16bit/reset16.ld)):
Copy file name to clipboardExpand all lines: Booting/linux-bootstrap-3.md
+2-2
Original file line number
Diff line number
Diff line change
@@ -299,7 +299,7 @@ io_delay();
299
299
300
300
At first, there is an inline assembly statement with a `cli` instruction which clears the interrupt flag (`IF`). After this, external interrupts are disabled. The next line disables NMI (non-maskable interrupt).
301
301
302
-
An interrupt is a signal to the CPU which is emitted by hardware or software. After getting such a signal, the CPU suspends the current instruction sequence, saves its state and transfers control to the interrupt handler. After the interrupt handler has finished it's work, it transfers control back to the interrupted instruction. Non-maskable interrupts (NMI) are interrupts which are always processed, independently of permission. They cannot be ignored and are typically used to signal for non-recoverable hardware errors. We will not dive into the details of interrupts now but we will be discussing them in the coming posts.
302
+
An interrupt is a signal to the CPU which is emitted by hardware or software. After getting such a signal, the CPU suspends the current instruction sequence, saves its state and transfers control to the interrupt handler. After the interrupt handler has finished its work, it transfers control back to the interrupted instruction. Non-maskable interrupts (NMI) are interrupts which are always processed, independently of permission. They cannot be ignored and are typically used to signal for non-recoverable hardware errors. We will not dive into the details of interrupts now but we will be discussing them in the coming posts.
303
303
304
304
Let's get back to the code. We can see in the second line that we are writing the byte `0x80` (disabled bit) to `0x70` (the CMOS Address register). After that, a call to the `io_delay` function occurs. `io_delay` causes a small delay and looks like:
305
305
@@ -326,7 +326,7 @@ static int a20_test(int loops)
326
326
327
327
saved = ctr = rdfs32(A20_TEST_ADDR);
328
328
329
-
while (loops--) {
329
+
while (loops--) {
330
330
wrfs32(++ctr, A20_TEST_ADDR);
331
331
io_delay(); /* Serialize and make delay constant */
Copy file name to clipboardExpand all lines: Booting/linux-bootstrap-5.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -204,7 +204,7 @@ Like before, we push `rsi` onto the stack to preserve the pointer to `boot_param
204
204
*`output` - the start address of the decompressed kernel;
205
205
*`output_len` - the size of the decompressed kernel;
206
206
207
-
All arguments will be passed through registers as per the [System V Application Binary Interface](http://www.x86-64.org/documentation/abi.pdf). We've finished all the preparations and can now decompress the kernel.
207
+
All arguments will be passed through registers as per the [System V Application Binary Interface](https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf). We've finished all the preparations and can now decompress the kernel.
Copy file name to clipboardExpand all lines: Booting/linux-bootstrap-6.md
+3-3
Original file line number
Diff line number
Diff line change
@@ -46,7 +46,7 @@ This function takes five parameters:
46
46
* `input`;
47
47
* `input_size`;
48
48
* `output`;
49
-
* `output_isze`;
49
+
* `output_size`;
50
50
* `virt_addr`.
51
51
52
52
Let's try to understand what these parameters are. The first parameter, `input` is just the `input_data` parameter of the `extract_kernel` function from the [arch/x86/boot/compressed/misc.c](https://github.com/torvalds/linux/blob/v4.16/arch/x86/boot/compressed/misc.c) source code file, cast to `unsigned long`:
@@ -146,7 +146,7 @@ Now, we call another function:
146
146
initialize_identity_maps();
147
147
```
148
148
149
-
The `initialize_identity_maps` function is defined in the [arch/x86/boot/compressed/kaslr_64.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/kaslr_64.c) source code file. This function starts by initialising an instance of the `x86_mapping_info` structure called `mapping_info`:
149
+
The `initialize_identity_maps` function is defined in the [arch/x86/boot/compressed/kaslr_64.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/kaslr_64.c) source code file. This function starts by initializing an instance of the `x86_mapping_info` structure called `mapping_info`:
THe `mem_avoid_init` function first tries to avoid memory regions currently used to decompress the kernel. We fill an entry from the `mem_avoid` array with the start address and the size of the relevant region and call the `add_identity_map` function, which builds the identity mapped pages for this region. The `add_identity_map` function is defined in the [arch/x86/boot/compressed/kaslr_64.c](https://github.com/torvalds/linux/blob/v4.16/arch/x86/boot/compressed/kaslr_64.c) source code file and looks like this:
257
+
The `mem_avoid_init` function first tries to avoid memory regions currently used to decompress the kernel. We fill an entry from the `mem_avoid` array with the start address and the size of the relevant region and call the `add_identity_map` function, which builds the identity mapped pages for this region. The `add_identity_map` function is defined in the [arch/x86/boot/compressed/kaslr_64.c](https://github.com/torvalds/linux/blob/v4.16/arch/x86/boot/compressed/kaslr_64.c) source code file and looks like this:
258
258
259
259
```C
260
260
void add_identity_map(unsigned long start, unsigned long size)
see the first `c` letter in a permissions list. The second part is `5:0` is major and minor numbers of the device. You can see these numbers in the output of `ls` too. And the last `w` letter forbids tasks to write to the specified device. So let's start the `cgroup_test_script.sh` script:
148
148
149
149
```
150
-
~$ ./cgroup_test_script.sh
150
+
~$ ./cgroup_test_script.sh
151
151
print line
152
152
print line
153
153
print line
@@ -164,7 +164,7 @@ and add pid of this process to the `devices/tasks` file of our group:
164
164
The result of this action will be as expected:
165
165
166
166
```
167
-
~$ ./cgroup_test_script.sh
167
+
~$ ./cgroup_test_script.sh
168
168
print line
169
169
print line
170
170
print line
@@ -174,7 +174,7 @@ print line
174
174
./cgroup_test_script.sh: line 5: /dev/tty: Operation not permitted
175
175
```
176
176
177
-
Similar situation will be when you will run you [docker](https://en.wikipedia.org/wiki/Docker_\(software\)) containers for example:
177
+
Similar situation will be when you will run you [docker](https://en.wikipedia.org/wiki/Docker_(software)) containers for example:
178
178
179
179
```
180
180
~$ docker ps
@@ -213,7 +213,7 @@ Control group /:
213
213
│ └─6404 /bin/bash
214
214
```
215
215
216
-
Now we know a little about `control groups` mechanism, how to use it manually and what's purpose of this mechanism. It's time to look inside of the Linux kernel source code and start to dive into implementation of this mechanism.
216
+
Now we know a little about `control groups` mechanism, how to use it manually and what's the purpose of this mechanism. It's time to look inside of the Linux kernel source code and start to dive into implementation of this mechanism.
@@ -294,7 +294,7 @@ Here we may see call of the `init_cgroup_root` function which will execute initi
294
294
struct cgroup_root cgrp_dfl_root;
295
295
```
296
296
297
-
Its `cgrp` field represented by the `cgroup` structure which represents a `cgroup` as you already may guess and defined in the [include/linux/cgroup-defs.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/cgroup-defs.h) header file. We already know that a process which is represented by the `task_struct` in the Linux kernel. The `task_struct` does not contain direct link to a `cgroup` where this task is attached. But it may be reached via `css_set` field of the `task_struct`. This `css_set` structure holds pointer to the array of subsystem states:
297
+
Its `cgrp` field represented by the `cgroup` structure which represents a `cgroup` as you already may guess and defined in the [include/linux/cgroup-defs.h](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/include/linux/cgroup-defs.h) header file. We already know that a process is represented by the `task_struct` in the Linux kernel. The `task_struct` does not contain direct link to a `cgroup` where this task is attached. But it may be reached via `css_set` field of the `task_struct`. This `css_set` structure holds pointer to the array of subsystem states:
Copy file name to clipboardExpand all lines: Concepts/linux-cpu-2.md
+7-7
Original file line number
Diff line number
Diff line change
@@ -19,13 +19,13 @@ set_cpu_present(cpu, true);
19
19
set_cpu_possible(cpu, true);
20
20
```
21
21
22
-
Before we will consider implementation of these functions, let's consider all of these masks.
22
+
Before we consider implementation of these functions, let's consider all of these masks.
23
23
24
-
The `cpu_possible` is a set of cpu ID's which can be plugged in anytime during the life of that system boot or in other words mask of possible CPUs contains maximum number of CPUs which are possible in the system. It will be equal to value of the `NR_CPUS` which is which is set statically via the `CONFIG_NR_CPUS` kernel configuration option.
24
+
The `cpu_possible` is a set of cpu ID's which can be plugged in anytime during the life of that system boot or in other words mask of possible CPUs contains maximum number of CPUs which are possible in the system. It will be equal to value of the `NR_CPUS` which is set statically via the `CONFIG_NR_CPUS` kernel configuration option.
25
25
26
26
The `cpu_present` mask represents which CPUs are currently plugged in.
27
27
28
-
The `cpu_online` represents a subset of the `cpu_present` and indicates CPUs which are available for scheduling or in other words a bit from this mask tells to kernel is a processor may be utilized by the Linux kernel.
28
+
The `cpu_online` represents a subset of the `cpu_present` and indicates CPUs which are available for scheduling or in other words a bit from this mask tells the kernel if a processor may be utilized by the Linux kernel.
29
29
30
30
The last mask is `cpu_active`. Bits of this mask tells to Linux kernel is a task may be moved to a certain processor.
31
31
@@ -94,9 +94,9 @@ And returns `1` every time. We need it here for only one purpose: at compile tim
As we can define cpumask with one of the method, Linux kernel provides API for manipulating a cpumask. Let's consider one of the function which presented above. For example `set_cpu_online`. This function takes two parameters:
97
+
As we can define cpumask with one of the methods, Linux kernel provides API for manipulating a cpumask. Let's consider one of the function which presented above. For example `set_cpu_online`. This function takes two parameters:
98
98
99
-
* Number of CPU;
99
+
* Index of CPU;
100
100
* CPU status;
101
101
102
102
Implementation of this function looks as:
@@ -113,7 +113,7 @@ void set_cpu_online(unsigned int cpu, bool online)
113
113
}
114
114
```
115
115
116
-
First of all it checks the second `state` parameter and calls `cpumask_set_cpu` or `cpumask_clear_cpu`depends on it. Here we can see casting to the `struct cpumask *` of the second parameter in the `cpumask_set_cpu`. In our case it is `cpu_online_bits` which is a bitmap and defined as:
116
+
First of all it checks the second `state` parameter and calls `cpumask_set_cpu` or `cpumask_clear_cpu`depending on it. Here we can see casting to the `struct cpumask *` of the second parameter in the `cpumask_set_cpu`. In our case it is `cpu_online_bits` which is a bitmap and defined as:
The `set_bit` function takes two parameters too, and sets a given bit (first parameter) in the memory (second parameter or `cpu_online_bits` bitmap). We can see here that before `set_bit`will be called, its two parameters will be passed to the
131
+
The `set_bit` function takes two parameters too, and sets a given bit (first parameter) in the memory (second parameter or `cpu_online_bits` bitmap). We can see here that before `set_bit`is called, its two parameters will be passed to the
0 commit comments