От включения питания до приглашения Bash

Greg O'Keefe, gcokeefe@postoffice.utas.edu.au

v0.9, Ноябрь 2000

Перевод WintiX, wintix@bk.ru

Январь, 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. Официальная часть


1. Введение

Я нахожу огорчительным существование многих вещей в моей 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, ощущая неумолимую поступь прогресса.

Рекомендую вам начинать с чтения основного текста каждого раздела, пропуская упражнения и ссылки. Затем вы можете решить, насколько глубоко вы хотите понять данную тему и какие усилия вы готовы на это потратить, после чего можно начинать сначала, выполняя упражнения и изучая дополнительные материалы.


2. Железо

Когда вы включаете компьютер, он выполняет самотестирование дабы быть уверенным, что всё в порядке. Это называется "Самотестирование при включении" (``Power on self test''- POST). Затем начальный загрузчик, размещенный в ROM BIOS, ищет загрузочный сектор. Этот сектор является первым сектором диска и содержит небольшую программу для загрузки операционной системы. Загрузочные сектора помечаются "волшебным" числом 0xAA55 = 43603 в позиции 0x1FE = 510. Это последние два байта сектора. Это позволяет компьютеру решить является ли данный диск загрузочным.

Начальный загрузчик имеет список мест для поиска загрузочных секторов. Моя старая машина ищет на первом флоппи, затем на первом винчестере. Более современные машины могут просматривать CD-ROM. Если он находит загрузочный сектор, он загружает его содержимое в оперативную память и передает управление программе, которая продолжает процесс загрузки ОС. На типичной Linux-машине это будет программа первого шага загрузчика LILO. Существует много способов и конфигураций процесса загрузки. Подробности можно почерпнуть в LILO User's Guide. Ссылки приведены в разделе LILO.

На самом деле о железе PC и его поведении можно рассказать гораздо больше. Но здесь не место. На эту тему есть много хороших книг.

2.1 Настройка

Машина хранит информацию о настройках в CMOS. В том числе там хранятся сведения о дисках и количестве оперативной памяти. BIOS содержит специальную программу, позволяющую вам изменять эти настройки. Следите за сообщениями на экране сразу после включения машины чтобы определить какой клавишей прозводится запуск этой программы. На моей машине необходимо нажать клавишу Delete до начала загрузки ОС.

2.2 Упражнения

Хорошим способом изучения железа 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.

2.3 Дополнительные сведения


3. Lilo

Когда компьютер загружает загрузочный сектор на нормальной Linux-машине, то что он загружает является частью lilo (LInux LOader), называемой загрузчиком первого этапа. Эта крохотная программа имеет единственной целью своего существования загрузку и выполнение загрузчика второго этапа.

Загрузчик второго этапа предоставляет вам возможность выполнения команд и может загружать ОС по выбору.

Когда система установлена и запущена, вы можете выполнить команду lilo. В этом случае отрабатывает ``map installer''. Он зачитывает файл настроек /etc/lilo.conf и записывает загрузчики на жесткий диск.

Есть множество способов организации загрузки вашей системы. То, что я описал, является наиболее очевидным и "нормальным", по крайней мере для машин, где главной ОС является Linux. Lilo Users' Guide рассматривает несколько примеров стратегий загрузки. С этим стоит ознакомиться, а кое-что и опробовать на практике.

3.1 Настройка

Настройки lilo хранятся в файле /etc/lilo.conf. По этому файлу существует свой ман: наберите в шелле man lilo.conf. Главным содержанием lilo.conf являются строки описания для всех систем, которые мы можем грузить с помощью lilo. Описание для Linux содержит сведения о местонахождении ядра системы и о разделе диска, который будет смонтирован в качестве корневой файловой системы. Для других ОС основной информацией является указание раздела диска, с которого необходимо загрузиться.

3.2 Упражнения

ЭТО ОПАСНО: будте осторожны с этими упражнениями. Здесь легко ошибиться, испортить главную загрузочную запись (MBR) и привести систему в нерабочее состояние. Убедитесь, что у вас есть работающая загрузочная дискета и вы знаете как с её помощью восстанавливать загрузочные сектора. Ниже приведена ссылка на tomsrtbt - спасательный диск, который я использую и могу рекомендовать. Лучшая предосторожность - использовать машину на которой нет ничего важного.

