× К оглавлению На главную Об авторе

   Дата и время публикации:

Проблемы и решение

1. Суть проблемы

Заключается в том, что нужно имитировать физические блочные устройства /dev/mmcblk*, которые показаны в дампе 1.1

Дамп 1.1

 root@home:~# lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
mmcblk0     179:0    0   7,5G  0 disk 
└─mmcblk0p1 179:1    0   7,5G  0 part /media/user/78CA-E57D

Из которого видно, что носитель с меткой 78CA-E57D имеет файлы блочных устройств /dev/mmcblk0 и /dev/mmcblk0p1

Файл /dev/mmcblk0p1 является специальным блочным файлом устройства, который указывает на одну единственную созданную партицию или логический диск, как показано в дампе 1.2. В тоже время, из которого видно, что файл /dev/mmcblk0 указывает на весь носитель информации карты памяти SD, который включает в себя 8192 блоков по 512 байт .

Дамп 1.2

$ sudo fdisk -l /dev/mmcblk0 
Disk /dev/mmcblk0: 7,5 GiB, 8053063680 bytes, 15728640 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device         Boot Start      End  Sectors  Size Id Type
/dev/mmcblk0p1       8192 15728639 15720448  7,5G  b W95 FAT32

Поэтому изначально проблема лежит в плоскости имитации структуры карты памяти SD, без которой образ не может быть востребован эмулятором Qemu.

Так же, далее по тексту,после решения проблем, связанных с имитацией структуры карты памяти SD, будет рассказываться как выполнять симуляцию устройства карты SD (команда в CLI -drive sd-card,drive=sd1 ...) и подключать дополнительным накопителем (команда в CLI -drive id=sd1,if=none,...) c помощью эмулятора Qemu на базе встроенного гипервизора KVM, встроенного в ядро Linux, которое, в свою очередь также надо настраивать для подключения им драйвера sdhci_pci при выполнении команды -device sdhci-pci . А также почему в данном примере три устройства MMC, а не одно.

2. Решение

2.1 Создание имитирующий струтуру файл образа c использованием карты памяти SD

Самым простым и востребованным способом является создание файла дубликата диска с использованием команды DD(1), которая создает файл образа "точь-в-точь" согласно реальной физической структуры носителя информации, как показано в дампе 2.1

Дамп 2.1

sudo dd if=/dev/mmcblk0 of=sdcard.img bs=512 count=15720449 status=progres

Указываем,

В результате будем иметь файл работоспособного образа sdcard.img, как показано в дампе 2.2

Дамп 2.2

$ sudo fdisk -l sdcard.img
Disk sdcard.img: 7,5 GiB, 8048869888 bytes, 15720449 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device      Boot Start      End  Sectors  Size Id Type
sdcard.img1       8192 15728639 15720448  7,5G  b W95 FAT32

Соответственно, как показано в дампе 2.2, файл образа соответствует ранее указанной структуре, где партиция sdcard.img байт в байт повторяет /dev/mmcblk0p1, данные по который приводятся в дампе 1.2

2.2 Создание файла образа карты памяти SD программными средствами

Создание файла образа карты памяти SD показано в дампе 2.3

Дамп 2.3

$ qemu-img create ~/qemu-sdcard.img 7.5G
Formatting '/home/user/qemu-sdcard.img', fmt=raw size=8053063680

Затем создаем сетевое блочное устройство. Процесс можно запустить в фоновом режиме и с ожиданием присоединения клиента nbd-client к qemu-nmbd путем добавления через проблем символа амперсанда (&), как показано 2.4

Дамп 2.4

$ qemu-nbd ~/qemu-sdcard.img &

Теперь нам необходим сам клиент nbd-client, который устанавливается в Debian, как показано в дампе 2.5

Дамп 2.5

$ sudo apt update && sudo apt install nbd-client

Подгружаем необходимый драйвер ядра, как показано в дампе 2.6

Дамп 2.6

$ sudo modprobe nbd

