1 (03.11.2012 22:50:29 отредактировано evilslon)

Всем приятного времени суток! Не так давно я решил заняться интересным для меня (а, еще, возможно, и полезным для кого-то) делом: перевести интерфейс ip-камеры D-Link DCS-930 (не L) на русский язык, для чего я взял отсюда скрипт и успешно распаковал файловую систему из прошивки камеры. Как видно из текста скрипта, ФС запакована в формат CPIO (file ../filename сообщает ASCII cpio archive (SVR4 with no CRC)). Перевод завершён, вычитан и протестирован, и теперь хочется собрать прошивку, однако изначально ФС упакована в cpio-архив с абсолютными путями. Мой вопрос: как мне упаковать эту ФС, распакованную в папку, с сохранением всех путей и прав (т.е. фактически перепаковать архив)? Как я понимаю, мне нужно сделать что-то вроде chroot в эту папку, но разве возможно сделать chroot в систему, скомпилированную для другой архитектуры? Подскажите, пожалуйста, в какую сторону мне копать?
В мире Linux я больше всё-таки пользователь, чем программист или админ, поэтому мне не остаётся ничего иного, кроме как просить помощи сообщества.

2

Начать стоило с прочтения man cpio, тем более, что его язык вам не совсем незнаком.
Затем применить прочитанное на практике, что-то вроде

cd /path/to/root/of/work
find . | cpio --create --format='newc' > /tmp/new_image

При необходимости пожать поддерживаемым компрессором.

3 (03.11.2012 23:46:54 отредактировано evilslon)

Большое спасибо Вам за ответ! Да, это почти то, что надо, но не совсем то, как я понимаю. Всё дело в том, что при этом способе упаковки создаётся не абсолютный путь к файлам, а относительный (т.е. например var/tmp, а надо /var/tmp). Или может я что-то путаю? Вот, нагуглил, здесь человек задаёт аналогичный вопрос, но у него дистрибутив для x86, а у меня ФС от системы на основе mips-процессора.

4 (03.11.2012 23:54:40 отредактировано yars)

evilslon пишет:

Или может я что-то путаю?

Путаете. По команде выше заархивируется текущий каталог, а перед этим текущим станет /path/to/root/of/work. Распаковываете свой архив куда-нибудь в /tmp/cpiotree, вносите изменения, выполняете

cd /tmp/cpiotree
find . | cpio --create --format='newc' > /tmp/new_image.cpio

Получаете свеженький "блинчик" в /tmp/new_image.cpio. Дальше уже сами разберетесь.

Истинный hotplug - это обычная электрическая розетка: воткнул - работает, и никаких драйверов.
Arch Linux/Xfce/Xiaomi Mi Notebook Pro 15.6 | Slackware64-current/Xfce/Lenovo G580

5 (04.11.2012 00:40:18 отредактировано evilslon)

Оххх, только сильно не ругайтесь...
Вот смотрите, если я распакую архив new_image.cpio, полученный мной в ходе работы команды find . | cpio --create --format='newc' > /tmp/new_image.cpio находясь в этот момент в, скажем, каталоге /tmp , то содержимое архива ведь распакуется в каталог /tmp , а не в корень файловой системы? Всё дело в том, что исходный архив упакован именно так, если при его распаковке не указать cpio ключ --no-absolute-filenames , то архив распакуется в корень ФС, а не в текущую папку, вот и мне хотелось бы сделать также. Т.е. мне нужно сделать что-то вроде chroot, как я понимаю, но как? Может это, конечно, и не важно и зря я сам забиваю себе мозг глупостями...

6

Готовите структуру, подлежащую упаковке, допустим в /newroot.
Дополнительно туда укладываете список подлежащих упаковке файлов, как он будет виден из /newroot, с указанием лидирующего /.
Создаёте в /newroot каталог, не подлежащий упаковке в архив, например, /newroot/toolchain, куда складываете бинарник cpio и всё, что ему нужно для исполнения (если собран статически, вам крупно повезло).
Выполняете
# chroot /newroot
# export PATH=/toolcahin
# cat /filelist | cpio --create --format='newc' > /image.cpio
# exit
Забираете пирожок: /newroot/image.cpio.

7

Поскольку тема в разделе "Программирование", возможен и иной путь (возможно, даже менее трудоёмкий).
Берёте исходники cpio, добавляете в них опцию, например, --assume-root, добавляете код, принудительно дописывающий перед каждым именем файла в архиве "/" и убирающий стартовую "." (или не убирающий, что даст свободу анализа, например, оставлять для "./нечто" относительный путь, а из "нечто" принудительно делать "/нечто"), собираете и используете безо всякой возни с chroot.

8

bormant пишет:

Готовите структуру, подлежащую упаковке, допустим в /newroot.
Дополнительно туда укладываете список подлежащих упаковке файлов, как он будет виден из /newroot, с указанием лидирующего /.
Создаёте в /newroot каталог, не подлежащий упаковке в архив, например, /newroot/toolchain, куда складываете бинарник cpio и всё, что ему нужно для исполнения (если собран статически, вам крупно повезло).
Выполняете
# chroot /newroot
# export PATH=/toolcahin
# cat /filelist | cpio --create --format='newc' > /image.cpio
# exit
Забираете пирожок: /newroot/image.cpio.

