Здравствуй дорогой читатель данного руководства. Меня зовут Андрей, и нет, я не алкоголик, а разработчик встраиваемых систем на базе Linux.

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

Для чего это нужно? Все процессорные платы, разрабатываемые нашим предприятием, обладают слотом для sdcard и установленной на плате mmc. Загрузка системы производится либо с sd, либо c mmc. sd-карта является, как правило, временным решением, подкупает простотой установки. А mmc является постоянным решением, куда устанавливается уже финальное программное обеспечение. Переключение между способами загрузки осуществляется перемычками (джамперами на плате).

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

В случае, когда мы говорим о производстве, и выпуске устройства, то мы знаем, что люди которые будут устанавливать на mmc конечный продукт, как правило, не умеют подключаться через терминал и работать с командной строкой u-boot или Linux, да и просто может не быть на это времени. В их задачи должны входить осуществление простого производственного цикла, например:

  1. получить устройство;

  2. подключить к стенду;

  3. установить джамперы и sd-карту;

  4. подать питание;

  5. дождаться сообщений об окончании установки ПО;

  6. выключить устройство;

  7. снять джамперы и извлечь sd-карту;

  8. подать питание;

  9. дождаться диагностических сообщений;

  10. выключить устройство и передать дальше...

Конечно, образ можно разместить, например на сервере, и накатывать через сеть, но такой вариант, все равно, требует, как минимум, наличие загрузчика на mmc.

Для того, чтобы не мучаться с каждой sd-картой для каждого варианта, можно заранее подготовить несколько образов. И тут возникает вопрос - каким образом? Подготовку можно даже автоматизировать, но это совсем другая история.

Что потребуется для понимания и осуществления происходящего:

  • ОС GNU/Linux Debian;

  • умение пользоваться командной строкой на уровне ввода команд;

  • понимать что такое переменная окружения и как ее значение использовать в командной строке.