Установите lilo на дискету. Неважно если там не окажется ничего кроме ядра - вы получите ``kernel panic'', когда ядро будет готово загрузить init, но по крайней мере вы убедитесь, что lilo работает.

Продолжайте и наблюдайте как много системы вы сможете запихнуть на одну дискету. Кажется это второй из лучших способов изучения Linux. За справками обращайтесь к Bootdisk HOWTO и tomsrtbt (ссылки приведены ниже).

Заставьте lilo грузить unios (см. раздел железо/упражнения). Будет совсем круто, если вы сможете проделать это на дискете.

Создайте загрузочную петлю. Пусть lilo в MBR грузит lilo в одном из загрузочных секторов первичных разделов диска. Последнюю надо заставить грузить lilo из MBR... Возможно также использовать MBR и все четыре первичных раздела диска для создания пятиузлового кольца. Наслаждайтесь!

3.3 Дополнительные сведения


4. Ядро Linux

Ядро выполняет множество полезной работы. Думаю, что правильно охарактеризовать его задачу можно так: оно заставляет железо выполнять задания программ точно, надежно и эффективно.

Процессор может единовременно выполнять только одну инструкцию, однако в системе Linux выполняются одновременно множество вещей. Ядро достигает этого быстрым переключением с задачи на задачу. Это приводит к лучшему использованию процессора, т.к. ядро отслеживает какие процессы готовы активно выполняться, а какие ожидают чего-либо вроде записи в файл или ввода с клавиатуры. Эта задача ядра называется scheduling.

Если программа ничего не делает -- её не надо держать в оперативной памяти. Если даже она что-то делает, могут найтись части, которые не делают ничего. Адресное пространство каждого процесса разделено на страницы. Ядро следит за тем, какие страницы каких процессов используются чаще. Редко используемые страницы могут быть перемещены в своп-раздел. Когда они понадобятся снова, другие неиспользуемые страницы перемещаются в своп, освобождая место в памяти. Это называется управлением виртуальной памятью.

Если вы уже компилировали своё собственное ядро, вы должны были заметить множество опций для различных устройств. Ядро содержит множество специального кода для взаимодействия с разнообразными видами железа и представляет все это для приложений достаточно простым и стандартным способом.

Ядро также управляет файловой системой, межпроцессным взаимодействием и всей этой сетевой кухней.

Будучи загруженным в память, первой задачей ядра является поиск и запуск программы init.

4.1 Настройка

Большинство настроек ядра выполняется при его построении посредством 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.

4.2 Упражнения

Осмысли следующее: /dev/hda3 является файлом специального типа и описывает раздел жесткого диска. Однако он находится в файловой системе подобно другим файлам. В момент, когда ядру надо решить который из разделов будет смонтирован в качестве корневого, ядро ещё не имеет файловой системы. Как же ядру прочитать /dev/hda3 чтобы смонтировать раздел?

Постройте собственное ядро, если вы ещё не сделали этого. Прочтите всю документацию по каждой из опций настройки.

Выясните насколько маленькое (работоспособное) ядро вы сможете создать. Вы сможете многому научиться избавляясь от ошибок.

Прочтите ``The Linux Kernel'' (URL приведен ниже) и последовательно отыскивайте соответствующие части исходного кода. На момент напмсания данного документа эта книга описывала ядро версии 2.0.33, которое явно устарело. Возможно будет проще скачать исходные тексты для старой версии. Как приятно обнаруживать куски C-кода озаглавленные ``process'' и ``page''.

Хакайте! Посмотрим, сможете ли вывести какие-либо дополнительные сообщения или что-то ещё.

4.3 Дополнительные сведения


5. Библиотека GNU C

Следующей, после загрузки ядра, вещью, является запуск процесса 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)

5.1 Настройка

Некоторые из библиотечных функций зависят от вашего места обитания. Например у нас в Австралии дату пишут как dd/mm/yy, а американцы пишут mm/dd/yy. Glibc предоставляет специальную программу для настройки национальных особенностей - localedef.

5.2 Упражнения

Используя ldd, выясните какие библиотеки использует ваше любимое приложение.

Используя ldd, выясните какие библиотеки использует программа init.