Спасибо, вот что-то вроде этого мне и нужно! Как я понимаю, кроме cpio мне туда ещё нужно добавить и bash? Вечером попробую, отпишу сюда ab

9

Не могу понять, как мне сделать chroot в директорию с этими файлами:

root@Sergey-PC:/camfs/fs# chroot /camfs/fs /toolchain/bash
chroot: failed to run command `/toolchain/bash': No such file or directory
root@Sergey-PC:/camfs/fs# ls /camfs/fs/toolchain/
bash  cpio
root@Sergey-PC:/camfs/fs# 

Поскольку bash в этом устройстве отсутствует, я попробовал скопировать файл bash из моей системы в папку /bin этой файловой системы, и всё равно при попытке chroot выдается

chroot: failed to run command `/bin/bash': No such file or directory

Подскажите, пожалуйста, где я делаю ошибку или что я делаю не так?

10 (04.11.2012 17:48:40 отредактировано yars)

evilslon пишет:

Подскажите, пожалуйста, где я делаю ошибку или что я делаю не так?

Во-первых, кроме самого Bash'a, нужны еще и его зависимости:

# ldd $(which bash)
    linux-gate.so.1 (0xffffe000)
    libtermcap.so.2 => /lib/libtermcap.so.2 (0xb7713000)
    libdl.so.2 => /lib/libdl.so.2 (0xb770e000)
    libc.so.6 => /lib/libc.so.6 (0xb7589000)
    /lib/ld-linux.so.2 (0xb7734000)

Во-вторых, после

cp /bin/bash /camfs/fs/bin/bash

нужно сделать

chmod +x /camfs/fs/bin/bash
croot /camfs/fs /bin/bash

Как-то так...

Истинный hotplug - это обычная электрическая розетка: воткнул - работает, и никаких драйверов.
Arch Linux/Xfce/Xiaomi Mi Notebook Pro 15.6 | Slackware64-current/Xfce/Lenovo G580

11

yars, bormant: ребят, спасибо вам большое, всё получилось! Посыпаю свою голову пеплом, но я забыл про зависимости! Не закрывайте пока тему пожалуйста, чуть позже я опишу всё, что делал, может кому пригодится.  ab

12

да, для этих целей есть статически собранный busybox, обычно распологается в /bin/bb, это относительно полноценный шелл с полным набором утилит в одном бинарнике...

95% процентов проблем находятся между клавиатурой и стулом.

13 (04.11.2012 23:33:56 отредактировано evilslon)

Итак, как и обещал, для истории и Гугла опишу всё, что сделал, надеюсь, что это кому-то окажется полезным. Всё описанное производится в ОС Ubuntu 12.10 x64.
Допустим, у нас имеется файловая система Linux, скомпилированная для не-x86 устройства и распакованная в каталог /camfs/fs, в которую необходимо внести изменения и заархивировать обратно в архив cpio. Чтобы сохранить сжатие "от корня", я сделал следующее:

  • прежде всего, я получил список файлов, которые необходимо будет добавить в cpio, и сохранил его в текстовый файл: find . > filelist, затем вручную убрал в полученном текстовом списке у имён всех файлов ведущую точку, так, чтобы список файлов выглядел как будто сделан "от корня" этой файловой системы;

  • в каталог /camfs/fs/bin я скопировал файл bash из моей системы, создал каталог /camfs/fs/toolchain и скопировал туда файлы cpio (сам архиватор), cat (нужен для  работы cpio) и ls (для своего  удобства);

  • затем (это тот момент, который я упустил из виду) я узнал, от каких библиотек зависят скопированные мной компоненты: ldd /bin/bash и ldd /bin/cpio. На моё счастье все они находились в /lib/x86_64-linux-gnu и в /lib64/ и вместо того, чтобы отыскивать и копировать их поштучно, я скопировал эти директории в собираемую мной файловую систему полностью;

  • теперь убеждаемся в наличии у скопированных bash и cpio прав на запуск, при необходимости даём его им: chmod +x /camfs/fs/bin/bash, chmod +x /camfs/fs/toolchain/cpio, chmod +x /camfs/fs/toolchain/cat;

  • всё готово к запуску chroot, для этого выполняем chroot /camfs/fs /bin/bash (разумеется с правами root), появляется новая командная строка;

  • теперь надо указать полученной системе, где искать архиватор (и, возможно, другие компоненты, если с ФС нужно будет сделать что-то еще): export PATH=/toolchain. Теперь убедиться в том, что корень изменился, можно командой ls;

  • и, наконец, выполняем cat /filelist | cpio --create --format='newc' > /image.cpio и получаем заветный файлик image.cpio, содержащий перепакованную ФС для нашего устройства. Выйти из консоли chroot можно командой exit.

Большое спасибо всем, кто помог мне разобраться с chroot и cpio. Еще раз я убеждаюсь, что сила Open Source - в сообществе.