mirror of
https://github.com/0xAX/linux-insides.git
synced 2025-07-04 00:02:33 +00:00
Обновление ссылки с корректным номером строки
This commit is contained in:
parent
1526623107
commit
fd1b5f25c3
@ -32,7 +32,7 @@
|
||||
* Сегментация
|
||||
* Подкачка страниц
|
||||
|
||||
Здесь мы будем рассматривать только сегментацию. Подкачка страниц будет обсуждаться в следующих разделах.
|
||||
Здесь мы будем рассматривать только сегментацию. Подкачка страниц будет обсуждаться в следующих разделах.
|
||||
|
||||
Как вы можете помнить из предыдущей части, адреса в режиме реальных адресов состоят из двух частей:
|
||||
|
||||
@ -80,15 +80,15 @@ lgdt gdt
|
||||
* Если `G` равен 1, а предел сегмента равен 0xfffff, то размер сегмента составляет 4 гигабайта
|
||||
|
||||
Таким образом, если
|
||||
|
||||
|
||||
* G равен 0, предел интерпретируется в терминах 1 байта, а максимальный размер сегмента может составлять 1 мегабайт.
|
||||
* G равен 1, предел интерпретируется в терминах 4096 байт = 4 килобайта = 1 страница, а максимальный размер сегмента может составлять 4 гигабайта. На самом деле, когда G равен 1, значение предела сдвигается на 12 бит влево. Таким образом, 20 бит + 12 бит = 32 бита и 2<sup>32</sup> = 4 гигабайта.
|
||||
|
||||
2. Базовый адрес (32 бита) находится в пределах 0-15, 32-39 и 56-63 бит. Он определяет физический адрес начального расположения сегмента.
|
||||
|
||||
3. Тип/Атрибут (40-47 бит) определяет тип сегмента и виды доступа к нему.
|
||||
3. Тип/Атрибут (40-47 бит) определяет тип сегмента и виды доступа к нему.
|
||||
* Флаг `S` (бит 44) определяет тип дескриптора. Если `S` равен 0, то этот сегмент является системным сегментом, а если `S` равен 1, то этот сегмент является сегментом кода или сегментом данных (сегменты стека являются сегментами данных, которые должны быть сегментами для чтения/записи).
|
||||
|
||||
|
||||
Для того чтобы определить, является ли сегмент сегментом кода или сегментом данных, мы можем проверить атрибут (бит 43), обозначенный как 0 в приведённой выше схеме. Если он равен 0, то сегмент является сегментом данных, в противном случае это сегмент кода.
|
||||
|
||||
Сегмент может быть одного из следующих типов:
|
||||
@ -154,7 +154,7 @@ lgdt gdt
|
||||
|
||||
* Видимая - здесь хранится селектор сегмента
|
||||
* Скрытая - дескриптор сегмента (базовый адрес, предел, атрибуты, флаги)
|
||||
|
||||
|
||||
Необходимы следующие шаги, чтобы получить физический адрес в защищённом режиме:
|
||||
|
||||
* Селектор сегмента должен быть загружен в один из сегментных регистров
|
||||
@ -310,13 +310,13 @@ ENDPROC(memset)
|
||||
Остальная часть `memset` делает почти то же самое, что и `memcpy`.
|
||||
|
||||
После того как структура `biosregs` заполнена с помощью `memset`, `bios_putchar` вызывает прерывание [0x10](http://www.ctyme.com/intr/rb-0106.htm) для вывода символа. Затем она проверяет, инициализирован ли последовательный порт, и в случае если он инициализирован, записывает в него символ с помощью инструкций [serial_putchar](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/tty.c#L30) и `inb/outb`.
|
||||
|
||||
|
||||
Инициализация кучи
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
После подготовки стека и BSS в [header.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S) (смотрите предыдущую [часть](linux-bootstrap-1.md)), ядро должно инициализировать [кучу](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/main.c#L116) с помощью функции [`init_heap`](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/main.c#L116).
|
||||
|
||||
В первую очередь `init_heap` проверяет флаг [`CAN_USE_HEAP`](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/include/uapi/asm/bootparam.h#L21) в [`loadflags`](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S#L321) в заголовке настройки ядра и если флаг был установлен, вычисляет конец стека:
|
||||
В первую очередь `init_heap` проверяет флаг [`CAN_USE_HEAP`](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/include/uapi/asm/bootparam.h#L22) в [`loadflags`](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/header.S#L321) в заголовке настройки ядра и если флаг был установлен, вычисляет конец стека:
|
||||
|
||||
```C
|
||||
char *stack_end;
|
||||
@ -463,7 +463,7 @@ int query_mca(void)
|
||||
08h БАЙТ байт свойства 4 (смотрите #00513)
|
||||
09h БАЙТ байт свойства 5 (смотрите #00514)
|
||||
---AWARD BIOS---
|
||||
0Ah N БАЙТ Уведомление об авторских правах AWARD
|
||||
0Ah N БАЙТ Уведомление об авторских правах AWARD
|
||||
---Phoenix BIOS---
|
||||
0Ah БАЙТ ??? (00h)
|
||||
0Bh БАЙТ мажорная версия
|
||||
@ -549,4 +549,3 @@ for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
|
||||
* [Спецификация EDD](http://www.t13.org/documents/UploadedDocuments/docs2004/d1572r3-EDD3.pdf)
|
||||
* [Документация TLDP для процесса загрузки Linux](http://www.tldp.org/HOWTO/Linux-i386-Boot-Code-HOWTO/setup.html) (старая)
|
||||
* [Предыдущая часть](linux-bootstrap-1.md)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user