Создаем образ:

  1. Создаём файл образа диска заданного размера:

    dd if=/dev/zero of=${FILENAME} bs=${BYTES} count=${NUMBER_OF_BYTES}
    # или
    truncate -s ${SIZE} ${FILENAME}
  2. Подключаем диск к системе, разбиваем и форматируем:

    fdisk ${FILENAME} # как делить диск и на какое количество разделов, личное дело каждого
    DEVLOOP=$(sudo losetup --show -fP ${FILENAME})
    # форматируем разделы, если образ диска включает два раздела, то:
    sudo mkfs.${FSTYPE} ${DEVLOOP}p1
    sudo mkfs.${FSTYPE} ${DEVLOOP}p2
  3. Монтируем разделы и записываем информацию:

    sudo mount ${DEVLOOP}p${N} ${MOUNTPOINT}${N}
    sudo cp -aR /rootfs/* ${MOUNTPOINT}${N}/ # что записываем и куда, каждый решает сам
    # если вам также как и мне требуется на диске u-boot, то не забываем установить:
    sudo dd if=u-boot.img of=${DEVLOOP} bs=1k seek=1
  4. Отключаем диски в обратном порядке:

    sudo umount ${MOUNTPOINT}${N}
    sudo losetup -d ${DEVLOOP}
  5. Записываем полученный образ на соотвествующее устройство, если есть необходимость, например, для проверки и тестирования:

    sudo dd if=${FILENAME} of=${BLKDEV} conv=fsync

    Передаём полученный ${FILENAME} заказчику или производству, с инструкцией, как пользоваться.

Заключение

Подготовить образ диска можно двумя способами:

  • сделав образ с реального физического носителя при помощи программы dd;

  • создав изначально целиком виртуальный образ, который может быть установлен на любой внешний носитель при помощи той же dd.

Почему первый способ не всегда подходит? Если вы разрабатываете одну систему, пользуетесь одной sd-картой, то этот способ кажется вполне приемлемым. Но, как только, вы попробуете установить образ с этой единственной sd-карты на другую, похожую, например другого размера, вас ждет разочарование в таком подходе. У меня в работе, как правило несколько встраиваемых систем, и держать по несколько разных sd-карт для каждой - просто незволительная роскошь. Виртуальный же образ всегда легко модифицируем и распространяем. Но есть недостаток - это его фиксированный размер, он в таком же виде попадет на sd-карту, ограничив размер используемого места, но для случая когда это необходимо для разворачивания системы это не имеет значения.

UPD: Руководство исправлено в соответствии с замечаниями комментаторов. Спасибо.

Комментарии (22)


  1. Gumrak
    23.02.2022 18:23
    +1

    Но, как только, вы попробуете установить образ с этой единственной sd-карты на другую, похожую, например другого размера, вас ждет разочарование в таком подходе. 

    Не совсем понятно в чем разочарование. Было у меня две флешки : одна 8 Гб с рабочей системой, другая чуть меньше оказалась и решил задействовать её для экспериментов над системой.. Ну как бы урезал раздел за счёт незанятого пространства и, с помощью dd , скопировал с большей на меньшую. Я в этом слабо разбираюсь, может и есть какая-то фатальная кривость в том , что я сделал. Но малина работает 24/7 уже дней 10.


    1. somebyte Автор
      23.02.2022 18:35

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


      1. Gumrak
        23.02.2022 18:53

        Ясно. Спасибо.


  1. unsignedchar
    23.02.2022 20:49
    +1

    sudo лишнее. Готовить образ можно и с правами обычного пользователя (dd, sfdisk, genext2fs/debugfs, для fat32/cramfs/squashfs тоже есть утилиты не требующие root). Зачем? Ну например если захочется завернуть это всё в CI/CD.

    root/sudo необходимо только при записи образа на карту.


    1. somebyte Автор
      23.02.2022 21:36

      Возможно. Тут я ориентировался на свою систему. То есть у меня в Debian, например, dmesg без sudo не работает. А в Ubuntu, dmesg работает прекрасно для обычного пользователя. Тут уж все индивидуально.) Хотя, конечно, мне нравится идея, чтобы это мог делать обычный пользователь, и возможность завернуть в CI/CD, хотя в этом я пока профан. :-) Не все устройства и не всегда добираются до конвеера, не говоря уже про крупную серию, где это, думаю, это было бы оправдано.


      1. edo1h
        23.02.2022 23:09
        +2

        Тут я ориентировался на свою систему. То есть у меня в Debian, например, dmesg без sudo не работает. А в Ubuntu, dmesg работает прекрасно для обычного пользователя

        честно говоря, похоже, вы просто не понимаете что делаете.
        dmesg требует sudo потому что читает данные из буфера ядра, и по умолчанию ядро не отдаёт непривилегированным приложениям содержимое этого буфера.


        если разработчики дистрибутива считают, что непривилегированным пользователям нужен доступ в dmesg, то, как вы уже знаете, это реально.
        можно сменить настройки ядра:
        https://unix.stackexchange.com/questions/401623/dmesg-with-without-sudo-on-debian-mint
        или можно навесить на бинарник dmesg suid.


        только какое это всё имеет отношение к созданию файла для образа? создавать файл может обычный пользователь.


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


        1. somebyte Автор
          24.02.2022 00:37

          Я прекрасно понимаю, что все зависит от настроек системы, просто не стал вдаваться в детали, каких и для чего. Зачем?

          Я как администратор своей системы волен ограничить использование чего угодно в ней, как и доступ к чему угодно, ради безопастности. Так или нет?

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

          Согласен, что чтобы создать сам файл права рута не нужны. Тут исправлюсь при первой возможности.


          1. edo1h
            24.02.2022 00:50

            лучше пусть люди набирают sudo, чем будут сидеть под рутом

            почему?


            1. somebyte Автор
              24.02.2022 01:03

              Как почему, неопотный пользователь просто опасен под рутом, всегда что-то идет не так) А опытный, он итак разберется, как ему поступить.


              1. edo1h
                24.02.2022 01:11

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


                1. somebyte Автор
                  24.02.2022 01:23
                  +1

                  Это зависит от настроек sudo. В общедоступной системе, то есть не специализированной, думаю да, так и есть, опасность не снижается.


  1. osipov_dv
    23.02.2022 20:51

    А можете пояснить, зачем создавали loop device через losetup? Оно вроде работает и так, я так понимаю что есть нюансы, но не понимаю в чем. Гугл не помог.


    1. somebyte Автор
      23.02.2022 21:21
      +1

      Если имеется в виду способ через "mount -o loop ...", то да работает, но для случая когда уже есть образ с файловой системой и одним форматированным разделом. Даже если есть несколько, то монтируется всегда первый. А если нужно создать несколько разделов, а тем более если нужно отформатировать только некоторые из них, да еще и когда, например, первый монтировать совсем не нужно, то уже не очень работает. Хотя я вполне могу чего-то не знать.


  1. edo1h
    23.02.2022 22:47

    как-то вы сложно начинаете )


    1. файл проще создать так:


      edo@edo-home:~$ truncate -s 1G testfile 

      это будет sparse файл, он создастся почти моментально и не будет занимать место на диске.


    2. fdisk отлично работает с обычными файлами от не-суперпользователя, так что не нужны ни losetup, ни sudo.
      но он лежит в /sbin, который не входит в PATH обычного пользователя, так что надо явно указывать путь:


      edo@edo-home:~$ fdisk testfile
      bash: fdisk: команда не найдена
      edo@edo-home:~$ /sbin/fdisk testfile


    # если вам также как и мне требуется на диске u-boot, то не забываем установить:
    sudo dd if=u-boot.img of=/dev/loop0 bs=1k seek=1 conv=fsync

    способ установки бутлоадера сильно зависит от вашего оборудования, где оно ожидает этот самый бутлоадер увидеть.
    и да, conv=fsync тут бесполезен.


    1. somebyte Автор
      24.02.2022 00:04

      Такой вопрос, conv=fsync бесполезен, если я перед этим выполнял буферезированные чтение/запись на диск? То есть синхронизация будет или нет?


      1. edo1h
        24.02.2022 00:54

        честно скажу, не понял ваш вопрос.
        при записи на флешку conv=fsync используют для того, чтобы сразу произошла запись на физический носитель и можно было вынуть флешку с записанными данными.
        зачем вам нужен fsync при записи в файл?


        1. somebyte Автор
          24.02.2022 01:01

          Перед тем, как я использовал dd, я выполнял операции копирования (cp) на смонтированный диск с файловой системой. Операции копирования, как правило, буферезируются или кэшируются. conv=fsync нужен чтобы буферезированные изменения записались на диск, правильно? То есть conv=fsync будет верен и работать в отношении предыдущей операции cp?


          1. edo1h
            24.02.2022 01:32
            +2

            давайте всё с самого начала.


            есть отложенная запись (writeback). операционная система принимает команды записи и сразу отмечает их выполненными; но на самом деле сохраняет изменённые данные в буфере и потом в фоновом режиме сбрасывает их на накопитель.
            в некоторых сценариях это очень сильно повышает производительность, например, если программа по кругу переписывает данные в одном и том же месте, или пишет очень маленькими блоками.
            пример: вы копируете кучу мелких файлов, на каждый файл нужно обновить (притом в нескольких местах) метаинформацию. если писать синхронно (без кэширования), то в случае с hdd, например, это приводит к постоянному перемещению головок, которое занимает относительно много времени, условно говоря, запись идёт в сектора: 11, 21, 1001, 11, 22, 1002, 11, 23, 1003. при использовании отложенной записи операционная система может упорядочить и объединить эти записи, получается 11, 21-22-23, 1001-1002-1003.


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


            для борьбы с такими ситуациями и придумали принудительный сброс кэшей (fsync и т. п.).


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


    1. saboteur_kiev
      24.02.2022 01:51

      Еще лучше для создания файла использовать fallocate


    1. somebyte Автор
      25.02.2022 11:38
      +1

      Поправил в соответствии с вашими замечаниями и комментатора чуть ниже. Спасибо.)


  1. kvazimoda24
    24.02.2022 09:28

    Вместо kpartx можно обойтись одним losetup:

    losetup --show -fP /наш/файл.образа


    1. somebyte Автор
      24.02.2022 10:48

      Спасибо, не знал.) Бывает всегда что-то упускаешь из виду.