1
0
mirror of https://github.com/0xAX/linux-insides.git synced 2024-11-16 04:59:13 +00:00

Уточнения адреса загрузки

This commit is contained in:
proninyaroslav 2018-08-05 13:42:19 +03:00
parent 1a0d714f8e
commit c27b4dced5
2 changed files with 8 additions and 9 deletions

View File

@ -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`, необходимо соблюсти следующие условия:
* Убедиться, что все значения всех сегментных регистров равны

View File

@ -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` - сегмент кода, на который мы хотим перейти.
После этого мы наконец-то в защищённом режиме: