From c27b4dced5af0c6e5ebff43af95a2d24c4b5831a Mon Sep 17 00:00:00 2001 From: proninyaroslav Date: Sun, 5 Aug 2018 13:42:19 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D1=82=D0=BE=D1=87=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B0=D0=B4=D1=80=D0=B5=D1=81=D0=B0=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Booting/linux-bootstrap-1.md | 5 +---- Booting/linux-bootstrap-3.md | 12 +++++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Booting/linux-bootstrap-1.md b/Booting/linux-bootstrap-1.md index 1aade8c..18cc32b 100644 --- a/Booting/linux-bootstrap-1.md +++ b/Booting/linux-bootstrap-1.md @@ -325,16 +325,13 @@ state.gs = state.fs = state.es = state.ds = state.ss = segment; state.cs = segment + 0x20; ``` -Это означает, что после начала настройки ядра регистры сегмента будут иметь следующие значения: +В моём случае, ядро загружается по адресу `0x10000`. Это означает, что после начала настройки ядра регистры сегмента будут иметь следующие значения: ``` gs = fs = es = ds = ss = 0x1000 cs = 0x1020 ``` - -В моём случае, ядро загружается по адресу `0x10000`. - После перехода на метку `start_of_setup`, необходимо соблюсти следующие условия: * Убедиться, что все значения всех сегментных регистров равны diff --git a/Booting/linux-bootstrap-3.md b/Booting/linux-bootstrap-3.md index c7f2bc1..1fa713b 100644 --- a/Booting/linux-bootstrap-3.md +++ b/Booting/linux-bootstrap-3.md @@ -443,9 +443,9 @@ Aligned - 16 `GDT_ENTRY` - это макрос, который принимает флаги, базовый адрес, предел и создаёт запись в GDT. Для примера посмотрим на запись сегмента кода. `GDT_ENTRY` принимает следующие значения: -* базовый адрес - 0 -* предел - 0xfffff -* флаги - 0xc09b +* базовый адрес - `0` +* предел - `0xfffff` +* флаги - `0xc09b` Что это значит? Базовый адрес сегмента равен 0, а предел (размер сегмента) равен `0xffff` (1 Мб). Давайте посмотрим на флаги. В двоичном виде значение `0xc09b` будет выглядеть следующим образом: @@ -506,7 +506,9 @@ protected_mode_jump(boot_params.hdr.code32_start, (u32)&boot_params + (ds() << 4 Давайте заглянем внутрь `protected_mode_jump`. Как я уже писал выше, вы можете найти его в `arch/x86/boot/pmjump.S`. Первый параметр находится в регистре `eax`, второй в `edx`. -В первую очередь мы помещаем адрес `boot_params` в регистр `esi` и адрес регистра сегмента кода `cs` (0x1000) в `bx`. Далее мы сдвигаем `bx` на 4 бита и добавляем к нему адрес метки `2` (после этого мы будем иметь физический адрес метки `2` в `bx`) и переходим на метку `1`. Далее мы помещаем сегмент данных и сегмент состояния задачи в регистры `cs` и `di`: +В первую очередь мы помещаем адрес `boot_params` в регистр `esi` и адрес регистра сегмента кода `cs` в `bx`. Далее мы сдвигаем `bx` на 4 бита и добавляем к нему адрес метки `2` (`(cs << 4) + in_pm32`, физический адрес для "прыжка" после перехода в 32-битный режим) и переходим на метку `1`. После этого `in_pm32` в метке `2` будет перезаписан следующим образом: `(cs << 4) + in_pm32`. + +Далее мы помещаем сегмент данных и сегмент состояния задачи в регистры `cx` и `di`: ```assembly movw $__BOOT_DS, %cx @@ -535,7 +537,7 @@ movl %edx, %cr0 * `0x66` - префикс размера операнда, который позволяет смешивать как 16-битный, так и 32-битный код, * `0xea` - опкод инструкции перехода, -* `in_pm32` - смещение сегмента +* `in_pm32` - смещение сегмента или `(cs << 4) + in_pm` * `__BOOT_CS` - сегмент кода, на который мы хотим перейти. После этого мы наконец-то в защищённом режиме: