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`, необходимо соблюсти следующие условия:
|
||||
|
||||
@ -354,14 +354,14 @@ cs = 0x1020
|
||||
cld
|
||||
```
|
||||
|
||||
Как я уже писал ранее, `grub2` загружает код настройки ядра по адресу `0x10000` (адрес по умолчанию) и `cs` по адресу `0x1020`, потому что выполнение не начинается с начала файла, а с инструкции `jump`:
|
||||
Как я уже писал ранее, `grub2` загружает код настройки ядра по адресу `0x1000` (адрес по умолчанию) и `cs` по адресу `0x1020`, потому что выполнение не начинается с начала файла, а с инструкции `jump`:
|
||||
|
||||
```assembly
|
||||
_start:
|
||||
.byte 0xeb
|
||||
.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
|
||||
pushw %ds
|
||||
@ -385,13 +385,13 @@ _start:
|
||||
|
||||
Это может привести к трём различны сценариям:
|
||||
|
||||
* `ss` имеет верное значение `0x10000` (как и все остальные сегментные регистры рядом с `cs`)
|
||||
* `ss` имеет верное значение `0x1000` (как и все остальные сегментные регистры рядом с `cs`)
|
||||
* `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
|
||||
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