Update linux-bootstrap-1.md

This commit is contained in:
proninyaroslav 2018-08-01 20:28:41 +03:00
parent 37b402f157
commit 464643eb1f

View File

@ -163,7 +163,7 @@ objdump -D -b binary -mi386 -Maddr16,data16,intel boot
где `0x10ffef` равен `1 Мб + 64 Кб - 16 байт`. Процессор [8086](https://en.wikipedia.org/wiki/Intel_8086) (который был первым процессором с режимом реальных адресов), в отличии от этого, имеет 20-битную шину адресации. Поскольку `2^20 = 1048576` это 1 Мб, получается, что фактический объём доступной памяти составляет 1 Мб.
Основная карта разделов в режиме реальных адресов выглядит следующим образом:
В целом, карта разделов в режиме реальных адресов выглядит следующим образом:
```
0x00000000 - 0x000003FF - Таблица векторов прерываний
@ -209,7 +209,7 @@ hdr:
boot_flag: .word 0xAA55
```
Загрузчик должен заполнить этот и другие заголовки (которые помеченные как тип `write` в протоколе загрузки Linux, например, в [данном примере](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/Documentation/x86/boot.txt#L354)) значениями, которые он получил из командной строки или значениями, вычисленными во время загрузки. (Мы не будет вдаваться в подробности и описывать все поля заголовка ядра, но, когда он будет их использовать, вернёмся к этому; тем не менее вы можете найти полное описание всех полей в [протоколе загрузки](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/Documentation/x86/boot.txt#L156).)
Загрузчик должен заполнить этот и другие заголовки (которые помеченные как тип `write` в протоколе загрузки Linux, например, в [данном примере](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/Documentation/x86/boot.txt#L354)) значениями, которые он получил из командной строки или значениями, вычисленными во время загрузки. (Мы не будет вдаваться в подробности и описывать все поля заголовка ядра, но мы сделаем это, когда будем обсуждать как их использует ядро; тем не менее вы можете найти полное описание всех полей в [протоколе загрузки](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/Documentation/x86/boot.txt#L156).)
Как мы видим из протокола, после загрузки ядра карта распределения памяти будет выглядеть следующим образом:
@ -249,9 +249,9 @@ X + sizeof(KernelBootSector) + 1
Сейчас загрузчик поместил ядро Linux в память, заполнил поля заголовка, а затем переключился на него. Теперь мы можем перейти непосредственно к коду настройки ядра.
Запуск настройки ядра
Начальный этап настройки ядра
--------------------------------------------------------------------------------
Наконец, мы находимся в ядре! Технически, ядро ещё не работает; во-первых, часть ядра, отвественная за настройку, должна подготовить такие вещи как декомпрессор, вещи связанные с управлением памятью и т.д. После всех подготовок код настройки ядра должен распаковывать фактическое ядро и совершить переход на него. Выполнение настройки начинается в файле [arch/x86/boot/header.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S), начиная с метки [_start](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S#L292). Это немного странно на первый взгляд, так как перед этим есть ещё несколько инструкций.
Наконец, мы находимся в ядре! Технически, ядро ещё не работает; во-первых, часть ядра, отвественная за настройку, должна подготовить декомпрессор, вещи связанные с управлением памятью и т.д. После всех подготовок код настройки ядра должен распаковывать фактическое ядро и совершить переход на него. Выполнение настройки начинается в файле [arch/x86/boot/header.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S), начиная с метки [_start](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S#L292). Это немного странно на первый взгляд, так как перед этим есть ещё несколько инструкций.
Давным-давно у Linux был свой загрузчик, но сейчас, если вы запустите, например:
@ -289,7 +289,7 @@ pe_header:
_start:
```
Загрузчик (grub2 или другой) знает об этой метке (смещение `0x200` от `MZ`) и сразу переходит на неё, несмотря на то, что `header.S` начинается с секции `.bstext`, который выводит сообщение об ошибке:
Загрузчик (grub2 или другой) знает об этой метке (при смещении `0x200` от `MZ`) и сразу переходит на неё, несмотря на то, что `header.S` начинается с секции `.bstext`, который выводит сообщение об ошибке:
```
//
@ -353,14 +353,14 @@ cs = 0x1020
cld
```
Как я уже писал ранее, `grub2` загружает код настройки ядра по адресу `0x1000` (адрес по умолчанию) и `cs` по адресу `0x1020`, потому что выполнение не начинается с начала файла, а с инструкции `jump`:
Как я уже писал ранее, `grub2` загружает код настройки ядра по адресу `0x1000` (адрес по умолчанию) и `cs` по адресу `0x1020`, потому что выполнение не начинается с начала файла, а с метки `_start`:
```assembly
_start:
.byte 0xeb
.byte start_of_setup-1f
```
расположеной по смещению в `512` байт от [4d 5a](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S#L46). Также необходимо выровнять `cs` с `0x1020` на `0x1000`, а также остальные сегментные регистры. После этого мы настраиваем стек:
расположеной в `512` байтах от [4d 5a](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S#L46). Нам также необходимо выровнять `cs` с `0x1020` на `0x1000` и остальные сегментные регистры. После этого мы настраиваем стек:
```assembly
pushw %ds