From 6b4aa3e3d6d1e0b308b83d2c08022f8423d0bc5c Mon Sep 17 00:00:00 2001 From: Aleksey Lagoshin Date: Sat, 30 Dec 2017 00:34:36 +0200 Subject: [PATCH 1/2] Fixed mistakes in the segment descriptors part --- Booting/linux-bootstrap-2.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Booting/linux-bootstrap-2.md b/Booting/linux-bootstrap-2.md index c175353..d4628ad 100644 --- a/Booting/linux-bootstrap-2.md +++ b/Booting/linux-bootstrap-2.md @@ -60,21 +60,24 @@ where the `lgdt` instruction loads the base address and limit(size) of global de As mentioned above the GDT contains `segment descriptors` which describe memory segments. Each descriptor is 64-bits in size. The general scheme of a descriptor is: ``` -31 24 19 16 7 0 + 63 56 51 48 45 39 32 ------------------------------------------------------------ | | |B| |A| | | | |0|E|W|A| | -| BASE 31:24 |G|/|L|V| LIMIT |P|DPL|S| TYPE | BASE 23:16 | 4 +| BASE 31:24 |G|/|L|V| LIMIT |P|DPL|S| TYPE | BASE 23:16 | | | |D| |L| 19:16 | | | |1|C|R|A| | +------------------------------------------------------------ + + 31 16 15 0 ------------------------------------------------------------ | | | -| BASE 15:0 | LIMIT 15:0 | 0 +| BASE 15:0 | LIMIT 15:0 | | | | ------------------------------------------------------------ ``` -Don't worry, I know it looks a little scary after real mode, but it's easy. For example LIMIT 15:0 means that bit 0-15 of the Descriptor contain the value for the limit. The rest of it is in LIMIT 19:16. So, the size of Limit is 0-19 i.e 20-bits. Let's take a closer look at it: +Don't worry, I know it looks a little scary after real mode, but it's easy. For example LIMIT 15:0 means that bits 0-15 of Limit are located in the beginning of the Descriptor. The rest of it is in LIMIT 19:16, which is located at bits 48-51 of the Descriptor. So, the size of Limit is 0-19 i.e 20-bits. Let's take a closer look at it: -1. Limit[20-bits] is at 0-15,16-19 bits. It defines `length_of_segment - 1`. It depends on `G`(Granularity) bit. +1. Limit[20-bits] is at 0-15, 48-51 bits. It defines `length_of_segment - 1`. It depends on `G`(Granularity) bit. * if `G` (bit 55) is 0 and segment limit is 0, the size of the segment is 1 Byte * if `G` is 1 and segment limit is 0, the size of the segment is 4096 Bytes @@ -85,9 +88,9 @@ Don't worry, I know it looks a little scary after real mode, but it's easy. For * if G is 0, Limit is interpreted in terms of 1 Byte and the maximum size of the segment can be 1 Megabyte. * if G is 1, Limit is interpreted in terms of 4096 Bytes = 4 KBytes = 1 Page and the maximum size of the segment can be 4 Gigabytes. Actually, when G is 1, the value of Limit is shifted to the left by 12 bits. So, 20 bits + 12 bits = 32 bits and 232 = 4 Gigabytes. -2. Base[32-bits] is at (0-15, 32-39 and 56-63 bits). It defines the physical address of the segment's starting location. +2. Base[32-bits] is at 16-31, 32-39 and 56-63 bits. It defines the physical address of the segment's starting location. -3. Type/Attribute (40-47 bits) defines the type of segment and kinds of access to it. +3. Type/Attribute[5-bits] is at 40-44 bits. It defines the type of segment and kinds of access to it. * `S` flag at bit 44 specifies descriptor type. If `S` is 0 then this segment is a system segment, whereas if `S` is 1 then this is a code or data segment (Stack segments are data segments which must be read/write segments). To determine if the segment is a code or data segment we can check its Ex(bit 43) Attribute marked as 0 in the above diagram. If it is 0, then the segment is a Data segment otherwise it is a code segment. @@ -138,7 +141,7 @@ As we can see the first bit(bit 43) is `0` for a _data_ segment and `1` for a _c Segment registers contain segment selectors as in real mode. However, in protected mode, a segment selector is handled differently. Each Segment Descriptor has an associated Segment Selector which is a 16-bit structure: ``` -15 3 2 1 0 + 15 3 2 1 0 ----------------------------- | Index | TI | RPL | ----------------------------- From 163ba61dbe5802ba5e815fbeaca6a3ec28f642b3 Mon Sep 17 00:00:00 2001 From: proninyaroslav Date: Wed, 1 Aug 2018 19:48:02 +0300 Subject: [PATCH 2/2] Replace invalid links to the images --- Misc/linux-misc-1.md | 14 +++++++------- SysCall/linux-syscall-4.md | 12 ++++++------ Timers/linux-timers-1.md | 2 +- Timers/linux-timers-4.md | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Misc/linux-misc-1.md b/Misc/linux-misc-1.md index cccf2bb..381095a 100644 --- a/Misc/linux-misc-1.md +++ b/Misc/linux-misc-1.md @@ -10,11 +10,11 @@ After writing some assembler code I began to understand how my program looks aft I'm writing this part nine and a half months after I've started to learn from the source code of the Linux kernel and published the first [part](https://0xax.gitbooks.io/linux-insides/content/Booting/linux-bootstrap-1.html) of this book. Now it contains forty parts and it is not the end. I decided to write this series about the Linux kernel mostly for myself. As you know the Linux kernel is very huge piece of code and it is easy to forget what does this or that part of the Linux kernel mean and how does it implement something. But soon the [linux-insides](https://github.com/0xAX/linux-insides) repo became popular and after nine months it has `9096` stars: -![github](http://s2.postimg.org/jjb3s4frt/stars.png) +![github](http://i63.tinypic.com/2lbgc9f.png) It seems that people are interested in the insides of the Linux kernel. Besides this, in all the time that I have been writing `linux-insides`, I have received many questions from different people about how to begin contributing to the Linux kernel. Generally people are interested in contributing to open source projects and the Linux kernel is not an exception: -![google-linux](http://s4.postimg.org/yg9z5zx0d/google_linux.png) +![google-linux](http://i64.tinypic.com/2j4ot5e.png) So, it seems that people are interested in the Linux kernel development process. I thought it would be strange if a book about the Linux kernel would not contain a part describing how to take a part in the Linux kernel development and that's why I decided to write it. You will not find information about why you should be interested in contributing to the Linux kernel in this part. But if you are interested how to start with Linux kernel development, this part is for you. @@ -102,7 +102,7 @@ $ cat /proc/config.gz | gunzip > ~/dev/linux/.config If you are not satisfied with the standard kernel configuration that is provided by the maintainers of your distro, you can configure the Linux kernel manually. There are a couple of ways to do it. The Linux kernel root [Makefile](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/Makefile) provides a set of targets that allows you to configure it. For example `menuconfig` provides a menu-driven interface for the kernel configuration: -![menuconfig](http://s21.postimg.org/zcz48p7yf/menucnonfig.png) +![menuconfig](http://i64.tinypic.com/zn5zbq.png) The `defconfig` argument generates the default kernel configuration file for the current architecture, for example [x86_64 defconfig](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/configs/x86_64_defconfig). You can pass the `ARCH` command line argument to `make` to build `defconfig` for the given architecture: @@ -112,7 +112,7 @@ $ make ARCH=arm64 defconfig The `allnoconfig`, `allyesconfig` and `allmodconfig` arguments allow you to generate a new configuration file where all options will be disabled, enabled, and enabled as modules respectively. The `nconfig` command line arguments that provides `ncurses` based program with menu to configure Linux kernel: -![nconfig](http://s29.postimg.org/hpghikp4n/nconfig.png) +![nconfig](http://i68.tinypic.com/jjmlfn.png) And even `randconfig` to generate random Linux kernel configuration file. I will not write about how to configure the Linux kernel or which options to enable because it makes no sense to do so for two reasons: First of all I do not know your hardware and second, if you know your hardware, the only remaining task is to find out how to use programs for kernel configuration, and all of them are pretty simple to use. @@ -224,7 +224,7 @@ $ make -j4 `busybox` is an executable file - `/bin/busybox` that contains a set of standard tools like [coreutils](https://en.wikipedia.org/wiki/GNU_Core_Utilities). In the `busysbox` menu we need to enable: `Build BusyBox as a static binary (no shared libs)` option: -![busysbox menu](http://s18.postimg.org/sj92uoweh/busybox.png) +![busysbox menu](http://i68.tinypic.com/11933bp.png) We can find this menu in the: @@ -273,7 +273,7 @@ We can now run our kernel in the virtual machine. As I already wrote I prefer [q $ qemu-system-x86_64 -snapshot -m 8GB -serial stdio -kernel ~/dev/linux/arch/x86_64/boot/bzImage -initrd ~/dev/initrd_x86_64.gz -append "root=/dev/sda1 ignore_loglevel" ``` -![qemu](http://s22.postimg.org/b8ttyigup/qemu.png) +![qemu](http://i67.tinypic.com/15i6law.png) From now we can run the Linux kernel in the virtual machine and this means that we can begin to change and test the kernel. @@ -330,7 +330,7 @@ Device Drivers ----> Digi EPCA PCI products ``` -![dgap menu](http://s4.postimg.org/d3pozpge5/digi.png) +![dgap menu](http://i65.tinypic.com/v8o5rs.png) Now is time to make commit. I'm using following combination for this: diff --git a/SysCall/linux-syscall-4.md b/SysCall/linux-syscall-4.md index 1d800b6..9190591 100644 --- a/SysCall/linux-syscall-4.md +++ b/SysCall/linux-syscall-4.md @@ -20,7 +20,7 @@ There are many different ways to launch an application from a user perspective. In this part we will consider the way when we just launch an application from the shell. As you know, the standard way to launch an application from shell is the following: We just launch a [terminal emulator](https://en.wikipedia.org/wiki/Terminal_emulator) application and just write the name of the program and pass or not arguments to our program, for example: -![ls shell](http://s14.postimg.org/d6jgidc7l/Screenshot_from_2015_09_07_17_31_55.png) +![ls shell](http://i66.tinypic.com/214w6so.jpg) Let's consider what does occur when we launch an application from the shell, what does shell do when we write program name, what does Linux kernel do etc. But before we will start to consider these interesting things, I want to warn that this book is about the Linux kernel. That's why we will see Linux kernel insides related stuff mostly in this part. We will not consider in details what does shell do, we will not consider complex cases, for example subshells etc. @@ -52,7 +52,7 @@ execve (command, args, env); The `execve` system call has the following signature: ``` -int execve(const char *filename, char *const argv [], char *const envp[]); +int execve(const char *filename, char *const argv [], char *const envp[]); ``` and executes a program by the given filename, with the given arguments and [environment variables](https://en.wikipedia.org/wiki/Environment_variable). This system call is the first in our case and only, for example: @@ -299,8 +299,8 @@ int search_binary_handler(struct linux_binprm *bprm) return retval; } } - - return retval; + + return retval; ``` Where the `load_binary` for example for the [elf](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) checks the magic number (each `elf` binary file contains magic number in the header) in the `linux_bprm` buffer (remember that we read first `128` bytes from the executable binary file): and exit if it is not `elf` binary: @@ -406,7 +406,7 @@ Links * [System call](https://en.wikipedia.org/wiki/System_call) * [shell](https://en.wikipedia.org/wiki/Unix_shell) * [bash](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29) -* [entry point](https://en.wikipedia.org/wiki/Entry_point) +* [entry point](https://en.wikipedia.org/wiki/Entry_point) * [C](https://en.wikipedia.org/wiki/C_%28programming_language%29) * [environment variables](https://en.wikipedia.org/wiki/Environment_variable) * [file descriptor](https://en.wikipedia.org/wiki/File_descriptor) @@ -420,7 +420,7 @@ Links * [#!](https://en.wikipedia.org/wiki/Shebang_%28Unix%29) * [elf](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) * [a.out](https://en.wikipedia.org/wiki/A.out) -* [flat](https://en.wikipedia.org/wiki/Binary_file#Structure) +* [flat](https://en.wikipedia.org/wiki/Binary_file#Structure) * [Alpha](https://en.wikipedia.org/wiki/DEC_Alpha) * [FDPIC](http://elinux.org/UClinux_Shared_Library#FDPIC_ELF) * [segments](https://en.wikipedia.org/wiki/Memory_segmentation) diff --git a/Timers/linux-timers-1.md b/Timers/linux-timers-1.md index 8f4d05d..5b75636 100644 --- a/Timers/linux-timers-1.md +++ b/Timers/linux-timers-1.md @@ -259,7 +259,7 @@ The `jiffies` clock source uses the `NSEC_PER_JIFFY` multiplier conversion to sp Where `CONFIG_HZ` can be one of the following values: -![HZ](http://s9.postimg.org/xy85r3jrj/image.png) +![HZ](http://i63.tinypic.com/v8d6ph.png) This means that in our case the timer interrupt frequency is `250 HZ` or occurs `250` times per second or one timer interrupt each `4ms`. diff --git a/Timers/linux-timers-4.md b/Timers/linux-timers-4.md index e8e8e09..6a71270 100644 --- a/Timers/linux-timers-4.md +++ b/Timers/linux-timers-4.md @@ -117,7 +117,7 @@ struct tvec_root { type. Note that the value of the `TVR_SIZE` depends on the `CONFIG_BASE_SMALL` kernel configuration option: -![base small](http://s17.postimg.org/db3towlu7/base_small.png) +![base small](http://i68.tinypic.com/aylkt2.png) that reduces size of the kernel data structures if disabled. The `v1` is array that may contain `64` or `256` elements where an each element represents a dynamic timer that will decay within the next `255` system timer interrupts. Next three fields: `tv2`, `tv3` and `tv4` are lists with dynamic timers too, but they store dynamic timers which will decay the next `2^14 - 1`, `2^20 - 1` and `2^26` respectively. The last `tv5` field represents list which stores dynamic timers with a large expiring period.