mirror of
https://github.com/0xAX/linux-insides
synced 2024-11-19 15:25:41 +00:00
Исправление форматирования констант
This commit is contained in:
parent
bdc548b809
commit
ab0e47ad65
@ -31,7 +31,7 @@ IP 0xfff0
|
||||
CS selector 0xf000
|
||||
CS base 0xffff0000
|
||||
```
|
||||
Процессор начинает свою работу в [режиме реальных адресов](https://en.wikipedia.org/wiki/Real_mode). Давайте немного задержимся и попытаемся понять сегментацию памяти в этом режиме. Режим реальных адресов поддерживается всеми x86-совместимыми процессорами, от [8086](https://en.wikipedia.org/wiki/Intel_8086) до самых новых 64-битных ЦПУ Intel. Процессор 8086 имел 20-битную шину адреса, т.е. он мог работать с адресным пространством в диапазоне 0-0xFFFFF (1 мегабайт). Но регистры у него были только 16-битные, а в таком случае максимальный размер адресуемой памяти составляет 2^16 - 1 или 0xffff (64 килобайта). [Сегментация памяти](http://en.wikipedia.org/wiki/Memory_segmentation) используется для того, чтобы задействовать всё доступное адресное пространство. Вся память делится на небольшие, фиксированного размера сегменты по 65536 байт (64 Кб). Поскольку мы не можем адресовать память свыше 64 Кб с помощью 16-битных регистров, был придуман альтернативный метод. Адрес состоит из двух частей: селектора сегмента, который содержит базовый адрес, и смещение от этого базового адреса. В режиме реальных адресов базовый адрес селектора сегмента это `Селектор Сегмента * 16`. Таким образом, чтобы получить физический адрес в памяти, нужно умножить селектор сегмента на 16 и прибавить смещение:
|
||||
Процессор начинает свою работу в [режиме реальных адресов](https://en.wikipedia.org/wiki/Real_mode). Давайте немного задержимся и попытаемся понять сегментацию памяти в этом режиме. Режим реальных адресов поддерживается всеми x86-совместимыми процессорами, от [8086](https://en.wikipedia.org/wiki/Intel_8086) до самых новых 64-битных ЦПУ Intel. Процессор 8086 имел 20-битную шину адреса, т.е. он мог работать с адресным пространством в диапазоне 0-0xFFFFF (1 мегабайт). Но регистры у него были только 16-битные, а в таком случае максимальный размер адресуемой памяти составляет `2^16 - 1` или `0xffff` (64 килобайта). [Сегментация памяти](http://en.wikipedia.org/wiki/Memory_segmentation) используется для того, чтобы задействовать всё доступное адресное пространство. Вся память делится на небольшие, фиксированного размера сегменты по 65536 байт (64 Кб). Поскольку мы не можем адресовать память свыше 64 Кб с помощью 16-битных регистров, был придуман альтернативный метод. Адрес состоит из двух частей: селектора сегмента, который содержит базовый адрес, и смещение от этого базового адреса. В режиме реальных адресов базовый адрес селектора сегмента это `Селектор Сегмента * 16`. Таким образом, чтобы получить физический адрес в памяти, нужно умножить селектор сегмента на 16 и прибавить смещение:
|
||||
|
||||
```
|
||||
Физический адрес = Селектор сегмента * 16 + Смещение
|
||||
@ -56,7 +56,7 @@ CS base 0xffff0000
|
||||
Хорошо, теперь мы знаем о режиме реальных адресов и адресации памяти. Давайте вернёмся к обсуждению значений регистров после сброса.
|
||||
|
||||
Регистр `CS` состоит из двух частей: видимый селектор сегмента и скрытый базовый адрес.
|
||||
В то время как базовый адрес, как правило, формируется путём умножения значения селектора сегмента на 16, во время аппаратного перезапуска в селектор сегмента в регистре `CS` записывается 0xf000, а в базовый адрес - 0xffff0000. Процессор использует этот специальный базовый адрес, пока регистр `CS` не изменится.
|
||||
В то время как базовый адрес, как правило, формируется путём умножения значения селектора сегмента на 16, во время аппаратного перезапуска в селектор сегмента в регистре `CS` записывается `0xf000`, а в базовый адрес - `0xffff0000`. Процессор использует этот специальный базовый адрес, пока регистр `CS` не изменится.
|
||||
|
||||
Начальный адрес формируется путём добавления базового адреса к значению в регистре `EIP`:
|
||||
|
||||
@ -77,7 +77,7 @@ reset_vector:
|
||||
...
|
||||
```
|
||||
|
||||
Здесь мы можем видеть [опкод инструкции jmp](http://ref.x86asm.net/coder32.html#xE9) - 0xe9, и его адрес назначения `_start - ( . + 2)`. Мы также можем видеть, что секция `reset` занимает 16 байт и начинается с `0xfffffff0`:
|
||||
Здесь мы можем видеть [опкод инструкции jmp](http://ref.x86asm.net/coder32.html#xE9) - `0xe9`, и его адрес назначения `_start - ( . + 2)`. Мы также можем видеть, что секция `reset` занимает 16 байт и начинается с `0xfffffff0`:
|
||||
|
||||
```
|
||||
SECTIONS {
|
||||
@ -373,13 +373,13 @@ _start:
|
||||
|
||||
Это может привести к трём различны сценариям:
|
||||
|
||||
* `ss` имеет верное значение 0x10000 (как и все остальные сегментные регистры рядом с `cs`)
|
||||
* `ss` имеет верное значение `0x10000` (как и все остальные сегментные регистры рядом с `cs`)
|
||||
* `ss` является некорректным и установлен флаг `CAN_USE_HEAP` (см. ниже)
|
||||
* `ss` является некорректным и флаг `CAN_USE_HEAP` не установлен (см. ниже)
|
||||
|
||||
Давайте рассмотрим все три сценария:
|
||||
|
||||
* `ss` имеет верный адрес (0x10000). В этом случае мы переходим на метку [2](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S#L481):
|
||||
* `ss` имеет верный адрес (`0x10000`). В этом случае мы переходим на метку [2](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S#L481):
|
||||
|
||||
```assembly
|
||||
2: andw $~3, %dx
|
||||
|
Loading…
Reference in New Issue
Block a user