- Регистрация
- 23 Август 2023
- Сообщения
- 3 641
- Лучшие ответы
- 0
- Реакции
- 0
- Баллы
- 243
Offline
В данной статье я хотел бы показать, как работать с внешними устройствами в Linux. Это важная часть любой ОС, и в каждой это реализовано довольно по-разному. Особенно если сравнивать это с Windows.
Важно понимать, что я буду говорить только про управление и использование через терминал, а не про графический интерфейс. Графика довольно похожа на то, что есть в Windows, поэтому её затрагивать смысла не вижу.
Для меня Linux это всё же Terminal-first система (хотя и не так выраженно, как, например, в FreeBSD), а GUI так, нашлёпка, которой вполне может и не быть (что довольно часто встречается на серверах или мейнфреймах).
Изначально я хотел сделать статью чисто про USB-устройства, но чуть позже я решил затронуть и блочные устройства, так как это самое частое, с чем вы будете иметь дело в любой ФС.
Также я затрону Диски (HDD) и CD-Диски (DVD, Music), так как это тоже может вызывать вопросы.
Затрону ещё и работу с принтерами (это можно отнести к USB-устройствам).
Сюда бы можно было бы ещё и отнести работу с COM-устройствами, но что COM, что LPT портов у меня не наблюдается, так что это я опущю.
Работа с блочными устройствами
Возможно, вам очень непривычно слышать название “блочные устройства”, но тут нет ничего уж сильно странного.
Блочными устройствами в *NIX-системах называют любые диски и флешки (т. е. носители информации, которые можно “разбить”).
(Если более техническим языком, то это устройства, которые хранят информацию в фиксированных блоках, секторах или кластерах. Как раз описание дисков или флешек)
Все блочные устройства работают одинаково. Что флешки, что диски. Разницы в дисках тоже нет (что HDD, что SSD будут работать идентично для конечного пользователя).
Под работой с блочными устройствами я буду иметь в виду разбиение на разделы и форматирование этих разделов в определённую ФС. Начнём с разбиения на разделы.
Разбиение на разделы
Для создания и редактирования разделов я использую программу fdisk. У неё есть TUI-версия под названием cfdisk, но я ей не пользуюсь, так как мне удобнее классическая версия fdisk.
Если вы пользовались DOS или *BSD, то у меня для вас плохие новости. Fdisk на всех этих трёх системах абсолютно разный. И на Linux он мне нравится в разы больше, чем на том же DOS или BSD (на ДОС он умеет разбивать только в fat16/32 и управление у него своеобразное).
Для того, чтобы разбить флешку на разделы, нужно знать, что бить. При вставке флешки в систему у неё появляется “интерфейс” в /dev (чуть позже я буду более подробно рассказывать про это).
Чтобы понять, какое блочное устройство предстоит разбивать на разделы, введём команду lsblk (от list block).
Что мы видим? Под названием указывается имя устройства (интерфейс в /dev), в mountpoint - куда оно примонтировано. Под цифрами в названии подразумевается раздел (то есть, sda1 - это 1й раздел, а sda2 - второй и тд.).
Разбивать нужно НЕ РАЗДЕЛЫ, а само устройство. Поэтому пишем в консоли (я буду равноценно использовать что терминал, что консоль. Для конечного пользователя разницы нет никакой, чисто разница в терминологии) sudo fdisk /dev/sda
Если вы впервые разбиваете блочное устройство в fdisk, он может показаться очень “недружелюбным”, но это на первый взгляд. Он простой в обращении, нужно всего лишь ввести букву под действие. Чтобы вывести список команд, введите m в интерфейс и получите вот такую справку
Короткая справка от меня:
БУ - Блочное Устройство.
Тут нужно сделать небольшую справку про MBR и GPT
Что такое таблицы разделов
Таблицы разделов, или на английском Partition Table, это то как будет ваши блочные устройства разбиты.
Таблица MBR (Master Boot Record) использовалась во время DOS и ранних Windows. В ней может быть максимум 4 раздела, каждый раздел может быть основным (primary) или добавочным (extended), у одного раздела из всех может быть флаг загрузочного (bootable), на, который обычно устанавливается загрузчик системы.
Когда раньше грузился ПК BIOS искал именно раздел с флагом загрузочного. Если такого не находилось, то ОС не загружалась.
С появлением UEFI систем (точнее с началом их распространения в 2010-х годах), MBR разделы стали устаревшими и теперь используется таблица GPT (Grand Partition Table).
Кол-во разделов было увеличено до 128, пропали загрузочные разделы, так как UEFI ищет не конкретный загрузочный раздел, а раздел в FAT32 с EFI папкой. Если таковой был найден, то ПК знает откуда ему загружать систему.
На одном диске может быть как 1 система, так и 2, 3 и тд. У каждой системы должен быть свой EFI раздел, чтобы UEFI мог загружать их независимо друг от друга.
Для создания простой флешки совершенно без разницы, в какой таблице она была разбита, но я покажу обе, так как у каждой есть свои подводные камни.
Разбиение в MBR
Чтобы разбить в MBR нужно ввести o и утилита предложит выбрать тип раздела. Выбираем всегда основной раздел, так как от добавочного смысла немного.
Далее, выбираем размер раздела. Для этого вводим в Last Sector плюс и цифру с буквой.
Если нужно создать раздел в 5 Гигов, то вводим +5G, или +5120M для того же объёма в мегабайтах (1024 * 5).
В конце нас спросят под сигнатуру раздела, всегда удаляйте старую сигнатуру.
Далее, нужно поговорить про типы разделов. Вот сводная таблица всех возможных типов разделов в MBR
Для Linux не сильно важно какой тип стоит в разделе, а вот для Windows жизненно необходимо указывать правильный тип (это, по сути, заголовок раздела. Если заголовок не совпадает с типом, который ожидает форточка, то она просто не увидит диск. Linux в этом плане всеядный).
Для Windows в MBR подходят типы от 0b до 0f. Причём даже формат раздела не важен, главное, чтобы был выбран правильный тип.
Я выбираю обычно 0b (обычно я не делаю флешки в MBR вообще).
Меняем тип и на 0b и записываем изменения на устройство
После этого, в системе появится устройство /dev/sda1, пока что без форматирования, которое мы повесим позже. Сначала сделаем тоже самое, но для GPT.
Разбиение в GPT
Для того, чтобы разбить в GPT делаем тоже самое, но уже с буквой g в начале.
Стоит отметить, что при GPT уже не спрашивают про тип раздела (основной или добавочный), так как их просто нет в GPT.
Если не указывать объём раздела, то он создаться на всё свободное место.
Типы разделов тут также существуют и их ОЧЕНЬ много
Для нас тут нужен только один тип - 11, который позволит флешке (разделу) определится в Windows.
Дополнение
Чтобы удалить раздел, введём d и, если раздел один, то он удалит этот раздел, а, если несколько, то просто попросит ввести номер нужного.
Я создаю 2 раздела с одинаковыми типами раздела 11. Как можно видеть, перед определением типа, утилита спрашивает какому разделу присвоить тип.
После этого, вводим w и утилита записывает на устройство изменения.
Можно ввести lsblk чтобы убедится в наличии этих двух разделов
Форматирование разделов
Функция форматирования не входит в утилиту fdisk, поэтому для создания форматирование на разделе необходимо воспользоваться утилитой mkfs. Она не принимает параметры как другие утилиты, а тип указывается после точки в названии утилиты (форматирование под разные форматы это просто разные бинарники в системе, а не единая утилита с ключами).
Я форматирую разделы в exFAT (для этого нужен дополнительный пакет в системе. В Arch: exfat-utils и exfat-progs, в debian: exfat-fuse)
Если вам нужно сделать форматирование в fat, то нужно написать в консоли mkfs.fat -F 32 … для форматирования в FAT32 или mkfs.fat -F 16 … для форматирования в FAT16.
Другие файловые системы делаются аналогичным образом (для ntfs нужен пакет ntfs-3g).
Монтирование разделов
Чтобы потом на эти разделы записать информацию, их нужно примонтировать в систему.
Для этого воспользуемся командой mount, у, которой есть 2 способа монтирования (ну это не совсем способы, но назову их так).
Первым параметром утилита принимает раздел для монтирования, а вторым путь для монтирования (обычно это /mnt).
Для этого можно использовать 2 способа.
1й - явный.
Тут через -t обязательно указывается тип ФС на разделе (fat32, fat16, ntfs-3g, exfat, ext4).
2й - неявный.
Тут использования -t необязательно. Утилита mount умеет сама определять ФС на разделе (в *BSD, например, она это делать не умеет, там всегда нужно указывать явно ФС (это могло в последних версиях изменится, не слежу за FreeBSD так пристально)).
Отмонтирование раздела
После окончания работы с разделом, его нужно обязательно отмонтировать от системы.
Для этого есть утилита umount (да, именно umount, не unmount).
Больше никаких дополнительных ключей указывать не нужно для утилиты.
Проверка работоспособности раздела в Windows
Как вы могли видеть, я скопировал на флешку скриншоты для статьи
Давайте вставим флешку в windows и проверим, будет ли флешка там читаться
Да, всё работает.
Если бы не был указан тип раздела при его создании (0b, 11), то флешка бы просто не отобразилась.
На этом работа именно с блочными устройствами закончена (я не думаю, что стоит говорить как копировать файлы на флешку). Тут нужно затронуть тему “нейминга” устройств в /dev и вообще для чего он используется.
Что такое этот ваш /dev?
Папка /dev появилась ещё в UNIX, откуда перекочевала и в BSD, и в Linux как наследие. Но, если в BSD оно ещё сохраняет актуальность, то вот в Linux это скорее обрубок из прошлого.
Папка /dev изначально предназначалась для всех подключаемых устройств в ПК. Мышки, клавы, диски, дискеты и тп.
Во наше время USB устройств в Linux эта папка стала обрубком, куда стали выносится только “интерфейсы” для работы с устройствами, которые поддерживают низкоуровневое обращение. Это диски, CD, флешки (разделы, интерфейс самой флешки), флоппик, serial-устройства (микроконтроллеры), COM и LPT порты (если есть).
Но все usb устройства “фикция” или, как я назвал их, “интерфейсы” для работы. Сами устройства тут давно не лежат.
До того как на самом деле выглядят современные устройства в системы мы дойдём чуть позже, когда будем трогать принтер, а сейчас небольшой список по тому, какие “интерфейсы” в /dev самые распространённые.
tty - это интерфейс терминалов (причём аппаратных, а не виртуальных, к, которым нас цепляют эмуляторы терминала из GUI (Konsole, Gnome Terminal)).
Чтобы увидеть аппаратный терминальный интерфейс вы можете нажать комбинацию из Ctrl+Alt+F1-F7. tty1 исторически используется для вывода лога ядра Linux, tty2 - логинка (Display Manager; sddm, gdm, lightdm), tt7 - графическое окружение (если установлено) (KDE, Gnome, XFCE4).
Любые блочные устройства тоже будут там, и это уже будет не “интерфейс”, а реальное устройство.
Тут важно сказать, что в /dev выносятся те устройства/интерфейсы устройств, которые могут напрямую быть использованным ядром. Диски в их числе.
Но хоть интерфейс дисков и представлен там всегда, это совсем не означает, что ядро может их использовать напрямую. Если на разделе будет ФС, у которой нет низкоуровневого драйвера (в Linux драйверы — это модули ядра), то ядро не сможет с таким разделом работать напрямую.
Например у exfat нет такого модуля ядра и поэтому он работает только в пользовательском пространстве (userspace) через fuse (Filesystem in Userspace).
Заметили, что, когда я писал про пакеты для работы в системах для exfat, в debian пакете была приписка -fuse (exfat-fuse)? Вот это как раз оно и есть.
Собственно поэтому мы и не можем поставить систему на, например, exfat или ntfs-3g. Они все работают через fuse. Если бы мы и поставили систему на exfat, то загрузится мы бы просто не смогли. Ядро бы не смогло работать в таком режиме, так как отсутствует модуль ядра для этой ФС.
Далее обсудим интерфейсы конкретно блочных устройств.
Интерфейс sdXY или hdXY самые распространённые. Под эти интерфейсы попадают как диски (HDD,SSD), так и флешки.
На месте X стоит буква, которая определяет диск (не путать с DOS дисками). Например, если в системе установлен HDD или SSD как основной диск, то это будет sda, и, если к ПК с системой на sda подключить флешку, то она будет уже sdb (т.е. следующий диск в списке), или sdc.
Причём буква для конкретного диска не резервируется. В windows можно выбрать какой буквой будет диск на любых машинах (если эта буква диска не занята), а вот в linux - какой первый вставили, такой и a.
Дисков hd вы уже очень вряд ли встретите. Такое представление дисков было во времена IDE дисков.
В Linux вот это sd образовано от названия разъёма SCSI (у нас его ещё называют “скази”) (SCSI Disk) и Linux ВСЕ блочные устройства воспринимает именно как скази. И флешки, и диски (кроме некоторых).
В тоже время, у *BSD систем совсем другая логика. Там интерфейс называется по драйверу, который использует конкретный диск.
Например ada это ATA Driver Access, da - Direct Access, cd - CDROM.
Поэтому флешки там da, HDD/SSD - ada, НО вот SSD подключенный через USB - это уже da.
Плюс, там отличается то, что номер диска цифровой, и номер раздела тоже цифровой. Поэтому может быть вот такое распределение - ada1p1, то есть это ATA диск, раздел 1.
Мне *BSD-формат представления дисков не нравится, он слишком геморный для запоминания.
Я знаю два особых блочных устройства, получившее своё уникальное название в системе - NVME диски и SD-карты. Для NVME - это nvmeXnY, а для SD - mmcblkXpY, где X - номер диска (1..∞), а Y - номер раздела (1..∞).
Для CD выделено отдельное устройство (которое появляется только если есть сидюк в ПК) — sr0 (я в сомнениях, что у вас в системе может быть больше одного привода, щас один-то уже редкость).
Для флоппика тоже есть отдельное устройство fd.
Если ваше устройство поддерживает Serial-порт (у меня это только ардуинка и esp32), то они будут ttyACM0 для ардуинки или ttyUSB0 для esp32 (у меня было такое распределение, но в другом дистре может быть иначе).
Дополнение.
ttyACM0 это native-usb устройство (без дополнительного загрузчика (ch340 например)), тогда как ttyUSB0 с загрузчиком. У меня есть 2 esp32. Одна из них ttyUSB0 использует загрузчик ch341, а другая ttyACM0 использует native-usb и может быть определена в системе как HID (input) устройство, что-то типа bluepill или digispark, но с esp32.
Если вдруг у вас есть COM-порт, то он будет в системе определяться как ttyS0,ttyACM0 и ttyUSB0 только если COM-устройство через USB; LPT (параллельный порт) как lp0, иногда бывает parport0.
И есть ещё один специфический и только виртуальное устройство - loop. Его используют для работы с файлом, как с блочным устройством. Ну вот есть, например, дамп с телефона в img формате (например дамп системного раздела, я так делал), то, чтобы его редактировать, его нужно примонтировать в системе через loop устройство. Только так его можно будет использовать как RW устройство, а не как RO. Также так монтировать стоит ISO образ диска.
Пример монтирования файла через loop
mount -o loop,rw system.img ~/mount
Через -o указывается устройство через, которое идёт монтирование. Loop устройств в системе далеко не одно. А также режим монтирование (только чтение или чтение/запись).
И есть ещё одно специальное виртуальное устройство - zero. Это устройство просто выдаёт нули. И больше ничего. Его используют тогда, когда нужно записать куда-то нули (например перезаписать диск и удалить оттуда вообще всё, перезаписав каждый сектор нулями. Или, если надо искусственно расширить файл, записав в конец столько нулей, на сколько нужно расширить файл).
Пример расширения файла с ФС через zero
dd if=/dev/zero bs=1M count=512 >> system.img
Вот пример папки /dev на моём домашнем сервере на Debian. Это Intel NUC, в, котором есть встроенная SD карта на 32 гига. Поэтому тут есть mmcblk
Вроде бы на этом всё по папке /devи устройствам в ней.
Подключение принтера и “откуда у меня ссылка в названии устройства?!”
Вроде бы мы разобрались с тем, как представляются устройства в Linux, да? А вот нет. Это ещё не всё.
В Windows все устройства ограничиваются названием COM с циферкой, тут же целый зоопарк названий (думаю уже было понятно после прошлой секции какой), но и это не всё. Тут есть ещё ссылки в названии
. Откуда ссылки? А вот сейчас будем разбираться откуда.
Для начала настроим принтер. У меня довольно старый принтер от Canon - i-SENSYS MF4018. С его настройки в W10 было вылито не одно ведро мата с помоями в сторону драйверов от этого принтера.
В Linux же всё прощё и сложнее одновременно. На Arch его завести будет анрил, на Debian всё поднимается на раз два (дрова ток под него) (точнее скрипт под него только, а переписывать скрипт я уж не буду, спасибо).
Драйвера на Linux для принтеров представляют собой просто pdd файлы, которые умеет читать другой драйвер - CUPS. Поэтому установим сначала его с плагином gutenprint для поддержки большей части принтеров (кроме блин этого…).
И да, я переехал на другой ноут (там есть дисковод, он мне будет нужен позже). Там установлен свеженький mint.
Установим CUPS
После установки CUPS нужно принянуть дрова для самого принтера. Чапаем на сайт, там ищем дрова под линь (вот это нифига себе, под линь дрова есть, это редкость).
Дрова идут в тарболе, распаковываем их
Перед запуском скрипта, запустим утилиту дебага dmesg с флагом -w (это сообщения от ядра) и подключим принтер по USB
В конце можно видеть что он определился как /dev/usblp1 (но эт нам не поможет).
Когда запустим скрипт, будет запущена утилитка настройки каноновских принтеров, выбираем его
Дальше меня ждало разочарование - MF4018 там нет. Выбираем близкий MF4010 (его даже так утилитка распознала)
А вот тут наблюдаем ССЫЛКУ
вращаемся на пару шагов назад, а, где же устройство /dev/usblp1? Почему тут урла? Откуда?
Не, я бы понял что она там может быть, если бы я подключал его по сети, но я то через USB его подключаю. Откуда там урла? А вот это называется libusb.
В нынешнем Linux устройства могут определятся не только в /dev. Я почему и сказал, что в /dev находятся только интерфейсы устройств, но не сами устройства.
Объяснять откуда там урла я буду через пару шагов, сначала проверим принтер.
Заходим в LibreOffice и печатаем что-нибудь.
Печать прошла
Первое, запоминаем. Принтер работает, значит эта урла действительно ведёт на это устройство, но каким образом?
Для тех кто не знает как устроена URL: В URL есть несколько частей. Разберём ссылку на какой нибудь сайт.
“https://www.google.com/search?q=linux+fuse&oq=linux+fuse”
Вот эта часть “https://www.google.com/search” это адрес сайта, в данном случае поиск гугла.
После него идёт вопрос, это знак “переменных”. Эти переменные задаются разработчиком, их можно считывать.
Если переменных много, то они разделяются &.
Теперь посмотрим на URL в адресе принтера:
“usb://Canon/MF4010%20Series?serial=SD3003562100Q&interface=1”
Вот эта часть это ссылка (вернее её тело) “usb://Canon/MF4010%20Series”, это
“serial=SD3003562100Q” и это “interface=1” переменные, которые откуда-то берутся (где и есть само устройство).
Вот это “usb://” это обращение к протоколу, а, если точнее, то к библиотеке libusb, которая умеет обрабатывать такие вызовы.
То есть, эта ссылка буквально говорит “Найти мне устройство Canon, с моделью MF4010 20Series, с серийником serial=SD3003562100Q и на интерфейсе interface=1”.
Инетрфейс 1, в данном случае, это первый порт на материнке (один из трёх).
В Linux существует команда, которая позволяет вывести все USB устройства в системе (причём не только подключённые к USB в данный момент, но и во внутренние порты, которые являются тоже USB портами, просто внутренними).
Как можно видеть из вывода, наш принтер весит на втором BUS и является 5 устройством на этом BUS. Bus это шина.
Шины позволяют подключать к одному USB много устройств (USB хабы например так и работают, они вешают на одну шину данных много устройств, каждому присваивая уникальный номер).
Для каждой шины (когда та активна) в системе появляется папка, где и “лежит” устройство.
Папка это /sys/bus/usb/devices. Можно вывести её содержимое на экран
Тут можно наблюдать много устройств сразу, причём вообще не понятно какое за что отвечает. Типо я воткнул принтер в порт справа, а это какая из папок? Единственный способ это проверить, это посмотреть по содержимому файла, который всегда будет в этой папке.
Вот что я и сделал. Через grep можно смотреть, есть ли в файле нужная строчка. Через ключ -r можно посмотреть их рекурсивно, а поскольку в пути есть “*”, это означает ВСЕ папки в папке /sys/bus/usb/devices, он будет смотреть во всех папках, в, которых есть файл devnum (см. скрин, где написано “Bus 002 Device 007”, вот этот Device и лежит в файле devnum).
Таким образом, методом исключения, я пришёл к выводу, что принтер мой, это папка 2-1.1. Перейдём и посмотрим что там есть
Тут лежит множество файлов, которые отвечают за то, что это за устройство. Причём они динамические и подтягиваются напрямую с устройства.
То есть, когда вы в dmesg видите информацию об устройстве, вот она читается как раз отсюда в момент подключения в USB разъём.
Можно посмотреть какой нибудь другой файл, например idVendor
Перейдём на скрин с lsusb и там тоже есть такая строчка, вот, где два числа отделены “:”.
Идём копать дальше, отключим устройство, выведем все папки в /sys/bus/usb/devices, подключим назад, и сделаем тоже самое.
При подключении принтера, сюда добавились 4 новые папки: “2-1.1”, “2-1.4:1.0”,”2-1.4:1.0” и ”2-1.4:1.1”.
Вот “2-1.1” это наш принтер, а всё остальное это описание этого же устройства, но чуть иначе.
Теперь что значат эти цифры в названии папки: 2 - шина, 1 - порт на корневом хабе, .1 - порт на внешнем хабе.
То есть, вот это устройство “2-1.1” это устройство на 2 шине, на 1 порте на корневом хабе, и это устройство .1 на внешнем хабе.
Корневой хаб - это часть USB контроллера на мат. плате.
Внешний хаб - это буквально внешний хаб. У меня справа 2 порта, значит они висят на одном корневом хабе, но имеют разветвление на 2 порта, уже на внешнем хабе.
Одно устройство может представляться сразу несколькими папками, что и видно из этого вывода папки при подключении нового устройства.
А теперь самое интересное. Вот вы воткнули в комп клаву, у, которой есть 2 порта по бокам. Вот это стало внешним хабом. То есть, это внешний хаб, на внешнем хабе, который весит на внутреннем хабе. Отсюда такая странная портянка из названия папок.
Нам как пользователям это читать вообще смысла не имеет никакого. Библиотека libusb делает это за нас, находя в такой путаннице конкретное устройство, на конкретной шине, хабе, внешнем хабе и тп.
По сути, мы видит тут то, что есть везде, но в форточках это скрыто в реестре, хотя там такая же портянка из данных. Просто там это база данных, с ключ-значение (объект в ООП например), а тут это файл, в, котором лежит значение. Тоже самое, просто сделано иначе.
А теперь вернёмся к /dev. Почему это является интерфейсом? Да потому что там обычные файлы, через, которые дергаётся именно этот libusb, через, который в дровах описаны методы, которые конкретное устройство умеет выполнять.
Ну и по сути, /dev никогда и не было чисто “сырыми” устройствами. Всё равно ОС как то должна уметь их обрабатывать. По этому, даже до USB, там было всё ровно тоже самое. Там был интерфейс, в, котором уже было описано как взаимодействовать с устройством, через драйвер.
Просто раньше почти всегда было так, что вот, если есть устройство там, то это гарантия того, что именно оттуда и надо обращаться к нему. А, когда появились USB, тогда эта папка перестала быть гарантом. Вон, ссылки вообще появились для доступа к устройству.
Причём контекст с принтером довольно интересный.
Раньше принтеры принимали чисто сырой набор байт (byte stream). У них были зашиты шрифты, разметка, выделение текста (жирность там, италик и тп). Когда на устройство просто переводили поток байт, он просто печатал.
Щас же так нельзя сделать. Принтер вообще печатает всегда картинками. Он переводит условный docx, pdf в картинки и печатает уже их. У них логика стала очень сложной. Поэтому и пропал прямой интерфейс через /dev.
Подключение Serial-устройства
С устройствами использующий serial-порт для общения ситуация чуть лучше. Они гарантированно будут в /dev, но тут все зависит ещё и от последовательности подключения.
Вот представим себе, вы делаете проект, и у вас одновременно используется две ардуинки.
Пронумеруем их как X и Y.
Если вы подключите первым X, то он станет ttyUSB0. Потом подключится Y, и он будет ttyUSB1.
Теперь сделаем скрипт, который посылает на эти интерфейсы данные. И в моменте это всё работает хорошо.
Но вот вы решили закончить работу и отключили всё. А на следующий день может произойти следующее: вы подключили первым Y, а не X. И следовательно теперь Y стал ttyUSB0, а X ttyUSB1.
Тут вы запускаете скрипт и… у вас ничего не работает! Интерфейсы устройств-то поменялись.
На форточке такого произойти не может по определению. В Windows каждый порт имеет фиксированное название - COM и цифра под порт. Системе вообще фиолетово в какой последовательности вы подключаете устройства, если вы сегодня, через неделю, да хоть через год подключили X во 2 порт, он всегда будет COM2. Устройство Y на него вообще не влияет, он как был всегда COM3, так им и остался (если порт, конечно, не поменяли).
Я могу вполне наглядно продемонстрировать как будет в системе отличаться порядок подключения устройств. У меня есть две ардуинки.
Подключим их по очереди
Проблема в том, что у них идентично ВСЁ. Я думал, что у них могут отличаться vendor или product, а вот нет. Просто так показать разницу будет менее наглядно, но как есть. Тут только наслово верить.
Чтобы понять какие устройства были подключены на какие интерфейсы, я сделал самый простой вариант - положил в файлы выводы команд ls на трёх состояниях - без устройств, с 1 ардуинкой, с двумя ардуинками, и сравнил их друг с другом
При сравнении файлов dev1 и dev2 мы видим, что появилось новое устройство - ttyUSB0, при сравнении dev1 и dev3 видим уже 2 устройства - ttyUSB0 и ttyUSB1, а при сравнении dev2 и dev3 видим уже 1 устройство - ttyUSB1.
Так методом исключения можно понять что и какой порт воткнуто.
Далее, чтобы определить, где лежат сами USB устройства, найдём их в /sys по devnum (они меняются каждый раз, как они отключаются/подключаются заново)
Теперь отключим их
И подключим ещё раз в другой последовательности
Теперь вторая ардуинка под devnum 24, а первая стала под devnum 25.
Опять найдём их в /sys
Тут прям видно, что я поменял последовательность подключения устройств. То, что я подключал вторым, стало первым, а первой - вторым (2-1.1 стало из второго устройства под devnum 23 стало 24, значит было воткнуто первым, а то, что было под 22, стало 25).
И теперь проверим папку /dev
Точно такие же по названию устройства поменялись местами. Получилось ровно то, о чём я и говорил. Смена последовательности подключения меняет их номер местами. И, если бы у нас был скрипт, который должен считывать именно с первой ардуинки данные, начал бы их читать из второй.
Можно это сравнить с тем, как windows обрабатывает тоже самое.
Подключим 2 устройства и посмотрим в менеджере устройств на компорты
Воткнём эти же устройства, в эти же порты, но в другой последовательности
А ничего не поменялось. Вот о чём я и говорил. Форточке совершенно безразлично, в какой последовательности вы втыкаете устройства, она это отобразит как в первый раз. Поэтому тут конфузов с скриптом и чтением с порта не будет (только если вы порты не перепутаете).
Как работать с CD-дисками
Для того, чтобы понять, почему работа с дисками кардинально отличается, нужно понять то, как эти диски устроены.
Я могу выделить 2 типа диска (во всяком случае, у меня их есть только 2).
Первый - диск с медиа (музыка). У диска с музыкой нет файловой системы, есть только данные, записанные на секторах напрямую. Это так называемый формат wav без сжатия. Качество у такого близко к современному формату flac, с отличием в том, что flac это формат с сжатием, но без потерь.
Из GUI работать с такими дисками довольно просто. Просто вставьте диск, он сразу отображается в файловом менеджере, где вы можете включить любую композицию (по сути, играться будут просто данные с определённого сектора).
У меня есть пару диском в таком формате. Вставляю диск в дисковод и система сразу предлагает вариант что делать с этим диском
Он сразу появляется в ФМ, но с очень интересным адресом
Cdda - это не драйвер и не библиотека, это обращение к формату “compact disk digital audio” и в графике отображается как путь, хотя таковым не является.
В системе этот диск нигде не примонтирован, так как монтировать просто нечего. Монтировать можно только блочные устройства или файлы с разделами через loop-устройство. Диск же с музыкой не имеет файловой системы вообще, это просто сырой поток байт музыки.
После cdda идёт имя дисковода - sr0. Он есть в /dev
Но, как мы уже выяснили, в /dev лежат только интерфейсы, но не реальные устройства. Само устройство тоже хранится в /sys, но уже в другом месте. Для дисков этот путь /sys/class/block/sr0 (причём тут он будет лежать даже без самого диска в дисководе, так как тут лежат методы именно дисковода, что умеет делать с диском, а не самого диска/болванки)
Музыку с такого диска умеют проигрывать большинство плееров, один из Rytmicbox, который по дефолту установлен в mint.
Ну, а что делать, если нам нужно оттуда получить трек, и проиграть его независимо от диска? Из графики его можно просто скопировать, а вот с консоли начинаются проблемы - диска ведь нигде нет примонтированного. Напрямую обратиться к cdda как к пути тоже нельзя.
Нужно ставить дополнительную утилиту, которая “сдампит” определённые сектора и сделает их в виде файла с расширением wav. Одной из таких утилит - cdparanoia - я и буду пользоваться.
Установим её из пакетника
Работа с ней элементарная. Вводим просто название и номер трека, и он его дампит в папку, где мы сейчас находимся
Далее этот файл можно спокойно играть в любом плеере и без диска.
Можно получить информацию о диске с помощью утилитки udevadm
А вот дальше установим другой диск с музыкой, но уже с mp3 файлами на ней.
Тут мы видим реальный путь. А почему? Потому что у диска есть файловая система и это, по сути, блочное устройство.
Посмотрим как выглядит этот примонтированный раздел в системе
С таким диском можно работать точно также как и с флешкой. Никаких ограничений нет.
Можно ещё посмотреть объём этого диска (и доступный, если есть) через утилитку df с ключами Th (T - объём диска/раздела, h - в человекочитаемом формате (мегабайты, гигабайты))
Как видно, диск забит полностью (точнее, на нём закрыта возможность записывать в свободные сектора, если они есть).
Если нам нужен полный дамп диска, его можно получить через утилитку dd, где в качестве аргументов передаётся if- входной файл (интерфейс диска), of - выходной файл (куда писать данные с диска).
Такой ISO образ диска получается полный, не теряется ничего. Если нужно, его можно передать на другой ПК и спокойно его примонтировать (что в Windows, что в Linux).
Через утилиту fdisk можно посмотреть его (ISO) файловую систему, тут это iso9660
Давайте примонтируем этот файл в систему (это можно делать и без loop устройства, если не нужна возможность записи и работа с ним как с блочным устройством)
Но он всё равно монтируется через loop устройство, просто в автоматическом режиме
Работа с MTP устройствами
Последнее что я хотел бы затронуть в данной статье - это работа с MTP устройствами.
MTP или Media Transfer Protocol (протокол переноса/передачи медиа) используется большинством современных устройств для обмена информацией. Это и телефоны (по поводу яблочных огрызков не в курсе, но в режиме передачи фотографий может быть и MTP), и камеры, и другие внешние устройства.
Я буду показывать работу с MTP протоколом на двух устройствах - современном смартфоне Xiaomi 11 и старом телефоне Nokia E71. Они оба используют MTP для передачи файлов с ПК на устройство.
Вообще, если у кого-то были вопросы почему вообще такие устройства работают именно по MTP, а не просто как блочные устройства, то тут ответ довольно сложный. По сути, телефоны на андроиде вполне себе блочные устройства, но ради безопасности ему нельзя выдавать какие-то разделы на устройстве. Через MTP можно ограничиться определённым разделом и “вещать” только им.
Xiaomi 11
Вообще, я не думаю, что большинство читающих эту статью представляют, как внутри Android выглядят разделы. А там посмотреть есть на что.
Дам вам часть того, как это вообще всё внутри выглядит
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 ALIGN_TO_128K_1 -> /dev/block/sdd1
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 ALIGN_TO_128K_2 -> /dev/block/sdf1
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 abl_a -> /dev/block/sde8
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 abl_b -> /dev/block/sde32
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 aop_a -> /dev/block/sde1
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 aop_b -> /dev/block/sde25
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 apdp -> /dev/block/sde49
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 bk01 -> /dev/block/sda4
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 bk010 -> /dev/block/sda23
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 bk06 -> /dev/block/sda12
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 bluetooth_a -> /dev/block/sde5
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 bluetooth_b -> /dev/block/sde29
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 userdata -> /dev/block/sda33
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 boot_b -> /dev/block/sde35
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 catecontentfv -> /dev/block/sde61
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 catefv -> /dev/block/sde60
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 cdt -> /dev/block/sdd2
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 cpucp_a -> /dev/block/sde20
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 cpucp_b -> /dev/block/sde44
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 cust -> /dev/block/sda19
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 devcfg_a -> /dev/block/sde12
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 devcfg_b -> /dev/block/sde36
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 devinfo -> /dev/block/sda18
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 dip -> /dev/block/sde48
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 dsp_a -> /dev/block/sde9
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 dsp_b -> /dev/block/sde33
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 dtbo_a -> /dev/block/sde15
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 dtbo_b -> /dev/block/sde39
Внутренная память разбита на огромное кол-во разделов, каждый из, которых используется в разное время (я снимал эти разделы (их больше в разы чем тут) через кастомное рекавери для переноса в прошивку).
Если вы прошивали современные телефоны, то знаете, что допустим в dtbo лежат дрова (проприетарные блобы), а в boot лежит ядро с рекавери (раньше были отдельными разделами).
Вот в MTP вынесен только тот раздел, куда может писать пользователь (при форматировании даты до заводских именно он и форматируется, не трогая ничего остального). Вот у меня это sda33.
Это вообще никак не влияет на то, что и как мы будем делать дальше, просто дал как интересный факт.
Давайте подключим устройство и посмотрим на вывод dmesg
Дальше сделаем тоже самое что и раньше, найдём его в /sys
Собственно, он ничем и не отличается от прошлых примеров. Он выглядит ровно также.
Через GUI доступ к MTP можно получить сразу, но там опять будет ссылка в пути
Но GUI скучно, давайте залезем в терминал.
ADB способ
Для управления андроидом через терминал можно использовать adb. Сначала поставим его
Далее посмотрим что устройство подключено (нужно включить режим разработчика и там отладку по ADB)
Чтобы загрузить что-либо на устройство, нужно использовать метод push у adb и указать путь куда его положить (/sdcard и /storage/emulated/0/ одинаковые пути на большинстве устройств, тут “0” указывает на пользователя в системе. Если у вас на телефоне 2 пользователя, то там будет ещё /storage/emulated/1/ для второго пользователя, но куда именно будет указывать sdcard я не знаю (вроде от второго пользователя вообще нельзя использовать adb, так что только в 0 скорее всего, но сам не проверял))
Посмотрим из интерфейса, что файл передался на у-во
Чтобы файл “скачать” с у-ва, нужно использовать метод pull
Способ напрямую
Если вам не по душе adb и вы хотите работать с MTP как с обычным блочным устройством, то есть альтернативный способ.
На самом деле в системе есть место, куда “монтируется” MTP устройство и, где прямой интерфейс до внутренней (и внешней sdcard) памяти!
Причём обратите внимание на название папки с MTP у-ва. Это тот же путь, что можно было видеть в ссылке в GUI! (ну, почти. Тут :host добавился)
PS. Вот тут важно дополнить, что такой способ будет работать только тогда, когда установлены пакеты для MTP устройств. Если пакетов не стоит, то способ через ADB вам в помощь
Nokia e71
В отличии от андроида, у nokia не было единого инструмента типа adb (ну или был, но только для форточки), поэтому тут заработает только последний способ для доступа к памяти.
Но сначала, посмотрим на это через GUI
И сразу же как это выглядит в терминале
На симбах наружу тоже выводится только определённая папка (c:\data), а не весь корень
Ну и напоследок, что лежит в sys и вывод dmesg для нокии
Заключение
В данной статье я постарался осветить работу с большинством современных внешних устройств. Также разобрал то, как выглядят устройства на уровне системы, где они находятся и что из себя представляют.
Также затронул тему директории /dev, которая обычно вызывает огромное количество вопросов при более близком знакомстве (если вы любопытный, конечно).
Надеюсь эта статья была полезна и вы узнали что-то новое про Linux. Если у вас есть чем дополнить или поправить, то прошу в комментарии, буду рад услышать дополнения по теме.
Важно понимать, что я буду говорить только про управление и использование через терминал, а не про графический интерфейс. Графика довольно похожа на то, что есть в Windows, поэтому её затрагивать смысла не вижу.
Для меня Linux это всё же Terminal-first система (хотя и не так выраженно, как, например, в FreeBSD), а GUI так, нашлёпка, которой вполне может и не быть (что довольно часто встречается на серверах или мейнфреймах).
Изначально я хотел сделать статью чисто про USB-устройства, но чуть позже я решил затронуть и блочные устройства, так как это самое частое, с чем вы будете иметь дело в любой ФС.
Также я затрону Диски (HDD) и CD-Диски (DVD, Music), так как это тоже может вызывать вопросы.
Затрону ещё и работу с принтерами (это можно отнести к USB-устройствам).
Сюда бы можно было бы ещё и отнести работу с COM-устройствами, но что COM, что LPT портов у меня не наблюдается, так что это я опущю.
Работа с блочными устройствами
Возможно, вам очень непривычно слышать название “блочные устройства”, но тут нет ничего уж сильно странного.
Блочными устройствами в *NIX-системах называют любые диски и флешки (т. е. носители информации, которые можно “разбить”).
(Если более техническим языком, то это устройства, которые хранят информацию в фиксированных блоках, секторах или кластерах. Как раз описание дисков или флешек)
Все блочные устройства работают одинаково. Что флешки, что диски. Разницы в дисках тоже нет (что HDD, что SSD будут работать идентично для конечного пользователя).
Под работой с блочными устройствами я буду иметь в виду разбиение на разделы и форматирование этих разделов в определённую ФС. Начнём с разбиения на разделы.
Разбиение на разделы
Для создания и редактирования разделов я использую программу fdisk. У неё есть TUI-версия под названием cfdisk, но я ей не пользуюсь, так как мне удобнее классическая версия fdisk.
Если вы пользовались DOS или *BSD, то у меня для вас плохие новости. Fdisk на всех этих трёх системах абсолютно разный. И на Linux он мне нравится в разы больше, чем на том же DOS или BSD (на ДОС он умеет разбивать только в fat16/32 и управление у него своеобразное).
Для того, чтобы разбить флешку на разделы, нужно знать, что бить. При вставке флешки в систему у неё появляется “интерфейс” в /dev (чуть позже я буду более подробно рассказывать про это).
Чтобы понять, какое блочное устройство предстоит разбивать на разделы, введём команду lsblk (от list block).
Что мы видим? Под названием указывается имя устройства (интерфейс в /dev), в mountpoint - куда оно примонтировано. Под цифрами в названии подразумевается раздел (то есть, sda1 - это 1й раздел, а sda2 - второй и тд.).
Разбивать нужно НЕ РАЗДЕЛЫ, а само устройство. Поэтому пишем в консоли (я буду равноценно использовать что терминал, что консоль. Для конечного пользователя разницы нет никакой, чисто разница в терминологии) sudo fdisk /dev/sda
Если вы впервые разбиваете блочное устройство в fdisk, он может показаться очень “недружелюбным”, но это на первый взгляд. Он простой в обращении, нужно всего лишь ввести букву под действие. Чтобы вывести список команд, введите m в интерфейс и получите вот такую справку
Короткая справка от меня:
Команда | Что делает |
o | Создаёт MBR разметку на БУ |
g | Создаёт GPT разметку на БУ |
n | Создаёт новый раздел |
d | Удаляет выбранный раздел |
t | Меняет тип раздела (чуть позже) |
w | Сохраняет изменение |
q | Выход из утилиты |
БУ - Блочное Устройство.
Тут нужно сделать небольшую справку про MBR и GPT
Что такое таблицы разделов
Таблицы разделов, или на английском Partition Table, это то как будет ваши блочные устройства разбиты.
Таблица MBR (Master Boot Record) использовалась во время DOS и ранних Windows. В ней может быть максимум 4 раздела, каждый раздел может быть основным (primary) или добавочным (extended), у одного раздела из всех может быть флаг загрузочного (bootable), на, который обычно устанавливается загрузчик системы.
Когда раньше грузился ПК BIOS искал именно раздел с флагом загрузочного. Если такого не находилось, то ОС не загружалась.
С появлением UEFI систем (точнее с началом их распространения в 2010-х годах), MBR разделы стали устаревшими и теперь используется таблица GPT (Grand Partition Table).
Кол-во разделов было увеличено до 128, пропали загрузочные разделы, так как UEFI ищет не конкретный загрузочный раздел, а раздел в FAT32 с EFI папкой. Если таковой был найден, то ПК знает откуда ему загружать систему.
На одном диске может быть как 1 система, так и 2, 3 и тд. У каждой системы должен быть свой EFI раздел, чтобы UEFI мог загружать их независимо друг от друга.
Для создания простой флешки совершенно без разницы, в какой таблице она была разбита, но я покажу обе, так как у каждой есть свои подводные камни.
Разбиение в MBR
Чтобы разбить в MBR нужно ввести o и утилита предложит выбрать тип раздела. Выбираем всегда основной раздел, так как от добавочного смысла немного.
Далее, выбираем размер раздела. Для этого вводим в Last Sector плюс и цифру с буквой.
Если нужно создать раздел в 5 Гигов, то вводим +5G, или +5120M для того же объёма в мегабайтах (1024 * 5).
В конце нас спросят под сигнатуру раздела, всегда удаляйте старую сигнатуру.
Далее, нужно поговорить про типы разделов. Вот сводная таблица всех возможных типов разделов в MBR
Для Linux не сильно важно какой тип стоит в разделе, а вот для Windows жизненно необходимо указывать правильный тип (это, по сути, заголовок раздела. Если заголовок не совпадает с типом, который ожидает форточка, то она просто не увидит диск. Linux в этом плане всеядный).
Для Windows в MBR подходят типы от 0b до 0f. Причём даже формат раздела не важен, главное, чтобы был выбран правильный тип.
Я выбираю обычно 0b (обычно я не делаю флешки в MBR вообще).
Меняем тип и на 0b и записываем изменения на устройство
После этого, в системе появится устройство /dev/sda1, пока что без форматирования, которое мы повесим позже. Сначала сделаем тоже самое, но для GPT.
Разбиение в GPT
Для того, чтобы разбить в GPT делаем тоже самое, но уже с буквой g в начале.
Стоит отметить, что при GPT уже не спрашивают про тип раздела (основной или добавочный), так как их просто нет в GPT.
Если не указывать объём раздела, то он создаться на всё свободное место.
Типы разделов тут также существуют и их ОЧЕНЬ много
Для нас тут нужен только один тип - 11, который позволит флешке (разделу) определится в Windows.
Дополнение
Чтобы удалить раздел, введём d и, если раздел один, то он удалит этот раздел, а, если несколько, то просто попросит ввести номер нужного.
Я создаю 2 раздела с одинаковыми типами раздела 11. Как можно видеть, перед определением типа, утилита спрашивает какому разделу присвоить тип.
После этого, вводим w и утилита записывает на устройство изменения.
Можно ввести lsblk чтобы убедится в наличии этих двух разделов
Форматирование разделов
Функция форматирования не входит в утилиту fdisk, поэтому для создания форматирование на разделе необходимо воспользоваться утилитой mkfs. Она не принимает параметры как другие утилиты, а тип указывается после точки в названии утилиты (форматирование под разные форматы это просто разные бинарники в системе, а не единая утилита с ключами).
Я форматирую разделы в exFAT (для этого нужен дополнительный пакет в системе. В Arch: exfat-utils и exfat-progs, в debian: exfat-fuse)
Если вам нужно сделать форматирование в fat, то нужно написать в консоли mkfs.fat -F 32 … для форматирования в FAT32 или mkfs.fat -F 16 … для форматирования в FAT16.
Другие файловые системы делаются аналогичным образом (для ntfs нужен пакет ntfs-3g).
Монтирование разделов
Чтобы потом на эти разделы записать информацию, их нужно примонтировать в систему.
Для этого воспользуемся командой mount, у, которой есть 2 способа монтирования (ну это не совсем способы, но назову их так).
Первым параметром утилита принимает раздел для монтирования, а вторым путь для монтирования (обычно это /mnt).
Для этого можно использовать 2 способа.
1й - явный.
Тут через -t обязательно указывается тип ФС на разделе (fat32, fat16, ntfs-3g, exfat, ext4).
2й - неявный.
Тут использования -t необязательно. Утилита mount умеет сама определять ФС на разделе (в *BSD, например, она это делать не умеет, там всегда нужно указывать явно ФС (это могло в последних версиях изменится, не слежу за FreeBSD так пристально)).
Отмонтирование раздела
После окончания работы с разделом, его нужно обязательно отмонтировать от системы.
Для этого есть утилита umount (да, именно umount, не unmount).
Больше никаких дополнительных ключей указывать не нужно для утилиты.
Проверка работоспособности раздела в Windows
Как вы могли видеть, я скопировал на флешку скриншоты для статьи
Давайте вставим флешку в windows и проверим, будет ли флешка там читаться
Да, всё работает.
Если бы не был указан тип раздела при его создании (0b, 11), то флешка бы просто не отобразилась.
На этом работа именно с блочными устройствами закончена (я не думаю, что стоит говорить как копировать файлы на флешку). Тут нужно затронуть тему “нейминга” устройств в /dev и вообще для чего он используется.
Что такое этот ваш /dev?
Папка /dev появилась ещё в UNIX, откуда перекочевала и в BSD, и в Linux как наследие. Но, если в BSD оно ещё сохраняет актуальность, то вот в Linux это скорее обрубок из прошлого.
Папка /dev изначально предназначалась для всех подключаемых устройств в ПК. Мышки, клавы, диски, дискеты и тп.
Во наше время USB устройств в Linux эта папка стала обрубком, куда стали выносится только “интерфейсы” для работы с устройствами, которые поддерживают низкоуровневое обращение. Это диски, CD, флешки (разделы, интерфейс самой флешки), флоппик, serial-устройства (микроконтроллеры), COM и LPT порты (если есть).
Но все usb устройства “фикция” или, как я назвал их, “интерфейсы” для работы. Сами устройства тут давно не лежат.
До того как на самом деле выглядят современные устройства в системы мы дойдём чуть позже, когда будем трогать принтер, а сейчас небольшой список по тому, какие “интерфейсы” в /dev самые распространённые.
tty - это интерфейс терминалов (причём аппаратных, а не виртуальных, к, которым нас цепляют эмуляторы терминала из GUI (Konsole, Gnome Terminal)).
Чтобы увидеть аппаратный терминальный интерфейс вы можете нажать комбинацию из Ctrl+Alt+F1-F7. tty1 исторически используется для вывода лога ядра Linux, tty2 - логинка (Display Manager; sddm, gdm, lightdm), tt7 - графическое окружение (если установлено) (KDE, Gnome, XFCE4).
Любые блочные устройства тоже будут там, и это уже будет не “интерфейс”, а реальное устройство.
Тут важно сказать, что в /dev выносятся те устройства/интерфейсы устройств, которые могут напрямую быть использованным ядром. Диски в их числе.
Но хоть интерфейс дисков и представлен там всегда, это совсем не означает, что ядро может их использовать напрямую. Если на разделе будет ФС, у которой нет низкоуровневого драйвера (в Linux драйверы — это модули ядра), то ядро не сможет с таким разделом работать напрямую.
Например у exfat нет такого модуля ядра и поэтому он работает только в пользовательском пространстве (userspace) через fuse (Filesystem in Userspace).
Заметили, что, когда я писал про пакеты для работы в системах для exfat, в debian пакете была приписка -fuse (exfat-fuse)? Вот это как раз оно и есть.
Собственно поэтому мы и не можем поставить систему на, например, exfat или ntfs-3g. Они все работают через fuse. Если бы мы и поставили систему на exfat, то загрузится мы бы просто не смогли. Ядро бы не смогло работать в таком режиме, так как отсутствует модуль ядра для этой ФС.
Далее обсудим интерфейсы конкретно блочных устройств.
Интерфейс sdXY или hdXY самые распространённые. Под эти интерфейсы попадают как диски (HDD,SSD), так и флешки.
На месте X стоит буква, которая определяет диск (не путать с DOS дисками). Например, если в системе установлен HDD или SSD как основной диск, то это будет sda, и, если к ПК с системой на sda подключить флешку, то она будет уже sdb (т.е. следующий диск в списке), или sdc.
Причём буква для конкретного диска не резервируется. В windows можно выбрать какой буквой будет диск на любых машинах (если эта буква диска не занята), а вот в linux - какой первый вставили, такой и a.
Дисков hd вы уже очень вряд ли встретите. Такое представление дисков было во времена IDE дисков.
В Linux вот это sd образовано от названия разъёма SCSI (у нас его ещё называют “скази”) (SCSI Disk) и Linux ВСЕ блочные устройства воспринимает именно как скази. И флешки, и диски (кроме некоторых).
В тоже время, у *BSD систем совсем другая логика. Там интерфейс называется по драйверу, который использует конкретный диск.
Например ada это ATA Driver Access, da - Direct Access, cd - CDROM.
Поэтому флешки там da, HDD/SSD - ada, НО вот SSD подключенный через USB - это уже da.
Плюс, там отличается то, что номер диска цифровой, и номер раздела тоже цифровой. Поэтому может быть вот такое распределение - ada1p1, то есть это ATA диск, раздел 1.
Мне *BSD-формат представления дисков не нравится, он слишком геморный для запоминания.
Я знаю два особых блочных устройства, получившее своё уникальное название в системе - NVME диски и SD-карты. Для NVME - это nvmeXnY, а для SD - mmcblkXpY, где X - номер диска (1..∞), а Y - номер раздела (1..∞).
Для CD выделено отдельное устройство (которое появляется только если есть сидюк в ПК) — sr0 (я в сомнениях, что у вас в системе может быть больше одного привода, щас один-то уже редкость).
Для флоппика тоже есть отдельное устройство fd.
Если ваше устройство поддерживает Serial-порт (у меня это только ардуинка и esp32), то они будут ttyACM0 для ардуинки или ttyUSB0 для esp32 (у меня было такое распределение, но в другом дистре может быть иначе).
Дополнение.
ttyACM0 это native-usb устройство (без дополнительного загрузчика (ch340 например)), тогда как ttyUSB0 с загрузчиком. У меня есть 2 esp32. Одна из них ttyUSB0 использует загрузчик ch341, а другая ttyACM0 использует native-usb и может быть определена в системе как HID (input) устройство, что-то типа bluepill или digispark, но с esp32.
Если вдруг у вас есть COM-порт, то он будет в системе определяться как ttyS0,ttyACM0 и ttyUSB0 только если COM-устройство через USB; LPT (параллельный порт) как lp0, иногда бывает parport0.
И есть ещё один специфический и только виртуальное устройство - loop. Его используют для работы с файлом, как с блочным устройством. Ну вот есть, например, дамп с телефона в img формате (например дамп системного раздела, я так делал), то, чтобы его редактировать, его нужно примонтировать в системе через loop устройство. Только так его можно будет использовать как RW устройство, а не как RO. Также так монтировать стоит ISO образ диска.
Пример монтирования файла через loop
mount -o loop,rw system.img ~/mount
Через -o указывается устройство через, которое идёт монтирование. Loop устройств в системе далеко не одно. А также режим монтирование (только чтение или чтение/запись).
И есть ещё одно специальное виртуальное устройство - zero. Это устройство просто выдаёт нули. И больше ничего. Его используют тогда, когда нужно записать куда-то нули (например перезаписать диск и удалить оттуда вообще всё, перезаписав каждый сектор нулями. Или, если надо искусственно расширить файл, записав в конец столько нулей, на сколько нужно расширить файл).
Пример расширения файла с ФС через zero
dd if=/dev/zero bs=1M count=512 >> system.img
Вот пример папки /dev на моём домашнем сервере на Debian. Это Intel NUC, в, котором есть встроенная SD карта на 32 гига. Поэтому тут есть mmcblk
Вроде бы на этом всё по папке /devи устройствам в ней.
Подключение принтера и “откуда у меня ссылка в названии устройства?!”
Вроде бы мы разобрались с тем, как представляются устройства в Linux, да? А вот нет. Это ещё не всё.
В Windows все устройства ограничиваются названием COM с циферкой, тут же целый зоопарк названий (думаю уже было понятно после прошлой секции какой), но и это не всё. Тут есть ещё ссылки в названии
Для начала настроим принтер. У меня довольно старый принтер от Canon - i-SENSYS MF4018. С его настройки в W10 было вылито не одно ведро мата с помоями в сторону драйверов от этого принтера.
В Linux же всё прощё и сложнее одновременно. На Arch его завести будет анрил, на Debian всё поднимается на раз два (дрова ток под него) (точнее скрипт под него только, а переписывать скрипт я уж не буду, спасибо).
Драйвера на Linux для принтеров представляют собой просто pdd файлы, которые умеет читать другой драйвер - CUPS. Поэтому установим сначала его с плагином gutenprint для поддержки большей части принтеров (кроме блин этого…).
И да, я переехал на другой ноут (там есть дисковод, он мне будет нужен позже). Там установлен свеженький mint.
Установим CUPS
После установки CUPS нужно принянуть дрова для самого принтера. Чапаем на сайт, там ищем дрова под линь (вот это нифига себе, под линь дрова есть, это редкость).
Дрова идут в тарболе, распаковываем их
Перед запуском скрипта, запустим утилиту дебага dmesg с флагом -w (это сообщения от ядра) и подключим принтер по USB
В конце можно видеть что он определился как /dev/usblp1 (но эт нам не поможет).
Когда запустим скрипт, будет запущена утилитка настройки каноновских принтеров, выбираем его
Дальше меня ждало разочарование - MF4018 там нет. Выбираем близкий MF4010 (его даже так утилитка распознала)
А вот тут наблюдаем ССЫЛКУ
вращаемся на пару шагов назад, а, где же устройство /dev/usblp1? Почему тут урла? Откуда?
Не, я бы понял что она там может быть, если бы я подключал его по сети, но я то через USB его подключаю. Откуда там урла? А вот это называется libusb.
В нынешнем Linux устройства могут определятся не только в /dev. Я почему и сказал, что в /dev находятся только интерфейсы устройств, но не сами устройства.
Объяснять откуда там урла я буду через пару шагов, сначала проверим принтер.
Заходим в LibreOffice и печатаем что-нибудь.
Печать прошла
Первое, запоминаем. Принтер работает, значит эта урла действительно ведёт на это устройство, но каким образом?
Для тех кто не знает как устроена URL: В URL есть несколько частей. Разберём ссылку на какой нибудь сайт.
“https://www.google.com/search?q=linux+fuse&oq=linux+fuse”
Вот эта часть “https://www.google.com/search” это адрес сайта, в данном случае поиск гугла.
После него идёт вопрос, это знак “переменных”. Эти переменные задаются разработчиком, их можно считывать.
Если переменных много, то они разделяются &.
Теперь посмотрим на URL в адресе принтера:
“usb://Canon/MF4010%20Series?serial=SD3003562100Q&interface=1”
Вот эта часть это ссылка (вернее её тело) “usb://Canon/MF4010%20Series”, это
“serial=SD3003562100Q” и это “interface=1” переменные, которые откуда-то берутся (где и есть само устройство).
Вот это “usb://” это обращение к протоколу, а, если точнее, то к библиотеке libusb, которая умеет обрабатывать такие вызовы.
То есть, эта ссылка буквально говорит “Найти мне устройство Canon, с моделью MF4010 20Series, с серийником serial=SD3003562100Q и на интерфейсе interface=1”.
Инетрфейс 1, в данном случае, это первый порт на материнке (один из трёх).
В Linux существует команда, которая позволяет вывести все USB устройства в системе (причём не только подключённые к USB в данный момент, но и во внутренние порты, которые являются тоже USB портами, просто внутренними).
Как можно видеть из вывода, наш принтер весит на втором BUS и является 5 устройством на этом BUS. Bus это шина.
Шины позволяют подключать к одному USB много устройств (USB хабы например так и работают, они вешают на одну шину данных много устройств, каждому присваивая уникальный номер).
Для каждой шины (когда та активна) в системе появляется папка, где и “лежит” устройство.
Папка это /sys/bus/usb/devices. Можно вывести её содержимое на экран
Тут можно наблюдать много устройств сразу, причём вообще не понятно какое за что отвечает. Типо я воткнул принтер в порт справа, а это какая из папок? Единственный способ это проверить, это посмотреть по содержимому файла, который всегда будет в этой папке.
Вот что я и сделал. Через grep можно смотреть, есть ли в файле нужная строчка. Через ключ -r можно посмотреть их рекурсивно, а поскольку в пути есть “*”, это означает ВСЕ папки в папке /sys/bus/usb/devices, он будет смотреть во всех папках, в, которых есть файл devnum (см. скрин, где написано “Bus 002 Device 007”, вот этот Device и лежит в файле devnum).
Таким образом, методом исключения, я пришёл к выводу, что принтер мой, это папка 2-1.1. Перейдём и посмотрим что там есть
Тут лежит множество файлов, которые отвечают за то, что это за устройство. Причём они динамические и подтягиваются напрямую с устройства.
То есть, когда вы в dmesg видите информацию об устройстве, вот она читается как раз отсюда в момент подключения в USB разъём.
Можно посмотреть какой нибудь другой файл, например idVendor
Перейдём на скрин с lsusb и там тоже есть такая строчка, вот, где два числа отделены “:”.
Идём копать дальше, отключим устройство, выведем все папки в /sys/bus/usb/devices, подключим назад, и сделаем тоже самое.
При подключении принтера, сюда добавились 4 новые папки: “2-1.1”, “2-1.4:1.0”,”2-1.4:1.0” и ”2-1.4:1.1”.
Вот “2-1.1” это наш принтер, а всё остальное это описание этого же устройства, но чуть иначе.
Теперь что значат эти цифры в названии папки: 2 - шина, 1 - порт на корневом хабе, .1 - порт на внешнем хабе.
То есть, вот это устройство “2-1.1” это устройство на 2 шине, на 1 порте на корневом хабе, и это устройство .1 на внешнем хабе.
Корневой хаб - это часть USB контроллера на мат. плате.
Внешний хаб - это буквально внешний хаб. У меня справа 2 порта, значит они висят на одном корневом хабе, но имеют разветвление на 2 порта, уже на внешнем хабе.
Одно устройство может представляться сразу несколькими папками, что и видно из этого вывода папки при подключении нового устройства.
А теперь самое интересное. Вот вы воткнули в комп клаву, у, которой есть 2 порта по бокам. Вот это стало внешним хабом. То есть, это внешний хаб, на внешнем хабе, который весит на внутреннем хабе. Отсюда такая странная портянка из названия папок.
Нам как пользователям это читать вообще смысла не имеет никакого. Библиотека libusb делает это за нас, находя в такой путаннице конкретное устройство, на конкретной шине, хабе, внешнем хабе и тп.
По сути, мы видит тут то, что есть везде, но в форточках это скрыто в реестре, хотя там такая же портянка из данных. Просто там это база данных, с ключ-значение (объект в ООП например), а тут это файл, в, котором лежит значение. Тоже самое, просто сделано иначе.
А теперь вернёмся к /dev. Почему это является интерфейсом? Да потому что там обычные файлы, через, которые дергаётся именно этот libusb, через, который в дровах описаны методы, которые конкретное устройство умеет выполнять.
Ну и по сути, /dev никогда и не было чисто “сырыми” устройствами. Всё равно ОС как то должна уметь их обрабатывать. По этому, даже до USB, там было всё ровно тоже самое. Там был интерфейс, в, котором уже было описано как взаимодействовать с устройством, через драйвер.
Просто раньше почти всегда было так, что вот, если есть устройство там, то это гарантия того, что именно оттуда и надо обращаться к нему. А, когда появились USB, тогда эта папка перестала быть гарантом. Вон, ссылки вообще появились для доступа к устройству.
Причём контекст с принтером довольно интересный.
Раньше принтеры принимали чисто сырой набор байт (byte stream). У них были зашиты шрифты, разметка, выделение текста (жирность там, италик и тп). Когда на устройство просто переводили поток байт, он просто печатал.
Щас же так нельзя сделать. Принтер вообще печатает всегда картинками. Он переводит условный docx, pdf в картинки и печатает уже их. У них логика стала очень сложной. Поэтому и пропал прямой интерфейс через /dev.
Подключение Serial-устройства
С устройствами использующий serial-порт для общения ситуация чуть лучше. Они гарантированно будут в /dev, но тут все зависит ещё и от последовательности подключения.
Вот представим себе, вы делаете проект, и у вас одновременно используется две ардуинки.
Пронумеруем их как X и Y.
Если вы подключите первым X, то он станет ttyUSB0. Потом подключится Y, и он будет ttyUSB1.
Теперь сделаем скрипт, который посылает на эти интерфейсы данные. И в моменте это всё работает хорошо.
Но вот вы решили закончить работу и отключили всё. А на следующий день может произойти следующее: вы подключили первым Y, а не X. И следовательно теперь Y стал ttyUSB0, а X ttyUSB1.
Тут вы запускаете скрипт и… у вас ничего не работает! Интерфейсы устройств-то поменялись.
На форточке такого произойти не может по определению. В Windows каждый порт имеет фиксированное название - COM и цифра под порт. Системе вообще фиолетово в какой последовательности вы подключаете устройства, если вы сегодня, через неделю, да хоть через год подключили X во 2 порт, он всегда будет COM2. Устройство Y на него вообще не влияет, он как был всегда COM3, так им и остался (если порт, конечно, не поменяли).
Я могу вполне наглядно продемонстрировать как будет в системе отличаться порядок подключения устройств. У меня есть две ардуинки.
Подключим их по очереди
Проблема в том, что у них идентично ВСЁ. Я думал, что у них могут отличаться vendor или product, а вот нет. Просто так показать разницу будет менее наглядно, но как есть. Тут только наслово верить.
Чтобы понять какие устройства были подключены на какие интерфейсы, я сделал самый простой вариант - положил в файлы выводы команд ls на трёх состояниях - без устройств, с 1 ардуинкой, с двумя ардуинками, и сравнил их друг с другом
При сравнении файлов dev1 и dev2 мы видим, что появилось новое устройство - ttyUSB0, при сравнении dev1 и dev3 видим уже 2 устройства - ttyUSB0 и ttyUSB1, а при сравнении dev2 и dev3 видим уже 1 устройство - ttyUSB1.
Так методом исключения можно понять что и какой порт воткнуто.
Далее, чтобы определить, где лежат сами USB устройства, найдём их в /sys по devnum (они меняются каждый раз, как они отключаются/подключаются заново)
Теперь отключим их
И подключим ещё раз в другой последовательности
Теперь вторая ардуинка под devnum 24, а первая стала под devnum 25.
Опять найдём их в /sys
Тут прям видно, что я поменял последовательность подключения устройств. То, что я подключал вторым, стало первым, а первой - вторым (2-1.1 стало из второго устройства под devnum 23 стало 24, значит было воткнуто первым, а то, что было под 22, стало 25).
И теперь проверим папку /dev
Точно такие же по названию устройства поменялись местами. Получилось ровно то, о чём я и говорил. Смена последовательности подключения меняет их номер местами. И, если бы у нас был скрипт, который должен считывать именно с первой ардуинки данные, начал бы их читать из второй.
Можно это сравнить с тем, как windows обрабатывает тоже самое.
Подключим 2 устройства и посмотрим в менеджере устройств на компорты
Воткнём эти же устройства, в эти же порты, но в другой последовательности
А ничего не поменялось. Вот о чём я и говорил. Форточке совершенно безразлично, в какой последовательности вы втыкаете устройства, она это отобразит как в первый раз. Поэтому тут конфузов с скриптом и чтением с порта не будет (только если вы порты не перепутаете).
Как работать с CD-дисками
Для того, чтобы понять, почему работа с дисками кардинально отличается, нужно понять то, как эти диски устроены.
Я могу выделить 2 типа диска (во всяком случае, у меня их есть только 2).
Первый - диск с медиа (музыка). У диска с музыкой нет файловой системы, есть только данные, записанные на секторах напрямую. Это так называемый формат wav без сжатия. Качество у такого близко к современному формату flac, с отличием в том, что flac это формат с сжатием, но без потерь.
Из GUI работать с такими дисками довольно просто. Просто вставьте диск, он сразу отображается в файловом менеджере, где вы можете включить любую композицию (по сути, играться будут просто данные с определённого сектора).
У меня есть пару диском в таком формате. Вставляю диск в дисковод и система сразу предлагает вариант что делать с этим диском
Он сразу появляется в ФМ, но с очень интересным адресом
Cdda - это не драйвер и не библиотека, это обращение к формату “compact disk digital audio” и в графике отображается как путь, хотя таковым не является.
В системе этот диск нигде не примонтирован, так как монтировать просто нечего. Монтировать можно только блочные устройства или файлы с разделами через loop-устройство. Диск же с музыкой не имеет файловой системы вообще, это просто сырой поток байт музыки.
После cdda идёт имя дисковода - sr0. Он есть в /dev
Но, как мы уже выяснили, в /dev лежат только интерфейсы, но не реальные устройства. Само устройство тоже хранится в /sys, но уже в другом месте. Для дисков этот путь /sys/class/block/sr0 (причём тут он будет лежать даже без самого диска в дисководе, так как тут лежат методы именно дисковода, что умеет делать с диском, а не самого диска/болванки)
Музыку с такого диска умеют проигрывать большинство плееров, один из Rytmicbox, который по дефолту установлен в mint.
Ну, а что делать, если нам нужно оттуда получить трек, и проиграть его независимо от диска? Из графики его можно просто скопировать, а вот с консоли начинаются проблемы - диска ведь нигде нет примонтированного. Напрямую обратиться к cdda как к пути тоже нельзя.
Нужно ставить дополнительную утилиту, которая “сдампит” определённые сектора и сделает их в виде файла с расширением wav. Одной из таких утилит - cdparanoia - я и буду пользоваться.
Установим её из пакетника
Работа с ней элементарная. Вводим просто название и номер трека, и он его дампит в папку, где мы сейчас находимся
Далее этот файл можно спокойно играть в любом плеере и без диска.
Можно получить информацию о диске с помощью утилитки udevadm
А вот дальше установим другой диск с музыкой, но уже с mp3 файлами на ней.
Тут мы видим реальный путь. А почему? Потому что у диска есть файловая система и это, по сути, блочное устройство.
Посмотрим как выглядит этот примонтированный раздел в системе
С таким диском можно работать точно также как и с флешкой. Никаких ограничений нет.
Можно ещё посмотреть объём этого диска (и доступный, если есть) через утилитку df с ключами Th (T - объём диска/раздела, h - в человекочитаемом формате (мегабайты, гигабайты))
Как видно, диск забит полностью (точнее, на нём закрыта возможность записывать в свободные сектора, если они есть).
Если нам нужен полный дамп диска, его можно получить через утилитку dd, где в качестве аргументов передаётся if- входной файл (интерфейс диска), of - выходной файл (куда писать данные с диска).
Такой ISO образ диска получается полный, не теряется ничего. Если нужно, его можно передать на другой ПК и спокойно его примонтировать (что в Windows, что в Linux).
Через утилиту fdisk можно посмотреть его (ISO) файловую систему, тут это iso9660
Давайте примонтируем этот файл в систему (это можно делать и без loop устройства, если не нужна возможность записи и работа с ним как с блочным устройством)
Но он всё равно монтируется через loop устройство, просто в автоматическом режиме
Работа с MTP устройствами
Последнее что я хотел бы затронуть в данной статье - это работа с MTP устройствами.
MTP или Media Transfer Protocol (протокол переноса/передачи медиа) используется большинством современных устройств для обмена информацией. Это и телефоны (по поводу яблочных огрызков не в курсе, но в режиме передачи фотографий может быть и MTP), и камеры, и другие внешние устройства.
Я буду показывать работу с MTP протоколом на двух устройствах - современном смартфоне Xiaomi 11 и старом телефоне Nokia E71. Они оба используют MTP для передачи файлов с ПК на устройство.
Вообще, если у кого-то были вопросы почему вообще такие устройства работают именно по MTP, а не просто как блочные устройства, то тут ответ довольно сложный. По сути, телефоны на андроиде вполне себе блочные устройства, но ради безопасности ему нельзя выдавать какие-то разделы на устройстве. Через MTP можно ограничиться определённым разделом и “вещать” только им.
Xiaomi 11
Вообще, я не думаю, что большинство читающих эту статью представляют, как внутри Android выглядят разделы. А там посмотреть есть на что.
Дам вам часть того, как это вообще всё внутри выглядит
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 ALIGN_TO_128K_1 -> /dev/block/sdd1
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 ALIGN_TO_128K_2 -> /dev/block/sdf1
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 abl_a -> /dev/block/sde8
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 abl_b -> /dev/block/sde32
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 aop_a -> /dev/block/sde1
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 aop_b -> /dev/block/sde25
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 apdp -> /dev/block/sde49
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 bk01 -> /dev/block/sda4
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 bk010 -> /dev/block/sda23
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 bk06 -> /dev/block/sda12
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 bluetooth_a -> /dev/block/sde5
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 bluetooth_b -> /dev/block/sde29
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 userdata -> /dev/block/sda33
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 boot_b -> /dev/block/sde35
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 catecontentfv -> /dev/block/sde61
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 catefv -> /dev/block/sde60
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 cdt -> /dev/block/sdd2
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 cpucp_a -> /dev/block/sde20
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 cpucp_b -> /dev/block/sde44
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 cust -> /dev/block/sda19
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 devcfg_a -> /dev/block/sde12
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 devcfg_b -> /dev/block/sde36
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 devinfo -> /dev/block/sda18
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 dip -> /dev/block/sde48
lrwxrwxrwx 1 root root 15 1973-12-08 22:46 dsp_a -> /dev/block/sde9
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 dsp_b -> /dev/block/sde33
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 dtbo_a -> /dev/block/sde15
lrwxrwxrwx 1 root root 16 1973-12-08 22:46 dtbo_b -> /dev/block/sde39
Внутренная память разбита на огромное кол-во разделов, каждый из, которых используется в разное время (я снимал эти разделы (их больше в разы чем тут) через кастомное рекавери для переноса в прошивку).
Если вы прошивали современные телефоны, то знаете, что допустим в dtbo лежат дрова (проприетарные блобы), а в boot лежит ядро с рекавери (раньше были отдельными разделами).
Вот в MTP вынесен только тот раздел, куда может писать пользователь (при форматировании даты до заводских именно он и форматируется, не трогая ничего остального). Вот у меня это sda33.
Это вообще никак не влияет на то, что и как мы будем делать дальше, просто дал как интересный факт.
Давайте подключим устройство и посмотрим на вывод dmesg
Дальше сделаем тоже самое что и раньше, найдём его в /sys
Собственно, он ничем и не отличается от прошлых примеров. Он выглядит ровно также.
Через GUI доступ к MTP можно получить сразу, но там опять будет ссылка в пути
Но GUI скучно, давайте залезем в терминал.
ADB способ
Для управления андроидом через терминал можно использовать adb. Сначала поставим его
Далее посмотрим что устройство подключено (нужно включить режим разработчика и там отладку по ADB)
Чтобы загрузить что-либо на устройство, нужно использовать метод push у adb и указать путь куда его положить (/sdcard и /storage/emulated/0/ одинаковые пути на большинстве устройств, тут “0” указывает на пользователя в системе. Если у вас на телефоне 2 пользователя, то там будет ещё /storage/emulated/1/ для второго пользователя, но куда именно будет указывать sdcard я не знаю (вроде от второго пользователя вообще нельзя использовать adb, так что только в 0 скорее всего, но сам не проверял))
Посмотрим из интерфейса, что файл передался на у-во
Чтобы файл “скачать” с у-ва, нужно использовать метод pull
Способ напрямую
Если вам не по душе adb и вы хотите работать с MTP как с обычным блочным устройством, то есть альтернативный способ.
На самом деле в системе есть место, куда “монтируется” MTP устройство и, где прямой интерфейс до внутренней (и внешней sdcard) памяти!
Причём обратите внимание на название папки с MTP у-ва. Это тот же путь, что можно было видеть в ссылке в GUI! (ну, почти. Тут :host добавился)
PS. Вот тут важно дополнить, что такой способ будет работать только тогда, когда установлены пакеты для MTP устройств. Если пакетов не стоит, то способ через ADB вам в помощь
Nokia e71
В отличии от андроида, у nokia не было единого инструмента типа adb (ну или был, но только для форточки), поэтому тут заработает только последний способ для доступа к памяти.
Но сначала, посмотрим на это через GUI
И сразу же как это выглядит в терминале
На симбах наружу тоже выводится только определённая папка (c:\data), а не весь корень
Ну и напоследок, что лежит в sys и вывод dmesg для нокии
Заключение
В данной статье я постарался осветить работу с большинством современных внешних устройств. Также разобрал то, как выглядят устройства на уровне системы, где они находятся и что из себя представляют.
Также затронул тему директории /dev, которая обычно вызывает огромное количество вопросов при более близком знакомстве (если вы любопытный, конечно).
Надеюсь эта статья была полезна и вы узнали что-то новое про Linux. Если у вас есть чем дополнить или поправить, то прошу в комментарии, буду рад услышать дополнения по теме.