Команда dev в linux

Обновлено: 06.07.2024

Работа с устройствами в Linux очень сильно отличается от Windows. Главная концепция Linux в том, что все есть файл, не только пользовательские файлы с информацией, но и различные настройки ядра, подключенные устройства, память, сетевые соединения, все это представлено в виде файлов, которые размещены в специальных файловых системах.

С помощью этих файлов система работает с устройствами, и вы можете ими управлять с помощью различных утилит. В этой статье мы рассмотрим как выполняется работа с устройствами Linux, что из себя представляют устройства Linux, а также рассмотрим несколько примеров создания файлов устройств и обращения к ним. Это довольно интересная тема.

Файлы устройств Linux

Все файлы устройств расположены в каталоге /dev, который есть неотделимой частью корневой файловой системы, поскольку они должны быть доступны на всех этапах загрузки. Они также известны как специальные файлы устройств. Эти файлы используются операционной системой для обеспечения пользователю и программам интерфейса доступа к устройствам, подключенным к компьютеру.

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

dboth-dev-dir_0

На схеме приведена схема передачи данных для команды cat /etc/resolv.conf. Вы выполняете команду из терминала, утилита отправляет запрос файла драйверу, который ищет файл на диске и читает его содержимое. Данные передаются через файл устройства, а затем опять же, через файл устройства псевдо-терминала передаются в эмулятор терминала 6, где они будут отображены.

Если мы перенаправим вывод команды в файл, например, cat /etc/resolv.conf > /etc/resolv.bak, то левая часть схемы останется неизменной, а правая сторона будет вести к файлу устройства /dev/sda2. Эти устройства делают очень простым использование стандартных потоков ввода/вывода для доступа к каждому устройству. Простое перенаправление потока данных в файл устройства приведет к записи данных на устройство.

Классификация файлов устройств

Файлы устройств можно классифицировать по меньшей мере двумя способами. Первая и наиболее широкая классификация - на основе потока данных. В устройствах TTY и других символьных устройствах, данные обрабатываются по одному символу или байту за раз. В блочных устройствах, таких как жесткие диски данные передаются блоками, как правило, с размером, кратным 256 байт.

Если вы еще этого не делали, то перейдите в папку /dev/ и посмотрите список находящихся там файлов с помощью команды ls. Вы увидите очень длинный список файлов с их правами доступа, владельцами и группами - это список устройств linux. Обратите внимание на самый первый символ в каждой строке. Он указывает тип устройства. Символом "b" - обозначаются блочные устройства linux (block), а символом "c" - символьные (character).

device

Более точно можно идентифицировать устройства по их младшему и старшему номеру. Например, жесткие диски имеют старший номер 8, что обозначает их как блочные устройства SCSI. Обратите внимание, что все жесткие диски PATA и SATA находятся под управлением SCSI. Раньше использовалась подсистема ATA, но она уже устарела, поэтому диски, которые раньше обозначались как hd[a-z] теперь обозначаются sd[a-z].

Младший номер диска означает раздел устройства, например, номера 8/0 - это весь диск /dev/sda, а 8/1 уже файл первого раздела на диске, 8/6 - /dev/sda6. Файлы TTY именуются немного по-другому, от tty0 до tty63. Все значения старших номеров устройств Linux вы можете найти на официальном сайте ядра.

Работа с устройствами в Linux

Давайте проведем несколько экспериментов, которые помогут вам понять как работают устройства Linux и как ими управлять в этой операционной системе. Большинство дистрибутивов Linux имеют несколько виртуальных консолей, обычно от 1 до 7, которые могут использоваться для входа в сеанс командной оболочки. К этим виртуальным консолям можно получить доступ с помощью сочетаний клавиш Ctrl+Alt+Fn, например, Ctrl+Alt+F1 для первой консоли, Ctrl+Alt+F2 для второй и так далее.

Сейчас нажмите Ctrl+Alt+F2 для перехода во вторую консоль, в некоторых дистрибутивах, кроме запроса логина и пароля, будет выведена информация про активную TTY связанную с этой консолью. Но этой информации может и не быть. В данном случае консоль будет связана с устройством tty2.

Войдите от имени обычного пользователя, затем наберите такую команду, чтобы посмотреть номер устройства tty:

device4

У меня вы видите устройство /dev/pts/0, это виртуальное устройство эмулятора терминала, но если вы будете выполнять задачу в tty2, то отобразиться именно она. Теперь давайте посмотрим список tty устройств с помощью команды ls:

device1

Нас будут интересовать не все устройства, а только первые три. В этих устройствах нет ничего особенного, это обычные устройства символьного типа. Устройство tty2 подключено к консоли 2, устройство tty3 подключено к консоли 3.

Нажмите сочетание клавиш Ctrl+Alt+F3, чтобы переключиться в третью консоль, затем выполните команду:

echo "Hello world" > /dev/tty2

device6