Создайте игрушечную библиотеку с одной - двумя функциями. Для создания библиотек используется программа ar, так что начать следует с чтения соответствующего ман(уала). Напишите, скомпилируйте и соберите программу, которая будет использовать эту библиотеку.

5.3 Дополнительные сведения


6. Init

Я расскажу вам только о программе 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.

6.1 Настройка

Файлом верхнего уровня настройки init является /etc/inittab.

Директории rcN.d, где N = 0, 1, ..., 6 определяют какие подсистемы и в каком порядке будут запущены.

В одном из скриптов, вызываемых init, будет использована команда mount -a. Это приказ смонтировать все файловые системы какие должны быть смонтированы. Последнее определяется файлом /etc/fstab. Вы можете отредактировать этот файл, если решите изменить список файловых систем, монтируемых при старте системы. Синтаксис файла описан в man fstab.

6.2 Упражнения

Найдите директорию rcN.d для вашего "уровня запуска" по умолчанию и выполните команду ls -l, чтобы узнать на какие файлы указывают ссылки.

Измените количество виртуальных терминалов в системе.

Уберите любую не нужную вам подсистему из "уровня запуска" по умолчанию.

Оцените сколько вам удалось сэкономить на старте.

Создайте загрузочную дискету с lilo, ядром и "статически" собранной программой "hello world", причем последнюю назовите /sbin/init. Убедитесь, что система грузится и приветствует вас как положено.

Отследите все сообщения, выдаваемые системой при запуске. Или распечатайте содержимое системного журнала /var/log/messages с момента последнего старта. Затем, начиная с inittab, проследуйте по всем выполненным скриптам, отмечая кто что делает. Вы также можете вставить в скрипты дополнительные сообщения типа

        echo "Hello, I am rc.sysinit"

Это упражнение помогает также в изучении техники написания скриптов под bash. Некоторые из скриптов устроены весьма непросто, поэтому справочник по командам bash окажется весьма кстати.

6.3 Дополнительные сведения


7. Файловая система

В данном разделе я буду использовать терми "файловая система" в двух разных смыслах. Есть файловые системы на разделах дисков и других устройствах, и есть файловая система как она представлена для вас работающей системой 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, вы можете многому научиться.

7.1 Настройка

Команда mke2fs, создающая файловую систему типа ext2, имеет параметры, управляющие размером блока, числом inode и т.п. Прочтите ман для mke2fs, чтобы уточнить детали.

Всё, что должно быть смонтировано в вашей файловой системе определяется файлом /etc/fstab. По этому файлу также имеется ман.

7.2 Упражнения

Создайте очень маленькую файловую систему и рассмотрите её с помощью шестнадцатеричного вьюера. Найдите inod'ы, суперблоки и содержимое файла.

Я верю в существование программ, которые представляют файловую систему в графическом виде. Найдите, опробуйте и пришлите мне ссылку и ваши впечатления.

Исследуйте код ядра, относящийся к файловой системе ext2.

7.3 Дополнительные сведения


8. Демоны Ядра

Когда вы используете команду 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.

8.1 Настройка

Программа update позволяет настроить kflushd и kswapd. Для справки наберите update -h.

Включение свопа происходит по команде swapon, а выключение - по команде swapoff. Скрипт инициализации (/etc/rc.sysinit или /etc/rc.d/rc.sysinit) обычно вызывает swapon. Использование swapoff позволяет экономить энергию на ноутбуках.

8.2 Упражнения

Выполните update -d, и обратите внимание на предупреждение в последней строке относительно нарушения границ (?) (``threshold for buffer fratricide''). В настоящий момент это не понятно, давайте исследовать!

Перейдите в директорию /proc/sys/vm выполните cat для файлов этой директории. Посмотрите что с этим можно сделать.

8.3 Дополнительные сведения

``The Linux Kernel'' из LDP (The Linux Documentation Project) (для сылок см. раздел The Linux Kernel)

Исходные тексты ядра Linux, если вы достаточно отважны! Код kswapd обитает в linux/mm/vmscan.c, коды kflushd и kupdate живут в linux/fs/buffer.c.


9. Системный Логгер

