От включения питания до приглашения Bash
Greg O'Keefe, v0.9, Ноябрь 2000
Перевод
WintiX, Январь, 2003
Это краткое описание того, что происходит в системе Linux с момента, когда
вы включаете питание до момента входа в систему и получения командной строки
bash. Понимание этих вещей помогает в решении проблем и настройке системы.
1. Введение
2. Железо
3. Lilo
4. Ядро
Linux
5. Библиотека GNU
C
6. Init
7. Файловая
система
8. Демоны
Ядра
9. Системный
Логгер
10. Getty и
Login
11. Bash
12. Команды
13. Заключение
14. Официальная
часть
Я нахожу огорчительным существование многих вещей в моей Linux, которые я не
понимаю. И, если вы, подобно мне, хотите по настоящему разбираться в вашей
системе, вместо того чтобы просто знать как ею пользоваться, этот документ может
помочь вам начать. Подобные базовые знания будут также необходимымы вам, если вы
хотите стать специалистом по решению проблем Linux.
Я буду предполагать, что вы имеете компьютер работающий под Linux, и имеете
базовые знания системы UNIX и железа PC. Если это не так, обратитесь к
превосходному документу от Эрика Рэймонда (Eric S. Raymond) The
Unix and Internet Fundamentals HOWTO Он краток, понятен и охватывает все
основы.
Главная тема этого документа - как Linux себя запускает. Однако эта тема
попыталась стать несколько шире. Я включил упражнения для каждого раздела и,
если вы действительно выполните их - вы научитесь гораздо большему, чем при
простом чтении.
Надеюсь, что некоторые читатели предпочтут лучшее, из известных мне, учебное
упражнение, а именно - построение системы из исходного кода. Итальянский философ
Giambattista Vico (1668-1744) сказал: ``verum ipsum factum'', что значит:
``понимание приходит через делание''. Спасибо Alex'у (см. Благодарности)
за эту цитату.
Так что, если вы предпочитаете настоящую самостоятельность, вам надо
обратиться к документу Джерарда Бикмана (Gerard Beekmans) Linux From Scratch HOWTO (LFS). LFS
содержит подробные инструкции по построению полнофункциональной системы "с
листа". На сайте LFS вы также найдете почтовую рассылку для личностей, которые
строят системы этим способом. Фрагменты более ранних версий документа,
посвященные данной теме, сейчас выделены в отдельный документ ``Building a
Minimal Linux System from Source Code'', который может быть найден на странице
From PowerUp to Bash
Prompt home page. Он объясняет, как правильно мучить систему в чисто учебных
целях.
Пакеты рассмотрены в порядке их появления при загрузке системы. Это означает,
что если вы устанавливаете пакеты в этом порядке и перегружаете систему после
установки очередного пакета, вы каждый раз будете оказываться немного ближе к
появлению командной строки bash, ощущая неумолимую поступь прогресса.
Рекомендую вам начинать с чтения основного текста каждого раздела, пропуская
упражнения и ссылки. Затем вы можете решить, насколько глубоко вы хотите понять
данную тему и какие усилия вы готовы на это потратить, после чего можно начинать
сначала, выполняя упражнения и изучая дополнительные материалы.
Когда вы включаете компьютер, он выполняет самотестирование дабы быть
уверенным, что всё в порядке. Это называется "Самотестирование при включении"
(``Power on self test''- POST). Затем начальный загрузчик, размещенный в ROM
BIOS, ищет загрузочный сектор. Этот сектор является первым сектором диска и
содержит небольшую программу для загрузки операционной системы. Загрузочные
сектора помечаются "волшебным" числом 0xAA55 = 43603 в позиции 0x1FE = 510. Это
последние два байта сектора. Это позволяет компьютеру решить является ли данный
диск загрузочным.
Начальный загрузчик имеет список мест для поиска загрузочных секторов. Моя
старая машина ищет на первом флоппи, затем на первом винчестере. Более
современные машины могут просматривать CD-ROM. Если он находит загрузочный
сектор, он загружает его содержимое в оперативную память и передает управление
программе, которая продолжает процесс загрузки ОС. На типичной Linux-машине это
будет программа первого шага загрузчика LILO. Существует много способов и
конфигураций процесса загрузки. Подробности можно почерпнуть в LILO User's
Guide. Ссылки приведены в разделе LILO.
На самом деле о железе PC и его поведении можно рассказать гораздо больше. Но
здесь не место. На эту тему есть много хороших книг.
Машина хранит информацию о настройках в CMOS. В том числе там хранятся
сведения о дисках и количестве оперативной памяти. BIOS содержит специальную
программу, позволяющую вам изменять эти настройки. Следите за сообщениями на
экране сразу после включения машины чтобы определить какой клавишей прозводится
запуск этой программы. На моей машине необходимо нажать клавишу Delete до начала
загрузки ОС.
Хорошим способом изучения железа PC являетс самостоятельная сборка компьютера
из б/у частей. Для запуска Linux нужна машина с процессором от 386. Это не может
дорого стоить. Расспросите друзей и знакомых - наверняка что-нибудь найдете.
Загрузите, скомпилируйте и создайте загрузочный диск для Unios. (В качестве их
домашней страницы значится http://www.unios.org/, но это не работает) Это
всего лишь загрузочная программа ``Hello World!'', состоящая из немногим более
100 строк ассемблерного кода. Было бы не плохо увидеть её преобразованной к
формату ассемблера GNU as
.
Откройте образ загрузочного сектора unios в шеснадцатеричном редакторе. Этот
файл содержит 512 байт - ровно один сектор. Найдите "волшебное число" 0xAA55.
Проделайте тоже самое с загрузочной дискетой или диском вашего компьютера. Вы
можете использовать команду dd
для копирования сектора в файл:
dd if=/dev/fd0 of=boot.sector
. Будьте весьма аккуратны при
назначении параметров if
(input file) и of
(output
file)!
Прочитайте исходные тексты загрузчика LILO.
- The
Unix and Internet Fundamentals HOWTO Эрика Рэймонда (Eric S. Raymond),
особенно раздел 3, What happens when you switch on a computer?
- Первая часть The LILO User's Guide дает прекрасное представление
о разбиении дисков и загрузке. Ссылки в разделе LILO.
- The NEW Peter Norton Programmer's Guide to the IBM PC & PS/2,
Питера Нортона и Ричарда Уилтона (Richard Wilton), Microsoft Press 1988 Это
новая книга Нортона, которая хорошо выглядит, но сейчас я не могу себе её
позволить.
- Одна из множества книг по апгрейду PC
Когда компьютер загружает загрузочный сектор на нормальной Linux-машине, то
что он загружает является частью lilo (LInux LOader), называемой загрузчиком
первого этапа. Эта крохотная программа имеет единственной целью своего
существования загрузку и выполнение загрузчика второго этапа.
Загрузчик второго этапа предоставляет вам возможность выполнения команд и
может загружать ОС по выбору.
Когда система установлена и запущена, вы можете выполнить команду
lilo
. В этом случае отрабатывает ``map installer''. Он зачитывает
файл настроек /etc/lilo.conf
и записывает загрузчики на жесткий
диск.
Есть множество способов организации загрузки вашей системы. То, что я описал,
является наиболее очевидным и "нормальным", по крайней мере для машин, где
главной ОС является Linux. Lilo Users' Guide рассматривает несколько примеров
стратегий загрузки. С этим стоит ознакомиться, а кое-что и опробовать на
практике.
Настройки lilo хранятся в файле /etc/lilo.conf
. По этому файлу
существует свой ман: наберите в шелле man lilo.conf
. Главным
содержанием lilo.conf
являются строки описания для всех систем,
которые мы можем грузить с помощью lilo. Описание для Linux содержит сведения о
местонахождении ядра системы и о разделе диска, который будет смонтирован в
качестве корневой файловой системы. Для других ОС основной информацией является
указание раздела диска, с которого необходимо загрузиться.
ЭТО ОПАСНО: будте осторожны с этими упражнениями. Здесь легко
ошибиться, испортить главную загрузочную запись (MBR) и привести систему в
нерабочее состояние. Убедитесь, что у вас есть работающая загрузочная дискета и
вы знаете как с её помощью восстанавливать загрузочные сектора. Ниже приведена
ссылка на tomsrtbt - спасательный диск, который я использую и могу
рекомендовать. Лучшая предосторожность - использовать машину на которой нет
ничего важного.
Установите lilo на дискету. Неважно если там не окажется ничего кроме ядра -
вы получите ``kernel panic'', когда ядро будет готово загрузить init, но по
крайней мере вы убедитесь, что lilo работает.
Продолжайте и наблюдайте как много системы вы сможете запихнуть на одну
дискету. Кажется это второй из лучших способов изучения Linux. За справками
обращайтесь к Bootdisk HOWTO и tomsrtbt (ссылки приведены ниже).
Заставьте lilo грузить unios (см. раздел железо/упражнения).
Будет совсем круто, если вы сможете проделать это на дискете.
Создайте загрузочную петлю. Пусть lilo в MBR грузит lilo в одном из
загрузочных секторов первичных разделов диска. Последнюю надо заставить грузить
lilo из MBR... Возможно также использовать MBR и все четыре первичных раздела
диска для создания пятиузлового кольца. Наслаждайтесь!
- Страница man lilo.
- Пакет Lilo ( lilo), содержит ``LILO
User's Guide''
lilo-u-21.ps.gz
(или более поздний). Скорее всего
вы уже имеете этот документ. Посмотрите в /usr/doc/lilo
или
где-то рядом. Постскриптовская версия лучше текстовой, поскольку содержит
графики и таблицы.
- tomsrtbt крутейший однодискетный
Linux. Создаёт прекрасную спасательную дискету.
- The Bootdisk
HOWTO
Ядро выполняет множество полезной работы. Думаю, что правильно
охарактеризовать его задачу можно так: оно заставляет железо выполнять задания
программ точно, надежно и эффективно.
Процессор может единовременно выполнять только одну инструкцию, однако в
системе Linux выполняются одновременно множество вещей. Ядро достигает этого
быстрым переключением с задачи на задачу. Это приводит к лучшему использованию
процессора, т.к. ядро отслеживает какие процессы готовы активно выполняться, а
какие ожидают чего-либо вроде записи в файл или ввода с клавиатуры. Эта задача
ядра называется scheduling.
Если программа ничего не делает -- её не надо держать в оперативной памяти.
Если даже она что-то делает, могут найтись части, которые не делают ничего.
Адресное пространство каждого процесса разделено на страницы. Ядро следит за
тем, какие страницы каких процессов используются чаще. Редко используемые
страницы могут быть перемещены в своп-раздел. Когда они понадобятся снова,
другие неиспользуемые страницы перемещаются в своп, освобождая место в памяти.
Это называется управлением виртуальной памятью.
Если вы уже компилировали своё собственное ядро, вы должны были заметить
множество опций для различных устройств. Ядро содержит множество специального
кода для взаимодействия с разнообразными видами железа и представляет все это
для приложений достаточно простым и стандартным способом.
Ядро также управляет файловой системой, межпроцессным взаимодействием и всей
этой сетевой кухней.
Будучи загруженным в память, первой задачей ядра является поиск и запуск
программы init
.
Большинство настроек ядра выполняется при его построении посредством
make menuconfig
, или make xconfig
в
/usr/src/linux/
(или где вы там держите исходники ядра). С помощью
rdev
вы можете изменить видеомоду по умолчанию, корневую файловую
систему, раздел для свопа и размер RAM-диска. Эти и другие параметры могут быть
также переданы ядру через lilo. При этом передаваемые параметры могут быть
прописаны в lilo.conf или могут быть введены в строке подсказки lilo в процессе
загрузки. Например, если вам понадобилось использовать в качестве корневого
раздел hda3 вместо hda2, вы должны ввести:
LILO: linux root=/dev/hda3
Если вы строите систему из исходников, вы можете упростить себе жизнь, создав
"монолитное" ядро. Такое ядро не имеет загружаемых модулей. Следовательно вам не
понадобится копировать модули ядра на целевую систему.
ВАЖНО: Файл System.map
используется логгером ядра для
определения имен модулей, посылающих сообщения. Программа top
также
использует эту информацию. Так что, копируя ядро на целевую систему, не забудьте
скопировать и System.map
.
Осмысли следующее: /dev/hda3
является файлом специального типа и
описывает раздел жесткого диска. Однако он находится в файловой системе подобно
другим файлам. В момент, когда ядру надо решить который из разделов будет
смонтирован в качестве корневого, ядро ещё не имеет файловой системы. Как же
ядру прочитать /dev/hda3
чтобы смонтировать раздел?
Постройте собственное ядро, если вы ещё не сделали этого. Прочтите всю
документацию по каждой из опций настройки.
Выясните насколько маленькое (работоспособное) ядро вы сможете создать. Вы
сможете многому научиться избавляясь от ошибок.
Прочтите ``The Linux Kernel'' (URL приведен ниже) и последовательно
отыскивайте соответствующие части исходного кода. На момент напмсания данного
документа эта книга описывала ядро версии 2.0.33, которое явно устарело.
Возможно будет проще скачать исходные тексты для старой версии. Как приятно
обнаруживать куски C-кода озаглавленные ``process'' и ``page''.
Хакайте! Посмотрим, сможете ли вывести какие-либо дополнительные сообщения
или что-то ещё.
Следующей, после загрузки ядра, вещью, является запуск процесса init. Однако
init, подобно другим программам, использует вызовы функций из системных
библиотек.
Вы наверняка знакомы с демо-программами похожими на эту:
main() {
printf("Hello World!\n");
}
Программа не содержит определения функции printf
, так откуда она
её вызывает? Функция берется из стандартной библиотеки C, в системе GNU/Linux
это glibc. Если вы скомпилируете её под Visual C++, функция будет взята из
стандартной библиотеки реализации Microsoft. Существуют зиллионы стандартных
функций для математических и строковых операций, манипулирования датой/временем,
оперативной памятью и т.д. и т.п. Всё в мире Unix (включая Linux) либо написано
на C либо старается быть написанным, так что всё использует эти функции.
Если вы заглянете в /lib
на вашей Linux машине, вы обнаружите
множество файлов libsomething.so
или libsomething.a
и
т.п. Это библиотеки таких функций. Glibc является просто реализацией этих
функций проектом GNU.
Для программ существует два способа использования библиотечных функций. Если
программа собирается статически, эти функции будут скопированы в
создаваемый исполняемый код. Код при этом будет взят из библиотеки типа
libsomething.a
. Если программа собирается динамически,
(что происходит по умолчанию) эти функции будут загружаться при выполнении
программы по мере надобности. При этом будет использован код из файлов типа
libsomething.so
.
Команда ldd
будет вашим помощником, если вам понадобится
выяснить какие библиотеки нужны для работы некоторой программы. В качестве
примера приведу список библиотек необходимых для запуска bash
:
[greg@Curry power2bash]$ ldd /bin/bash
libtermcap.so.2 => /lib/libtermcap.so.2 (0x40019000)
libc.so.6 => /lib/libc.so.6 (0x4001d000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Некоторые из библиотечных функций зависят от вашего места обитания. Например
у нас в Австралии дату пишут как dd/mm/yy, а американцы пишут mm/dd/yy. Glibc
предоставляет специальную программу для настройки национальных особенностей -
localedef
.
Используя ldd
, выясните какие библиотеки использует ваше любимое
приложение.
Используя ldd
, выясните какие библиотеки использует программа
init.
Создайте игрушечную библиотеку с одной - двумя функциями. Для создания
библиотек используется программа ar
, так что начать следует с
чтения соответствующего ман(уала). Напишите, скомпилируйте и соберите программу,
которая будет использовать эту библиотеку.
Я расскажу вам только о программе init в стиле ``System V'', которая
используется большинством Linux систем. Существуют и другие варианты. На самом
деле вы можете поместить любую программу в /sbin/init
и ядро
запустит её как только закончит загружаться.
Задачей init
'а является запуск всего остального нужным образом.
Он проверяет состояние файловых систем и монтирует их. Он запускает демонов для
записи системных сообщений, сетевого взаимодействия, обслуживания веб-страниц,
обработки сообщений мыши и т.п. Он также запускает процессы getty, которые
выдают запросы на вход в систему на ваших виртуальных терминалах.
Я мог бы расказать вам длинную историю о проблеме переключения "уровней
запуска" (``run-levels''), однако я пропущу большую её часть, остановившись
исключительно на моментах связанных с запуском системы.
Init читает файл /etc/inittab
, в котором содержатся инструкции
для дальнейшей работы. Первой инструкцией, обычно, является запуск скрипта
инициализации. Программой, которая будет выполнять (интерпретировать) данный
скрипт, является bash
, та самая программа, которая предоставляет
вам командную строку. В системах, основанных на Debian, скриптом инициализации
будет /etc/init.d/rcS
, в Red Hat -
/etc/rc.d/rc.sysinit
. Это то место где происходит проверка и
монтирование файловых систем, установка часов системного времени, включение
своп-раздела, присвоение имени хоста и т.д.
Далее будет вызван следующий скрипт, который переведёт нас на "уровень
запуска" по умолчанию. Это подразумевает просто некоторый набор подсистем,
которые должны быть запущены. Для обслуживания уровней запуска существует набор
директорий /etc/rc.d/rc0.d
, /etc/rc.d/rc1.d
, ...,
/etc/rc.d/rc6.d
в Red Hat, или /etc/rc0.d
,
/etc/rc1.d
, ..., /etc/rc6.d
в Debian, которые отвечают
за соответствующие уровни. Когда мы заходим на "уровень запуска" 3 в Debian,
этот скрипт будет запускать все скрипты в /etc/rc3.d
, начинающиеся
на букву `S' (старт). Эти скрипты обычно являются символьными ссылками на
скрипты расположенные в init.d
.
Итак, скрипт "уровня запуска", вызван процессом init
и ищет в
соответствующей директории скрипты начинающиеся на `S'. Пусть первым
обнаруженным файлом окажется S10syslog
. Порядок запуска скриптов
определяется номерами. В нашем случае S10syslog
оказался первым,
поскольку не нашлось скриптов, начинающихся на S00 ... S09. На самом деле
S10syslog
является ссылкой на /etc/init.d/syslog
,
который и является скриптом, отвечающим за запуск и остановку системного
логгера. Поскольку ссылка начинается на `S', скрипт "уровня запуска" запустит
syslog
с параметром ``start''. Ссылки, названия которых начинаются
на `K' (kill, убить) определяют порядок действий при останове системы или при
переходе на другой "уровень запуска".
Для изменения списка подсистем, запускаемых по умолчанию, вы должны
установить соответствующие ссылки в директории rcN.d
, где N -
"уровень запуска" по умолчанию, установленный в вашем inittab
.
Последним важным действием init является запуск некоторого количества
getty
. Они прописываются как ``respawned'', что означает - если
данный процесс будет остановлен, init
запустит его снова.
Большинство дистрибутивов используют шесть виртуальных терминалов. Вы можете
захотеть уменьшить их количество для экономии памяти, или, наоборот, увеличить,
что позволит запускать множество приложений одновременно и быстро переключаться
между ними по мере надобности. Также может возникнуть потребность в запуске
getty
на текстовом терминале или при подключении по модему. В этом
случае вам надо будет отредактировать файл inittab
.
Файлом верхнего уровня настройки init является /etc/inittab
.
Директории rcN.d
, где N = 0, 1, ..., 6 определяют какие
подсистемы и в каком порядке будут запущены.
В одном из скриптов, вызываемых init, будет использована команда mount
-a
. Это приказ смонтировать все файловые системы какие должны быть
смонтированы. Последнее определяется файлом /etc/fstab
. Вы можете
отредактировать этот файл, если решите изменить список файловых систем,
монтируемых при старте системы. Синтаксис файла описан в man fstab
.
Найдите директорию rcN.d
для вашего "уровня запуска" по
умолчанию и выполните команду ls -l
, чтобы узнать на какие файлы
указывают ссылки.
Измените количество виртуальных терминалов в системе.
Уберите любую не нужную вам подсистему из "уровня запуска" по умолчанию.
Оцените сколько вам удалось сэкономить на старте.
Создайте загрузочную дискету с lilo, ядром и "статически" собранной
программой "hello world", причем последнюю назовите /sbin/init
.
Убедитесь, что система грузится и приветствует вас как положено.
Отследите все сообщения, выдаваемые системой при запуске. Или распечатайте
содержимое системного журнала /var/log/messages
с момента
последнего старта. Затем, начиная с inittab
, проследуйте по всем
выполненным скриптам, отмечая кто что делает. Вы также можете вставить в скрипты
дополнительные сообщения типа
echo "Hello, I am rc.sysinit"
Это упражнение помогает также в изучении техники написания скриптов под bash.
Некоторые из скриптов устроены весьма непросто, поэтому справочник по командам
bash окажется весьма кстати.
В данном разделе я буду использовать терми "файловая система" в двух разных
смыслах. Есть файловые системы на разделах дисков и других устройствах, и есть
файловая система как она представлена для вас работающей системой Linux. Под
Linux вы монтируете дисковые файловые системы в системную файловую систему.
В предыдущем разделе я упомянул, что скрипты загрузки проверяют и монтируют
файловые системы. Эти действия выполняются соответственно командами
fsck
и mount
.
Жесткий диск - это просто большое пространство, на котором можно записывать
единицы и нули. Файловая система предлагает метод структурирования информации на
диске и представляет нам его в виде файлов, размещенных внутри директорий ,
размещенных внутри директорий, размещенных внутри директорий... Каждый файл
представлен inode, который знает чей это файл, когда создан и где размещено его
содержимое. Директории таже представляются inod'ами, которые знают где найти
inod'ы файлов принадлежащих данной директории. Если система хочет прочитать
/home/greg/bigboobs.jpeg
, она во-первых должна отыскать inode для
корневой директории /
в суперблоке, затем найти inode для
директории home
в содержимом /
, затем директорию
greg
в содержимом /home
, затем inode для
bigboobs.jpeg
который скажет какие блоки диска следует прочитать.
Если мы добавляем некоторые данные в конец файла, может случиться так, что
данные будут записаны на диск до того как содержание inode для этого файла
успеет обновиться, или наоборот. Если питание компьютера будет отключено в этот
момент, файловая система будет попорчена. Это тот случай, который должен быть
определен командой fsck
, она же предринимает попытку
восстановления.
Команда mount
берет файловую систему устройства и добавляет её в
иерархию, которую вы привыкли наблюдать работая в системе. Обычно ядро монтирует
корневую файловую систему в режиме "только для чтения". Команда
mount
перемонтирует её в режиме "чтение/запись" после того как она
проверена fsck
.
Система Linux поддерживает некоторые другие файловые системы: msdos, vfat,
minix и т.п. Специфические детали этих систем скрыты путем использования
абстракции виртуальной файловой системы (VFS). Мне бы не хотелось вдаваться в
детали. Обсуждение этой темы есть в ``The Linux Kernel''. (для ссылок см. раздел
Ядро
Linux)
Существенно иной вид файловой системы смонтирован в /proc
. Это
некоторое представление объектов ядра. Здесь присутствуют директории для для
каждого запущенного процесса, причем номер процесса используется в качестве
имени директории. Присутствуют также такие файлы как interrupts
и
meminfo
, которые могут сообщить информацию об используемом железе.
Исследуя /proc
, вы можете многому научиться.
Команда mke2fs
, создающая файловую систему типа ext2, имеет
параметры, управляющие размером блока, числом inode и т.п. Прочтите ман для
mke2fs
, чтобы уточнить детали.
Всё, что должно быть смонтировано в вашей файловой системе определяется
файлом /etc/fstab
. По этому файлу также имеется ман.
Создайте очень маленькую файловую систему и рассмотрите её с помощью
шестнадцатеричного вьюера. Найдите inod'ы, суперблоки и содержимое файла.
Я верю в существование программ, которые представляют файловую систему в
графическом виде. Найдите, опробуйте и пришлите мне ссылку и ваши впечатления.
Исследуйте код ядра, относящийся к файловой системе ext2.
- Превосходное описание файловых систем есть в разделе 9 книги LDP ``The
Linux Kernel''. Вы найдете её на Австралийском зеркале проекта LDP.
- Команда
mount
является частью пакета util-linux, ссылка на
него приведена в Building
a Minimal Linux System from Source Code
- Страницы ман для
mount
, fstab
,
fsck
, mke2fs
и proc
- Файл
Documentation/proc.txt
в исходном коде Linux описывает
файловую систему /proc
.
- Утилиты для файловой системы EXT2: ext2fsprogs -
домашняя страница и ext2fsprogs
- Австралийское зеркало. Здесь также был обзор файловой системы Ext2fs, однако
он устарел и читается хуже, чем 9-я глава из ``The Linux Kernel''
- Unix File
System Standard и другая ссылка
на the Unix File System Standard. Стандарт описывает что и где должно
находится в файловой системе Unix и почему. Сформулированы также минимальные
требования к содержимому директорий
/bin
, /sbin
и
т.д. Это хороший источник информации если вы поставите себе задачу создания
минимальной, но полной системы.
Когда вы используете команду ps aux
, вы видите нечто вроде
приведенного ниже:
USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND
root 1 0.1 8.0 1284 536 ? S 07:37 0:04 init [2]
root 2 0.0 0.0 0 0 ? SW 07:37 0:00 (kflushd)
root 3 0.0 0.0 0 0 ? SW 07:37 0:00 (kupdate)
root 4 0.0 0.0 0 0 ? SW 07:37 0:00 (kpiod)
root 5 0.0 0.0 0 0 ? SW 07:37 0:00 (kswapd)
root 52 0.0 10.7 1552 716 ? S 07:38 0:01 syslogd -m 0
root 54 0.0 7.1 1276 480 ? S 07:38 0:00 klogd
root 56 0.3 17.3 2232 1156 1 S 07:38 0:13 -bash
root 57 0.0 7.1 1272 480 2 S 07:38 0:01 /sbin/agetty 38400 tt
root 64 0.1 7.2 1272 484 S1 S 08:16 0:01 /sbin/agetty -L ttyS1
root 70 0.0 10.6 1472 708 1 R Sep 11 0:01 ps aux
Это список процессов, выполняющихся в системе. Информация берется из файловой
системы /proc
, описанной в предыдущем разделе. Заметьте, что
init
всегда имеет номер один. Процессами номер 2, 3, 4 и 5 являются
kflushd, kupdate, kpiod и kswapd. Есть в них нечто странное: в обеих колонках
виртуального размера (SIZE) и реального размера (RSS) стоят нули. Как процесс
может не использовать память?
Эти процессы являются демонами ядра. Большая часть функций ядра не
проявляется в списке процессов, и вы можете оценить объем потребляемой ядром
памяти только путем вычитания доступной памяти из общего размера памяти
компьютера. Демоны ядра стартуют после init и, следовательно, получают номера
подобно другим процессам. Но их код и данные остаются в памяти, принадлежащей
ядру.
Имена этих процессов заключены в скобки, поскольку файловая система
/proc
не имеет информации о командах, которыми эти процессы были
запущены.
Так для чего нужны демоны ядра? Предыдущие версии документа содержали просьбу
о помощи, так как я очень мало знал о демонах ядра. Последующее изложение было
собрано из нескольких разных откликов на эту просьбу, за которые я весьма
признателен. Приветствуются и будущие советы, ссылки и исправления!
Ввод и вывод выполняются через расположенные в памяти буферы. Это
позволяет программам выполняться быстрее. То, что программа записывает может
быть сохранено в памяти, в буфере, и записано на диск позднее, более крупной и
эффективной порцией. Эта работа выполняется демонами kflushd
и
kupdate
: kupdate
выполняется периодически (5 секунд?)
проверяя существование "грязных" буферов. Если таковые присутствуют, он
командует kflushd
записать их на диск.
Процессы часто остаются без работы, а некоторым нет необходимости держать
весь свой код и данные в памяти. Это значит, что мы могли бы использовать память
лучшим образом, перемещая неиспользуемые части программ в своп-раздел(ы) на
жестком диске. Работа по перемещению данных и кода из памяти на диск и обратно
выполняется демонами kpiod
и kswapd
. Каждую секунду
или около того kswapd
просыпается чтобы проверить обстановку в
памяти и, если что-либо требуется загрузить из свопа в память или не хватает
свободной памяти он вызывает kpiod
.
Если вы настроили использование автоматического управления питанием (APM),
здесь будет присутствовать и демон kapmd
.
Программа update
позволяет настроить kflushd
и
kswapd
. Для справки наберите update -h
.
Включение свопа происходит по команде swapon
, а выключение - по
команде swapoff
. Скрипт инициализации (/etc/rc.sysinit
или /etc/rc.d/rc.sysinit
) обычно вызывает swapon
.
Использование swapoff
позволяет экономить энергию на ноутбуках.
Выполните update -d
, и обратите внимание на предупреждение в
последней строке относительно нарушения границ (?) (``threshold for buffer
fratricide''). В настоящий момент это не понятно, давайте исследовать!
Перейдите в директорию /proc/sys/vm
выполните cat
для файлов этой директории. Посмотрите что с этим можно сделать.
``The Linux Kernel'' из LDP (The Linux Documentation Project) (для сылок см.
раздел The
Linux Kernel)
Исходные тексты ядра Linux, если вы достаточно отважны! Код
kswapd
обитает в linux/mm/vmscan.c
, коды
kflushd
и kupdate
живут в
linux/fs/buffer.c
.
Init запускает демонов syslogd
и klogd
. Они
занимаются записью сообщений в журналы (логи). Сообщения ядра обрабатывает
klogd
, а syslogd
обрабатывает сообщения от остальных
процессов. Главным журналом является /var/log/messages
. Это
правильное место для поиска неисправностей в системе. Часто здесь можно
обнаружить решение проблемы.
Файл /etc/syslog.conf
разъясняет логгерам какие сообщения куда
записывать. Сообщения различаются по имени службы, от которой они исходят, и
уровню приоритета. Строки этого файла содержат информацию о том, что сообщения
от службы x с приоритетом y следует направлять в z, где z - файл, терминал,
принтер, удаленный хост или что угодно.
ВАЖНО: Syslog требует присутствия файла /etc/services
. Этот файл
отвечает за распределение портов. Я не знаю, то ли syslog нуждается в портах для
выполнения удаленного журналирования, то ли локальное журналирование происходит
через порт, а может быть syslog просто использует /etc/services
для
преобразования имени службы которое вы прописали в /etc/syslog.conf
к номеру порта.
Загляните в системный журнал. Найдите непонятное вам сообщение и отыщите
информацию о том что оно значит.
Направьте все сообщения на терминал (tty). (Потом верните всё обратно).
Австралийское зеркало
syslogd
Getty - это программа, которая позволяет вам войти в систему через устройство
последовательного доступа такое как виртуальный терминал, текстовый терминал или
модем. Она отображает приглашение для регистрации (login prompt). Получив от вас
имя пользователя getty передает его login
'у, который запрашивает
пароль, проверяет его и предоставляет вам шелл.
Существует много getty. Некоторые дистрибутивы, включая Red Hat, используют
один из самых маленьких - mingetty
, который поддерживает только
виртуальные терминалы.
Программа login
является частью пакета util-linux, который также
включает хорошо работающий getty - agetty
. Этот пакет содержит
также mkswap
, fdisk
, passwd
,
kill
, setterm
, mount
,
swapon
, rdev
, renice
, more
(программу) and more (т.е. больше программ).
Сообщение, появляющееся вверху экрана вместе с приглашением ввести имя
пользователя, прописывается в /etc/issue
. Getty запускаются из
/etc/inittab
. Login проверяет сведения о пользователе в
/etc/passwd
, и, если используется механизм теневых паролей, в
/etc/shadow
.
Создайте файл /etc/passwd
вручную. Пароли могут быть установлены
в null и изменены программой passwd
после регистрации. Прочтите ман
на этот файл. Запустите его командой man 5 passwd
чтобы получить
информацию о файле, а не о программе.
Если вы ввели правильную комбинацию имя пользователя/пароль,
login
выберет из файла /etc/passwd
шелл, который нужно
для вас загрузить. Для Linux систем в большинстве случаев это будет
bash
. Работа bash
заключается в том, чтобы читать ваши
команды и следить за тем, чтобы они были выполнены. Он является и интерфейсом
пользователя и интерпретатором командного языка.
Как интерфейс пользователя он читает ваши команды и выполняет их сам (если
это "внутренние" команды типа cd
) или находит и выполняет программу
(т.е. "внешнюю" команду типа cp
или startx
). Он также
проделывает такие приятные вещи как сохранение истории команд и автоматическое
завершение имени файла.
Мы уже наблюдали работу bash
в качестве интерпретатора языка
программирования. Скрипты, запускаемые программой init
при старте
системы являются обычно сценариями оболочки и выполняются при помощи
bash
. Сочетание удобного языка программирования с обычными
системными утилитами, доступными из командной строки, представляет очень мощную
комбинацию в случае, если вы знаете что делаете. Например (включен режим
самодовольства) мне необходимо применить большой набор патчей к директории
содержащей некоторые исходные тексты. Я могу сделать это, набрав единственную
команду:
for f in /home/greg/sh-utils-1.16*.patch; do patch -p0 < $f; done;
Будут найдены все файлы в моей домашней директории, чьи имена начинаются на
sh-utils-1.16
и заканчиваются на .patch
. Далее в цикле
переменной f
будут присваиваться имена этих файлов и выполняться
команды заключенные между операторами do
и done
. В
данном случае присутствовало всего 11 файлов-патчей, но это было-бы также просто
будь их хоть 3000.
Файл /etc/profile
содержит общесистемные настройки bash. То что
вы здесь напишете повлияет на каждого, кто использует bash в вашей системе.
Обычно здесь выполняются такие вещи как добавление директорий к переменной
PATH
, и установка переменных типа MAIL
.
Поведение клавиатуры по умолчанию обычно оставляет желать лучшего. Эти
проблемы решаются с помощью readline. Readline - это отдельный пакет, который
поддерживает интерфейс командной строки, предоставляя историю команд и
автозавершение имен файлов, также как и расширенные возможности редактирования.
Он вкомпилирован в bash. По умолчанию readline настраивается редактированием
файла .inputrc
в вашей домашней директории. Переменная bash INPUTRC
позволяет это изменить. Например в Red Hat 6 INPUTRC
установлена в
/etc/inputrc
в /etc/profile
. Это значит, что клавиши
backspace, delete, home и end будут работать для всех одинаково хорошо.
Прочтя общесистемный файл настройки, bash ищет ваш персональный файл
настройки. Он ищет его в вашей домашней директории проверяя имена
.bash_profile
, .bash_login
и .profile
.
Выполняется первый из найденных файлов. Если вы хотите изменить поведение bash
только для себя - делайте это здесь. Например, многие приложения используют
переменные окружения для контроля собственной работы. Я имею переменную
EDITOR
установленной в значение vi
и могу использовать
vi в Midnight Commander'е (превосходный консольный файл-менеджер) вместо его
встроенного редактора.
Основы bash легки в изучении. Однако вам не следует останавливаться: глубины
невообразимы. Заведите привычку всегда искать лучшие пути для выполнения работы.
Читайте скрипты, найдите вещи которые вы не понимаете.
- Существует ``Bash Reference Manual'' достаточно понятный, но не слишком
легкий для чтения.
- Есть также книга про Bash издания O'Rielly, не уверен, что хорошая.
- Я не знаю ни одного хорошего, свежего и свободного учебника по bash. Если
вы знаете, пришлите пожалуйста ссылку.
- Исходные тексты, ссылки на странице Building a Minimal Linux
System from Source Code
Большинство работы в bash может быть выполнено с использованием команд типа
cp
. Большинство из этих команд являются небольшими программами,
однако некоторые (типа cd
) встроены в шелл.
Команды собраны в пакеты, многие из которых разработаны Фондом Свободного ПО
(Free Software Foundation or GNU). Вместо перечисления пакетов я направлю вас к
документу Linux From Scratch
HOWTO. Там вы найдете полный и свежий перечень пакетов, работающих с Linux,
также как и инструкции по их сборке.
Лучшей чертой Linux, по моему скромному мнению, является то, что вы можете
залезть вовнутрь и разобраться как оно работает. Я надеюсь, что вы сможете
насладиться этим не менее чем я. Я также надеюсь, что эти небольшие заметки
помогут вам преуспеть в этом занятии.
Авторские права на этот документ принадлежат (c) 1999, 2000 Greg O'Keefe. Вы
можете использовать, копировать, распространять или изменять этот документ не
взымая за это денег, следуя соглашениям Общественной Лицензии GNU - GNU General Public Licence.
Прошу уведомить меня, если вы используете его целиком или частично как часть
другого документа.
Последнюю версию этого документа можно найти на From Powerup To Bash
Prompt также как и сопутствующий материал ``Building a Minimal Linux System
from Source Code''.
Перевод на французский: From
Powerup To Bash Prompt спасибо Dominique van den Broeck. Японский перевод
Yuji Senda ожидается, если его ещё нет на Japanese Documentation and FAQ Project
Буду признателен за любые комментарии, критику и предложения по улучшению.
Пожалуйста, присылайте их мне: Greg O'Keefe
Названия продуктов являются торговыми марками соответствующих владельцев.
Есть несколько людей, которым я хотел бы сказать спасибо за помощь в
подготовке этого документа.
- Michael Emery
-
За напоминание про Unios.
- Tim Little
-
За несколько хороших советов по поводу /etc/passwd
- sPaKr on #linux in efnet
-
Который заметил, что syslogd требует присутствия
/etc/services
, и подсказал мне выражение ``rolling your own''
применительно к построению системы из исходного кода.
- Alex Aitkin
-
За привлечение моего внимания к Vico и его ``verum ipsum factum''
(понимание приходит через делание).
- Dennis Scott
-
За исправление моей шеснадцатеричной арифметики.
- jdd
-
За указание нескольких опечаток.
- David Leadbeater
-
За вклад в тему демонов ядра.
- Dominique van den Broeck
-
За перевод этого документа на французский.
- Matthieu Peeters
-
За полезную информацию о демонах ядра.
- John Fremlin
-
За полезную информацию о демонах ядра.
- Yuji Senda
-
За перевод этого документа на японский.
- Antonius de Rozari
-
предоставившему версию UNIOS на ассемблере GNU (см. раздел ресурсов на
домашней странице)
0.8 -> 0.9 (November 2000)
- Incorporated some information from Matthieu Peeters and John Fremlin on
kernel deamons and the
/proc
filesystem.
0.7 -> 0.8 (September 2000)
- Removed instructions on how to build a system, placing them in a separate
document. Adjusted a few links accordingly.
- Changed homepage from http://learning.taslug.org.au/power2bash
to my own webspace.
- Completely failed to incorporate a lot of good material contributed by
various people. Maybe next time :(
0.6 -> 0.7
- more emphasis on explanation, less on how to build a system, building info
gathered together in a separate section and the system built is trimmed down,
direct readers to Gerard Beekmans' ``Linux From Scratch'' doc for serious
building
- added some ramblings contributed by David Leadbeater
- fixed a couple of url's, added link to unios download at
learning.taslug.org.au/resources
- tested and fixed url's
- generally rewrite, tidy up
0.5 -> 0.6
- added change history
- added some todos
- объяснить работу модулей ядра, depmod, modprobe, insmod и всё такое (я
буду должен сначала это найти!)
- описать файловую систему /proc, возможно добавить упражнений
- преобразовать в docbook sgml
- добавить упражнений, возможно целый раздел больших упражнений, типа
создания минимальной системы путём добавления файла за файлом из
дистрибутивной инсталляции.
- add makefile hack to bash build instructions - see easter notes.