Затем вернитесь во вторую консоль. Здесь вы увидите отправленную строку, Hello World. Все это можно повторить с помощью эмуляторов терминала в графическом интерфейсе, только здесь будут использоваться псевдо-терминальные устройства /dev/pts/*. Теперь попробуем отобразить содержимое файла fstab с помощью cat в другом терминале:

cat /etc/fstab > /dev/tty2

device5

cat test.pdf > /dev/usb/lp0

Каталог /dev/ содержит много интересных файлов устройств. Это интерфейсы доступа к аппаратному обеспечению и вам не нужно думать, что это, жесткий диск или экран. Например, вся оперативная память компьютера доступна в виде устройства /dev/mem. С помощью него вы можете иметь прямой доступ к памяти. Мы можем вывести содержимое памяти в терминал:

dd if=/dev/mem bs=2048 count=100

device2

Утилита dd, в отличие от cat дает больше контроля над процессом и позволяет указать сколько данных нужно прочитать. Но не ко всей памяти вы можете получить доступ. В ядре встроена защита, поэтому обычно, вы можете читать память, только для своего процесса.

Также тут есть файлы, которые несвязанны ни с какими реальными устройствами, это null, zero, random и urandom. Устройство /dev/null может использоваться для перенаправления вывода команд, чтобы данные никуда не выводились. Устройство /dev/zero используется для получения строки, заполненной нулями.

Вы можете использовать ту же команду dd, чтобы попытаться вывести ряд символов с устройства /dev/null:

dd if=/dev/null bs=512 count=500 | od -c

device7

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

Устройства /dev/random и /dev/urandom позволяют получить случайные комбинации чисел или байт. Вы можете использовать такую команду, чтобы получить случайные байты информации:

device3

Для остановки нажмите Ctrl+C. Устройство urandom позволяет генерировать случайные последовательности независимые от предыдущего числа, в качестве источника энтропии используется нажатия клавиш и движения мыши.

Устройство /dev/zero позволяет получить строку, заполненную нулями. Для проверки используйте такую команду:

dd if=/dev/zero bs=512 count=500 | od -c

device8

Обратите внимание, что восьмеричные нули и нули ASCII это не одно и то же.

Создание устройств в Linux

В прошлом все устройства из каталога /dev создавались во время установки системы, а это означало, что каталог содержал все возможные поддерживаемые устройства, даже если они не использовались. Если вам нужно было создавать или переинициализировать файлы устройств, использовалась утилита mknod. Но для работы с ней вам нужно знать старший и младший номер устройства.

Сейчас ситуация изменилась и все файлы устройств linux создаются во время загрузки только для нужных устройств. Менеджер устройств следит за подключаемыми и отключаемыми устройствами и добавляет или удаляет соответствующие файлы. Вы можете убедиться, что устройства были созданы сейчас просмотрев дату создания в с помощью команды ls.

Команда mknod все еще есть, но уже существует более новая разработка - makedev. Она предоставляет очень простой интерфейс для создания устройств.

Выводы

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

В Linux существуют две директории - /dev и /proc, которые не имеют Windows-аналогов, и их назначение начинающим пользователям обычно непонятно. Но именно они являются мощными инструментами для понимания и более эффективного использования Linux.
Эта статья - обзор файловых систем Device (/dev) и Process (/proc). Здесь обьясняется, что это такое, как они работают, и как они используются на практике.

/dev: Файловая система устройств.

Устройства: В Linux устройство - это любая вещь (или программа, эмулирующая эту вещь), которая предоставляет методы для осуществления ввода/вывода. Например, клавиатура - это устройство ввода. В Linux большинство устройств представлены, как файлы в этой файловой системе (сетевые карты - исключение). Эти специальные файлы хранятся в /dev, и легко доступны для всех процессов, работающих с устройствами.

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

Блокирующие устройства читают данные большими обьемами. Обычно это - устройства хранения данных, такие, как жесткие диски IDE (/dev/hd), SCSI (/dev/sd) и CD-ROMы (/dev/cdrom). В операциях ввода-вывода учавствуют большие массивы данных, что обеспечивает более эффективную работу.

Наименования устройств: Устройства часто называются сокращенными названиями вещей, которые они представляют. Например, /dev/fb представляет Frame Buffer для графики, а /dev/hd - жесткие диски IDE. Иногда более удобны бывают символьные ссылки, например - /dev/mouse может ссылаться на USB, PS2, и т.д.

Иногда может быть несколько одинаковых устройств. Если на компьютере 2 CD-ROMа, то первый будет называться /dev/cdrom0, а второй - /dev/cdrom1.

В случае с жесткими дисками наименование становится сложнее. Имя устройства состоит из типа, позиции и номера раздела. Например, первый жесткий диск может быть назван /dev/hda, где "hd" обозначает "диск IDE", а "a" - что это первый HDD. /dev/hdb будет указыать на второй жесткий диск. Первый раздел на первом диске будет называться /dev/hda1, где число 1 - номер раздела. Заметьте, что у некоторых устройств нумерация может начинаться и с нуля (/dev/cdrom0). Список всех разделов может выглядеть примерно так:

/dev/hda
/dev/hda1
/dev/hda2
/dev/hda3
/dev/hda4
/dev/hdb
/dev/hdb1
/dev/hdb2
/dev/hdb3

Жесткие диски SCSI используют /dev/sd вместо /dev/hd, но их правила наименования ничем не отличаются.

Специальные устройства: Существует несколько специальных устройств, которые иногда могут быть полезны - /dev/null, /dev/zero, / dev/full, and /dev/random.

Устройство /dev/null физически не существует, но данные, помещенные туда, просто исчезают и их уже невозможно вернуть обратно. Во многих случаях программы выводят много лишней информации. В shell-скриптах /dev/null часто используется, чтобы не беспокоить пользователя различными ненужными вещами. В примере, приведенном ниже, в ядро помещается модуль и вывод перенаправляется в /dev/null.

$ modprobe cipher-twofish > /dev/null

/dev/zero выполняет почти те же функции, что и /dev/null. Это устройство так же используется, чтобы убрать ненужные данные, но чтение из /dev/zero постоянно дает символы \0. (Чтение из /dev/null дает символы End of file). Поэтому /dev/zero часто используется для создания пустых файлов:

dd if=/dev/zero of=/my-file bs=1k count=100

Эта команда создает файл размером 100 Kb, состоящий только из нулевых символов.

/dev/full изображает полное устройство. Запись в /dev/full возвращает ошибку. Это устройство полезно при тестировании, как программа поведет себя при доступе к устройству, не имеющему свободного места.

$ cp test-file /dev/full
cp: writing /dev/full": No space left on device
$ df -k /dev/full
file system 1k-blocks Used Available Use% Mounted on
/dev/full 0 0 0 -

Устройства /dev/random и /dev/urandom генерируют "случайную" информацию. Хотя вывод из обоих этих устройств может показаться совершенно случайным, но /dev/random на самом деле более случайно, чем /dev/urandom. /dev/random генерирует случайные символы на основе "шума окружающей среды", который имеет ограниченное количество, поэтому /dev/random работает медленно, и может иногда останавливаться и ждать поступления новых данных. /dev/urandom использует те же данные, что и /dev/random, но если случайные данные заканчиваются, начинается генерация псевдослучайных чисел. Это делает /dev/urandom более быстрым, но менее безопасным.

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

Обычно /dev занимала очень много места, чтобы поддерживать множество жестких дисков, консолей, и т.д. Например, в старой файловой системе размещались сразу же 11 записей для жестких дисков - с /dev/hdb1 по /dev/hdb11. И чтобы выяснить, какой из этих файлов действительно соответствует устройству, нужна была команда:

$ file -s /dev/hdb?
/dev/hdb1: Linux/i386 ext2 file system
/dev/hdb2: Linux/i386 ext2 file system
/dev/hdb3: Linux/i386 ext2 file system
/dev/hdb4: empty
/dev/hdb5: empty
/dev/hdb6: empty
/dev/hdb7: empty
/dev/hdb8: empty
/dev/hdb9: empty

Если файл для устройства не присутствовал, есго нужно было создавать специальной программой mknod или MAKEDEV. Хотя старая модель работала, но она была сложной и неудобной.

DevFS: В ядрах версии 2.4 появилась альтернатива под названием DevFS. Принцип - файловая система /dev создается ядром при каждой загрузке и хранится в оперативной памяти. Если добавляются новые устройства, ядро просто добавляет запись, соответствующую им, в /dev. Если устройство требует специальной конфигурации для корректной работы с DevFS, то существует конфигурационный файл (обычно /etc/devfsd.conf).

/proc: Файловая система для процессов.

Процессы: В любое время Linux имеет много процессов, запущенных одновременно. Некоторые процессы доступны пользователю, а некоторые находятся на заднем плане и обрабатывают задачи, которые не требуют взаимодействия с пользователем. Запуск "ps -ef" в консоли выведет список всех процессов. Это выглядит примерно так:

$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 11:08 ? 00:00:04 init
root 2 1 0 11:08 ? 00:00:00 [keventd]
root 3 0 0 11:08 ? 00:00:00 [ksoftirqd_CPU0]
root 4 0 0 11:08 ? 00:00:00 [kswapd]
root 5 0 0 11:08 ? 00:00:00 [bdflush]
root 6 0 0 11:08 ? 00:00:00 [kupdated]
root 8 1 0 11:08 ? 00:00:00 [kjournald]
root 86 1 0 11:08 ? 00:00:00 /sbin/devfsd /dev
root 165 1 0 11:09 ? 00:00:00 [kjournald]
root 168 1 0 11:09 ? 00:00:00 [khubd]
root 294 1 0 11:09 ? 00:00:00 [kapmd]
root 515 1 0 11:09 ? 00:00:00 metalog [MASTER]
root 521 515 0 11:09 ? 00:00:00 metalog [KERNEL]
root 531 1 0 11:09 ? 00:00:00 /sbin/dhcpcd eth0
/etc/X11/fs/config -droppriv -user xfs
root 572 1 0 11:09 ? 00:00:00 /usr/kde/2/bin/kdm
root 593 572 2 11:09 ? 00:04:27 /usr/X11R6/bin/X -auth /var/lib/kdm/authfiles/A:0-25pIgI
root 644 1 0 11:09 vc/1 00:00:00 /sbin/agetty 38400 tty1 linux
root 1045 572 0 12:16 ? 00:00:00 -:0
mbutcher 1062 1045 0 12:16 ? 00:00:00 /bin/sh /etc/X11/Sessions/kde-2.2.2
mbutcher 1091 1062 0 12:16 ? 00:00:00 /bin/bash --login /usr/kde/2/bin/startkde
mbutcher 1132 1 0 12:16 ? 00:00:00 kdeinit: Running.
mbutcher 1157 1132 0 12:16 ? 00:00:01 kdeinit: kwin
mbutcher 1159 1 0 12:16 ? 00:00:07 kdeinit: kdesktop
mbutcher 1168 1 0 12:16 ? 00:00:00 kdeinit: kwrited
mbutcher 1171 1168 0 12:16 pty/s0 00:00:00 /bin/cat
mbutcher 1173 1 0 12:16 ? 00:00:00 alarmd
mbutcher 1207 1132 0 12:23 ? 00:00:08 kdeinit: konsole -icon konsole -miniicon konsole
mbutcher 1219 1207 0 12:23 pty/s2 00:00:00 /bin/bash
mbutcher 1309 1260 0 13:48 pty/s3 00:00:01 vi dev-and-proc.html
root 1314 1220 0 14:03 pty/s2 00:00:00 ps -ef

Многие из задач в списке, выведенном ps - это процессы, выполняемые на заднем плане. Процессы, заключенные в квадратные скобки - это процессы на уровне ядра. И только несколько задач, таких, как процессы KDE и записи в нижней части списка, взаимодействуют с пользователем.

Чтобы управлять системой, ядро должно следить за каждым запущенным процессом, включая себя. Так же информация о запущенных процессах должна быть доступна и для многих пользовательских приложений, таких, как "ps" и "top". В файловой системе /proc ядро хранит информацию о процессах.

Как DevFS, /proc хранится в памяти, а не на диске. Если посмотреть на файл /proc/mounts (который перечисляет все смонтированные файловые системы), то вы увидите строку:

proc /proc proc rw 0 0

/proc контролируется ядром и не имеет соответствующего устройства.

Информация о запущенных процессах: Чтобы следить за процессами, ядро назначает каждому из них номер PID (Process ID). Запуск команды "ps -ef", как мы уже делали ранее, напечатает список процессов, отсортированный по номеру PID (вторая колонка). В /proc хранится информация о каждом PID.

Многие директории в /proc - это числа, соответствующие номерам PID. Внутри директорий есть файлы, предоставляющие важные детали о процессе. Например, в выводе ps (выше) была строка:

mbutcher 1219 1207 0 12:23 pty/s2 00:00:00 /bin/bash

Этот процесс запускает bash, и имеет PID 1219. Директория /proc/1219 содержит информацию об этом процессе.

$ ls /proc/1219
cmdline cpu cwd environ exe fd maps mem root stat statm status

Файл "cmdline" содержит команду, данную для запуска этого процесса. Файл "environ" содержит переменные для процесса. "status" имеет статусную информацию, включая номер пользователя (UID) и номер группы (GID) пользователя, запустившего процесс, номер родительского процесса PPID (parent process ID), который запустил PID, и текущее состояние процесса, такое, как "Sleeping" или "Running".

$ cat status
Name: bash
State: S (sleeping)
Tgid: 1219
Pid: 1219
PPid: 1207
TracerPid: 0
Uid: 501 501 501 501
Gid: 501 501 501 501
FDSize: 256
Groups: 501 10 18
VmSize: 2400 kB
VmLck: 0 kB
VmRSS: 1272 kB
VmData: 124 kB
VmStk: 20 kB
VmExe: 544 kB
VmLib: 1604 kB
SigPnd: 0000000000000000
SigBlk: 0000000080010000
SigIgn: 8000000000384004
SigCgt: 000000004b813efb
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000

Каждая директория процесса также содержит несколько символических ссылок. "cwd" - ссылка на текущую рабочую директорию для этого процесса, "exe" - ссылка на саму программу, и "root" ссылается на директорию, которую программа считает корневой (обычно "/"). Директория "fd" содержит список символических ссылок на описания файлов, используемых процессом.

Так же в директории есть и другие файлы, предоставляющие информацию обо всем, начиная от использования процессора и памяти до количества времени, в течении которого этот процесс работал. Они описаны в исходниках ядра под "Documentation/file systems/proc.txt" и в man-странице "man proc".

Информация ядра: Кроме информации о процессах, /proc содержит много информации, генерируемой ядром для описания состояния системы.

Ядро и его модули могут генерировать файлы в /proc для предоставления информации об их состоянии. Например, /proc/fb предоставляет информацию о доступных устройствах frame buffer (чаще всего используются для демонстрации логотипа при загрузке).

$ cat fb
0 VESA VGA

Число 0 - это индекс устройства, соответствующего /dev/fb0. Если бы имелся второй frame buffer, то имелась бы еще одна запись, соответствующая /dev/fb1. Вообще, данные в /proc часто ссылаются на устройства в /dev или дают о них больше информации.

Много информации об устройствах хранится в /proc. Файл /proc/pci содержит информацию о почти каждом PCI-устройстве, обнаруженном в системе. Запуск команды "lspci" выводит похожий список, потому что в качестве источника информации используется именно /proc/pci. /proc/bus содержит директории для различных шинных архитектур (PCI, PCCard, USB), которые в свою очередь содержат информацию об устройствах, подключенных к этим шинам. Сетевая информация и статистика хранится в /proc/net. Информация о жестких дисках хранится в /proc/ide и /proc/scsi, в зависимости от типа жесткого диска. /proc/devices перечисляет все устройства, разделенные на категории "block" и "characters".

$ cat /proc/devices
Character devices:
1 mem
2 pty/m%d
3 pty/s%d
4 tts/%d
5 cua/%d
7 vcs
10 misc
14 sound
29 fb
116 alsa
162 raw
180 usb
226 drm
254 pcmcia

Block devices:
1 ramdisk
2 fd
3 ide0
22 ide1

А вообще - в /proc имеется намного больше файлов, чем описано здесь. Для каждого ядра формат /proc может быть разным, в зависимости от конфигурации и версии ядра, установленных устройств, и состояния компьютера. Формат информации может быть разным, но большинство из этих файлов документированы в Documentation/file systems/proc.txt.

Взаимодействие с процессами через /proc: Некоторые файлы из /proc предназначены не только для чтения. Запись в них может изменять параметры ядра. Чтение файлов из каталога /proc обычно безопасно, но записывать информацию в эти файлы, не зная их формата, опасно. Но все равно, иногда запись в /proc - это единственный способ взаимодействия с ядром.

Заключение: /proc и /dev предоставляют в виде файлов интерфейсы для взаимодействия с Linux. Они помогают в определении конфигурации и состояния различных устройств и процессов системы. Так же они обеспечивают простое взаимодействие с операционной системой. Понимание и применение этих двух файловых систем - ключ к эффективной работе в Linux.

Ядро Linux реализует поддержку двух типов устройств – символьных и блочных. Основное их отличие в том, что для блочных устройств операции ввода вывода осуществляются не отдельными байтами (символами), а блоками фиксированного размера.

В Linux вся работа с устройствами ведется через специальные файлы, которые обычно расположены в каталоге /dev . Специальные файлы не содержат данных, а просто служат точками, через которые можно обратиться к драйверу соответствующего устройства. У каждого специального файла есть три характеристики – тип устройства (character или block), старший номер устройства (major number) и младший номер (minor number). Для примера, посмотрим на содержимое каталога /dev :

Как видно, в листинге присутствует описание семи устройств, четырех блочных и трех символьных. Для каждого файла можно увидеть его тип (первая буква в списке прав доступа), пользователя-владельца, группу-владельца, major number, minor number, дату модификации и имя файла.

Для поддержки работы с устройствами в ядре хранятся две таблицы, одна для списка символьных устройств, другая для списка блочных устройств. Каждая строка таблицы сопоставлена какой-то разновидности устройств соответствующего типа – например, для типа “символьные устройства” можно выделить следующие разновидности: COM-порты, LPT-порты, PS/2-мыши, USB-мыши и т.д., для типа “блочные устройства” можно выделить SCSI-диски, IDE-диски, SCSI-CD-приводы, виртуальные диски которыми представляются RAID-контролеры и т.п.

Каждая ячейка в этих системных таблицах сопоставляется конкретному экземпляру устройства. Таким образом, с точки зрения ядра каждое устройство оказывается однозначно проидентифицировано тремя параметрами – типом устройства (блочное или символьное) и двумя числами – номерами строки и номером столбца таблицы, в которой хранится ссылка на драйвер этого устройства.

Пример таблицы символьных и устройств

Диспетчер томов LVM

Микшер первой зв. карты

Первая видеокарта NVidia

Пример таблицы блочных устройств

IDE Primary Master

Раздел 1 на IDE Primary Master

Раздел 2 на IDE Primary Master

Раздел 16 на IDE Primary Master

IDE Primary Slave

Раздел 1 на IDE Primary Slave

Раздел 1 на SCSI-диске 1

Раздел 2 на SCSI-диске 1

Раздел 1 на SCSI-диске 4

При попытке обращения к такому специальному файлу ядро переадресует обращение через нужный драйвер на устройство в соответствии с теми данными, которые указаны в таблице устройств, причем конкретная таблица устройств будет выбрана в зависимости от типа устройства, строка из таблицы будет выбрана по major number, и столбец будет выбран по minor number. Если мы посмотрим на примеры наших таблиц, то увидим, что обращение на специальный файл /dev/ttyS1 , который представляет символьное устройство со старшим номером 4 и младшим номером 65 будет адресовано на последовательный порт COM2, а обращение к файлу /dev/hda2 (блочное устройство со старшим номером 3 и младшим номером 2) будет адресовано на 2-й раздел жесткого диска IDE, работающего в режиме primary master.

13.1. Статическая организация каталога /dev

В настоящее время существует два подхода к организации /dev – статическая организация и динамическая организация. В первом случае в каталоге /dev заранее создаются специальные файлы для всех возможных устройств вне зависимости от того, загружен драйвер соответствующего устройства или нет. Во втором случае специальные файлы в /dev создаются по мере инициализации устройств и загрузки драйверов, и удаляются при выгрузке соответствующего драйвера или удалении устройства.

Процесс работы со статическим /dev особых проблем не вызывает – системный администратор при необходимости просто создает отсутствующие файлы командой mknod или MAKEDEV . В том случае, когда какая-либо программа обращается к устройству, чей драйвер не загружен (или загружен, но ни одного соответствующего устройства не было обнаружено), операционная система возвращает ошибку при попытке открытия файла такого “неверного” устройства. Ниже приведен пример создания специального файла, соответствующего блочному устройству с мажором 8 и минором 33 и попытка его использования (отметим, что этот специальный файл соответствует разделу на жестком диске, который не существует на тестовой машине, где выполнялись эти команды):

Ядро Linux совместно с некоторыми системными утилитами поддерживает такую интересную возможность, как загрузка драйверов “по требованию”. Реализуется это следующим образом – в момент, когда какая-либо программа пытается открыть специальный файл, не связанный ни с каким драйвером, ядро делает попытку подобрать соответствующий драйвер самостоятельно. Необходимый драйвер для каждого специального файла определяется в файле /etc/modules.conf путем задания специального алиаса (alias) для модуля. Для активизации автоматической загрузки драйвера какого-либо символьного устройства в большинстве случаев достаточно просто записать в /etc/modules.conf строку следующего вида:

Для блочных устройств соответствующая запись слегка меняет свою форму:

X и Y – это major и minor специального файла, попытка открыть который должна активизировать автоматическую загрузку драйвера. Владельцы видеокарт на чипе nVidia могут увидеть этот подход в действии – программа инсталляции драйвера nVidia автоматически прописывает в modules.conf запись для загрузки «по требованию» той части драйвера, которая работает в режиме ядра.

Вместо X или Y может также быть подставлен символ “*” , означающий “любое число”. Например, пусть в modules.conf будет написан следующий текст:

Тогда при обращении к любому символьному устройству с major number равным 81 и которое не ассоциировано ни с каким драйвером, система попытается загрузить драйвер bttv (драйвер TV-тюнера на основе чипа bt848).

Эта возможность обеспечивает Linux возможность плавной загрузки и эффективного использования ресурсов – драйвер не загружается, пока в нем не возникнет необходимости. К сожалению, за простоту этой схемы приходится платить большим количеством специальных файлов в /dev .

13.2. Что такое DevFS

Для того, чтобы избавить администратора от ручного создания специальных файлов и для уменьшения количества файлов в /dev был реализован второй способ организации /dev – динамическое создание специальных файлов процессе загрузки драйверов. Реализовано это было следующим образом:

Ядро монтирует к каталогу /dev специальную файловую систему, называемую devfs – эта файловая система хранится целиком в оперативной памяти и не занимает никакого места на диске. Когда какой-либо драйвер в процессе загрузки или работы обнаруживает обслуживаемое им устройство, он регистрирует это устройство и сообщает о нем драйверу devfs. Драйвер devfs создает специальный файл, который виден прикладным программам и может быть корректно открыт. При выгрузке же драйвер устройства сообщает devfs о том, что соответствующее устройство уже не активно, и драйвер devfs удаляет запись о соответствующем специальном файле из файловой системы devfs.

Файловая система devfs отличается тем, что как правило специальный файл для устройства создается с длинным путем – например, для раздела на scsi-диске путь может выглядеть примерно так: /dev/scsi/host1/bus1/target3/lun4/partition2 .

Эта особенность является весьма важным плюсом devfs, поскольку она позволяет адресовать дисковые устройства путем указания логического пути их подключения и избежать смены имен SCSI-дисков в некоторых случаях (об этих случаях будет рассказано позднее).

Для того, чтобы организовать более прозрачную структуру каталогов и файлов устройств, используется специальный демон devfsd. Он взаимодействует с драйвером devfs и ядром и в процессе активизации и деактивизации устройств он создает и удаляет символьные ссылки вида /dev/disks/disc0 или /dev/hda1 .

Надо отметить, что схема динамического /dev в некотором смысле близка к той организации каталога /dev , которая используется некоторыми коммерческими UNIX-системами (например, в Solaris), когда есть виртуальная файловая система /devices , и на ее файлы создаются ссылки из /dev , только в Linux роль программы cfgadm играет демон devfsd, и все изменения в состав /dev вносятся автоматически.

С помощью devfsd файловая система devfs также реализует автоматическую загрузку модулей, но в этом случае выбор модуля идет не через комбинацию type/major/minor, а путем указания имени запрошенного файла – когда приложение пытается открыть несуществующий файл устройства, devfs передает имя запрошенного файла демону devfsd, и последний загружает необходимые модули, например такой код в файле modules.devfs :

Приведет к тому, что при попытке обращения к любому файлу, чей полный путь начинается строкой /dev/nvidia , будет произведена попытка загрузить драйвер nvidia.o (для ядра 2.6 nvidia.ko )

В принципе, на сегодняшний день выбор того, каким именно образом необходимо организовывать /dev , остается за пользователем и создателем дистрибутива. Например, в Mandrake Linux используется devfs, а в RedHat, Fedora и SUSE каталог /dev организован статическим образом, а опытные пользователи часто меняют способ организации /dev в зависимости от своих предпочтений.

13.3. Немного о UDEV

В современных дистрибутивах и ядрах поддержка devfs/devfsd отключена, и на смену этой паре пришел специальный демон, называемый udev. В отличие от devsfd, который требовал поддержки со стороны ядра, udev такой поддержки не требует. При инициализации устройства ядро подает сигнал через файловую систему sysfs, и демон udevd, получив сигнал об этом событии, самостоятельно создает соответствующий специальный файл устройства в каталоге /dev в соответствии с правилами, описанными в его конфигурационных файлах. При необходимости в этих файлах можно указать например вызов некоторой внешней программы, создание символьной ссылки и так далее.

Например, если некоторое устройство после подключения перед началом работы требует дополнительной настройки с использованием внешних программ, можно создать соответствующее правило для udev, в котором будет указано какую программу вызвать и какие параметры ей необходимо передать – в частности, это может потребоваться для data-кабелей к некоторым мобильным телефонам Nokia, для устройств которым для корректной работы требуется firmware, или для сохранения или восстановления текущих настроек устройства.

Тем не менее, несмотря на внешние отличия между статической организацией /dev , devfs и udev, следует помнить что это всего лишь способ заполнения каталога /dev , и во всех случаях в конечном итоге на файловой системе создаются те же самые файлы символьных и блочных устройств.

Статья была опубликована 1 февраля 2010 года в 00:00, а последний раз правилась 4 февраля 2010 года в 00:05.

В Linux есть две файловые системы, которые абсолютно непоняты новым пользователям. У этих двух каталогов, /proc и /dev, нет аналогов в Windows. Тем не менее, они очень важны для понимания и использования Linux.

В Linux есть две файловые системы, которые абсолютно непоняты новым пользователям. У этих двух каталогов, /proc и /dev, нет аналогов в Windows. Тем не менее, они очень важны для понимания и использования Linux.

Данная статья представляет собой краткий обзор файловых систем для устройств (/dev) и для процессов (/proc). В ней рассказывается о том, что они из себя представляют, как работают и как используются.

/dev: файловая система для устройств

Устройства: В Linux’е устройство является специальным «оборудованием» (или кодом, эмулирующим его), которое представляет методы для ввода или вывода информации (IO — Input/Output). Например, клавиатура — устройство для ввода. Жесткий диск — устройства для ввода (запись) и вывода (чтение). Большинство устройств в Linux’е представлено как файлы в особой файловой системе (за исключением сетевых карт). Эти файлы хранятся в каталоге /dev, куда к ним обращается система для выполнения задач, связанных с вводом/выводом.

Грубо говоря, устройства можно разделить на две категории: символьные и блочные. Символьные устройства вводят/выводят по символам. Наиболее показательным примером служит клавиатура, у которой нажатие каждой клавиши формирует символ, передаваемый компьютеру. Мышь работает немного по-другому. Каждое движение или нажатие на кнопку отправляет символ на /dev/mouse.

Блочные устройства считывают данные большими объемами. Примерами служат устройства для хранения данных, такие как IDE жесткие диски (/dev/hd), SCSI жесткие диски (/dev/sd) и CD-ROM’ы (например, /dev/cdrom0 — символическая ссылка на первый CD-ROM). Операции ввода/вывода блочные устройства проводят с определенными блоками данных, что позволяет работать с большими объемами информации более эффективно.

Названия устройств: Устройства часто называются путем сокращения имен представляемого ими оборудования. Устройства с именами /dev/fb представляют буферы фреймов (frame buffers) для графики. Устройства /dev/hd представляют IDE жесткие диски (hard disks). В некоторых случаях для пояснения того, чем является устройство, используются символические ссылки: например, /dev/mouse, устройство, представляющее мышь, может быть прилинковано к последовательному, USB или PS2 устройству, в зависимости от железа. Символическая ссылка помогает и человеку, и машине разобраться, какое из устройств — мышь.

Иногда бывает несколько устройств одного типа. Например, у машины два ATAPI CD-ROM’а. Каждому CD-приводу нужен файл в /dev. В таком случае, возможен вариант, что /dev/cdrom0 будет первым CD-ROM’ом, а /dev/cdrom1 — вторым.

С именами жестких дисков немного сложнее. Название устройства жесткого диска зависит от типа диска, его позиции и раздела (partition’а). Первый жесткий диск может быть назван /dev/hda, где часть «hd» означает, что это IDE жесткий диск, а «a» показывает, что это первый жесткий диск. Тогда /dev/hdb будет ссылаться на второй жесткий диск. Каждый жесткий диск разбит на разделы. Первый раздел первого жесткого диска получит название /dev/hda1, где единица в конце обозначает номер раздела. Обратите внимание на то, что, если индексы некоторых устройств (например, /dev/cdrom0) могут начинаться с нуля, то индекс устройств с разделами обычно начинается с единицы. Вот примерный список файлов в /dev для двух IDE жестких дисков:

  • /dev/hda;
  • /dev/hda1;
  • /dev/hda2;
  • /dev/hda3;
  • /dev/hda4;
  • /dev/hdb;
  • /dev/hdb1;
  • /dev/hdb2;
  • /dev/hdb3.

SCSI жесткие диски используют /dev/sd вместо /dev/hd, но все остальное выглядит также. /dev/sda1 ссылается на первый раздел первого SCSI жесткого диска.

Специальные устройства: Существует несколько специальных устройств, которые порой бывают очень полезны: /dev/null, /dev/zero, /dev/full и /dev/random.

/dev/zero близок к /dev/null. Как и /dev/null, устройство может быть использовано для блокирования вывода ненужной информации, но чтение /dev/zero возвращает \0 символы (чтение /dev/null возвращает символы end-of-file — конец файла). Поэтому /dev/zero обычно используется для создания пустых файлов.

Такая команда (см. выше) создаст файл размером в 100 кб, наполненный null-символами.

/dev/full служит для имитации «полного» устройства. Запись в /dev/full сопровождается ошибкой. «Полное» устройство полезно для того, чтобы посмотреть, как тестируемое приложение будет себя вести при попытки доступа к заполненному устройству (т.е. например, к жесткому диску, на котором не осталось места).

Устройства /dev/random и /dev/urandom создают «случайные» данные. Хотя вывод обоих может показаться абсолютно случайным, /dev/random более случаен чем /dev/urandom. /dev/random создает случайные символы, основываясь на «окружающем шуме». Так как количество этого случайного шума ограничено, /dev/random работает медленно и может временно останавливаться для дальнейшего сбора данных. /dev/urandom использует тот же шум, что и /dev/random, но если случайных данных больше нет, оно создает псевдо-случайные данные. Таким образом увеличивается его скорость, но уменьшается безопасность.

Старая файловая система /dev: Раньше файловая система /dev была частью обычной файловой системы. Она состояла из специальных файлов, созданных однажды (обычно при установке системы) и сохраненных на жестком диске.

В старых системах файловая система /dev должна содержать информацию обо всех устройствах, которые могут быть подключены к компьютеру. Из-за этого /dev была слишком большой — приходилось хранить сведения о множестве жестких дисков, дисководов и т.п. Ранее мы рассматривали список разделов жесткого диска hdb. В старой файловой системе /dev приходилось содержать файлы с /dev/hdb1 до /dev/hdb11. Чтобы выяснить, какие устройства действительно привязаны к разделам жесткого диска (если помните, у меня всего три раздела на hdb), нужно вызвать специальную утилиту. Команда «file -s hdb*» поможет в этом разобраться:

Если указанного файла устройства не было, приходилось его создавать с помощью mknod или другой программы (типа MAKEDEV). Хотя «старый способ» работал, он был сложен и неудобен.

DevFS: В ядрах 2.4.x была представлена альтернативная дисковая файловая система /dev. Эта альтернатива, DevFS, подключала код нового устройства в ядро. В DevFS файловая система /dev создается во время каждого запуска компьютера и сохраняется в оперативной памяти, а не на жестком диске. При использовании этой модели пропадает нужда в поддержке списка всех возможных устройств, а когда появляется новое устройство, ядро просто делает для него запись в /dev. Если же устройствам нужна особая настройка в DevFS, существует конфигурационный файл (обычно /etc/devfsd.conf).

/proc: Файловая система для процессов

Процессы: В любое время в Linux’е одновременно запущено множество процессов. Некоторые из них, такие как оконные менеджеры, email-клиенты и Web-браузеры, видны конечному пользователю. Другие, вроде серверов и вспомогательных процессов, в глаза не бросаются, но запущены в фоновом режиме, выполняя задания, не требующие каких-либо действий со стороны пользователя. Запуск «ps -ef» в shell’е выведет список всех запущенных на данный момент процессов. А выглядеть будет примерно так:

Многие из задач в выводе ps являются процессами, работающими в фоновом режиме. Те, что взяты в квадратные скобочки — процессы ядра. Только некоторые, вроде процессов kde и записей в конце списка, являются процессами, с которыми я взаимодействую напрямую.

Для управления системой ядро должно хранить информацию о каждом запущенном процессе, включая само себя. Также должна быть возможность просмотра сведений о запущенных приложениях пользовательского уровня (хорошим примером служит «ps», а также «top»). В файловой системе /proc ядро и хранит информацию о процессах.

Как и DevFS, /proc хранится в памяти, а не на диске. Если вы посмотрите в файл /proc/mounts (в котором приводится список всех примонтированных файловых систем), то увидите строку вроде этой:

/proc контролируется ядром, у этой файловой системы нет «под собой» какого-либо устройства. Так как в ней в основном содержится информация, управляемая ядром, наиболее логичным место для хранения такой информации является память, также контролируемая ядром.

Информация о запущенных процессах: Чтобы хранить информацию обо всех процессах, ядро присваивает каждому из них PID (Process ID — идентификатор процесса) в виде числа. Запуск команды «ps -ef» (см. выше) выведет список всех запущенных процессов в порядке их PID’ов (вторая колонка). Файловая система /proc хранит информацию о каждом PID.

В /proc названиями многих каталогов являются числа. Эти директории ссылаются на номера PID. В таких каталогах находятся файлы, которые предоставляют подробную информацию о положении, окружении и прочих деталях процесса. В выводе ps (см. выше) была следующая строка:

Этот процесс — запущенный bash shell, имеющий PID 1219. Каталог /proc/1219 содержит информацию об этом процессе.

В файле «cmdline» располагается команда, которая вызвала процесс. В файле «environ» находятся данные о значениях окружения для процесса. «status» содержит информацию о статусе процесса, среди которой пользовательский (UID) и групповой (GID) идентификаторы для пользователя, запустившего процесс, идентификатор родительского процесса (parent process ID — PPID) и текущий статус процесса (например, «Sleep» или «Running»).

У каждого каталога процесса есть несколько символических ссылок. «cwd» ссылается на текущий рабочий каталог для процесса. «exe» — ссылка на исполняемую программу процесса, а «root» ссылается на каталог, который процесс рассматривает как корневой (обычно «/»). В каталоге «fd» содержится список символических ссылок на дескрипторы файлов, используемых процессом.

Существуют и другие файлы в каталоге процесса, предоставляющие исчерпывающую информацию: от занятности процессора и памяти до количества времени, которое запущен процесс. Большая часть этих файлов описана в документации исходников ядра («Documentation/file systems/proc.txt»), а также доступна в man — «man proc».

Информация о ядре: Кроме хранения сведений о процессах, файловая система /proc содержит множество информации, самостоятельно созданной ядром для описания общего состояния системы.

Ядро и модули могут создавать файлы в /proc для того, чтобы предоставить информацию о своем текущем состоянии. Например, /proc/fb показывает, какие сейчас доступны устройства типа frame buffer (буферы фреймов обычно используются для отображения загрузочного логотипа).

Обратите внимание, что 0 ссылается на индекс frame buffer’а и устройство /dev/fb0. Если бы у меня был второй framebuffer, то появилась бы еще и строка с 1, соответствующая /dev/fb1. Часто данные proc ссылаются на устройства в /dev.

В /proc хранится немало информации о железе. В файле /proc/pci написано про все обнаруженные в системе PCI устройства. Запуск команды «lspci» выводит идентичную информацию, так как использует /proc/pci для получения сведений об устройствах. В /proc/bus находятся каталоги для bus-архитектур (PCI, PCCard, USB), в которых содержится информация об устройствах, присоединенных таким образом (PCI, PCCard, USB). Информация о сети располагается в /proc/net. Информацию о жестких дисках можно найти в /proc/ide и /proc/scsi (в зависимости от типа устройства). В /procs/devices присутствует список всех устройств системы (они разделены на две категории: «block» — блочные, «character» — символьные).

В действительности, в /proc находится намного больше файлов, чем было описано здесь. У каждого ядра они могут несколько различаться, в зависимости от того, что было включено в ядро, какое железо и программное обеспечение используется и в каком состоянии в настоящий момент находится компьютер. К некоторым из этих файлов постоянно обращается машина, а другие предоставляют «интуитивную» информацию.

Работа с процессами через /proc: Некоторые файлы /proc предназначены не только для чтения. Запись в них может влиять на состояние ядра. Просмотр содержимого файла в /proc обычно безопасно, но запись в них без точной уверенности в своих действиях может приводить к фатальным последствиям. Несмотря на это, иногда запись в /proc — единственный способ связи с ядром.

Существуют десятки других настраиваемых параметров в /proc — некоторые для конфигурации железа, другие для управления ядром. Однако, многие из них являются низкоуровневыми и могут привести к печальным последствиям, если указать неправильные значения. Поэтому, если вы твердо не уверены в своих действиях, менять параметры в /proc строго не рекомендуется.

/proc и /dev представляют интерфейсы к внутренностям Linux’а с помощью файлов. Они способствуют настройке и получению сведений об устройствах и процессах системы. Благодаря ним, можно с легкостью обновлять, изучать, запускать систему и устранять разнообразные неполадки. Понимание и применение знаний этих двух файловых систем являются ключом к созданию «более вашей» Linux-системы.

Читайте также: