Merge branch 'master' of github.com:0xAX/linux-internals

pull/89/head
0xAX 9 years ago
commit 9c22ce6063

@ -4,7 +4,7 @@ Data Structures in the Linux Kernel
Doubly linked list
--------------------------------------------------------------------------------
Linux kernel provides it's own doubly linked list implementation which you can find in the [include/linux/list.h](https://github.com/torvalds/linux/blob/master/include/linux/list.h). We will start `Data Structures in the Linux kernel` from the doubly linked list data structure. Why? Because it is very popular in the kernel, just try to [search](http://lxr.free-electrons.com/ident?i=list_head)
Linux kernel provides its own doubly linked list implementation which you can find in the [include/linux/list.h](https://github.com/torvalds/linux/blob/master/include/linux/list.h). We will start `Data Structures in the Linux kernel` from the doubly linked list data structure. Why? Because it is very popular in the kernel, just try to [search](http://lxr.free-electrons.com/ident?i=list_head)
First of all let's look on the main structure:
@ -24,7 +24,7 @@ struct GList {
};
```
Usually linked list structure contains pointer to the item. Linux kernel implementation of the list has not. So the main question is here - `where list stores data?`. Actually implementation of lists in the kernel is - `Intrusive list`. An intrusive linked list does not contain data in it's nodes and nodes just contain pointers to the to the next and previous node and list nodes part of the data that are added to the list. This makes data structure generic, so it does not care about entry data type anymore.
Usually a linked list structure contains a pointer to the item. Linux kernel implementation of the list does not. So the main question is - `where does the list store the data?`. The actual implementation of lists in the kernel is - `Intrusive list`. An intrusive linked list does not contain data in its nodes - A node just contains pointers to the next and previous node and list nodes part of the data that are added to the list. This makes the data structure generic, so it does not care about entry data type anymore.
For example:
@ -35,7 +35,7 @@ struct nmi_desc {
};
```
Let's look on some examples, how `list_head` uses in the kernel. As i already wrote about, there are many, really many different places where lists are used in the kernel. Let's look for example in miscellaneous character drivers. Misc character drivers API from the [drivers/char/misc.c](https://github.com/torvalds/linux/blob/master/drivers/char/misc.c) for writing small drivers for handling simple hardware or virtual devices. This drivers share major number:
Let's look at some examples, how `list_head` is used in the kernel. As I already wrote about, there are many, really many different places where lists are used in the kernel. Let's look for example in miscellaneous character drivers. Misc character drivers API from the [drivers/char/misc.c](https://github.com/torvalds/linux/blob/master/drivers/char/misc.c) for writing small drivers for handling simple hardware or virtual devices. This drivers share major number:
```C
#define MISC_MAJOR 10
@ -205,7 +205,7 @@ int main() {
will print `2`.
The next point is `typeof`, it's simple. As you can understand from it's name, it just returns the type of the given varible. When I first time saw implementation of the `container_of` macro, the stranges thing for me was the zero in the `((type *)0)` expression. Actually this pointers magic calculates the offset of the given field from the address of the structure, but as we have `0` here, it will be just adds offset of the given field to zero. Let's look on the one simple example:
The next point is `typeof`, it's simple. As you can understand from its name, it just returns the type of the given varible. When I first time saw implementation of the `container_of` macro, the stranges thing for me was the zero in the `((type *)0)` expression. Actually this pointers magic calculates the offset of the given field from the address of the structure, but as we have `0` here, it will be just adds offset of the given field to zero. Let's look on the one simple example:
```C
#include <stdio.h>
@ -224,7 +224,7 @@ int main() {
will print `0x5`.
The next offsetof macro calculates offset from the beggining of the structure to the given structure's field. It's implementation very similar to the previous code:
The next offsetof macro calculates offset from the beginning of the structure to the given structure's field. Its implementation is very similar to the previous code:
```C
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

@ -1,7 +1,7 @@
# Kernel initialization process
You will see here a couple of posts which describes full cycle of the kernel initialization from the first steps after kernel decompressed to starting of the first process runned by kernel.
You will find here a couple of posts which describe the full cycle of kernel initialization from its first steps after the kernel has decompressed to the start of the first process run by the kernel itself.
* [First steps after kernel decompressed](https://github.com/0xAX/linux-insides/blob/master/Initialization/linux-initialization-1.md) - describes first steps in the kernel.
* [First steps after kernel decompression](https://github.com/0xAX/linux-insides/blob/master/Initialization/linux-initialization-1.md) - describes first steps in the kernel.
* [Early interupt and exception handling](https://github.com/0xAX/linux-insides/blob/master/Initialization/linux-initialization-2.md) - describes early interrupts initialization and early page fault handler.
* [Last preparations before kernel entry point](https://github.com/0xAX/linux-insides/blob/master/Initialization/linux-initialization-3.md) - describes the last preparations before the call of the `start_kernel`.
* [Last preparations before the kernel entry point](https://github.com/0xAX/linux-insides/blob/master/Initialization/linux-initialization-3.md) - describes the last preparations before the call of the `start_kernel`.

@ -33,7 +33,14 @@ GCC and GAS
* [GCC type attributes](https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html)
* [Assembler Directives](http://www.chemie.fu-berlin.de/chemnet/use/info/gas/gas_toc.html#TOC65)
Important data structures
--------------------------
* [task_struct definition](http://lxr.free-electrons.com/source/include/linux/sched.h#L1274)
Other architectures
------------------------
* [PowerPC and Linux Kernel Inside](http://www.systemcomputing.org/ppc/)

@ -10,15 +10,20 @@
* [First steps in the kernel](Initialization/linux-initialization-1.md)
* [Early interrupts handler](Initialization/linux-initialization-2.md)
* [Last preparations before the kernel entry point](Initialization/linux-initialization-3.md)
* [Kernel entry point]()
* [Continue architecture-specific boot-time initializations]()
* [Initial ram disk]()
* [initrd]()
* [Memory management](mm/README.md)
* [Memblock](mm/linux-mm-1.md)
* [Data Structures in the Linux Kernel](DataStructures/README.md)
* [Doubly linked list](DataStructures/dlist.md)
* [Concepts](Conecpts/README.md)
* [Per-CPU variables](Conecpts/per-cpu.md)
* [Cpumasks]()
* [Theory](Theory/README.md)
* [Paging](Theory/Paging.md)
* [Elf64](Theory/ELF.md)
* [Per-CPU variables](Theory/per-cpu.md)
* [Lockdep]()
* [CPUID]()
* [MSR]()
* [Misc]()

@ -0,0 +1,7 @@
# Theory
This chapter describes various concepts which are used in the Linux kernel.
* [Paging](http://0xax.gitbooks.io/linux-insides/content/Theory/Paging.html)
* [Elf64 format](http://0xax.gitbooks.io/linux-insides/content/Theory/ELF.html)
* [Per-CPU variables](http://0xax.gitbooks.io/linux-insides/content/Theory/per-cpu.html)

@ -32,4 +32,6 @@ Thank you to all contributors:
* [LYF610400210](https://github.com/LYF610400210)
* [Cam Cope](https://github.com/ccope)
* [Miquel Sabaté Solà](https://github.com/mssola)
* [Michael Aquilina](https://github.com/MichaelAquilina)
* [Gabriel Sullice](https://github.com/gabesullice)

@ -3,4 +3,4 @@
This chapter describes memory management in the linux kernel. You will see here a
couple of posts which describe different parts of the linux memory management framework:
* [Memblock](https://github.com/0xAX/linux-insides/blob/master/MM/linux-mm-1.md) - describes early `memblock` allocator.
* [Memblock](https://github.com/0xAX/linux-insides/blob/master/mm/linux-mm-1.md) - describes early `memblock` allocator.

@ -4,15 +4,15 @@ Linux kernel memory management Part 1.
Introduction
--------------------------------------------------------------------------------
Memory management is a one of the most complex (and i think that it is the most complex) parts of the operating system kernel. In the [last preparations before the kernel entry point](http://0xax.gitbooks.io/linux-insides/content/Initialization/linux-initialization-3.html) part we stopped right before call of the `start_kernel` function. This function makes initialization of the all kernel features (including architecture-dependent features) before the kernel will run first `init` process. You may remember as we built early page tables, identity page tables and fixmap page tables in the boot time. No compilcated memory management is working now. Now as `start_kernel` function called we will see the transition to the more complex data structures and techniques for memory management. For good understand initialization process of the linux kernel we need to have clear understanding of the techniques. This chapter will provide overview of the different parts of the linux kernel memory management framework and its API and we will start from the `memblock`.
Memory management is a one of the most complex (and I think that it is the most complex) parts of the operating system kernel. In the [last preparations before the kernel entry point](http://0xax.gitbooks.io/linux-insides/content/Initialization/linux-initialization-3.html) part we stopped right before call of the `start_kernel` function. This function initializes all the kernel features (including architecture-dependent features) before the kernel runs the first `init` process. You may remember as we built early page tables, identity page tables and fixmap page tables in the boot time. No compilcated memory management is working yet. When the `start_kernel` function is called we will see the transition to more complex data structures and techniques for memory management. For a good understanding of the initialization process in the linux kernel we need to have clear understanding of the techniques. This chapter will provide an overview of the different parts of the linux kernel memory management framework and its API, starting from the `memblock`.
Memblock
--------------------------------------------------------------------------------
Memblock is one of methods of managing memory regions during the early bootstrap period while when usual kernel memory allocators are not up and
running yet. Previously it was called - `Logical Memory Block`, but from the [patch](https://lkml.org/lkml/2010/7/13/68) by Yinghai Lu, it was renamed to the `memblock`. As Linux kernel for `x86_64` architecture uses this method. We already met `memblock` in the [Last preparations before the kernel entry point](http://0xax.gitbooks.io/linux-insides/content/Initialization/linux-initialization-3.html) part. And now time to get acquainted with it closer. We will see how it implemented.
Memblock is one of methods of managing memory regions during the early bootstrap period while the usual kernel memory allocators are not up and
running yet. Previously it was called - `Logical Memory Block`, but from the [patch](https://lkml.org/lkml/2010/7/13/68) by Yinghai Lu, it was renamed to the `memblock`. As Linux kernel for `x86_64` architecture uses this method. We already met `memblock` in the [Last preparations before the kernel entry point](http://0xax.gitbooks.io/linux-insides/content/Initialization/linux-initialization-3.html) part. And now time to get acquainted with it closer. We will see how it is implemented.
We will start to learn `memblock` from the data structures. Definitions of the all data structures you can find in the [include/linux/memblock.h](https://github.com/torvalds/linux/blob/master/include/linux/memblock.h) header file.
We will start to learn `memblock` from the data structures. Definitions of the all data structures can be found in the [include/linux/memblock.h](https://github.com/torvalds/linux/blob/master/include/linux/memblock.h) header file.
The first structure has the same name as this part and it is:
@ -28,7 +28,7 @@ struct memblock {
};
```
This structure contains five fields. First is `bottom_up` which allows to allocate memory in bottom-up mode when it is `true`. Next field is `current_limit`. This field describes the limit size of the memory block. The next three feilds describes the type of the memory block. It can be: reserved, memory andphysical memory if `CONFIG_HAVE_MEMBLOCK_PHYS_MAP` configuration option is enabled. Now we met yet another data structure - `memblock_type`. Let's look on its definition:
This structure contains five fields. First is `bottom_up` which allows to allocate memory in bottom-up mode when it is `true`. Next field is `current_limit`. This field describes the limit size of the memory block. The next three fields describes the type of the memory block. It can be: reserved, memory and physical memory if `CONFIG_HAVE_MEMBLOCK_PHYS_MAP` configuration option is enabled. Now we met yet another data structure - `memblock_type`. Let's look on its definition:
```C
struct memblock_type {

Loading…
Cancel
Save