Настольный Linux. Часть 2. Изгоняем из системы злого духа неповиновения
Продолжим первоначальную настройку Linux, которая порой требуется сразу после установки, а также продолжим изучение самой системы. В прошлой статье мы остановились на загрузке системы и подошли к такой фундаментальной абстракции, как процесс. Процесс — это программа, которая выполняется в системе. Т.е. это сама программа, ее глобальные данные, значения регистров и т.д. Впервые этот термин появился в 60-е годы, а одной из первых систем, где был реализован, является Multics — прародительница Unix. В Unix процессы бывают трех видов. Обычный процесс — тот, который в данный момент работает и использует терминал (клавиатуру и дисплей) для ввода-вывода. В это определение входят также и все графические приложения, ибо они так или иначе тоже используют терминал. Зато оставшиеся два вида процессов — сплошное мракобесие. Демон — это фоновый процесс (не блокирует терминал), который выполняет определенную функцию или предоставляет некоторый сервис. Впервые слово "демон" (daemon) как компьютерный термин употребил, опять же, в начале 60-х программист Массачусетского технологического института англичанин Мик Бейли (Mick Bailey). В отличие от "demon" слово "daemon" более древнее и дословно означает "дух-хранитель человека, формирующий его характер". То есть "daemon" — это не воплощение зла, а независимое существо со своими намерениями и желаниями. Кстати, init — самый первый процесс, создаваемый системой — является демоном. Третий вид процессов — процессы-зомби. Это такие процессы, которые уже завершились, но их родительский процесс еще не запросил результат их работы. Предполагается, что этот результат как-то пригодится родительскому процессу. На самом деле процесс-зомби технически уже не процесс, а только структура в памяти ядра, контролировавшая его ранее. В ней и остался нужный родительскому процессу код возврата. Разумеется, зомби появляются от небрежного отношения к "смерти" обычных процессов и являются ошибками программистов. Чувствуют ли процессы-зомби голод? Этот вопрос скорее эзотерический, нежели технический. Но что бы там зомби ни чувствовали, а все-таки память они "едят", и потому являются паразитами. Есть еще один, четвертый, переходный вид процессов: процессы-сироты. Это такие процессы, которые утратили своего родителя. Процессы-сироты тут же наследуются процессом init и становятся вполне нормальными процессами.
Все процессы в Linux делятся на процессы уровня ядра и пользовательские процессы. Им соответствует и аппаратный уровень привилегий: в архитектуре x86 для ядра используется наивысший, 0-й, уровень, для пользовательских процессов — 3-й (1-й и 2-й уровни x86 так и не нашли своего применения в современных ОС). В Linux в режиме ядра формально работает только один процесс — ядро. По крайней мере, если исходить из определения процесса, данного Эндрю Таненбаумом (Andrew Tanenbaum) — самым солидным специалистом в области теории операционных систем: "...С каждым процессом связывается его адресное пространство... Адресное пространство содержит саму программу, данные к ней и ее стек". Короче, адресное пространство в ядре Linux действительно одно, посему его можно считать одним процессом.
Команды для управления процессами:
1) ps — показать снапшот текущего состояния процессов;
2) top — показать состояние процессов (выглядит примерно как taskmanager в консоли);
3) kill — насильно завершить процесс по указанному идентификатору процесса;
4) killall — насильно завершить все процессы с указанным именем;
5) pidof — получить идентификатор процесса с указанным именем.
То есть, например, если вы запустили какую-нибудь жутко глючную прогу, а она вдруг исчезла страшным исчезом, но явно где-то продолжает свою гнусную деятельность, тут же появляется желание ее "прибить". Для этого введите команду "killall proga", где proga — имя убиваемого процесса. Другой, более тонкий, способ завершить процесс — сначала при помощи команд ps, top или pidof определить PID (Process IDentifier), а затем прибить процесс командой kill. И третий, последний, способ завершить процесс, который используется, пожалуй, чаще других — это нажатие Ctrl-C. Правда, здесь есть разница. Все способы "убивания" процессов реализованы при помощи механизма сигналов Linux. Команды kill и killall посылают процессу сигнал SIGKILL. Этот сигнал не может быть перехвачен и обработан и предназначен единственно для насильного завершения процесса. А вот комбинация Ctrl-C посылает процессу сигнал SIGINT, функция обработки которого может быть заменена на другую. Значит, комбинации Ctrl-C подвластны не все процессы. Самые "умные" установили свой обработчик на SIGINT, и зачастую у них есть на это причины.
Теперь, когда более-менее прояснилось, что такое процесс, можно перейти к настройке графической подсистемы. В Linux графическая подсистема реализована как обычный процесс пользовательского уровня. В некоторых других ОС графическая подсистема работает как часть ядра. У этих двух подходов свои преимущества и недостатки: реализация графики как части ядра увеличивает ее интерактивность, но уменьшает безопасность. В Linux, как и во всех других Unix- и Unix-like-системах, упор делается на безопасность. Практически во всех современных дистрибутивах Linux используется x.org — свободная реализация стандарта X11R6.4 графических подсистем Unix-подобных ОС. Вообще x.org — это свободный клон XFree86, который пару лет назад попытались "коммерциализировать". А до этого XFree86 был вполне свободным клоном другой коммерческой системы — X Window, поэтому и сейчас частенько говорят "иксы" или "икс-виндовс", подразумевая под этим свою графическую подсистему, у кого какая есть.
Проект X Window начали в далеком 1984 году. Первые десять (!) версий X Window создавались фактически всего тремя людьми — Робертом Шейфлером (Robert Sheifler), Джимом Геттисом (Jim Gettys) и Роном Ньюменом (Ron Newman). В названии проекта буква "X" на самом деле ничего серьезного не значит и к моде завершать свои системы буквой "x" для Unix-like ОС не имеет отношения. Просто графическая подсистема X Window была создана после системы W (в латинском алфавите X идет после W, а не между Z и C;-)). Наибольшую популярность завоевала 11-я версия X Window, в разработку которой включилось OpenSource-сообщество. Кстати, сегодня даже в самых свежих x.org используются названия от 11-й X Window. Пример: файлы конфигурации для x.org находятся в каталоге /etc/X11. Вся система X Window подразделяется на серверную и клиентскую части. Здесь сервер — это процесс (обычно запускается как демон), который предоставляет некоторые свои ресурсы: растровую память, информацию о событиях от клавиатуры и устройства позиционирования курсора и т.д. Клиентская часть — это графические приложения, которые используют ресурсы X Server'а. Разумеется, сервер предоставляет только самые базовые возможности, поэтому поверху сервера используются оконные менеджеры.
Перейдем к настройке x.org, то есть к файлу /etc/X11/xorg.conf. Раньше он назывался XF86Config, а еще раньше — XF86Config-4. Это главный файл, который обычно приходится править при сбоях графической подсистемы. Следуя принципам Unix, файл настроек x.org выполнен в текстовом виде, удобном для восприятия человеком. Это позволяет "поднять" систему буквально "из пепла" при помощи одного только текстового редактора. В последнее время в Linux наблюдаются тенденции к переходу на графические утилиты настройки. Для начинающих это действительно очень удобно, потому что в Linux с нуля наскоком не разберешься. Но все же, постепенно изучая эту замечательную систему, линуксоиды стараются избегать графических утилит настройки. Ведь эти утилиты разрабатываются отдельно от тех продуктов, которые настраивают. Поэтому иногда случаются казусы, когда утилита настройки "не понимает" конфигурационный файл новой версии. А еще из собственного опыта добавлю: некоторые графические настройщики очень плохо воспринимают конфигурационные файлы, правленные человеком. Поэтому, конечно, когда требуется тонкая настройка какой-нибудь софтины, лучше старого доброго ViM'а, пожалуй что, и нету. Файл xorg.conf генерируется установочным скриптом и содержит информацию о мониторе, графической карте, клавиатуре, мыши, шрифтах, некоторых дополнительных модулях и флагах XServer'а. Все логические части x.org объединены в секции. Секция "Files" содержит описания внешних по отношению к X Window файлов: устройства ввода, шрифты и т.д. В первую очередь в этой секции нас интересуют пути к шрифтам. Обычно они находятся в каталоге /usr/X11R6/lib/X11/fonts или /usr/lib/X11/fonts в зависимости от дистрибутива. Так что, если будете русифицировать систему или добавлять шрифты вручную — прописывать их для использования X Server'ом придется именно здесь. В некоторых реализациях X Window шрифты управляются при помощи отдельного сервера шрифтов. В принципе, без него можно прекрасно обойтись и просто пользоваться секцией "Files". Секция "Modules" предназначена для перечисления загружаемых модулей. До самого недавнего времени мне приходилось здесь удалять строку Load "dri" и добавлять строку Load "glx", чтобы заставить работать OpenGL и поиграть наконец во что-нибудь 3D'шное. Но когда я установил Suse 9.3, то с удивлением обнаружил, что меня избавили и от этой необходимости. Дело в том, что у меня видеокарта GeForce, и драйверы от Nvidia для нее — совсем не OpenSource. А дистрибутивы обычно не содержат ни закрытого ПО, ни настроек для него. Зато компания Novell, которая не так давно приобрела Suse Linux, решила предоставлять в своем дистрибутиве ПО mixed-source, и уже в дистрибутиве Suse Linux 9.3 присутствуют не только OpenSource-продукты, но и продукты с закрытым исходным кодом, и даже shareware (Adobe Acrobat Reader, Real Player, Text Maker и др.). На мой взгляд, это действительно трезвое решение, потому что избавляет от необходимости искать дополнительные программы где- то на стороне. Так, например, те же драйверы для Nvidia-карт присутствуют на сайте Suse Linux.
Следующая интересная секция xorg.conf — "InputDevice". Таких секций может быть несколько, т.к. устройств ввода тоже несколько. Но минимально, естественно, две: для клавиатуры и мыши. Секция клавиатуры обычно достаточно толково настроена во всех дистрибутивах и серьезного вмешательства не требует. Впрочем, некоторые украшательства не помешают. Опция "XkbLayout" предназначена для указания порядка переключения между раскладками клавиатуры. Например, "us,ru" — если вы хотите начинать с английского языка. Для опции XkbVariant обычно указывают значение ",winkeys", чтобы заработали дополнительные клавиши в Microsoft Windows совместимой клавиатуре. А где вы сейчас видели другие клавиатуры? Так что опция пригодится. И еще одна опция, которую лично я правлю всегда — это XkbOptions. В ней указывается комбинация клавиш для переключения между раскладками. Мне нравится переключаться Alt-Shift'ом, для этого нужно указать значение grp:alt_shift_toggle, а установочный скрипт прописывает переключение Ctrl-Shift'ом (grp:ctrl_shift_toggle). И еще очень удобная вещь — включение светового индикатора на клавиатуре, когда система перешла в русскую раскладку. Поскольку в Linux индикатор Scroll Lock никак не используется, то индикация раскладки — прекрасное для него применение. Для этого через запятую нужно указать еще одно значение XkbOptions: grp_led:scroll. В секции "InputDevice" для мыши особых настроек тоже не предвидится. Бывало, в старых дистрибутивах установочный скрипт неправильно определял USB-мышь. В этом случае в опции Device должен быть указан файл /dev/input/mice. Если у вас мышь PS/2, и она себя странно ведет — значит, указан неверный протокол.
В опции Protocol попробуйте значения PS/2 и ImPS/2. Если у вас все в порядке, но в мыши не работает колесо — попробуйте опцию ZAxisMapping со значением "4 5". Правда, с описанными проблемами я сталкивался только в дистрибутиве Debian Woody — все же остальные дистрибутивы прекрасно настраивают мышь сами. Секция "Monitor" отвечает за режим работы. Если почему-то в графическом режиме монитор работает на частоте 60 Hz, то вам сюда. Нужно указать правильные значения диапазонов для опций HorizSync и VertRefresh, и X Server без проблем сделает вам 85 Hz. Мало 85? Можно и больше, но для этого не обойтись без специфических настроек, а иногда и шаманского бубна. В более ранних реализациях XFree86 X Server не умел сам по параметрам монитора толково настроить частоту обновления. Для этого использовалась опция Modeline, где указывались различные тонкие хардварные настройки. И не так давно приходилось еще высчитывать эту опцию на калькуляторе, проштудировав перед этим немалое количество документации. Дело это жуткое, и лучше доверить его простой специализированной утилите gtf. Например, для 100 Hz на разрешении 1024x768 нужно выполнить команду "gtf 1024 768 100", и утилита посчитает вам значение Modeline. Вставьте его в секцию "Monitor", ребутните X Server — и все будет ok. Вообще для каждого разрешения нужен свой Modeline. Указывать их в секции "Monitor" не стоит, т.к. предназначена она не для этого. Все Modeline'ы обычно хранятся в секции "Modes". А в сеции "Screen" указано, какие режимы работы можно использовать для каждого значения глубины цвета. Последняя секция, в которой может понадобиться правка — "Device". Она предназначена для описания видеокарты. В опции Driver указывается название используемого драйвера. Так, nv — встроенный драйвер для всех видеокарт Nvidia, который практически ничего не умеет. Если у вас установлены "родные" драйверы от Nvidia, то в опции Driver нужно указать "nvidia" (почему и как установить драйверы — ниже).
Теперь, когда вы внесли изменения в xorg.conf, нужно их "применить". Для этого нужно перезапустить только X Server, а вовсе не перегружать всю систему. Самый простой способ перезапустить X Server — волшебная комбинация "Ctrl-Alt-Backspace". Она "убьет" процесс сервера, после чего демон init перезапустит его по новой, если, конечно, он на это настроен. Следующий способ — запустить скрипт /etc/init.d/xdm с параметром restart, как это было описано в прошлом номере. Оставшиеся способы "убивания" процессов обсуждались выше. Теперь поговорим об установке драйверов в целом и для видеокарты в частности. Все современные операционные системы ограничивают доступ пользовательских процессов к аппаратной части. Поэтому доступ к ней можно получить только из режима ядра. А в режиме ядра работает всего один процесс, имя которому — linux. Каким образом драйвера переходят в привилегированный режим? Разумеется, они становятся частью процесса ядра! На самом деле о том, быть ли драйверам в едином с ядром адресном пространстве или создавать для них отдельные процессы, написано множество литературы. Тот же Эндрю Таненбаум очень активно занимается изучением эффективности различных видов ядра: микроядра и монолита. Если упрощенно, то микроядро — это ма-ахонький процесс-супервизор, который всего-то и умеет, что загружать/выгружать процессы ядра. А остальная функциональность ложится на другие процессы включая планирование, распределение памяти, поддержку файловой системы и т.д.
Так устроены операционные системы Windows 2000, QNX, Mach. Монолитное ядро, в отличие от микроядра, представляет собой один гигантских размеров процесс, в адресном пространстве которого содержится вся необходимая функциональность. Так устроены Windows 9x (частично), FreeBSD, Linux и многие другие системы. Разница между монолитом и микроядром, опять же, в безопасности и интерактивности. Так, микроядро гораздо безопаснее монолита, потому что кривой драйвер гарантированно не сможет "подвесить" систему, ведь он находится в отдельном адресном пространстве. Кроме того, микроядро занимает меньше памяти за счет того, что загружает исключительно нужные в данный момент модули. А преимущества монолита в его скорости. Эндрю Таненбаум посчитал, что на передачу сообщений между разными подсистемами ОС с микроядром уходит до 20% процессорного времени — монолит лишен этого недостатка. Когда чуть больше десяти лет назад Линус Торвальдс начинал писать свое ядро (изначально названное Freax, но по совету друзей переименованное в Linux), скорость работы была самым критически важным параметром любой ОС. Представьте сами, какова она была тогда на 386-й машине. Поэтому выбор в сторону монолита был очевиден. Со временем ядро Linux все больше и больше приобретало черты микроядра, и в теперешнем его виде от свойств монолита осталось, наверное, только единое адресное пространство. Дело в том, что микроядро, естественно, более современная парадигма ОС, и все системы стараются развиваться именно в сторону увеличения модульности. Впрочем, у Линуса Торвальдса есть на это свое мнение. Когда вышел первый релиз Linux, Эндрю Таненбаум в сетевой конференции отругал Линуса за монолитность ядра и сказал, что Linux уже создан устаревшим. Лично я считаю, это была банальная зависть, потому как его, Таненбаума, ядро minix хоть и было микроядром, но здорово уступало в эффективности Linux'у. На это Линус Торвальдс в той же конференции ответил, цитирую: "...message passing as the fundamental operation of the OS is just an excercise in computer science masturbation. It may feel good, but you don't actually get anything DONE". Коротко и емко. Так что сегодня Linux — это монолит с чертами микроядра, позволяющими на ходу загружать/выгружать в пространство ядра дополнительные модули. Один из видов модулей ядра — драйверы устройств, так что загрузка драйвера и загрузка модуля — это одно и то же. Команды, которые необходимо знать, чтобы работать с модулями ядра:
1) lsmod — вывести список загруженных модулей;
2) insmod — загрузить указанный модуль;
3) modprobe — загрузить указанный модуль и все остальные, от которых он зависит;
4) rmmod — выгрузить указанный модуль.
Все модули ядра обычно находятся в каталоге /lib/modules и далее в подкаталогах для каждой конкретной версии ядра. В ядрах 2.6.x модули имеют расширение *.ko (kernel object), а в более ранних версиях Linux — *.o. Так что, если вам нужно загрузить, например, driver.ko, то нужно выполнить команду "modprobe driver". Тогда modprobe посмотрит в файле /lib/modules/linux/modules.dep, есть ли у driver'а какие-нибудь зависимости, которые нужно загрузить до загрузки driver.ko. Например, модуль msdos.ko потребует загрузки fat.ko, а fat.ko тоже может зависеть от других модулей и т.д. Утилита modprobe загрузит их все при помощи команды insmod. Таким образом, загрузка стандартных модулей не представляет проблемы. А что если нужно установить драйвер для видеокарты? Во-первых, нужно установить пакет kernel-development, который включает исходники и заголовочные файлы ядра. Фирменные драйверы для устройств обычно распространяются в виде исходных текстов, которые можно собрать и установить как любую другую программу, а при сборке обязательно потребуются заголовочные файлы Linux'а. Но Nvidia пошла дальше и сделала для своих пользователей бинарный файл, в который включено все, что нужно для установки драйверов одним нажатием ввода (кроме самого Linux'а, конечно). Так что идем на сайт www.nvidia.com и качаем соответствующую версию драйверов, затем прибиваем X Server или загружаемся в Single mode (команда "init 1"). Подробно про уровни исполнения системы я рассказывал в прошлом номере. Теперь, когда X Server точно не работает, запускаем установочный файл драйверов для Nvidia, соглашаемся на все (а Nvidia просит только не подавать в суд в случае чего), и вскоре драйвер ядра будет скомпилирован и положен в соответствующий каталог. Если все прошло гладко, то далее нужно его загрузить командой modprobe, затем в файле xorg.conf в секции Device значение опции Driver nv заменить на nvidia, в секции Modules проследить, чтобы не было строки Load "dri", а была Load "glx", и можно стартовать X Server. Если вы уже находитесь на уровне 5, то это можно сделать командой startx или запустить демона X Server'а при помощи скрипта /etc/init.s/xdm. Ну и потом, когда убедитесь, что все работает, нужно проследить, чтобы драйвер nvidia.ko постоянно загружался при старте системы. Один из способов загружать его вместе с системой — написать скрипт по примеру тех, что лежат в /etc/init.d, и сделать на него ссылку в каталоге /etc/init.d/rc5.d.
И последняя важная тема, которой обязательно нужно коснуться — установка/удаление дополнительного ПО. Традиционно в Unix это делалось при помощи сборки программы из исходников и копирования ее туда, куда пользователь пожелает. Так, например, чтобы установить программу proga.tar.gz, сначала ее нужно распаковать командой "tar -zxf proga.tar.gz", перейти в распакованный каталог, почитать README.txt (команда "cat README.txt | less", для выхода из less — клавиша "q") чтобы убедиться, не пропустили ли мы чего-нибудь важного, создать Makefile командой "./configure", затем собрать программу командой "make" и установить командой "make install". Способ этот, конечно, довольно долгий и неудобный. Поэтому все дистрибутивы предоставляют некоторый базовый набор заранее собранных программ и упаковывают их в пакеты — установочные файлы. Сегодня наибольшей популярностью пользуются два формата пакетов: rpm и deb. По сути, это те же архивы, но в них есть установочный скрипт. Соответственно, чтобы установить пакет packet.rpm, нужно выполнить команду "rpm -i packet.rpm". Для packet.deb — "dpkg -i packet.deb". Не удивляйтесь, если вдруг установщик откажется выполнять команду. Некоторые пакеты зависят от остановки других пакетов. Например, 3D-игры будут требовать, чтобы были установлены библиотеки OpenGL. Так что порой приходится вручную довольно долго лазить по всему дистрибутиву, устанавливая сначала все зависимости и зависимости зависимостей, чтобы запустить наконец tuxracer:-). Конечно, эту работу нужно было бы как-то автоматизировать. Тот же Suse Linux предлагает довольно удобную утилиту конфигурирования системы — YaST2. В числе прочего YaST2 позволяет выполнить поиск пакетов среди имеющихся на установочных компактах по имени, описанию и другим параметрам. Выбранные пакеты можно установить, и YaST2 автоматически установит все зависимости; также автоматизировано и удаление пакетов. Аналог YaST2 в дистрибутиве Debian — dselect. Есть еще графические утилиты вроде kpackage. У них у всех один недостаток: эти утилиты реализованы с интерфейсом пользователя. Самая, на мой взгляд, удобная вещь, работающая из командной строки — apt для Debian и apt4rpm для rpm-пакетов. Чтобы пользоваться apt'ом, вам не нужно знать ни полного, с версией, названия пакета, ни где он находится. Просто дайте команду "apt-get install package", и apt сам разберется, где поискать пакет (на установочных компактах, на жестком диске, в локальной сети или в Интернете — в зависимости от настроек), установит самую свежую версию со всеми зависимостями и даже запишет у себя, что куда установил. Так что когда дадите команду "apt-get remove package", apt полностью удалит весь пакет package вместе со всеми его библиотеками, мануалками и прочим мусором.
На этом, я считаю, можно закончить рассказ о "подводных камнях" свежеустановленного Linux'а.
Дмитрий Бушенко, nop@list.ru
Все процессы в Linux делятся на процессы уровня ядра и пользовательские процессы. Им соответствует и аппаратный уровень привилегий: в архитектуре x86 для ядра используется наивысший, 0-й, уровень, для пользовательских процессов — 3-й (1-й и 2-й уровни x86 так и не нашли своего применения в современных ОС). В Linux в режиме ядра формально работает только один процесс — ядро. По крайней мере, если исходить из определения процесса, данного Эндрю Таненбаумом (Andrew Tanenbaum) — самым солидным специалистом в области теории операционных систем: "...С каждым процессом связывается его адресное пространство... Адресное пространство содержит саму программу, данные к ней и ее стек". Короче, адресное пространство в ядре Linux действительно одно, посему его можно считать одним процессом.
Команды для управления процессами:
1) ps — показать снапшот текущего состояния процессов;
2) top — показать состояние процессов (выглядит примерно как taskmanager в консоли);
3) kill — насильно завершить процесс по указанному идентификатору процесса;
4) killall — насильно завершить все процессы с указанным именем;
5) pidof — получить идентификатор процесса с указанным именем.
То есть, например, если вы запустили какую-нибудь жутко глючную прогу, а она вдруг исчезла страшным исчезом, но явно где-то продолжает свою гнусную деятельность, тут же появляется желание ее "прибить". Для этого введите команду "killall proga", где proga — имя убиваемого процесса. Другой, более тонкий, способ завершить процесс — сначала при помощи команд ps, top или pidof определить PID (Process IDentifier), а затем прибить процесс командой kill. И третий, последний, способ завершить процесс, который используется, пожалуй, чаще других — это нажатие Ctrl-C. Правда, здесь есть разница. Все способы "убивания" процессов реализованы при помощи механизма сигналов Linux. Команды kill и killall посылают процессу сигнал SIGKILL. Этот сигнал не может быть перехвачен и обработан и предназначен единственно для насильного завершения процесса. А вот комбинация Ctrl-C посылает процессу сигнал SIGINT, функция обработки которого может быть заменена на другую. Значит, комбинации Ctrl-C подвластны не все процессы. Самые "умные" установили свой обработчик на SIGINT, и зачастую у них есть на это причины.
Теперь, когда более-менее прояснилось, что такое процесс, можно перейти к настройке графической подсистемы. В Linux графическая подсистема реализована как обычный процесс пользовательского уровня. В некоторых других ОС графическая подсистема работает как часть ядра. У этих двух подходов свои преимущества и недостатки: реализация графики как части ядра увеличивает ее интерактивность, но уменьшает безопасность. В Linux, как и во всех других Unix- и Unix-like-системах, упор делается на безопасность. Практически во всех современных дистрибутивах Linux используется x.org — свободная реализация стандарта X11R6.4 графических подсистем Unix-подобных ОС. Вообще x.org — это свободный клон XFree86, который пару лет назад попытались "коммерциализировать". А до этого XFree86 был вполне свободным клоном другой коммерческой системы — X Window, поэтому и сейчас частенько говорят "иксы" или "икс-виндовс", подразумевая под этим свою графическую подсистему, у кого какая есть.
Проект X Window начали в далеком 1984 году. Первые десять (!) версий X Window создавались фактически всего тремя людьми — Робертом Шейфлером (Robert Sheifler), Джимом Геттисом (Jim Gettys) и Роном Ньюменом (Ron Newman). В названии проекта буква "X" на самом деле ничего серьезного не значит и к моде завершать свои системы буквой "x" для Unix-like ОС не имеет отношения. Просто графическая подсистема X Window была создана после системы W (в латинском алфавите X идет после W, а не между Z и C;-)). Наибольшую популярность завоевала 11-я версия X Window, в разработку которой включилось OpenSource-сообщество. Кстати, сегодня даже в самых свежих x.org используются названия от 11-й X Window. Пример: файлы конфигурации для x.org находятся в каталоге /etc/X11. Вся система X Window подразделяется на серверную и клиентскую части. Здесь сервер — это процесс (обычно запускается как демон), который предоставляет некоторые свои ресурсы: растровую память, информацию о событиях от клавиатуры и устройства позиционирования курсора и т.д. Клиентская часть — это графические приложения, которые используют ресурсы X Server'а. Разумеется, сервер предоставляет только самые базовые возможности, поэтому поверху сервера используются оконные менеджеры.
Перейдем к настройке x.org, то есть к файлу /etc/X11/xorg.conf. Раньше он назывался XF86Config, а еще раньше — XF86Config-4. Это главный файл, который обычно приходится править при сбоях графической подсистемы. Следуя принципам Unix, файл настроек x.org выполнен в текстовом виде, удобном для восприятия человеком. Это позволяет "поднять" систему буквально "из пепла" при помощи одного только текстового редактора. В последнее время в Linux наблюдаются тенденции к переходу на графические утилиты настройки. Для начинающих это действительно очень удобно, потому что в Linux с нуля наскоком не разберешься. Но все же, постепенно изучая эту замечательную систему, линуксоиды стараются избегать графических утилит настройки. Ведь эти утилиты разрабатываются отдельно от тех продуктов, которые настраивают. Поэтому иногда случаются казусы, когда утилита настройки "не понимает" конфигурационный файл новой версии. А еще из собственного опыта добавлю: некоторые графические настройщики очень плохо воспринимают конфигурационные файлы, правленные человеком. Поэтому, конечно, когда требуется тонкая настройка какой-нибудь софтины, лучше старого доброго ViM'а, пожалуй что, и нету. Файл xorg.conf генерируется установочным скриптом и содержит информацию о мониторе, графической карте, клавиатуре, мыши, шрифтах, некоторых дополнительных модулях и флагах XServer'а. Все логические части x.org объединены в секции. Секция "Files" содержит описания внешних по отношению к X Window файлов: устройства ввода, шрифты и т.д. В первую очередь в этой секции нас интересуют пути к шрифтам. Обычно они находятся в каталоге /usr/X11R6/lib/X11/fonts или /usr/lib/X11/fonts в зависимости от дистрибутива. Так что, если будете русифицировать систему или добавлять шрифты вручную — прописывать их для использования X Server'ом придется именно здесь. В некоторых реализациях X Window шрифты управляются при помощи отдельного сервера шрифтов. В принципе, без него можно прекрасно обойтись и просто пользоваться секцией "Files". Секция "Modules" предназначена для перечисления загружаемых модулей. До самого недавнего времени мне приходилось здесь удалять строку Load "dri" и добавлять строку Load "glx", чтобы заставить работать OpenGL и поиграть наконец во что-нибудь 3D'шное. Но когда я установил Suse 9.3, то с удивлением обнаружил, что меня избавили и от этой необходимости. Дело в том, что у меня видеокарта GeForce, и драйверы от Nvidia для нее — совсем не OpenSource. А дистрибутивы обычно не содержат ни закрытого ПО, ни настроек для него. Зато компания Novell, которая не так давно приобрела Suse Linux, решила предоставлять в своем дистрибутиве ПО mixed-source, и уже в дистрибутиве Suse Linux 9.3 присутствуют не только OpenSource-продукты, но и продукты с закрытым исходным кодом, и даже shareware (Adobe Acrobat Reader, Real Player, Text Maker и др.). На мой взгляд, это действительно трезвое решение, потому что избавляет от необходимости искать дополнительные программы где- то на стороне. Так, например, те же драйверы для Nvidia-карт присутствуют на сайте Suse Linux.
Следующая интересная секция xorg.conf — "InputDevice". Таких секций может быть несколько, т.к. устройств ввода тоже несколько. Но минимально, естественно, две: для клавиатуры и мыши. Секция клавиатуры обычно достаточно толково настроена во всех дистрибутивах и серьезного вмешательства не требует. Впрочем, некоторые украшательства не помешают. Опция "XkbLayout" предназначена для указания порядка переключения между раскладками клавиатуры. Например, "us,ru" — если вы хотите начинать с английского языка. Для опции XkbVariant обычно указывают значение ",winkeys", чтобы заработали дополнительные клавиши в Microsoft Windows совместимой клавиатуре. А где вы сейчас видели другие клавиатуры? Так что опция пригодится. И еще одна опция, которую лично я правлю всегда — это XkbOptions. В ней указывается комбинация клавиш для переключения между раскладками. Мне нравится переключаться Alt-Shift'ом, для этого нужно указать значение grp:alt_shift_toggle, а установочный скрипт прописывает переключение Ctrl-Shift'ом (grp:ctrl_shift_toggle). И еще очень удобная вещь — включение светового индикатора на клавиатуре, когда система перешла в русскую раскладку. Поскольку в Linux индикатор Scroll Lock никак не используется, то индикация раскладки — прекрасное для него применение. Для этого через запятую нужно указать еще одно значение XkbOptions: grp_led:scroll. В секции "InputDevice" для мыши особых настроек тоже не предвидится. Бывало, в старых дистрибутивах установочный скрипт неправильно определял USB-мышь. В этом случае в опции Device должен быть указан файл /dev/input/mice. Если у вас мышь PS/2, и она себя странно ведет — значит, указан неверный протокол.
В опции Protocol попробуйте значения PS/2 и ImPS/2. Если у вас все в порядке, но в мыши не работает колесо — попробуйте опцию ZAxisMapping со значением "4 5". Правда, с описанными проблемами я сталкивался только в дистрибутиве Debian Woody — все же остальные дистрибутивы прекрасно настраивают мышь сами. Секция "Monitor" отвечает за режим работы. Если почему-то в графическом режиме монитор работает на частоте 60 Hz, то вам сюда. Нужно указать правильные значения диапазонов для опций HorizSync и VertRefresh, и X Server без проблем сделает вам 85 Hz. Мало 85? Можно и больше, но для этого не обойтись без специфических настроек, а иногда и шаманского бубна. В более ранних реализациях XFree86 X Server не умел сам по параметрам монитора толково настроить частоту обновления. Для этого использовалась опция Modeline, где указывались различные тонкие хардварные настройки. И не так давно приходилось еще высчитывать эту опцию на калькуляторе, проштудировав перед этим немалое количество документации. Дело это жуткое, и лучше доверить его простой специализированной утилите gtf. Например, для 100 Hz на разрешении 1024x768 нужно выполнить команду "gtf 1024 768 100", и утилита посчитает вам значение Modeline. Вставьте его в секцию "Monitor", ребутните X Server — и все будет ok. Вообще для каждого разрешения нужен свой Modeline. Указывать их в секции "Monitor" не стоит, т.к. предназначена она не для этого. Все Modeline'ы обычно хранятся в секции "Modes". А в сеции "Screen" указано, какие режимы работы можно использовать для каждого значения глубины цвета. Последняя секция, в которой может понадобиться правка — "Device". Она предназначена для описания видеокарты. В опции Driver указывается название используемого драйвера. Так, nv — встроенный драйвер для всех видеокарт Nvidia, который практически ничего не умеет. Если у вас установлены "родные" драйверы от Nvidia, то в опции Driver нужно указать "nvidia" (почему и как установить драйверы — ниже).
Теперь, когда вы внесли изменения в xorg.conf, нужно их "применить". Для этого нужно перезапустить только X Server, а вовсе не перегружать всю систему. Самый простой способ перезапустить X Server — волшебная комбинация "Ctrl-Alt-Backspace". Она "убьет" процесс сервера, после чего демон init перезапустит его по новой, если, конечно, он на это настроен. Следующий способ — запустить скрипт /etc/init.d/xdm с параметром restart, как это было описано в прошлом номере. Оставшиеся способы "убивания" процессов обсуждались выше. Теперь поговорим об установке драйверов в целом и для видеокарты в частности. Все современные операционные системы ограничивают доступ пользовательских процессов к аппаратной части. Поэтому доступ к ней можно получить только из режима ядра. А в режиме ядра работает всего один процесс, имя которому — linux. Каким образом драйвера переходят в привилегированный режим? Разумеется, они становятся частью процесса ядра! На самом деле о том, быть ли драйверам в едином с ядром адресном пространстве или создавать для них отдельные процессы, написано множество литературы. Тот же Эндрю Таненбаум очень активно занимается изучением эффективности различных видов ядра: микроядра и монолита. Если упрощенно, то микроядро — это ма-ахонький процесс-супервизор, который всего-то и умеет, что загружать/выгружать процессы ядра. А остальная функциональность ложится на другие процессы включая планирование, распределение памяти, поддержку файловой системы и т.д.
Так устроены операционные системы Windows 2000, QNX, Mach. Монолитное ядро, в отличие от микроядра, представляет собой один гигантских размеров процесс, в адресном пространстве которого содержится вся необходимая функциональность. Так устроены Windows 9x (частично), FreeBSD, Linux и многие другие системы. Разница между монолитом и микроядром, опять же, в безопасности и интерактивности. Так, микроядро гораздо безопаснее монолита, потому что кривой драйвер гарантированно не сможет "подвесить" систему, ведь он находится в отдельном адресном пространстве. Кроме того, микроядро занимает меньше памяти за счет того, что загружает исключительно нужные в данный момент модули. А преимущества монолита в его скорости. Эндрю Таненбаум посчитал, что на передачу сообщений между разными подсистемами ОС с микроядром уходит до 20% процессорного времени — монолит лишен этого недостатка. Когда чуть больше десяти лет назад Линус Торвальдс начинал писать свое ядро (изначально названное Freax, но по совету друзей переименованное в Linux), скорость работы была самым критически важным параметром любой ОС. Представьте сами, какова она была тогда на 386-й машине. Поэтому выбор в сторону монолита был очевиден. Со временем ядро Linux все больше и больше приобретало черты микроядра, и в теперешнем его виде от свойств монолита осталось, наверное, только единое адресное пространство. Дело в том, что микроядро, естественно, более современная парадигма ОС, и все системы стараются развиваться именно в сторону увеличения модульности. Впрочем, у Линуса Торвальдса есть на это свое мнение. Когда вышел первый релиз Linux, Эндрю Таненбаум в сетевой конференции отругал Линуса за монолитность ядра и сказал, что Linux уже создан устаревшим. Лично я считаю, это была банальная зависть, потому как его, Таненбаума, ядро minix хоть и было микроядром, но здорово уступало в эффективности Linux'у. На это Линус Торвальдс в той же конференции ответил, цитирую: "...message passing as the fundamental operation of the OS is just an excercise in computer science masturbation. It may feel good, but you don't actually get anything DONE". Коротко и емко. Так что сегодня Linux — это монолит с чертами микроядра, позволяющими на ходу загружать/выгружать в пространство ядра дополнительные модули. Один из видов модулей ядра — драйверы устройств, так что загрузка драйвера и загрузка модуля — это одно и то же. Команды, которые необходимо знать, чтобы работать с модулями ядра:
1) lsmod — вывести список загруженных модулей;
2) insmod — загрузить указанный модуль;
3) modprobe — загрузить указанный модуль и все остальные, от которых он зависит;
4) rmmod — выгрузить указанный модуль.
Все модули ядра обычно находятся в каталоге /lib/modules и далее в подкаталогах для каждой конкретной версии ядра. В ядрах 2.6.x модули имеют расширение *.ko (kernel object), а в более ранних версиях Linux — *.o. Так что, если вам нужно загрузить, например, driver.ko, то нужно выполнить команду "modprobe driver". Тогда modprobe посмотрит в файле /lib/modules/linux/modules.dep, есть ли у driver'а какие-нибудь зависимости, которые нужно загрузить до загрузки driver.ko. Например, модуль msdos.ko потребует загрузки fat.ko, а fat.ko тоже может зависеть от других модулей и т.д. Утилита modprobe загрузит их все при помощи команды insmod. Таким образом, загрузка стандартных модулей не представляет проблемы. А что если нужно установить драйвер для видеокарты? Во-первых, нужно установить пакет kernel-development, который включает исходники и заголовочные файлы ядра. Фирменные драйверы для устройств обычно распространяются в виде исходных текстов, которые можно собрать и установить как любую другую программу, а при сборке обязательно потребуются заголовочные файлы Linux'а. Но Nvidia пошла дальше и сделала для своих пользователей бинарный файл, в который включено все, что нужно для установки драйверов одним нажатием ввода (кроме самого Linux'а, конечно). Так что идем на сайт www.nvidia.com и качаем соответствующую версию драйверов, затем прибиваем X Server или загружаемся в Single mode (команда "init 1"). Подробно про уровни исполнения системы я рассказывал в прошлом номере. Теперь, когда X Server точно не работает, запускаем установочный файл драйверов для Nvidia, соглашаемся на все (а Nvidia просит только не подавать в суд в случае чего), и вскоре драйвер ядра будет скомпилирован и положен в соответствующий каталог. Если все прошло гладко, то далее нужно его загрузить командой modprobe, затем в файле xorg.conf в секции Device значение опции Driver nv заменить на nvidia, в секции Modules проследить, чтобы не было строки Load "dri", а была Load "glx", и можно стартовать X Server. Если вы уже находитесь на уровне 5, то это можно сделать командой startx или запустить демона X Server'а при помощи скрипта /etc/init.s/xdm. Ну и потом, когда убедитесь, что все работает, нужно проследить, чтобы драйвер nvidia.ko постоянно загружался при старте системы. Один из способов загружать его вместе с системой — написать скрипт по примеру тех, что лежат в /etc/init.d, и сделать на него ссылку в каталоге /etc/init.d/rc5.d.
И последняя важная тема, которой обязательно нужно коснуться — установка/удаление дополнительного ПО. Традиционно в Unix это делалось при помощи сборки программы из исходников и копирования ее туда, куда пользователь пожелает. Так, например, чтобы установить программу proga.tar.gz, сначала ее нужно распаковать командой "tar -zxf proga.tar.gz", перейти в распакованный каталог, почитать README.txt (команда "cat README.txt | less", для выхода из less — клавиша "q") чтобы убедиться, не пропустили ли мы чего-нибудь важного, создать Makefile командой "./configure", затем собрать программу командой "make" и установить командой "make install". Способ этот, конечно, довольно долгий и неудобный. Поэтому все дистрибутивы предоставляют некоторый базовый набор заранее собранных программ и упаковывают их в пакеты — установочные файлы. Сегодня наибольшей популярностью пользуются два формата пакетов: rpm и deb. По сути, это те же архивы, но в них есть установочный скрипт. Соответственно, чтобы установить пакет packet.rpm, нужно выполнить команду "rpm -i packet.rpm". Для packet.deb — "dpkg -i packet.deb". Не удивляйтесь, если вдруг установщик откажется выполнять команду. Некоторые пакеты зависят от остановки других пакетов. Например, 3D-игры будут требовать, чтобы были установлены библиотеки OpenGL. Так что порой приходится вручную довольно долго лазить по всему дистрибутиву, устанавливая сначала все зависимости и зависимости зависимостей, чтобы запустить наконец tuxracer:-). Конечно, эту работу нужно было бы как-то автоматизировать. Тот же Suse Linux предлагает довольно удобную утилиту конфигурирования системы — YaST2. В числе прочего YaST2 позволяет выполнить поиск пакетов среди имеющихся на установочных компактах по имени, описанию и другим параметрам. Выбранные пакеты можно установить, и YaST2 автоматически установит все зависимости; также автоматизировано и удаление пакетов. Аналог YaST2 в дистрибутиве Debian — dselect. Есть еще графические утилиты вроде kpackage. У них у всех один недостаток: эти утилиты реализованы с интерфейсом пользователя. Самая, на мой взгляд, удобная вещь, работающая из командной строки — apt для Debian и apt4rpm для rpm-пакетов. Чтобы пользоваться apt'ом, вам не нужно знать ни полного, с версией, названия пакета, ни где он находится. Просто дайте команду "apt-get install package", и apt сам разберется, где поискать пакет (на установочных компактах, на жестком диске, в локальной сети или в Интернете — в зависимости от настроек), установит самую свежую версию со всеми зависимостями и даже запишет у себя, что куда установил. Так что когда дадите команду "apt-get remove package", apt полностью удалит весь пакет package вместе со всеми его библиотеками, мануалками и прочим мусором.
На этом, я считаю, можно закончить рассказ о "подводных камнях" свежеустановленного Linux'а.
Дмитрий Бушенко, nop@list.ru
Компьютерная газета. Статья была опубликована в номере 35 за 2005 год в рубрике ос