Цепляемся к диску, как показано в дампе 2.7

Дамп 2.7

$ sudo nbd-client localhost /dev/nbd0
Warning: the oldstyle protocol is no longer supported.
This method now uses the newstyle protocol with a default export
Negotiation: ..size = 7680MB
Connected /dev/nbd0

Размечаем nbd-диск с использованием fdisk, как показано в дампе 2.8

Дамп 2.8

$ sudo fdisk /dev/nbd0

При этом, как показано в дампе 2.9, должны получить результаты, такие же показанные ранее в дампе 2.2

Дамп 2.9

...
Command (m for help): p
Disk /dev/nbd0: 7,5 GiB, 8053063680 bytes, 15728640 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x6b766460

Device      Boot Start      End  Sectors  Size Id Type
/dev/nbd0p1       8192 15728639 15720448  7,5G  b W95 FAT32
...

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

Дамп 2.10

$ sudo mkfs.vfat /dev/nbd0p1
mkfs.fat 4.1 (2017-01-24)
$ sudo mount /dev/nbd0p1 /mnt
$ sudo umount /mnt

Отцепляем диск и освобождаем файл блочного устройства /dev/nbd0, как показано в дампе 2.11

Дамп 2.11

$ sudo nbd-client -d /deb/nbd0

Иначе, при последующем подключении диска клиент nbd-client может завершится с ошибкой, как показано в дампе 2.12

Дамп 2.12

...
Warning: the oldstyle protocol is no longer supported.
This method now uses the newstyle protocol with a default export
Negotiation: ..size = 7680MB
Error: Failed to setup device, check dmesg
Exiting.
...

А также в случае преждевременного закрытия qemu-nbd , как показано в дампе 2.13

Дамп 2.13

...
Warning: the oldstyle protocol is no longer supported.
This method now uses the newstyle protocol with a default export
Error: Socket failed: Connection refused
...

2.3 Подключение файла образа

Для добавления носителей информации, подобных карте памяти SD, производится по правилу, приведенному в дампе 2.14, с использованием команд, передаваемых в командной строке -drive и -device во время запуска эмулятору Qemu

Дамп 2.14

$ qemu-system-arm … -device sdhci-pci -device sd-card,drive=sd1 -drive id=sd1,if=none,format=raw,file=sdcard.img  ...

В котором показано, что команды -drive и -device связываются через опции drive= и id=, соответсвенно. Плюс некоторые интересные опции регулирующие тип устройства, источник нахождения файла образа симуляции карты памяти и т.д.

Опция file= указывает откуда на хозяйской машине эмулятор Qemu буедет брать файл образа sdcard.img, симулирующий структуру карты памяти SD.

Опция if= устанавливает тип интерфейса, используемого устройством при запуске эмулятор Qemu и выбором одного из значений ide, scsi, sd, mtd, floppy, pflash, virtio . В данном случае, опция if=none, потому что указано автоматически подключаемое устройство в виде карты памяти SD, которая требует игнорировать эту опцию. Иначе, можно получить ошибку и рекомендацию попробовать использовать if=none, как показано в дамп 2.15

Дамп 2.15

...
ERROR qemu-system-arm: -device sd-card,drive=sd0: Drive 'sd0' is already in use because it has been automatically connected to another device (did you need 'if=none' in the drive options?)
...

Опция format= устанавливает формат структуры диска. Так, в данном случае, нужно указывать format=raw во избежании неправильного определения структуры носителя информации.

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

В результате загрузки гостевой ОС в её журнале dmesg или systemd-journal должны быть зарегистрированны сообщения, подобно тем, что показаны в дампе 2.16

Дамп 2.16

