LINUX.ORG.RU

Ответ на: комментарий от superuser

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

Если после незапакованного cpio идёт cpio.gz (как у меня на федоре), то однострочник для распаковки будет примерно таким:

(cpio -ivd && gunzip | cpio -ivd) <initrd.img-4.18.0-16-generic
Если у тебя что-то другое, то скрипт надо будет подправить.

mironov_ivan ★★★★★ ()
Последнее исправление: mironov_ivan (всего исправлений: 1)
Ответ на: комментарий от superuser

у меня немного по другому :)

~/pfg/test/kernell$ (cpio -ivd && cat >./second.img) < /boot/initrd.img-4.18.0-16-generic 
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/.enuineIntel.align.0123456789abc
kernel/x86/microcode/GenuineIntel.bin
32 блока

~/pfg/test/kernell$ file ./second.img 
./second.img: gzip compressed data, last modified: Fri Mar 22 23:37:12 2019, from Unix, original size 17290240

но тоже есть вопросы...

pfg ★★ ()
Ответ на: комментарий от mironov_ivan
file /tmp/third.img
/tmp/third.img: gzip compressed data, last modified: Thu Mar 21 21:17:46 2019, from Unix

Ура!

(cpio -ivd && cpio -ivd && gunzip | cpio -ivd) < initrd.img-4.18.0-16-generic

жжжжж!
а Универсального скрипта не бывает? и в Ubuntu там какой-то страшный скрипт распаковывает

superuser ★★ ()
Последнее исправление: superuser (всего исправлений: 1)
Ответ на: комментарий от superuser

груб его распаковывает в подмонтированную tmpfs

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

pfg ★★ ()
Последнее исправление: pfg (всего исправлений: 1)
Ответ на: комментарий от zvezdochiot

в начале инит нет заголовка gzip вот и не может распаковать

инитрам грузит груб и передает его ядру, как хз. тонкие материи едреной магии :)

pfg ★★ ()
Последнее исправление: pfg (всего исправлений: 1)
Ответ на: комментарий от superuser

а Универсального скрипта не бывает?

Как-то так:

#!/bin/sh

unpack()
{
	local comp_alg decomp_cmd

	comp_alg=$( file --brief --mime-type "${1}" )
	case "${comp_alg}" in
		"application/x-gzip")
			decomp_cmd="gunzip"
		;;

		"application/octet-stream")
			decomp_cmd=""
		;;

		*)
			echo "Unknown compression: ${comp_alg}" >&2
			exit 1
		;;
	esac

	(
		rm --force "${TMPNEXT}"
		set -xeu

		if [ -n "${decomp_cmd}" ]; then
			$decomp_cmd | cpio -ivd
		else
			cpio -ivd
		fi

		cat >"${TMPNEXT}"
	) <"${1}"
}

set -xeu

TMPDIR=""
trap '[ -n "${TMPDIR}" ] && rm --force --recursive "${TMPDIR}"' EXIT
TMPDIR=$( mktemp --directory --tmpdir="/tmp" --suffix=".unpackinitcpio" )
TMPNEXT="${TMPDIR}/next"

next="${1}"

while [ -s "${next}" ]; do
	unpack "${next}"
	next="${TMPNEXT}"
done
Запускать с одним аргументом: путём до файла.

mironov_ivan ★★★★★ ()
Ответ на: комментарий от mironov_ivan
$ ./_uinitrd initrd.img-5.0.2-pc
+ TMPDIR=
+ trap [ -n "${TMPDIR}" ] && rm --force --recursive "${TMPDIR}" EXIT
+ mktemp --directory --tmpdir=/tmp --suffix=.unpackinitcpio
+ TMPDIR=/tmp/tmp.UJKYFGUx5y.unpackinitcpio
+ TMPNEXT=/tmp/tmp.UJKYFGUx5y.unpackinitcpio/next
+ next=initrd.img-5.0.2-pc
+ [ -s initrd.img-5.0.2-pc ]
+ unpack initrd.img-5.0.2-pc
+ local comp_alg decomp_cmd
+ file --brief --mime-type initrd.img-5.0.2-pc
+ comp_alg=application/octet-stream
+ decomp_cmd=
+ rm --force /tmp/tmp.UJKYFGUx5y.unpackinitcpio/next
+ set -xeu
+ [ -n  ]
+ cpio -ivd
.
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/AuthenticAMD.bin
56 блоков
+ cat
+ next=/tmp/tmp.UJKYFGUx5y.unpackinitcpio/next
+ [ -s /tmp/tmp.UJKYFGUx5y.unpackinitcpio/next ]
+ unpack /tmp/tmp.UJKYFGUx5y.unpackinitcpio/next
+ local comp_alg decomp_cmd
+ file --brief --mime-type /tmp/tmp.UJKYFGUx5y.unpackinitcpio/next
+ comp_alg=application/octet-stream
+ decomp_cmd=
+ rm --force /tmp/tmp.UJKYFGUx5y.unpackinitcpio/next
+ set -xeu
+ [ -n  ]
+ cpio -ivd
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/.enuineIntel.align.0123456789abc
kernel/x86/microcode/GenuineIntel.bin
3080 блоков
+ cat
+ next=/tmp/tmp.UJKYFGUx5y.unpackinitcpio/next
+ [ -s /tmp/tmp.UJKYFGUx5y.unpackinitcpio/next ]
+ unpack /tmp/tmp.UJKYFGUx5y.unpackinitcpio/next
+ local comp_alg decomp_cmd
+ file --brief --mime-type /tmp/tmp.UJKYFGUx5y.unpackinitcpio/next
+ comp_alg=application/gzip
+ echo Unknown compression: application/gzip
Unknown compression: application/gzip
+ exit 1
+ [ -n /tmp/tmp.UJKYFGUx5y.unpackinitcpio ]
+ rm --force --recursive /tmp/tmp.UJKYFGUx5y.unpackinitcpio
$ 
superuser ★★ ()
Ответ на: комментарий от superuser

Очевидный фикс:

diff --git a/unpackinitcpio b/unpackinitcpio
index c575bff137e9..f0c1c3b8a051 100755
--- a/unpackinitcpio
+++ b/unpackinitcpio
@@ -6,7 +6,7 @@ unpack()
 
 	comp_alg=$( file --brief --mime-type "${1}" )
 	case "${comp_alg}" in
-		"application/x-gzip")
+		"application/x-gzip" | "application/gzip")
 			decomp_cmd="gunzip"
 		;;
 
mironov_ivan ★★★★★ ()
Последнее исправление: mironov_ivan (всего исправлений: 1)
Ответ на: Очевидный фикс: от mironov_ivan

А как думаеш, что в Убунтовском скрипте что-то ещё парсят?

$ cat `which unmkinitramfs`
#!/bin/sh

set -eu

usage()
{
	echo "Usage: $(basename "$0") [-v] <initramfs file> <directory>"
}

# Extract a compressed cpio archive
xcpio()
{
	archive="$1"
	dir="$2"
	shift 2

	if zcat -t "$archive" >/dev/null 2>&1 ; then
		zcat "$archive"
	elif xzcat -t "$archive" >/dev/null 2>&1 ; then
		xzcat "$archive"
	elif bzip2 -t "$archive" >/dev/null 2>&1 ; then
		bzip2 -c -d "$archive"
	elif lzop -t "$archive" >/dev/null 2>&1 ; then
		lzop -c -d "$archive"
	# Ignoring other data, which may be garbage at the end of the file
	fi | (
		if [ -n "$dir" ]; then
			mkdir -p -- "$dir"
			cd -- "$dir"
		fi
		cpio "$@"
	)
}

# Read bytes out of a file, checking that they are valid hex digits
readhex()
{
	dd < "$1" bs=1 skip="$2" count="$3" 2> /dev/null | \
		LANG=C grep -E "^[0-9A-Fa-f]{$3}\$"
}

# Check for a zero byte in a file
checkzero()
{
	dd < "$1" bs=1 skip="$2" count=1 2> /dev/null | \
		LANG=C grep -q -z '^$'
}

# Split an initramfs into archives and call xcpio on each
splitinitramfs()
{
	initramfs="$1"
	dir="$2"
	shift 2

	# There may be a prepended uncompressed archive.  cpio
	# won't tell us the true size of this so we have to
	# parse the headers and padding ourselves.  This is
	# very roughly based on linux/lib/earlycpio.c
	offset=0
	while true; do
		if checkzero "$initramfs" $offset; then
			offset=$((offset + 4))
			continue
		fi
		magic="$(readhex "$initramfs" $offset 6)" || break
		test $magic = 070701 || test $magic = 070702 || break
		namesize=0x$(readhex "$initramfs" $((offset + 94)) 8)
		filesize=0x$(readhex "$initramfs" $((offset + 54)) 8)
		offset=$(((offset + 110)))
		offset=$(((offset + $namesize + 3) & ~3))
		offset=$(((offset + $filesize + 3) & ~3))
	done

	if [ $offset -ne 0 ]; then
		# uncompressed archive
		(
			if [ -n "$dir" ]; then
				mkdir -p -- "$dir/early"
				cd -- "$dir/early"
			fi
			cpio -i "$@"
		) < "$initramfs"

		# main archive
		subarchive=$(mktemp ${TMPDIR:-/var/tmp}/unmkinitramfs_XXXXXX)
		trap "rm -f '$subarchive'" EXIT
		dd < "$initramfs" bs="$offset" skip=1 2> /dev/null \
			> $subarchive
		xcpio "$subarchive" "${dir:+$dir/main}" -i "$@"
	else
		xcpio "$initramfs" "$dir" -i "$@"
	fi
}

OPTIONS=`getopt -o hv --long help,list,verbose -n "$0" -- "$@"`
# Check for non-GNU getopt
if [ $? != 0 ] ; then echo "W: non-GNU getopt" >&2 ; exit 1 ; fi

cpio_opts="--preserve-modification-time --no-absolute-filenames --quiet"
expected_args=2
eval set -- "$OPTIONS"

