mirror of
https://github.com/0xAX/linux-insides.git
synced 2025-07-04 08:12:37 +00:00
typo fixed (0bB800 -> 0xb800)
Signed-off-by: 0xF0D0 <goodbumsu@gmail.com>
This commit is contained in:
parent
3ed8adc0d3
commit
2e6ce3cd12
@ -30,11 +30,11 @@ Offset Proto Name Meaning
|
|||||||
|
|
||||||
```
|
```
|
||||||
vga=<mode>
|
vga=<mode>
|
||||||
<mode> может быть либо целочисленным значением (в C-нотации,
|
<mode> может быть либо целочисленным значением (в C-нотации,
|
||||||
десятичной, восьмеричной или шестнадцатеричной), либо одной из строк:
|
десятичной, восьмеричной или шестнадцатеричной), либо одной из строк:
|
||||||
"normal" (означает 0xFFFF), "ext" (означает 0xFFFE) или "ask"
|
"normal" (означает 0xFFFF), "ext" (означает 0xFFFE) или "ask"
|
||||||
(означает 0xFFFD). Это значение должно быть введено в поле
|
(означает 0xFFFD). Это значение должно быть введено в поле
|
||||||
vid_mode field, так как оно используется ядром до
|
vid_mode field, так как оно используется ядром до
|
||||||
парсинга командной строки.
|
парсинга командной строки.
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ static inline bool heap_free(size_t n)
|
|||||||
|
|
||||||
В первую очередь `store_cursor_position` инициализирует две переменные, которые имеют тип `biosregs` с `AH = 0x3`, и вызывает BIOS прерывание `0x10`. После того как прерывание успешно выполнено, она возвращает строку и столбец в регистрах `DL` и `DH`. Строка и столбец будут сохранены в полях `orig_x` и `orig_y` структуры `boot_params.screen_info`.
|
В первую очередь `store_cursor_position` инициализирует две переменные, которые имеют тип `biosregs` с `AH = 0x3`, и вызывает BIOS прерывание `0x10`. После того как прерывание успешно выполнено, она возвращает строку и столбец в регистрах `DL` и `DH`. Строка и столбец будут сохранены в полях `orig_x` и `orig_y` структуры `boot_params.screen_info`.
|
||||||
|
|
||||||
После выполнения `store_cursor_position` вызывается функция `store_video_mode`. Она просто получает текущий видеорежим и сохраняет его в `boot_params.screen_info.orig_video_mode`.
|
После выполнения `store_cursor_position` вызывается функция `store_video_mode`. Она просто получает текущий видеорежим и сохраняет его в `boot_params.screen_info.orig_video_mode`.
|
||||||
|
|
||||||
Далее она проверяет текущий видеорежим и устанавливает `video_segment`. После того как BIOS передаёт контроль в загрузочный сектор, для видеопамяти выделяются следующие адреса:
|
Далее она проверяет текущий видеорежим и устанавливает `video_segment`. После того как BIOS передаёт контроль в загрузочный сектор, для видеопамяти выделяются следующие адреса:
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ static inline bool heap_free(size_t n)
|
|||||||
0xB800:0x0000 32 Кб Видеопамять для цветного текста
|
0xB800:0x0000 32 Кб Видеопамять для цветного текста
|
||||||
```
|
```
|
||||||
|
|
||||||
Таким образом, мы устанавливаем переменную `video_segment` в `0xB000`, если текущий видеорежим MDA, HGC, или VGA в монохромном режиме, и в `0xB800`, если текущий видеорежим цветной. После настройки адреса видеофрагмента, размер шрифта должен быть сохранён в `boot_params.screen_info.orig_video_points`:
|
Таким образом, мы устанавливаем переменную `video_segment` в `0xb000`, если текущий видеорежим MDA, HGC, или VGA в монохромном режиме, и в `0xb800`, если текущий видеорежим цветной. После настройки адреса видеофрагмента, размер шрифта должен быть сохранён в `boot_params.screen_info.orig_video_points`:
|
||||||
|
|
||||||
```C
|
```C
|
||||||
set_fs(0);
|
set_fs(0);
|
||||||
@ -226,9 +226,9 @@ struct card_info {
|
|||||||
|
|
||||||
Это значит, что `video_cards` - просто адрес в памяти, и все структуры `card_info` размещаются в этом сегменте. Это также означает, что все структуры `card_info` размещаются между `video_cards` и `video_cards_end`, и мы можем воспользоваться этим, чтобы пройтись по ним в цикле. После выполнения `probe_cards` у нас есть все структуры `static __videocard video_vga` с заполненными `nmodes` (число видеорежимов).
|
Это значит, что `video_cards` - просто адрес в памяти, и все структуры `card_info` размещаются в этом сегменте. Это также означает, что все структуры `card_info` размещаются между `video_cards` и `video_cards_end`, и мы можем воспользоваться этим, чтобы пройтись по ним в цикле. После выполнения `probe_cards` у нас есть все структуры `static __videocard video_vga` с заполненными `nmodes` (число видеорежимов).
|
||||||
|
|
||||||
После завершения выполнения `probe_cards`, мы переходим в главный цикл функции `set_video`. Это бесконечный цикл, который пытается установить видеорежим с помощью функции `set_mode` и выводит меню, если установлен флаг `vid_mode=ask` командной строки ядра или если видеорежим не определён.
|
После завершения выполнения `probe_cards`, мы переходим в главный цикл функции `set_video`. Это бесконечный цикл, который пытается установить видеорежим с помощью функции `set_mode` и выводит меню, если установлен флаг `vid_mode=ask` командной строки ядра или если видеорежим не определён.
|
||||||
|
|
||||||
Функция `set_mode` определена в [video-mode.c](https://github.com/0xAX/linux/blob/master/arch/x86/boot/video-mode.c#L147) и принимает только один параметр - `mode`, который определяет количество видеорежимов (мы получили его из меню или в начале `setup_video`, из заголовка настройки ядра).
|
Функция `set_mode` определена в [video-mode.c](https://github.com/0xAX/linux/blob/master/arch/x86/boot/video-mode.c#L147) и принимает только один параметр - `mode`, который определяет количество видеорежимов (мы получили его из меню или в начале `setup_video`, из заголовка настройки ядра).
|
||||||
|
|
||||||
`set_mode` проверяет `mode` и вызывает функцию `raw_set_mode`. `raw_set_mode` вызывает `set_mode` для выбранной карты, т.е. `card->set_mode(struct mode_info*)`. Мы можем получить доступ к этой функции из структуры `card_info`. Каждый видеорежим определяет эту структуру со значениями, заполненными в зависимости от режима видео (например, для `vga` это функция `video_vga.set_mode`. См. выше пример структуры `card_info` для `vga`). `video_vga.set_mode` является `vga_set_mode`, который проверяет VGA-режим и вызывает соответствующую функцию:
|
`set_mode` проверяет `mode` и вызывает функцию `raw_set_mode`. `raw_set_mode` вызывает `set_mode` для выбранной карты, т.е. `card->set_mode(struct mode_info*)`. Мы можем получить доступ к этой функции из структуры `card_info`. Каждый видеорежим определяет эту структуру со значениями, заполненными в зависимости от режима видео (например, для `vga` это функция `video_vga.set_mode`. См. выше пример структуры `card_info` для `vga`). `video_vga.set_mode` является `vga_set_mode`, который проверяет VGA-режим и вызывает соответствующую функцию:
|
||||||
|
|
||||||
@ -293,7 +293,7 @@ io_delay();
|
|||||||
|
|
||||||
Первой вызывается ассемблерная инструкция `cli`, которая очищает флаг прерывания (`IF`). После этого внешние прерывания отключены. Следующая строка отключает NMI (немаскируемые прерывания).
|
Первой вызывается ассемблерная инструкция `cli`, которая очищает флаг прерывания (`IF`). После этого внешние прерывания отключены. Следующая строка отключает NMI (немаскируемые прерывания).
|
||||||
|
|
||||||
Прерывание является сигналом, который отправляется CPU от аппаратного или программного обеспечения.
|
Прерывание является сигналом, который отправляется CPU от аппаратного или программного обеспечения.
|
||||||
После получения сигнала, CPU приостанавливает текущую последовательность команд, сохраняет своё состояние и передаёт управление обработчику прерываний. После того как обработчик прерывания закончил свою работу, он передаёт управление прерванной инструкции. Немаскируемые прерывания (NMI) - это прерывания, которые обрабатываются всегда, независимо от запретов на другие прерывания. Их нельзя игнорировать, и, как правило, они используются для подачи сигнала о невосстанавливаемых аппаратных ошибок. Сейчас мы не будем погружаться в детали прерываний, но обсудим это в следующих постах.
|
После получения сигнала, CPU приостанавливает текущую последовательность команд, сохраняет своё состояние и передаёт управление обработчику прерываний. После того как обработчик прерывания закончил свою работу, он передаёт управление прерванной инструкции. Немаскируемые прерывания (NMI) - это прерывания, которые обрабатываются всегда, независимо от запретов на другие прерывания. Их нельзя игнорировать, и, как правило, они используются для подачи сигнала о невосстанавливаемых аппаратных ошибок. Сейчас мы не будем погружаться в детали прерываний, но обсудим это в следующих постах.
|
||||||
|
|
||||||
Давайте вернёмся к коду. Мы видим, что вторая строка пишет байт `0x80` (отключённый бит) в `0x70` (регистр CMOS Address). После этого происходит вызов функции `io_delay`. `io_delay` вызывает небольшую задержку и выглядит следующим образом:
|
Давайте вернёмся к коду. Мы видим, что вторая строка пишет байт `0x80` (отключённый бит) в `0x70` (регистр CMOS Address). После этого происходит вызов функции `io_delay`. `io_delay` вызывает небольшую задержку и выглядит следующим образом:
|
||||||
@ -591,4 +591,3 @@ jmpl *%eax
|
|||||||
* [GCC designated inits (назначенные инициализаторы)](https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html)
|
* [GCC designated inits (назначенные инициализаторы)](https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html)
|
||||||
* [Атрибуты типов GCC](https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html)
|
* [Атрибуты типов GCC](https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html)
|
||||||
* [Предыдущий пост](linux-bootstrap-2.md)
|
* [Предыдущий пост](linux-bootstrap-2.md)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user