Это - ядро. Следует иметь в виду, что клавиатура является аппаратными средствами и всем, что происходит, там проходит через ядро; в случае переключения VT это обрабатывает событие полностью само и ничего не передает на пространство пользователя (однако, я полагаю, что существует связанный ioctl, подразумевает, какие программы пространства пользователя могут быть уведомлены относительно появления переключателя, вовлекающего их, и возможно влиять на него, который X несомненно делает).
Ядро имеет контурную карту, встраивают в него; это может быть изменено при выполнении с loadkeys
, и просматриваемый с dumpkeys
:
[...]
keycode 59 = F1 F13 Console_13 F25
alt keycode 59 = Console_1
control alt keycode 59 = Console_1
keycode 60 = F2 F14 Console_14 F26
alt keycode 60 = Console_2
control alt keycode 60 = Console_2
keycode 61 = F3 F15 Console_15 F27
alt keycode 61 = Console_3
control alt keycode 61 = Console_3
[...]
Источник ядра содержит файл контурной карты по умолчанию, который точно походит на это; для 3.12.2 это src/drivers/tty/vt/defkeymap.map
. Вы также заметите, что существует соответствующий defkeymap.c файл (это может быть сгенерировано с loadkeys --mktable
). Обработка находится в keyboard.c
(все эти файлы находятся в том же каталоге), который звонит set_console()
от vt.c
:
» grep set_console *.c
keyboard.c: set_console(last_console);
keyboard.c: set_console(i);
keyboard.c: set_console(i);
keyboard.c: set_console(value);
vt.c:int set_console(int nr)
vt_ioctl.c: set_console(arg);
Я отредактировал некоторые хиты из того списка; Вы видите функциональную подпись на предпоследней строке.
Таким образом, это вещи, вовлеченные в переключение. При рассмотрении последовательности вызовов в конечном счете Вы возвращаетесь к kbd_event()
в keyboard.c
. Это регистрируется как обработчик событий для модуля:
(3.12.2 drivers/tty/vt/keyboard.c
строка 1473)
MODULE_DEVICE_TABLE(input, kbd_ids);
static struct input_handler kbd_handler = {
.event = kbd_event, <--- function pointer HERE
.match = kbd_match,
.connect = kbd_connect,
.disconnect = kbd_disconnect,
.start = kbd_start,
.name = "kbd",
.id_table = kbd_ids,
};
int __init kbd_init(void)
{
[...]
error = input_register_handler(&kbd_handler);
Следовательно, kbd_event()
должен быть назван, когда что-то пузырится от фактического драйвера оборудования (вероятно, что-то от drivers/hid/
или drivers/input/
). Однако Вы не будете видеть его называемый как kbd_event
за пределами того файла, так как это регистрируется через указатель функции.
printk
строки в источник как простое средство трассировки (не весь стандарт C lib может использоваться в коде ядра, включая printf от stdio). материал printk заканчивается в системном журнале.Wolfgang Mauerer записал замечательную большую книгу по 2,6 ядрам, Профессионал Архитектура Ядра Linux, которая проходит много источника. У Greg Kroah-Hartman, одного из принципа devs в течение прошлого десятилетия, также есть много вещей, перебрасывающихся.
Unix runlevels является ортогональным (в "не связанном" смысле, "независимый от" - см. комментарии) к защитным кольцам.
Runlevels являются в основном временем выполнения конфигурации/состояния операционной системы в целом, они описывают, какие сервисы доступны ("пользователю") - как доступ SSH, MTA, файловый сервер, GUI.
Кольца являются понятием аппаратных средств, которому помогают, которое позволяет более прекрасное гранулярное управление аппаратными средствами (как упомянуто на странице Википедии, которую Вы связываете с). Например, код, работающий в более высоком Кольце, не может выполнять некоторые инструкции ЦП.
Linux на x86 архитектуре обычно использует Ring0 для ядра (включая драйверы устройств) и Ring3 для приложений пространства пользователя (regerdless того, выполняются ли они корнем или другим обычным или привилегированным пользователем).
Следовательно Вы не можете действительно сказать, что runlevel работает в некотором определенном Кольце - существуют always1 приложения пространства пользователя (по крайней мере, PID 1 - init
) выполнение в Ring3 и ядре (Ring0).
1As всегда, "всегда" действительно означает "почти всегда", так как можно запустить "нормальные" программы в Ring0, но Вы вряд ли будете видеть, что в реальной жизни (если Вы не работаете над HPC).
Эти два понятия абсолютно не связаны. Системный уровень выполнения относится к набору сервисов, которые работают на системе, такой как, работает ли gui настольная среда. Кольцевые уровни являются аппаратным механизмом защиты на процессорах intel x86, которые разделяют код на различные уровни полномочия. Linux только использует кольца 0 и 3 для кода привилегированного и непривилегированного режима соответственно. Таким образом все процессы непривилегированного режима, работая, когда система находится на любом уровне выполнения, выполняются в кольце 3, пока они не звонят в код ядра, который переходит CPU для вызова 0.
Из Вашей собственной ссылки:
В монолитном ядре операционная система работает в привилегированном режиме и приложениях, запущенных в непривилегированном режиме. Другие типы операционных систем, как те, которые имеют экзоядро или микроядро, не обязательно совместно используют это поведение.
Некоторые примеры от мира ПК:
Linux и Windows являются двумя операционными системами тот супервизор/непривилегированный режим использования. Для выполнения специализированных функций код непривилегированного режима должен выполнить системный вызов в привилегированный режим или даже к пространству ядра, где доверяемый код операционной системы выполнит необходимую задачу и возвратит ее назад пространству пользователя.
Таким образом, Ваш ответ был бы 2. Супервизор (0) и пользователь (1).