while true; do
	case "$1" in
        -h|--help)
		usage
		exit 0
	;;
	--list)
		# For lsinitramfs
		cpio_opts="${cpio_opts:+${cpio_opts} --list}"
		expected_args=1
		shift
	;;
	-v|--verbose)
		cpio_opts="${cpio_opts:+${cpio_opts} --verbose}"
		shift
	;;
	--)
		shift
		break
	;;
	*)
		echo "Internal error!" >&2
		exit 1
	esac
done

if [ $# -ne $expected_args ]; then
	usage
	exit 2
fi

splitinitramfs "$1" "${2:-}" $cpio_opts
$

superuser ★★ ()
Последнее исправление: superuser (всего исправлений: 1)
Ответ на: комментарий от superuser

Это хорошо. Но я не гарантирую, что он работает правильно во всех возможных случаях =).

upd. Возможно мой работает быстрее потому что использует /tmp (обычно tmpfs) вместо /var/tmp (обычно на диске).

mironov_ivan ★★★★★ ()
Последнее исправление: mironov_ivan (всего исправлений: 1)
Ответ на: комментарий от mironov_ivan

Возможно мой работает быстрее потому что использует /tmp

Ну очевидно же, что вы юзаете file, а убунтовский — урезанную для только нескольких типов заголовка реализацию «file» на bash.

vodz ★★★★ ()
Ответ на: комментарий от pfg

pfg

груб его распаковывает в подмонтированную tmpfs в момент запуска ядра в нем нет ни одного подмонтированного раздела. так что монтировать не из чего...

AS

Потому, что это уже не очень обычный initrd, а новомодний, из двух cpio, в первом из которых микрокод, который грузится напрямую самим ядром. Параметр ядра «recovery» (комментарий)

что-то не сходитса!
Мужики, следующие поколения нуждаются в ваших знаниях!

superuser ★★ ()
Последнее исправление: superuser (всего исправлений: 2)

Как монтировать initrd.img ?.

Ни как.
Из них специально что-то удаляют чтобы какер их не смонтировал и не загрузил шпионский модуль.

Получить доступ к содержимому initrd можно так.

1. открываешь initrd в hex редакторе и находишь инициализационный скрипт.
2. Находишь начало строки и перебиваешь на /bin/bash или что подобное, оставшуюся часть строки удаляешь.

Грузишся с этим изменённым initrd и получаешь к нему доступ через оболочку.
Можно подмонтировать флешку и рекурсивно на неё содержимое эхтого initrd скопировать.

ИМХО ценность в этом initrd имеет только сам иницилизационный скрипт и несколько бинарников ищущих и монтирующих корневую систему по её UUID и метке.

torvn77 ★★★★ ()
Последнее исправление: torvn77 (всего исправлений: 1)
Ответ на: комментарий от superuser

груб его распаковывает в подмонтированную tmpfs в момент запуска ядра в нем нет ни одного подмонтированного раздела. так что монтировать не из чего...

Это работает не совсем так. Загрузчик (grub, например) просто загружает файл в память по какому-то адресу, а затем передаёт ядру этот адрес и размер файла. Распаковкой в tmpfs занимается уже само ядро.

Потому, что это уже не очень обычный initrd, а новомодний, из двух cpio, в первом из которых микрокод, который грузится напрямую самим ядром.

«Склеенных» cpio-архивов может быть хоть сколько. Файлы с микрокодом процессора в первом несжатом cpio-архиве - это специальный случай, реализованный видимо только для x86.

Эта информация размазана по документации к ядру:

mironov_ivan ★★★★★ ()
Последнее исправление: mironov_ivan (всего исправлений: 1)
Ответ на: комментарий от superuser

Это был мой сосед эмбендщик, ну или ЛОР, точно не помню.

А вообще, зачем исскусственно делать initrd не монтируемым, если вот как я вижу даже скрипты для распаковки initrd есть?
Единственного профитаот этой порчи по факту нет.

torvn77 ★★★★ ()
Последнее исправление: torvn77 (всего исправлений: 3)
Ответ на: комментарий от torvn77

Ну мне в своё время так объяснили.
А так если делаешь initrd сам то всё монтируется нормально.

Тебе видимо что-то объясняли именно про старый initrd. У автора это темы используется initramfs, хотя файл и называется «initrd» (видимо по историческим причинам).

Различие как раз в том, что в случае initrd в файле лежит образ ФС, который можно примонтировать, а в случае initramfs - архивы, которые ядро распаковывает в tmpfs.

Хотя специальное удаление чего-то из initrd против шпионских модулей - всё ещё бредово звучит.

mironov_ivan ★★★★★ ()
Ответ на: комментарий от torvn77

А вообще, зачем исскусственно делать initrd не монтируемым, если вот как я вижу даже скрипты для распаковки initrd есть?
Единственного профитаот этой порчи по факту нет.

Потому что так решили SJW-жидорептилоиды из RedHat^W^W^W^W^W^W^WТут описано: https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt. Смотри секцию «ramfs and ramdisk». Кратко: для повышения производительности и экономии памяти.

mironov_ivan ★★★★★ ()