jb1 wrote:Request to cmdr > Could you please tell us how to enable the mount loopback support in the initrd image ? Then I can also port the same in the latest gparted.
Here it is (but it's not quite simple):
Download my "initrd1.img" (8.5 MB; for "GParted" 0.4.5-3) from here (md5sum : 729F439C3F752BE662079031935B5097).
Copy it to the root directory of a USB stick, and boot "GParted Live"
from another medium with the attached USB stick.
Note the stick's device name (first primary partition) after "GParted" stopped scanning. Close "GParted". Then type at the prompt of a "Terminal" window and confirm each line with [Enter].
Omit comment lines, starting with "#".
#mount your USB stick, e.g. sdb1. Replace it with YOUR actual device name
mkdir /mnt/usb
mount /dev/sdb1 /mnt/usb
cd /mnt/usb
#Create new folders and copy/rename "initrd1.img" to folder "initrd1"
mkdir -p /mnt/usb/initrd1/cpio
cp ./initrd1.img /mnt/usb/initrd1/initrd1.gz
cd /mnt/usb/initrd1
#Unzip it
gzip -d ./initrd1.gz
#unpack cpio package
cd cpio
cpio -i --file=../initrd1
cd scripts
#open "live" with "nano" editor
nano ./live
#alternative, see below
As a (better) alternative to "nano", I prefer the built-in ASCII-Editor of
"mc"("Midnight Commander"), which is NOT activated by default. Activate it
within "mc" ([ F9 ] -> [ O ] -> [ Enter ] - [ I ] - [ Enter ]). Highlight file "live"
and press [ F4 ] to open it.
Here is "my work" :
Extract of (supplemental) code in "live" script (between "#***..." and "#---...).
Single line corrections were made to enable "mc"-editor's syntax checking,
which was corrupted by these lines before (a quotation mark issue).
BTW, the script "live" is selected by the initrd argument "boot=live".
...
copy_live_to ()
{
copyfrom="${1}"
copytodev="${2}"
copyto="${copyfrom}_swap"
if [ -z "${MODULETORAM}" ]
then
size=$(fs_size "" ${copyfrom} "used")
else
MODULETORAMFILE="${copyfrom}/${LIVE_MEDIA_PATH}/${MODULETORAM}"
if [ -f "${MODULETORAMFILE}" ]
then
size=$( expr $(ls -la ${MODULETORAMFILE} | awk '{print $5}') / 1024 + 5000 )
else
log_warning_msg "Error: toram-module ${MODULETORAM} (${MODULETORAMFILE}) could not be read."
return 1
fi
fi
if [ "${copytodev}" = "ram" ]
then
# copying to ram:
freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( awk '/\<Cached/{print $2}' /proc/meminfo ) )
mount_options="-o size=${size}k"
free_string="memory"
fstype="tmpfs"
dev="/dev/shm"
else
# it should be a writable block device
if [ -b "${copytodev}" ]
then
dev="${copytodev}"
free_string="space"
fstype=$(get_fstype "${dev}")
freespace=$(fs_size "${dev}")
else
log_warning_msg "${copytodev} is not a block device."
return 1
fi
fi
if [ "${freespace}" -lt "${size}" ]
then
log_warning_msg "Not enough free ${free_string} (${freespace}k free, ${size}k needed) to copy live media in ${copytodev}."
return 1
fi
# begin copying (or uncompressing)
mkdir "${copyto}"
echo "mount -t ${fstype} ${mount_options} ${dev} ${copyto}"
mount -t "${fstype}" ${mount_options} "${dev}" "${copyto}"
if [ "${extension}" = "tgz" ]
then
cd "${copyto}"
tar zxf "${copyfrom}/${LIVE_MEDIA_PATH}/$(basename ${FETCH})"
rm -f "${copyfrom}/${LIVE_MEDIA_PATH}/$(basename ${FETCH})"
mount -r -o move "${copyto}" "${rootmnt}"
cd "${OLDPWD}"
else
if [ -n "${MODULETORAMFILE}" ]
then
cp ${MODULETORAMFILE} ${copyto} # copy only the filesystem module
else
cp -a ${copyfrom}/* ${copyto} # "cp -a" from busybox also copies hidden files
fi
#Unmounting the source device
umount ${copyfrom}
#******************************************************************************
#Unmounting all helper devices for ISO image
if [ -d /mnt/iso ]; then
cd /
umount -l /mnt/iso > /dev/null 2>&1
umount -l /mnt/vol > /dev/null 2>&1
#Important: removing helper directories
rmdir /mnt/iso /mnt/vol /mnt
fi
#------------------------------------------------------------------------------
mount -r -o move ${copyto} ${copyfrom}
fi
rmdir ${copyto}
return 0
}
...
find_livefs ()
{
timeout="${1}"
# don't start autodetection before timeout has expired
if [ -n "${LIVE_MEDIA_TIMEOUT}" ]
then
if [ "${timeout}" -lt "${LIVE_MEDIA_TIMEOUT}" ]
then
return 1
fi
fi
# first look at the one specified in the command line
case "${LIVE_MEDIA}" in
removable-usb)
#*******************************************************************************
for sysblock in `echo /sys/block/* | tr ' ' '\n' | grep -vE "/(loop|ram|dm-|fd)`; do
#-------------------------------------------------------------------------------
if [ "$(cat ${sysblock}/removable)" = "1" ]
then
if readlink ${sysblock}/device | grep -q usb
then
for dev in $(subdevices "${sysblock}")
do
if check_dev "${dev}"
then
return 0
fi
done
fi
fi
done
;;
removable)
#*******************************************************************************
for sysblock in `echo /sys/block/* | tr ' ' '\n' | grep -vE '/(loop|ram|dm-|fd)'`; do
#-------------------------------------------------------------------------------
if [ "$(cat ${sysblock}/removable)" = "1" ]
then
for dev in $(subdevices "${sysblock}")
do
if check_dev "${dev}"
then
return 0
fi
done
fi
done
;;
iso=*)
#*******************************************************************************
#e.g. live-media=iso=/gparted.iso
ISO=${LIVE_MEDIA#iso=}
mpt1="/mnt/vol"
mpt2="/mnt/iso"
#loop not yet installed; we need it here
[ ! -d /dev/loop0 ] && modprobe loop
mkdir -p ${mpt1} ${mpt2}
devm=""
#Filter (physical) Block Devices and add partitions
for dev in `echo /sys/block/* | tr ' ' '\n' | grep -vE '/(loop|ram|dm-|fd)' | sed -e 's#.*\/##'`; do
devm=${devm}`echo /dev/${dev}* | sed -e 's#\/dev\/##g'`" "
done
devn=""
for dev in ${devm}; do
dev1=`echo $dev | cut -c -3`
if [ "$dev1" = "$dev" ]; then
if [ `echo /dev/${dev1}* | wc -w` -eq 1 ]; then
#Non-partitioned device, e.g. CDROM
devn=${devn}/dev/${dev}" "
fi
continue
else
#Exclude extended partitions (size=2)
[ $(( `cat /sys/block/${dev1}/$dev/size` )) -lt 10 ] && continue
fi
devn=${devn}/dev/${dev}" "
done
for devv in ${devn}; do
mount "${devv}" ${mpt1} > /dev/null 2>&1 || continue
#Placeholder * possible; last file of multiple gets detected
ISO1="${mpt1}${ISO}"
ISO1=`echo ${ISO1} | grep -ve '*' | sed -e 's#.*\ ##g'`
if [ -f ${ISO1} ]; then
mount -t iso9660 -o loop ${ISO1} ${mpt2} > /dev/null 2>&1
ii=0; ft=1
while [ ${ii} -le 5 ]; do
sleep 1
ii=$(( $ii + 1 ))
if [ `mount | grep -e ${mpt2} | wc -l` -ne 0 ]; then
ft=0
break
fi
done
if [ ${ft} -ne 0 ]; then
umount ${mpt2} > /dev/null 2>&1
umount ${mpt1} > /dev/null 2>&1
continue
fi
#Very important !
mount -o bind "${mpt2}" $mountpoint
if [ $? -ne 0 ]; then
umount ${mpt2} > /dev/null 2>&1
umount ${mpt1} > /dev/null 2>&1
continue
fi
if is_live_path ${mountpoint}; then
#Output !
echo "${mountpoint}"
#No unmounting here !
return 0
else
umount $mountpoint > /dev/null 2>&1
umount ${mpt2} > /dev/null 2>&1
umount ${mpt1} > /dev/null 2>&1
fi
else
umount ${mpt1} > /dev/null 2>&1
fi
done
cd /
rmdir ${mpt1} ${mpt2} /mnt
#------------------------------------------------------------------------------
;;
*)
if [ ! -z "${LIVE_MEDIA}" ]
then
if check_dev "null" "${LIVE_MEDIA}" "skip_uuid_check"
then
return 0
fi
fi
;;
esac
# or do the scan of block devices
#*******************************************************************************
for sysblock in `echo /sys/block/* | tr ' ' '\n' | grep -vE "/(loop|ram|dm-|fd)`; do
#-------------------------------------------------------------------------------
devname=$(sys2dev "${sysblock}")
fstype=$(get_fstype "${devname}")
if /lib/udev/cdrom_id ${devname} > /dev/null
then
if check_dev "null" "${devname}"
then
return 0
fi
elif is_nice_device "${sysblock}"
then
for dev in $(subdevices "${sysblock}")
do
if check_dev "${dev}"
then
return 0
fi
done
elif [ "${fstype}" = "squashfs" -o \
"${fstype}" = "ext2" -o \
"${fstype}" = "ext3" -o \
"${fstype}" = "ext4" -o \
"${fstype}" = "jffs2" ]
then
# This is an ugly hack situation, the block device has
# an image directly on it. It's hopefully
# live-initramfs, so take it and run with it.
ln -s "${devname}" "${devname}.${fstype}"
echo "${devname}.${fstype}"
return 0
fi
done
return 1
}
...
What you ought to know for understanding the initial startup is, that script "init" (one folder level above) is the primary starting script. It calls "live" process "mountroot()", which then uses "find_livefs()" and "copy_live_to()". Finally "init" switches to the filesystem contained in "filesystem.squashfs". An important key to understanding is commandline processing in "init" (main) and "live" (minor). Maybe you miss a parameter for your purposes ? Here are the locations to introduce one or more!
And now the "way back" (packing a new "initrd1.img"):
Hint: You may also use a (non-formatting) windows editor to work on "live" or "init", we automatically convert the text back to Unix style.
#mount your stick, e.g sdb1
mkdir /mnt/usb
mount /dev/sdb1 /mnt/usb
cd /mnt/usb/initrd1
#Delete old (unzipped) file
rm ./initrd1
cd cpio
#Convert "live" to Unix style (provided you edited the original file at its normal place or copied it there)
busybox dos2unix ./scripts/live
#Same conversion for "init"; commented out here
#busybox dos2unix ./init
#Create cpio package
#If we created it in the same folder, it would be packed, too !
#Now it's clear, why we use subfolders.
find | cpio -o --format=newc --file=../initrd1
cd ..
#Zip it
gzip -9 -S .img ./initrd1
#You find the usable file "initrd1.img" in folder /initrd1 of your stick.
Perhaps you also have to adapt "isolinux.cfg", if you introduced a new parameter ?
It's a plain Linux text file. No problem therefore.
How do we get "the toothpaste back to the tube" (initrd1.img to the ISO image) ?
Well, you could unpack the whole ISO image, exchange "initrd1.img" and create a new ISO with "mkisofs/genisoimage", which is NOT contained in GPL and needs a whole lot of parameters. Most of all - you have to use the right "syslinux/isolinux" version and do a "post-processing" to get it "isohybrided" again. Very complex, much parameters, much possible faults !
I chose a simpler way. I used a Windows hexadecimal editor (HxD), loaded the ISO image and exchanged the file(s) directly.
This is possible because involved files are contiguous (not fragmented) and differ very little in size ( well, "isolinux.cfg" might not be much bigger than it is now !). Of course, you have to correct file size in FAT, too.
What you ought to know is, that CDROMs use a sector size of 2048 Bytes(= 0x800 hexadecimal).
How to proceed ?
At first let the hexadecimal editor search for the FAT entry, e.g. initrd1.img.
You see :
To find the file location, multiply sector value with sector size. Since nearly all hex editors use hexadecimal addresses, do calculation in hexadecimal. Files always start at sector borders and don't fill sectors to the last Byte.
So you should see zero Bytes (00) in front of your calculated address. If not, look for calculation faults ! You should also inspect the file's end by adding file size to the start address. Again you should see zero Bytes past this address.
Scroll down the zero Bytes until you reach the next file to get an impression, how much space is "in reserve". Next load your "initrd1.img" file additionally to a new tab of the hex editor. Select "copy all" . You now see the end of the file and may read file size in hexadecimal (one Byte more than the last used, since it starts with Byte 0). Copy it and select other tab again. Be sure to "write" your new "initrd1.img" to the ISO image and NOT to "paste" it, which would add new size to the image, thus corrupting it ! Store the new Iso image and load it again to correct the FAT entry. Search it and correct values. Most often this is only one Byte, NEVER more than two ! Of course, you always correct both Little and Big Endian values. Don't forget to store ISO image again. Repeat this procedure for "isolinux.cfg" or other altered files. I do NOT recommend to do all corrections in one step and store the new ISO file once at the end, because it's not loaded totally to memory and might "forget" corrections, which are too far away from each other.
To just test your new changes, you don't need to create a new ISO image each time; you don't even need to "zip" "initrd1.img". Just rename the (big) new cpio file and put it in a /live folder together with "vmlinuz1" and "filesystem.squashfs", adapt your bootmenu entry (Grub2 or Grub4DOS) and run it. This works, even if you try to get "filesystem.squashfs" from an (unaltered!) ISO file. Just rename "filesystem.squashfs" within "live" folder, so that it gets out of focus. That's what I did to eliminate my programming faults faster.
Regards
cmdr