LinuxForum.Fans
Тема

Перепаковать "initrd"

Автор: Ciber_SLasH 2 сообщений 2285 просмотров
29.02.2024 16:58 #439251

Приветствую!
Хотел переупаковать "initrd" (нужна была правка скрипта "init") в Mods 455, но в итоге, при загрузке получаю: Failed to execute /init (error -2).
Распаковывал "/tiny/initrd" так (перед этим скопировав его в /tmp/initrdnew/initrd.xz):

text

[root /tmp/initrdnew]# xz -d ./initrd.xz && cat ./initrd | cpio -i -d -H newc
[root /tmp/initrdnew]# rm ./initrd.xz

Дальше заменил "init" в этой папке на такой же, но в котором вставлены 2 строки после 64 строки файла (после done):


echo "SQUASHFS_BIN_1: ${SQUASHFS_BIN}"
echo "SQUASHFS_BIN_2: ${SQUASHFS_BIN:1:$}"

И переупаковал:

text

find . -print | cpio -H newc -o | xz -z -F xz -C crc32 –x86 –lzma2=dict=8MiB > ../initrd.cpio.xz
cp -f ../initrd.cpio.xz /mnt/d/tiny/initrd

Но после подмены родного "initrd" на новый - получаем незагрузку.
Удаление "/tmp/initrdnew/bin/busybox" из распакованного "initrd" не помогает. При загрузке всё равно ошибка:


Failed to execute /init (error -2)
Kernel panic - not syncing: No working init found.
init
text
#!/bin/sh

# Copyright (c) 2009-2020, NVIDIA CORPORATION. All rights reserved. # See /etc/LICENSE file for details.

VERSION="20.10" CONSOLE="/dev/console" ROOTFS="/mnt/root" MNT_TIMEOUT="10" MNTNV="mnt/nv" MNTSQUASH="mnt/squash" MNTETC="mnt/etc" SQUASHFS_BIN="tiny/squash.bin" NFSSHARE="" NET="eth0" OVRCFG="1" COLDPLUG="1"

# Clear input and output exec >${CONSOLE} <${CONSOLE} 2>&1

# Display startup info echo -e "\033[1mBooting TinyLinux $VERSION\033[0m"

# Mount basic filesystems mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t devtmpfs devtmpfs /dev

# Install busybox symbolic links /bin/busybox --install -s

# Save kernel boot time for later KERNEL_BOOT_TIME=$(awk '{print $1*1000}' /proc/uptime)

# Prevent kernel logs from being sent to the console dmesg -n 1

# Setup hotplug # Use modprobe from busybox to avoid genkernel's modprobe sript # which does not process module aliases. echo '#!/bin/sh

[ "$ACTION" = "add" ] && busybox modprobe "$MODALIAS"' > /tmp/hotplug chmod 755 /tmp/hotplug echo /tmp/hotplug > /proc/sys/kernel/hotplug

# Allow overriding squash.bin location on the kernel command line parse_opt() { echo "$1" | cut -f 2- -d '=' } for ARG in `cat /proc/cmdline`; do case "$ARG" in squash\=*) SQUASHFS_BIN=`parse_opt "$ARG"` ;; partno\=*) PARTNUMBER=`parse_opt "$ARG"` ;; nfsshare\=*) NFSSHARE=`parse_opt "$ARG"` ;; net\=*) NET=`parse_opt "$ARG"` ;; ovrcfg\=*) OVRCFG=`parse_opt "$ARG"` ;; mount_timeout\=*) MNT_TIMEOUT=`parse_opt "$ARG"` ;; nocoldplug) COLDPLUG="" ;; esac done

echo "SQUASHFS_BIN_1: ${SQUASHFS_BIN}" echo "SQUASHFS_BIN_2: ${SQUASHFS_BIN:1:$}"

# Create root filesystem mkdir -p "${ROOTFS}" mount -t tmpfs tmpfs "${ROOTFS}"

# Coldplug if [ "$COLDPLUG" = "1" ]; then ls /sys/bus/pci/devices/*/uevent /sys/bus/usb/devices/*/uevent /sys/block/*/uevent /sys/block/*/*/uevent | while read UEVENT; do echo "add" > "$UEVENT" done fi

# Mounts squashed root filesystem and checks TinyLinux version mount_squash() { if ! mount -t squashfs -o loop,ro "${ROOTFS}/${MNTNV}/${SQUASHFS_BIN}" "${ROOTFS}/${MNTSQUASH}"; then echo "Error: Failed to mount ${1}/${SQUASHFS_BIN}" return 1 fi

# Check TinyLinux version in the squashed root filesystem SQUASHFS_VERSION=$(head -n 1 "${ROOTFS}/${MNTSQUASH}/etc/release" | sed "s/.*version //") if [ "$VERSION" != "$SQUASHFS_VERSION" ]; then echo "Error: initrd version $VERSION does not match TinyLinux version $SQUASHFS_VERSION" echo " found in ${1}/${SQUASHFS_BIN}" umount "${ROOTFS}/${MNTSQUASH}" return 1 fi }

# Mount non-volatile volume or NFS share mkdir -p "${ROOTFS}/${MNTNV}" "${ROOTFS}/${MNTSQUASH}" RETRYCOUNT=0 TRIEDDEVS="" FOUNDDEV="" while true; do if [ "$NFSSHARE" ]; then if [ -e "/sys/class/net/$NET" ]; then echo "Obtaining DHCP lease for $NET..." FOUNDDEV="$NET" ifconfig "$NET" up || exec /bin/sh udhcpc -n -T 1 -t 60 -q -i "$NET" || exec /bin/sh mount -t nfs -o nolock "$NFSSHARE" "${ROOTFS}/${MNTNV}" || exec /bin/sh mount_squash "$NFSSHARE" || exec /bin/sh fi else [ -z "$PARTNUMBER" ] || P_PARTNUMBER="p$PARTNUMBER" for DEVFILE in `find /dev/ -name "[sh]d[a-z]${PARTNUMBER}*" \ -o -name "sr${PARTNUMBER}*" \ -o -name "mmcblk*${P_PARTNUMBER}*" \ -o -name "nvme*n*${P_PARTNUMBER}*"`; do echo "$TRIEDDEVS" | grep -q "$DEVFILE\>" && continue mount "$DEVFILE" "${ROOTFS}/${MNTNV}" 2>/dev/null || continue

TRIEDDEVS="$TRIEDDEVS $DEVFILE" if [ -f "${ROOTFS}/${MNTNV}/${SQUASHFS_BIN}" ] && mount_squash "$DEVFILE"; then echo "Found root device ${DEVFILE}" FOUNDDEV="${DEVFILE}" break fi umount "${ROOTFS}/${MNTNV}" || exec /bin/sh done fi [ "$FOUNDDEV" ] && break if [ $RETRYCOUNT -eq 0 ]; then [ "$NFSSHARE" ] && echo "Ethernet device $NET not found. Waiting..." [ -z "$NFSSHARE" ] && echo "Partition with root filesystem not found. Waiting..." fi WAITTIME=$(($(awk '{print $1*1000}' /proc/uptime) - $KERNEL_BOOT_TIME)) [ $WAITTIME -gt $(($MNT_TIMEOUT * 1000)) ] && ( echo "Giving up..." && exec /bin/sh ) RETRYCOUNT=$(($RETRYCOUNT+1)) done

# Create symlinks to the squashed root filesystem cd "${ROOTFS}" ln -s "${MNTSQUASH}"/* . rm -f etc

# Create symlink to home dir ln -s "${MNTNV}/home" home

# Determine location of upper /etc filesystem for overlayfs CONFIG_DIR="${ROOTFS}/${MNTNV}/`dirname "$SQUASHFS_BIN"`"

# Mounts /etc using overlayfs mount_overlay() { mount -t overlay -o noatime,lowerdir="${ROOTFS}/${MNTSQUASH}/etc",upperdir="$1/etc",workdir="$1/work" overlay etc }

# Mounts /etc overlayfs using upper filesystem from config file mount_overlay_from_config() { local ETCOVR if [ -f "$CONFIG_DIR/config" ]; then ETCOVR="${ROOTFS}/${MNTETC}" mkdir -p "$ETCOVR" mount -o loop "$CONFIG_DIR/config" "$ETCOVR" || return $? else ETCOVR=etc_overlay mkdir -p "$ETCOVR" echo "Persistent configuration not found, storing configuration in tmpfs" fi

mkdir -p "${ETCOVR}/etc" "${ETCOVR}/work"

local RET RET=0 mount_overlay "${ETCOVR}" || RET=$?

[ $RET -eq 0 ] || umount "$ETCOVR"

return $RET }

# Creates a clean configuration in upper filesystem restore_previous_config() { echo "Restoring previous configuration"

local ETCOVR ETCOVR="${ROOTFS}/${MNTETC}" mkdir -p "$ETCOVR" mount -o loop "$CONFIG_DIR/config" "$ETCOVR" || return $?

mkdir -p /bak cp -ar "${ETCOVR}/etc" /bak/ rm -rf "${ETCOVR}/etc" "${ETCOVR}/work" mkdir -p "${ETCOVR}/etc" "${ETCOVR}/work"

local RET RET=0 mount_overlay "${ETCOVR}" || RET=$?

if [ $RET -ne 0 ]; then umount "$ETCOVR" return $RET fi

cp -arv /bak/etc / rm -rf /bak

return 0 }

# Set up /etc OVROK=0 mkdir etc ln -s /proc/mounts etc/mtab if [ "$OVRCFG" != "0" ]; then if [ ! -f "$CONFIG_DIR/config" ] && [ -f "$CONFIG_DIR/config.new" ]; then cp "$CONFIG_DIR/config.new" "$CONFIG_DIR/config" || echo "Error: Failed to copy config.new" fi if mount_overlay_from_config; then OVROK=1 else echo "Error: Failed to mount configuration overlay" if [ -f "$CONFIG_DIR/config" ]; then if restore_previous_config; then OVROK=1 else echo "Error: Failed to restore previous configuration" mv "$CONFIG_DIR/config" "$CONFIG_DIR/config.bad" if [ -f "$CONFIG_DIR/config.new" ]; then echo "Trying config.new" cp "$CONFIG_DIR/config.new" "$CONFIG_DIR/config" else echo "Trying config in ramdisk" fi if mount_overlay_from_config; then OVROK=1 else echo "Error: Failed to mount backup configuration overlay" fi fi fi fi fi if [ "$OVROK" != "1" ]; then echo "Copying configuration to ramdisk" cp -a "${ROOTFS}/${MNTSQUASH}"/etc/* etc/ fi

# Mount boot partition if [ "$PARTNUMBER" = "2" ] && [ -z "$NFSSHARE" ] && [ ! -f "${CONFIG_DIR}/kernel" ]; then mkdir "${ROOTFS}/boot" mount -o ro "${FOUNDDEV%2}1" "${ROOTFS}/boot" fi

# Copy resolv.conf [ "$NFSSHARE" ] && [ -f "/etc/resolv.conf" ] && cp /etc/resolv.conf etc/

# Create necessary directories mkdir dev mkdir proc mkdir root mkdir sys mkdir tmp chmod 1777 tmp mkdir -p var/tmp chmod 1777 var/tmp mkdir var/log chmod 755 var/log

# Create basic device nodes mknod dev/null c 1 3 mknod dev/console c 5 1

# Unmount filesystems umount /dev umount /sys rm /etc/mtab cp /proc/mounts /etc/mtab umount /proc

# Store kernel boot time for reporting in /sbin/rc echo "$KERNEL_BOOT_TIME" > var/log/kernel_boot_time

# Switch to the new root filesystem exec /bin/busybox switch_root -c /dev/console "${ROOTFS}" /sbin/init

# Fallback - enter shell exec /bin/busybox sh

08.03.2024 17:06 #439255

Разобрался.
Ошибка была в строке: echo "SQUASHFS_BIN_2: ${SQUASHFS_BIN:1:$}"
которая вызывала сбой выполнения скрипта.
Экспериментировал в загрузочном скрипте: нужно было удалить 1 символ из переменной SQUASHFS_BIN.
Правильная строка: echo "SQUASHFS_BIN_2: ${SQUASHFS_BIN:1:${#SQUASHFS_BIN}}"

Войдите или зарегистрируйтесь, чтобы ответить.