mirror of
https://github.com/0xAX/linux-insides.git
synced 2025-07-05 16:52:33 +00:00
Исправления linux-bootstrap-1.md
This commit is contained in:
parent
a688cc9077
commit
1003ae3547
@ -332,7 +332,7 @@ cs = 0x1020
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
В моём случае, ядро загружается в `0x10000`.
|
В моём случае, ядро загружается по адресу `0x10000`.
|
||||||
|
|
||||||
После перехода на метку `start_of_setup`, необходимо соблюсти следующие условия:
|
После перехода на метку `start_of_setup`, необходимо соблюсти следующие условия:
|
||||||
|
|
||||||
@ -354,14 +354,14 @@ cs = 0x1020
|
|||||||
cld
|
cld
|
||||||
```
|
```
|
||||||
|
|
||||||
Как я уже писал ранее, `grub2` загружает код настройки ядра по адресу `0x10000` (адрес по умолчанию) и `cs` по адресу `0x1020`, потому что выполнение не начинается с начала файла, а с инструкции `jump`:
|
Как я уже писал ранее, `grub2` загружает код настройки ядра по адресу `0x1000` (адрес по умолчанию) и `cs` по адресу `0x1020`, потому что выполнение не начинается с начала файла, а с инструкции `jump`:
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
_start:
|
_start:
|
||||||
.byte 0xeb
|
.byte 0xeb
|
||||||
.byte start_of_setup-1f
|
.byte start_of_setup-1f
|
||||||
```
|
```
|
||||||
расположеной по смещению в `512` байт от [4d 5a](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S#L46). Также необходимо выровнять `cs` с `0x10200` на `0x10000`, а также остальные сегментные регистры. После этого мы настраиваем стек:
|
расположеной по смещению в `512` байт от [4d 5a](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S#L46). Также необходимо выровнять `cs` с `0x1020` на `0x1000`, а также остальные сегментные регистры. После этого мы настраиваем стек:
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
pushw %ds
|
pushw %ds
|
||||||
@ -385,13 +385,13 @@ _start:
|
|||||||
|
|
||||||
Это может привести к трём различны сценариям:
|
Это может привести к трём различны сценариям:
|
||||||
|
|
||||||
* `ss` имеет верное значение `0x10000` (как и все остальные сегментные регистры рядом с `cs`)
|
* `ss` имеет верное значение `0x1000` (как и все остальные сегментные регистры рядом с `cs`)
|
||||||
* `ss` является некорректным и установлен флаг `CAN_USE_HEAP` (см. ниже)
|
* `ss` является некорректным и установлен флаг `CAN_USE_HEAP` (см. ниже)
|
||||||
* `ss` является некорректным и флаг `CAN_USE_HEAP` не установлен (см. ниже)
|
* `ss` является некорректным и флаг `CAN_USE_HEAP` не установлен (см. ниже)
|
||||||
|
|
||||||
Давайте рассмотрим все три сценария:
|
Давайте рассмотрим все три сценария:
|
||||||
|
|
||||||
* `ss` имеет верный адрес (`0x10000`). В этом случае мы переходим на метку [2](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S#L588):
|
* `ss` имеет верный адрес (`0x1000`). В этом случае мы переходим на метку [2](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S#L588):
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
2: andw $~3, %dx
|
2: andw $~3, %dx
|
||||||
@ -403,7 +403,7 @@ _start:
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Здесь мы видим выравнивание сегмента `dx` (содержащего значение `sp`, полученное загрузчиком) до 4 байт и проверку - является ли полученное значение нулём. Если ноль, то помещаем `0xfffx` (выровненный до `4` байт адрес до максимального значения сегмента в 64 Кб) в `dx`. Если не ноль, продолжаем использовать `sp`, полученный от загрузчика (в моём случае `0xf7f4`). После этого мы помещаем значение `ax` в `ss`, который хранит корректный адрес сегмента `0x10000` и устанавливает корректное значение `sp`. Теперь мы имеем корректный стек:
|
Здесь мы видим выравнивание сегмента `dx` (содержащего значение `sp`, полученное загрузчиком) до 4 байт и проверку - является ли полученное значение нулём. Если ноль, то помещаем `0xfffx` (выровненный до `4` байт адрес до максимального значения сегмента в 64 Кб) в `dx`. Если не ноль, продолжаем использовать `sp`, полученный от загрузчика (в моём случае `0xf7f4`). После этого мы помещаем значение `ax` в `ss`, который хранит корректный адрес сегмента `0x1000` и устанавливает корректное значение `sp`. Теперь мы имеем корректный стек:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user