...
[    6.414277] mmci-pl18x fpga:05: mmc0: PL181 manf 41 rev0 at 0x10005000 irq 59,60 (pio)
[    6.464211] mmci-pl18x fpga:0b: mmc1: PL181 manf 41 rev0 at 0x1000b000 irq 49,50 (pio)
...
[    6.420364] sdhci: Secure Digital Host Controller Interface driver
[    6.423949] sdhci: Copyright(c) Pierre Ossman
[    6.427320] sdhci-pci 0000:00:11.0: SDHCI controller found [1b36:0007] (rev 0)
[    6.438809] sdhci-pci 0000:00:11.0: enabling device (0100 -> 0102)
[    6.445422] mmc2: SDHCI controller on PCI [0000:00:11.0] using ADMA
...
[    6.813491] mmc2: Problem switching card into high-speed mode!
[    6.818252] mmc2: new SDHC card at address 4567
[    6.834510] mmcblk2: mmc2:4567 QEMU! 7.50 GiB 
[    6.855938]  mmcblk2: p1
[    6.858153] mmcblk2: p1 size 15720448 extends beyond EOD, truncated
...

При этом, были инициализированы два устройства mmc0 и mmc1, так как в выбранной симулируемой технической платформе versatile-pb уже имелось устройство карты памяти SD совместимое c ARM PrimeCell MMCI PL180/1 под управлением драйвера mmci-pl18x. Но, которые не удалось подключить в в используемом эмуляторе qemu-system-arm, потому что им поддерживается симуляция устройств карт памяти SD только "sd-card" и "sdhci-pci", которые оказалось работают в месте и одной связке, на что указывает инициализация третьего устройства mmc2, о подключении которого поговорим ниже.

2.4 Поддержка симмуляции контроллера SDHCI на PCI

Для этого необходимо, чтобы ядро linuх и эмулируемая техническая платформа на базе процессора ARM или RISC-V включали дрaйвер sdhci_pci и симмуляцию контроллера SDHCI на PCI, путем включения поддержки:

Настройка ядра для включения в него модуля производится с использованием сборочной машины yocto/poky, из под которой обычно запускаются встроенный в неё эмулятор qemu-system-arm или qemu-system-riscv. В виду возможности добавления в них некоторых функциональных возможностей на этапе сборки.

Для установки CONFIG_PCI=y в меню конфигурации ядра в разделе "Device Driver" должен быть выбран пункт "PCI support" и напротив него, в квадратных скобках, установлен символ звездочка (*), как показано на рисунке 2.17

Рисунок 2.17

Далее, возвращаемся в раздел "Device Driver" и выбираем "MMC/SD/SDIO card support" , как показано на рисунке 2.18

Рисунок 2.18

В нем включаем в ядро, используя символ звоздочка (*), последовательно "Secure Digital Host Controller Interface support" — CONFIG_MMC_SDHCI и "SDHCI support on PCI bus" — CONFIG_MMC_SDHCI_PCI, как показано рисунок 2.19

Рисунок 2.19

После чего, необходимо сохранить сделанные изменения и пересобрать ядро, выполняя действия необходимые по сборке ядра Linux для архитектуры ARM или RISC-V для сборочной машины Yocto/poky или согласно руководству для 5-й версии Debian

3. Библиография

3.1 Heiko's Blog. qemu-system-x86_64 -drive options

3.2 lists.nongnu.org. [Qemu-devel] sd: add SDHCI and eMMC support

3.3 lists.nongnu.org. [Qemu-devel]. [Qemu-devel] how to ues qemu -sd option?

3.4 www.raspberrypi.org. Generating an SD card image for QEMU emulation

3.5 Kele's Blog. Create SD Image for Xilinx Qemu

3.6 Kele's Blog. Create SD Image for Xilinx Qemu

3.7 Rasberry PI. How to make an image (.img) from what's on the SD card (but as compact as the original one)?

3.8 nixCraft. Linux dd Command Show Progress Copy Bar With Status

3.9 xboot-clone. How To Create SD Card Image For Qemu Emulator

3.10 HAIKU. [GSoC 2018: SDHCI MMC Driver]: Week #1 and #2

3.11 LKDDB:CONFIG_MMC_SDHCI_PCI: SDHCI support on PCI bus

3.12 Wiki.qemu.org. Documentation/Platforms/RISCV