Init запускает демонов syslogd и klogd. Они занимаются записью сообщений в журналы (логи). Сообщения ядра обрабатывает klogd, а syslogd обрабатывает сообщения от остальных процессов. Главным журналом является /var/log/messages. Это правильное место для поиска неисправностей в системе. Часто здесь можно обнаружить решение проблемы.

9.1 Настройка

Файл /etc/syslog.conf разъясняет логгерам какие сообщения куда записывать. Сообщения различаются по имени службы, от которой они исходят, и уровню приоритета. Строки этого файла содержат информацию о том, что сообщения от службы x с приоритетом y следует направлять в z, где z - файл, терминал, принтер, удаленный хост или что угодно.

ВАЖНО: Syslog требует присутствия файла /etc/services. Этот файл отвечает за распределение портов. Я не знаю, то ли syslog нуждается в портах для выполнения удаленного журналирования, то ли локальное журналирование происходит через порт, а может быть syslog просто использует /etc/services для преобразования имени службы которое вы прописали в /etc/syslog.conf к номеру порта.

9.2 Упражнения

Загляните в системный журнал. Найдите непонятное вам сообщение и отыщите информацию о том что оно значит.

Направьте все сообщения на терминал (tty). (Потом верните всё обратно).

9.3 Дополнительные сведения

Австралийское зеркало syslogd


10. Getty и Login

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 (т.е. больше программ).

10.1 Настройка

Сообщение, появляющееся вверху экрана вместе с приглашением ввести имя пользователя, прописывается в /etc/issue. Getty запускаются из /etc/inittab. Login проверяет сведения о пользователе в /etc/passwd, и, если используется механизм теневых паролей, в /etc/shadow.

10.2 Упражнения

Создайте файл /etc/passwd вручную. Пароли могут быть установлены в null и изменены программой passwd после регистрации. Прочтите ман на этот файл. Запустите его командой man 5 passwd чтобы получить информацию о файле, а не о программе.


11. Bash

Если вы ввели правильную комбинацию имя пользователя/пароль, 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.

11.1 Настройка

Файл /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'е (превосходный консольный файл-менеджер) вместо его встроенного редактора.

11.2 Упражнения

Основы bash легки в изучении. Однако вам не следует останавливаться: глубины невообразимы. Заведите привычку всегда искать лучшие пути для выполнения работы.

Читайте скрипты, найдите вещи которые вы не понимаете.

11.3 Дополнительные сведения


12. Команды

Большинство работы в bash может быть выполнено с использованием команд типа cp. Большинство из этих команд являются небольшими программами, однако некоторые (типа cd) встроены в шелл.

Команды собраны в пакеты, многие из которых разработаны Фондом Свободного ПО (Free Software Foundation or GNU). Вместо перечисления пакетов я направлю вас к документу Linux From Scratch HOWTO. Там вы найдете полный и свежий перечень пакетов, работающих с Linux, также как и инструкции по их сборке.


13. Заключение

Лучшей чертой Linux, по моему скромному мнению, является то, что вы можете залезть вовнутрь и разобраться как оно работает. Я надеюсь, что вы сможете насладиться этим не менее чем я. Я также надеюсь, что эти небольшие заметки помогут вам преуспеть в этом занятии.


14. Официальная часть

14.1 Авторские права

Авторские права на этот документ принадлежат (c) 1999, 2000 Greg O'Keefe. Вы можете использовать, копировать, распространять или изменять этот документ не взымая за это денег, следуя соглашениям Общественной Лицензии GNU - GNU General Public Licence. Прошу уведомить меня, если вы используете его целиком или частично как часть другого документа.

14.2 Домашняя страница

Последнюю версию этого документа можно найти на 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

14.3 Обратная связь

Буду признателен за любые комментарии, критику и предложения по улучшению. Пожалуйста, присылайте их мне: Greg O'Keefe

14.4 Благодарности

Названия продуктов являются торговыми марками соответствующих владельцев.

Есть несколько людей, которым я хотел бы сказать спасибо за помощь в подготовке этого документа.

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 (см. раздел ресурсов на домашней странице)

14.5 История изменений

0.8 -> 0.9 (November 2000)

0.7 -> 0.8 (September 2000)

0.6 -> 0.7

0.5 -> 0.6

14.6 Надо сделать


Hosted by uCoz