First commit.
This commit is contained in:
230
utilities/usb-boot/mbr2gpt.sh
Normal file
230
utilities/usb-boot/mbr2gpt.sh
Normal file
@ -0,0 +1,230 @@
|
||||
#!/bin/bash
|
||||
|
||||
trap '{ stty sane; echo ""; errexit "Aborted"; }' SIGINT SIGTERM
|
||||
|
||||
MNTPATH="/tmp/boot-gpt-mnt"
|
||||
|
||||
mntpart()
|
||||
{
|
||||
MNTED=TRUE
|
||||
if [ ! -d "${MNTPATH}/" ]; then
|
||||
mkdir "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to make partition mount point"
|
||||
fi
|
||||
fi
|
||||
mount "$1" "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to mount $2 partition"
|
||||
fi
|
||||
}
|
||||
|
||||
umntpart()
|
||||
{
|
||||
umount "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to unmount partition"
|
||||
fi
|
||||
rm -r "${MNTPATH}/"
|
||||
MNTED=FALSE
|
||||
}
|
||||
|
||||
errexit()
|
||||
{
|
||||
echo ""
|
||||
echo "$1"
|
||||
echo ""
|
||||
if [ "${MNTED}" = "TRUE" ]; then
|
||||
umount "${MNTPATH}/" &> /dev/null
|
||||
rm -rf "${MNTPATH}/" &> /dev/null
|
||||
fi
|
||||
echo "Usage: $0 /dev/sdX"
|
||||
echo ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
MNTED=FALSE
|
||||
if [ $(id -u) -ne 0 ]; then
|
||||
errexit "$0 must be run as root user"
|
||||
fi
|
||||
PGMNAME="$(basename $0)"
|
||||
for PID in $(pidof -x -o %PPID "${PGMNAME}"); do
|
||||
if [ ${PID} -ne $$ ]; then
|
||||
errexit "${PGMNAME} is already running"
|
||||
fi
|
||||
done
|
||||
gdisk -l /dev/null &> /dev/null
|
||||
if [ $? -eq 127 ]; then
|
||||
echo ""
|
||||
echo "gdisk not installed"
|
||||
echo ""
|
||||
echo -n "Ok to install gdisk (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
break
|
||||
else
|
||||
errexit "Aborted"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
echo "Installing gdisk"
|
||||
echo ""
|
||||
apt-get update
|
||||
apt-get install gdisk
|
||||
fi
|
||||
DEVICE="$1"
|
||||
if [ "${DEVICE}" = "" ]; then
|
||||
errexit "No device specified"
|
||||
fi
|
||||
if [[ ! "${DEVICE}" =~ ^/dev/sd[a-z]$ || ! -b "${DEVICE}" ]]; then
|
||||
errexit "Invalid DEVICE: ${DEVICE}"
|
||||
fi
|
||||
if [ $(mount | grep -c "^${DEVICE}") -ne 0 ]; then
|
||||
errexit "${DEVICE} is in use (mounted)"
|
||||
fi
|
||||
PTTYPE="$(blkid ${DEVICE} | sed -n 's|^.*PTTYPE="\(\S\+\)".*|\1|p')"
|
||||
PTTYPE="$(tr [a-z] [A-Z] <<< "${PTTYPE}")"
|
||||
if [ "${PTTYPE}" = "DOS" ]; then
|
||||
PTTYPE="MBR"
|
||||
fi
|
||||
if [[ "${PTTYPE}" != "MBR" && "${PTTYPE}" != "GPT" ]]; then
|
||||
errexit "Unsupported partition table type"
|
||||
fi
|
||||
echo ""
|
||||
echo "Partition table type is ${PTTYPE}"
|
||||
if [ "${PTTYPE}" = "MBR" ]; then
|
||||
echo ""
|
||||
echo -n "Ok to convert ${DEVICE} to GPT (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
break
|
||||
else
|
||||
errexit "Aborted"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
sgdisk -z "${DEVICE}" &> /dev/null
|
||||
fi
|
||||
INFO="$(gdisk -l ${DEVICE})"
|
||||
LAST=$(sed -n 's|^.*last usable sector is \(\S\+\).*|\1|p' <<< "${INFO}")
|
||||
START=$(sed -n 's|^\s\+2\s\+\(\S\+\).*|\1|p' <<< "${INFO}")
|
||||
END=$(sed -n 's|^\s\+2\s\+\S\+\s\+\(\S\+\).*|\1|p' <<< "${INFO}")
|
||||
SHRINK=FALSE
|
||||
EXPAND=FALSE
|
||||
SDBOOT=FALSE
|
||||
if [ $(grep -c "Warning! Secondary partition table overlaps the last partition" <<< "${INFO}") -ne 0 ]; then
|
||||
echo ""
|
||||
echo "ROOT partition overlaps the Secondary partition table area"
|
||||
echo ""
|
||||
echo -n "Ok to resize ROOT partition (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
break
|
||||
else
|
||||
errexit "Aborted"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
SHRINK=TRUE
|
||||
elif [ ${END} -lt ${LAST} ]; then
|
||||
echo ""
|
||||
echo -n "Expand ROOT partition to use all available space (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
EXPAND=TRUE
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ -b /dev/mmcblk0 ]; then
|
||||
echo ""
|
||||
echo -n "Set SD card to boot ${DEVICE} (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
SDBOOT=TRUE
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ "${PTTYPE}" = "MBR" || "${SHRINK}" = "TRUE" || "${EXPAND}" = "TRUE" || "${SDBOOT}" = "TRUE" ]]; then
|
||||
echo ""
|
||||
echo -n "Ok to process ${DEVICE} (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
break
|
||||
else
|
||||
errexit "Aborted"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [ "${SHRINK}" = "TRUE" ]; then
|
||||
echo ""
|
||||
resize2fs -f -M "${DEVICE}2"
|
||||
fi
|
||||
if [[ "${SHRINK}" = "TRUE" || "${EXPAND}" = "TRUE" ]]; then
|
||||
gdisk "${DEVICE}" <<EOF > /dev/null
|
||||
d
|
||||
2
|
||||
n
|
||||
2
|
||||
${START}
|
||||
|
||||
|
||||
w
|
||||
y
|
||||
EOF
|
||||
echo ""
|
||||
resize2fs -f "${DEVICE}2"
|
||||
fi
|
||||
gdisk "${DEVICE}" <<EOF > /dev/null
|
||||
r
|
||||
h
|
||||
1
|
||||
n
|
||||
0c
|
||||
n
|
||||
n
|
||||
w
|
||||
y
|
||||
EOF
|
||||
PARTUUID_1="$(blkid ${DEVICE}1 | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
PARTUUID_2="$(blkid ${DEVICE}2 | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
mntpart "${DEVICE}1" "BOOT"
|
||||
sed -i '/^[[:space:]]*#/!s|\(^.*rootwait\).*$|\1|' "${MNTPATH}/cmdline.txt"
|
||||
sed -i "/^[[:space:]]*#/!s|^\(.*root=\)\S\+\(\s\+.*\)$|\1PARTUUID=${PARTUUID_2}\2|" "${MNTPATH}/cmdline.txt"
|
||||
umntpart
|
||||
mntpart "${DEVICE}2" "ROOT"
|
||||
sed -i "/^[[:space:]]*#/!s|^\S\+\(\s\+/boot\s\+.*\)$|PARTUUID=${PARTUUID_1}\1|" "${MNTPATH}/etc/fstab"
|
||||
sed -i "/^[[:space:]]*#/!s|^\S\+\(\s\+/\s\+.*\)$|PARTUUID=${PARTUUID_2}\1|" "${MNTPATH}/etc/fstab"
|
||||
umntpart
|
||||
if [ "${SDBOOT}" = "TRUE" ]; then
|
||||
mntpart "/dev/mmcblk0p1" "BOOT"
|
||||
sed -i "/^[[:space:]]*#/!s|^\(.*root=\)\S\+\(\s\+.*\)$|\1PARTUUID=${PARTUUID_2}\2|" "${MNTPATH}/cmdline.txt"
|
||||
umntpart
|
||||
mntpart "${DEVICE}2" "ROOT"
|
||||
sed -i "/^[[:space:]]*#/!s|^\S\+\(\s\+/boot\s\+.*\)$|/dev/mmcblk0p1\1|" "${MNTPATH}/etc/fstab"
|
||||
umntpart
|
||||
fi
|
||||
if [[ "${SHRINK}" = "FALSE" && "${EXPAND}" = "FALSE" ]]; then
|
||||
echo ""
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo "Nothing to do!"
|
||||
echo ""
|
||||
fi
|
145
utilities/usb-boot/sdc-boot.sh
Normal file
145
utilities/usb-boot/sdc-boot.sh
Normal file
@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
|
||||
trap '{ stty sane; echo ""; errexit "Aborted"; }' SIGINT SIGTERM
|
||||
|
||||
MNTPATH="/tmp/sdc-boot-mnt"
|
||||
|
||||
mntpart()
|
||||
{
|
||||
MNTED=TRUE
|
||||
if [ ! -d "${MNTPATH}/" ]; then
|
||||
mkdir "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to make partition mount point"
|
||||
fi
|
||||
fi
|
||||
mount "$1" "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to mount $2 partition"
|
||||
fi
|
||||
}
|
||||
|
||||
umntpart()
|
||||
{
|
||||
umount "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to unmount partition"
|
||||
fi
|
||||
rm -r "${MNTPATH}/"
|
||||
MNTED=FALSE
|
||||
}
|
||||
|
||||
errexit()
|
||||
{
|
||||
echo ""
|
||||
echo "$1"
|
||||
echo ""
|
||||
if [ "${MNTED}" = "TRUE" ]; then
|
||||
umount "${MNTPATH}/" &> /dev/null
|
||||
rm -rf "${MNTPATH}/" &> /dev/null
|
||||
fi
|
||||
echo "Usage: $0 [ /dev/sdX2 | /dev/mmcblk0p2 | hhhhhhhh-02 | hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh ]"
|
||||
echo ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
MNTED=FALSE
|
||||
if [ $(id -u) -ne 0 ]; then
|
||||
errexit "$0 must be run as root user"
|
||||
fi
|
||||
PGMNAME="$(basename $0)"
|
||||
for PID in $(pidof -x -o %PPID "${PGMNAME}"); do
|
||||
if [ ${PID} -ne $$ ]; then
|
||||
errexit "${PGMNAME} is already running"
|
||||
fi
|
||||
done
|
||||
if [ ! -b /dev/mmcblk0 ]; then
|
||||
errexit "No SD card present"
|
||||
fi
|
||||
DEVICE="$1"
|
||||
if [ "${DEVICE}" = "" ]; then
|
||||
mntpart "/dev/mmcblk0p1" "SD card BOOT"
|
||||
DEVICE="$(sed -n '/^[[:space:]]*#/!s|^.*root=\(\S\+\)\s\+.*$|\1|p' "${MNTPATH}/cmdline.txt")"
|
||||
umntpart
|
||||
if [[ "${DEVICE}" =~ ^PARTUUID=.*$ ]]; then
|
||||
DEVICE="$(blkid -l -t "${DEVICE}" | sed -n 's|^\(/dev/.*\):.*|\1|p')"
|
||||
fi
|
||||
PARTUUID="$(blkid "${DEVICE}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
else
|
||||
DEVICE="$(tr [A-Z] [a-z] <<< "${DEVICE}")"
|
||||
if [[ "${DEVICE}" =~ ^[[:xdigit:]]{8}-02$ || "${DEVICE}" =~ ^[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}$ ]]; then
|
||||
PARTUUID="${DEVICE}"
|
||||
BLKID="$(blkid -l -t PARTUUID="${PARTUUID}")"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Invalid DEVICE: ${DEVICE}"
|
||||
fi
|
||||
DEVICE="$(sed -n 's|^\(/dev/.*\):.*$|\1|p' <<< "${BLKID}")"
|
||||
fi
|
||||
if [[ ("${DEVICE}" != "/dev/mmcblk0p2" && ! "${DEVICE}" =~ ^/dev/sd[a-z]2$) || ! -b "${DEVICE}" ]]; then
|
||||
errexit "Invalid DEVICE: ${DEVICE}"
|
||||
fi
|
||||
PARTUUID="$(blkid "${DEVICE}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
echo ""
|
||||
echo -n "Set SD card to boot to ${DEVICE} [PARTUUID=${PARTUUID}] (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
break
|
||||
else
|
||||
errexit "Aborted"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
mntpart "/dev/mmcblk0p1" "SD card BOOT"
|
||||
if [ "${DEVICE}" = "/dev/mmcblk0p2" ]; then
|
||||
sed -i "/^[[:space:]]*#/!s|^\(.*root=\)\S\+\(\s\+.*\)$|\1/dev/mmcblk0p2\2|" "${MNTPATH}/cmdline.txt"
|
||||
else
|
||||
sed -i "/^[[:space:]]*#/!s|^\(.*root=\)\S\+\(\s\+.*\)$|\1PARTUUID=${PARTUUID}\2|" "${MNTPATH}/cmdline.txt"
|
||||
fi
|
||||
umntpart
|
||||
if [ "${DEVICE}" != "/dev/mmcblk0p2" ]; then
|
||||
mntpart "${DEVICE}" "device ROOT"
|
||||
sed -i "/^[[:space:]]*#/!s|^\S\+\(\s\+/boot\s\+.*\)$|/dev/mmcblk0p1\1|" "${MNTPATH}/etc/fstab"
|
||||
umntpart
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
echo "SD card is set to boot to ${DEVICE} [PARTUUID=${PARTUUID}]"
|
||||
if [[ "${DEVICE}" != "/dev/mmcblk0p2" && "$(blkid /dev/mmcblk0p2 | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" = "${PARTUUID}" ]]; then
|
||||
echo ""
|
||||
echo "WARNING : SD card (/dev/mmcblk0p2) and USB device (${DEVICE}) have the same PARTUUID (${PARTUUID}) : SD card will boot instead of USB device"
|
||||
fi
|
||||
DEV_LIST=()
|
||||
DEV_LIST+=/dev/mmcblk0p2
|
||||
DEV_LIST+=($(ls -l /dev/sd?2 2> /dev/null | sed -n 's|^.*\(/dev/.*\)|\1|p'))
|
||||
if [ ${#DEV_LIST[@]} -gt 1 ]; then
|
||||
for i in ${!DEV_LIST[@]}; do
|
||||
if [ ${i} -lt $((${#DEV_LIST[@]} - 1)) ]; then
|
||||
j=$((i + 1))
|
||||
while [ ${j} -lt ${#DEV_LIST[@]} ]; do
|
||||
if [ "$(blkid "${DEV_LIST[i]}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" = "$(blkid "${DEV_LIST[j]}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" ];then
|
||||
if [[ "${DEV_LIST[i]}" != "/dev/mmcblk0p2" && ("${DEV_LIST[i]}" = "${DEVICE}" || "${DEV_LIST[j]}" = "${DEVICE}") ]]; then
|
||||
echo ""
|
||||
echo "WARNING : ${DEV_LIST[i]} and ${DEV_LIST[j]} have the same PARTUUID : $(blkid "${DEV_LIST[i]}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
fi
|
||||
fi
|
||||
((j += 1))
|
||||
done
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo ""
|
||||
if [ "$1" != "" ]; then
|
||||
echo -n "Reboot now (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ ${answer} = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ ${answer} = [yY] ]]; then
|
||||
shutdown -r now
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
193
utilities/usb-boot/set-partuuid.sh
Normal file
193
utilities/usb-boot/set-partuuid.sh
Normal file
@ -0,0 +1,193 @@
|
||||
#!/bin/bash
|
||||
|
||||
trap '{ stty sane; echo ""; errexit "Aborted"; }' SIGINT SIGTERM
|
||||
|
||||
MNTPATH="/tmp/set-partuuid-mnt"
|
||||
|
||||
mntpart()
|
||||
{
|
||||
MNTED=TRUE
|
||||
if [ ! -d "${MNTPATH}/" ]; then
|
||||
mkdir "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to make partition mount point"
|
||||
fi
|
||||
fi
|
||||
mount "$1" "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to mount $2 partition"
|
||||
fi
|
||||
}
|
||||
|
||||
umntpart()
|
||||
{
|
||||
umount "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to unmount partition"
|
||||
fi
|
||||
rm -r "${MNTPATH}/"
|
||||
MNTED=FALSE
|
||||
}
|
||||
|
||||
errexit()
|
||||
{
|
||||
echo ""
|
||||
echo "$1"
|
||||
echo ""
|
||||
if [ "${MNTED}" = "TRUE" ]; then
|
||||
umount "${MNTPATH}/" &> /dev/null
|
||||
rm -rf "${MNTPATH}/" &> /dev/null
|
||||
fi
|
||||
echo "Usage: $0 device [ hhhhhhhh-02 | hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh | random ]"
|
||||
echo ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
MNTED=FALSE
|
||||
if [ $(id -u) -ne 0 ]; then
|
||||
errexit "$0 must be run as root user"
|
||||
fi
|
||||
PGMNAME="$(basename $0)"
|
||||
for PID in $(pidof -x -o %PPID "${PGMNAME}"); do
|
||||
if [ ${PID} -ne $$ ]; then
|
||||
errexit "${PGMNAME} is already running"
|
||||
fi
|
||||
done
|
||||
gdisk -l "${DEVICE}" &> /dev/null
|
||||
if [ $? -eq 127 ]; then
|
||||
echo ""
|
||||
echo "gdisk not installed"
|
||||
echo ""
|
||||
echo -n "Ok to install gdisk (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
break
|
||||
else
|
||||
errexit "Aborted"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
echo "Installing gdisk"
|
||||
echo ""
|
||||
apt-get update
|
||||
apt-get install gdisk
|
||||
fi
|
||||
DEVICE="$1"
|
||||
PARTUUID="$2"
|
||||
if [[ (! "${DEVICE}" =~ ^/dev/sd[a-z]2$ && ! "${DEVICE}" = "/dev/mmcblk0p2") || ! -b "${DEVICE}" ]]; then
|
||||
errexit "Invalid DEVICE: ${DEVICE}"
|
||||
fi
|
||||
ORIGUUID="$(blkid "${DEVICE}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
if [ "${PARTUUID}" = "" ]; then
|
||||
PARTUUID="${ORIGUUID}"
|
||||
else
|
||||
DEVICE_P="$(sed 's/[0-9]\+$//' <<< "${DEVICE}")"
|
||||
DEVICE_D="${DEVICE_P}"
|
||||
if [ "${DEVICE_D}" = "/dev/mmcblk0p" ]; then
|
||||
DEVICE_D="${DEVICE_D:0:(${#DEVICE_D} - 1)}"
|
||||
fi
|
||||
SDCBOOT=FALSE
|
||||
if [ -b /dev/mmcblk0p1 ]; then
|
||||
mntpart "/dev/mmcblk0p1" "BOOT"
|
||||
CLRPART="$(sed -n '/^[[:space:]]*#/!s|^.*root=\(\S\+\)\s.*|\1|p' "${MNTPATH}/cmdline.txt")"
|
||||
if [ "${CLRPART}" != "/dev/mmcblk0p2" ]; then
|
||||
CLRUUID="$(sed -n 's|PARTUUID=\(\S\+\)|\1|p' <<< "${CLRPART}")"
|
||||
if [[ "${CLRUUID}" != "$(blkid /dev/mmcblk0p2 | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" && "${CLRUUID}" = "${ORIGUUID}" ]]; then
|
||||
SDCBOOT=TRUE
|
||||
fi
|
||||
fi
|
||||
umntpart
|
||||
fi
|
||||
PTTYPE="$(blkid "${DEVICE_D}" | sed -n 's|^.*PTTYPE="\(\S\+\)".*|\1|p')"
|
||||
if [[ "${PTTYPE}" != "dos" && "${PTTYPE}" != "gpt" ]]; then
|
||||
errexit "Unsupported partition table type: ${PTTYPE}"
|
||||
fi
|
||||
PARTUUID="$(tr [A-Z] [a-z] <<< "${PARTUUID}")"
|
||||
if [[ "${PARTUUID}" != "random" && (("${PTTYPE}" = "dos" && ! "${PARTUUID}" =~ ^[[:xdigit:]]{8}-02$) || \
|
||||
("${PTTYPE}" = "gpt" && ! "${PARTUUID}" =~ ^[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}$)) ]]; then
|
||||
errexit "Invalid PARTUUID: ${PARTUUID}"
|
||||
fi
|
||||
echo ""
|
||||
echo -n "Set PARTUUID on ${DEVICE} to ${PARTUUID} (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
break
|
||||
else
|
||||
errexit "Aborted"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
ORIGUUID_1="$(blkid "${DEVICE_P}1" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
ORIGUUID_2="$(blkid "${DEVICE_P}2" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
if [ "${PTTYPE}" = "dos" ]; then
|
||||
if [ "${PARTUUID}" = "random" ]; then
|
||||
PTUUID="$(hexdump -n 4 -e '"%08X"' /dev/random | tr [A-Z] [a-z])"
|
||||
else
|
||||
PTUUID="${PARTUUID:0:(${#PARTUUID} - 3)}"
|
||||
fi
|
||||
fdisk "${DEVICE_D}" <<EOF &> /dev/null
|
||||
x
|
||||
i
|
||||
0x${PTUUID}
|
||||
r
|
||||
w
|
||||
EOF
|
||||
else
|
||||
if [ "${PARTUUID}" = "random" ]; then
|
||||
sgdisk -u 2:'R' "${DEVICE_D}" > /dev/null
|
||||
else
|
||||
sgdisk -u 2:${PARTUUID} "${DEVICE_D}" > /dev/null
|
||||
fi
|
||||
fi
|
||||
partprobe
|
||||
PARTUUID="$(blkid "${DEVICE}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
PARTUUID_1="$(blkid "${DEVICE_P}1" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
PARTUUID_2="$(blkid "${DEVICE_P}2" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
mntpart "${DEVICE_P}2" "ROOT"
|
||||
sed -i "/^[[:space:]]*#/!s|^\(PARTUUID=\)${ORIGUUID_1}\(\s\+/boot\s\+.*\)$|\1${PARTUUID_1}\2|" "${MNTPATH}/etc/fstab"
|
||||
sed -i "/^[[:space:]]*#/!s|^\(PARTUUID=\)${ORIGUUID_2}\(\s\+/\s\+.*\)$|\1${PARTUUID_2}\2|" "${MNTPATH}/etc/fstab"
|
||||
umntpart
|
||||
mntpart "${DEVICE_P}1" "BOOT"
|
||||
sed -i "/^[[:space:]]*#/!s|^\(.*root=PARTUUID=\)${ORIGUUID_2}\(\s\+.*\)$|\1${PARTUUID_2}\2|" "${MNTPATH}/cmdline.txt"
|
||||
umntpart
|
||||
if [ "${SDCBOOT}" = "TRUE" ]; then
|
||||
mntpart "/dev/mmcblk0p1" "SD card BOOT"
|
||||
sed -i "/^[[:space:]]*#/!s|^\(.*root=PARTUUID=\)${ORIGUUID_2}\(\s\+.*\)$|\1${PARTUUID_2}\2|" "${MNTPATH}/cmdline.txt"
|
||||
umntpart
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
echo "PARTUUID on ${DEVICE} is set to ${PARTUUID}"
|
||||
if [ -b /dev/mmcblk0 ]; then
|
||||
if [[ "${DEVICE}" != "/dev/mmcblk0p2" && "$(blkid /dev/mmcblk0p2 | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" = "${PARTUUID}" ]]; then
|
||||
echo ""
|
||||
echo "WARNING : SD card (/dev/mmcblk0p2) and USB device (${DEVICE}) have the same PARTUUID (${PARTUUID}) : SD card will boot instead of USB device"
|
||||
fi
|
||||
fi
|
||||
DEV_LIST=()
|
||||
if [ -b /dev/mmcblk0 ]; then
|
||||
DEV_LIST+=/dev/mmcblk0p2
|
||||
fi
|
||||
DEV_LIST+=($(ls -l /dev/sd?2 2> /dev/null | sed -n 's|^.*\(/dev/.*\)|\1|p'))
|
||||
if [ ${#DEV_LIST[@]} -gt 1 ]; then
|
||||
for i in ${!DEV_LIST[@]}; do
|
||||
if [ ${i} -lt $((${#DEV_LIST[@]} - 1)) ]; then
|
||||
j=$((i + 1))
|
||||
while [ ${j} -lt ${#DEV_LIST[@]} ]; do
|
||||
if [ "$(blkid "${DEV_LIST[i]}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" = "$(blkid "${DEV_LIST[j]}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" ];then
|
||||
if [[ "${DEV_LIST[i]}" != "/dev/mmcblk0p2" && ("${DEV_LIST[i]}" = "${DEVICE}" || "${DEV_LIST[j]}" = "${DEVICE}") ]]; then
|
||||
echo ""
|
||||
echo "WARNING : ${DEV_LIST[i]} and ${DEV_LIST[j]} have the same PARTUUID : $(blkid "${DEV_LIST[i]}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
fi
|
||||
fi
|
||||
((j += 1))
|
||||
done
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo ""
|
403
utilities/usb-boot/usb-boot.sh
Normal file
403
utilities/usb-boot/usb-boot.sh
Normal file
@ -0,0 +1,403 @@
|
||||
#!/bin/bash
|
||||
|
||||
trap '{ stty sane; echo ""; errexit "Aborted"; }' SIGINT SIGTERM
|
||||
|
||||
MNTPATH="/tmp/usb-boot-mnt"
|
||||
|
||||
mntdev()
|
||||
{
|
||||
MNTED=TRUE
|
||||
if [ ! -d "${MNTPATH}/" ]; then
|
||||
mkdir "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to make ROOT partition mount point"
|
||||
fi
|
||||
fi
|
||||
mount "${1}2" "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to mount ROOT partition"
|
||||
fi
|
||||
if [ ! -d "${MNTPATH}/boot/" ]; then
|
||||
mkdir -p "${MNTPATH}/boot/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to make BOOT partition mount point"
|
||||
fi
|
||||
fi
|
||||
mount "${1}1" "${MNTPATH}/boot/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to mount BOOT partition"
|
||||
fi
|
||||
}
|
||||
|
||||
umntdev()
|
||||
{
|
||||
umount "${MNTPATH}/boot/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to unmount BOOT partition"
|
||||
fi
|
||||
umount "${MNTPATH}/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to unmount ROOT partition"
|
||||
fi
|
||||
rm -r "${MNTPATH}/"
|
||||
MNTED=FALSE
|
||||
}
|
||||
|
||||
errexit()
|
||||
{
|
||||
echo ""
|
||||
echo "$1"
|
||||
echo ""
|
||||
if [ "${MNTED}" = "TRUE" ]; then
|
||||
umount "${MNTPATH}/boot/" &> /dev/null
|
||||
umount "${MNTPATH}/" &> /dev/null
|
||||
rm -rf "${MNTPATH}/" &> /dev/null
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
MNTED=FALSE
|
||||
if [ $(id -u) -ne 0 ]; then
|
||||
errexit "Must be run as root user: sudo $0"
|
||||
fi
|
||||
PGMNAME="$(basename $0)"
|
||||
for PID in $(pidof -x -o %PPID "${PGMNAME}"); do
|
||||
if [ ${PID} -ne $$ ]; then
|
||||
errexit "${PGMNAME} is already running"
|
||||
fi
|
||||
done
|
||||
gdisk -l "${DEVICE}" &> /dev/null
|
||||
if [ $? -eq 127 ]; then
|
||||
echo ""
|
||||
echo "gdisk not installed"
|
||||
echo ""
|
||||
echo -n "Ok to install gdisk (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
break
|
||||
else
|
||||
errexit "Aborted"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
echo "Installing gdisk"
|
||||
echo ""
|
||||
apt-get update
|
||||
apt-get install gdisk
|
||||
fi
|
||||
rsync --version &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "rsync not installed (run: apt-get install rsync)"
|
||||
fi
|
||||
ROOT_PART="$(mount | sed -n 's|^\(/dev/.*\) on / .*|\1|p')"
|
||||
ROOT_DEV="$(sed 's/[0-9]\+$//' <<< "${ROOT_PART}")"
|
||||
if [ "${ROOT_DEV}" = "/dev/mmcblk0p" ]; then
|
||||
ROOT_DEV="${ROOT_DEV:0:(${#ROOT_DEV} - 1)}"
|
||||
fi
|
||||
ROOT_TYPE="$(blkid "${ROOT_PART}" | sed -n 's|^.*TYPE="\(\S\+\)".*|\1|p')"
|
||||
if [ -b /dev/mmcblk0 ]; then
|
||||
USESDC=TRUE
|
||||
else
|
||||
USESDC=FALSE
|
||||
fi
|
||||
if [[ $(cat /proc/cpuinfo | grep -c "^Revision\s\+:\s\+[abcd]0311[1245]$") -ne 0 || $(cat /proc/cpuinfo | grep -c "^Revision\s\+:\s\+c03130$") -ne 0 ]]; then
|
||||
RPI_4=TRUE
|
||||
else
|
||||
RPI_4=FALSE
|
||||
fi
|
||||
if [ "$(vcgencmd otp_dump | grep 17:)" = "17:3020000a" ]; then
|
||||
RPI_3=TRUE
|
||||
else
|
||||
RPI_3=FALSE
|
||||
fi
|
||||
if [[ "${USESDC}" = "TRUE" && "${RPI_4}" = "TRUE" ]]; then
|
||||
whiptail --backtitle "USB Boot" --title "USB Boot Method" --yesno --defaultno "\nUse SD card to boot the USB device?" 12 40
|
||||
YESNO=$?
|
||||
if [ ${YESNO} -eq 255 ]; then
|
||||
errexit "Aborted"
|
||||
elif [ ${YESNO} -ne 0 ]; then
|
||||
USESDC=FALSE
|
||||
fi
|
||||
elif [[ "${USESDC}" = "TRUE" && "${RPI_3}" = "TRUE" ]]; then
|
||||
whiptail --backtitle "USB Boot" --title "USB Boot Method" --yesno "\nUse SD card to boot the USB device (recommended)?" 12 54
|
||||
YESNO=$?
|
||||
if [ ${YESNO} -eq 255 ]; then
|
||||
errexit "Aborted"
|
||||
elif [ ${YESNO} -ne 0 ]; then
|
||||
USESDC=FALSE
|
||||
fi
|
||||
elif [[ "${USESDC}" = "FALSE" && "${RPI_4}" = "FALSE" && "${RPI_3}" = "FALSE" ]]; then
|
||||
errexit "Not a Raspberry Pi 4, Raspberry Pi 3B+, or Raspberry Pi 3B with OTP set, and no SD card present or used"
|
||||
fi
|
||||
USBDEVS=($(ls -l /dev/sd? 2> /dev/null | sed -n 's|^.*\(/dev/.*\)|\1|p'))
|
||||
if [ ${#USBDEVS[@]} -eq 0 ]; then
|
||||
errexit "No available USB mass storage devices found"
|
||||
fi
|
||||
for i in ${!USBDEVS[@]}; do
|
||||
USBDEVS[i]="${USBDEVS[i]} ${USBDEVS[i]} OFF"
|
||||
done
|
||||
USB_DEST="$(whiptail --backtitle "USB Boot" --title "USB Mass Storage Devices" --notags --radiolist \
|
||||
"\nSelect the USB mass storage device to boot" 13 47 ${#USBDEVS[@]} ${USBDEVS[@]} 3>&1 1>&2 2>&3)"
|
||||
if [[ $? -ne 0 || "${USB_DEST}" = "" ]]; then
|
||||
errexit "Aborted"
|
||||
fi
|
||||
USB_BOOT="${USB_DEST}1"
|
||||
USB_ROOT="${USB_DEST}2"
|
||||
if [ "${ROOT_DEV}" != "${USB_DEST}" ]; then
|
||||
whiptail --backtitle "USB Boot" --title "Replicate BOOT/ROOT Contents" --yesno "\nReplicate BOOT/ROOT contents from ${ROOT_DEV} to ${USB_DEST}?" 12 64
|
||||
YESNO=$?
|
||||
if [ ${YESNO} -eq 255 ]; then
|
||||
errexit "Aborted"
|
||||
elif [ ${YESNO} -eq 0 ]; then
|
||||
if [ $(mount | grep -c "^${USB_DEST}") -ne 0 ]; then
|
||||
errexit "USB mass storage device in use (mounted)"
|
||||
fi
|
||||
DEVSIZE=$(blockdev --getsz "${USB_DEST}")
|
||||
PTTYPES=()
|
||||
if [ ${DEVSIZE} -le 4294966784 ]; then
|
||||
PTTYPES[0]="dos MBR ON"
|
||||
PTTYPES[1]="gpt GPT OFF"
|
||||
else
|
||||
PTTYPES[0]="gpt GPT ON"
|
||||
fi
|
||||
PTTYPE="$(whiptail --backtitle "USB Boot" --title "Partition Table Type" --notags --radiolist \
|
||||
"\nSelect the partition table type to use (MBR = 2TB Maximum)" 10 62 ${#PTTYPES[@]} ${PTTYPES[@]} 3>&1 1>&2 2>&3)"
|
||||
if [[ $? -ne 0 || "${PTTYPE}" = "" ]]; then
|
||||
errexit "Aborted"
|
||||
fi
|
||||
whiptail --backtitle "USB Boot" --title "WARNING" --yesno "\nWARNING\n\nAll existing data on USB device ${USB_DEST} will be destroyed!\n\nDo you wish to continue?" 14 64
|
||||
YESNO=$?
|
||||
if [ ${YESNO} -ne 0 ]; then
|
||||
errexit "Aborted"
|
||||
fi
|
||||
echo ""
|
||||
echo "Replicating BOOT/ROOT contents from ${ROOT_DEV} to ${USB_DEST} (this will take a while)"
|
||||
if [ "${PTTYPE}" = "dos" ]; then
|
||||
DEVSIZE=$(blockdev --getsz "${USB_DEST}")
|
||||
dd bs=512 seek=0 count=34 if=/dev/zero of="${USB_DEST}" &> /dev/null
|
||||
dd bs=512 seek=$((${DEVSIZE} - 33)) count=33 if=/dev/zero of="${USB_DEST}" &> /dev/null
|
||||
partprobe
|
||||
echo "label: dos" | sfdisk "${USB_DEST}" > /dev/null
|
||||
sfdisk "${USB_DEST}" <<EOF &> /dev/null
|
||||
,256MiB,c
|
||||
,+,83
|
||||
EOF
|
||||
else
|
||||
sgdisk -Z "${USB_DEST}" &> /dev/null
|
||||
sgdisk -n 1:0:+256M "${USB_DEST}" &> /dev/null
|
||||
sgdisk -t 1:0700 "${USB_DEST}" > /dev/null
|
||||
sgdisk -n 2:0:0 "${USB_DEST}" &> /dev/null
|
||||
sgdisk -t 2:8300 "${USB_DEST}" > /dev/null
|
||||
fi
|
||||
partprobe
|
||||
mkfs.vfat -F 32 "${USB_BOOT}" > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to create BOOT filesystem"
|
||||
fi
|
||||
dosfsck "${USB_BOOT}" > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "BOOT filesystem appears corrupted"
|
||||
fi
|
||||
if [ "${ROOT_TYPE}" = "f2fs" ]; then
|
||||
mkfs.f2fs -f "${USB_ROOT}" > /dev/null
|
||||
else
|
||||
mkfs.ext4 -F -q -b 4096 "${USB_ROOT}" > /dev/null
|
||||
fi
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to create ROOT filesystem"
|
||||
fi
|
||||
mntdev "${USB_DEST}"
|
||||
rsync -aDH --partial --numeric-ids --delete --force --exclude "${MNTPATH}" --exclude '/dev' --exclude '/lost+found' --exclude '/media' --exclude '/mnt' \
|
||||
--exclude '/proc' --exclude '/run' --exclude '/sys' --exclude '/tmp' --exclude '/etc/udev/rules.d/70-persistent-net.rules' \
|
||||
--exclude '/var/lib/asterisk/astdb.sqlite3-journal' "${OPTIONS[@]}" / "${MNTPATH}/"
|
||||
if [[ $? -ne 0 && $? -ne 24 ]]; then
|
||||
errexit "Unable to replicate BOOT/ROOT contents from ${ROOT_DEV} to ${USB_DEST}"
|
||||
fi
|
||||
mkdir -p "${MNTPATH}/dev/" "${MNTPATH}/lost+found/" "${MNTPATH}/media/" "${MNTPATH}/mnt/" "${MNTPATH}/proc/" "${MNTPATH}/run/" "${MNTPATH}/sys/" "${MNTPATH}/tmp/"
|
||||
if [ $? -ne 0 ]; then
|
||||
errexit "Unable to create directories"
|
||||
fi
|
||||
chmod a+rwxt "${MNTPATH}/tmp/"
|
||||
umntdev
|
||||
echo ""
|
||||
echo "BOOT/ROOT contents replicated from ${ROOT_DEV} to ${USB_DEST}"
|
||||
fi
|
||||
fi
|
||||
if [ "${USESDC}" = "TRUE" ]; then
|
||||
if [ -b /dev/mmcblk0 ]; then
|
||||
while [ "$(blkid /dev/mmcblk0p2 | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" = "$(blkid ${USB_DEST}2 | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" ]
|
||||
do
|
||||
echo ""
|
||||
echo "WARNING : SD card (/dev/mmcblk0) and USB device (${USB_DEST}) have the same PARTUUID : SD card will boot instead of USB device"
|
||||
echo ""
|
||||
echo -n "Ok to change PARTUUID on USB device (${USB_DEST}) (y/n)? "
|
||||
while read -r -n 1 -s answer; do
|
||||
if [[ "${answer}" = [yYnN] ]]; then
|
||||
echo "${answer}"
|
||||
if [[ "${answer}" = [yY] ]]; then
|
||||
break
|
||||
else
|
||||
break 2
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
echo "Changing PARTUUID on USB device (${USB_DEST})"
|
||||
PTTYPE="$(blkid "${USB_DEST}" | sed -n 's|^.*PTTYPE="\(\S\+\)".*|\1|p')"
|
||||
if [ "${PTTYPE}" = "dos" ]; then
|
||||
PTUUID="$(hexdump -n 4 -e '"%08X"' /dev/random | tr [A-Z] [a-z])"
|
||||
fdisk "${USB_DEST}" <<EOF &> /dev/null
|
||||
x
|
||||
i
|
||||
0x${PTUUID}
|
||||
r
|
||||
w
|
||||
EOF
|
||||
else
|
||||
sgdisk -u 2:'R' "${USB_DEST}" &> /dev/null
|
||||
fi
|
||||
done
|
||||
else
|
||||
errexit "No SD card present"
|
||||
fi
|
||||
fi
|
||||
if [ "${PTTYPE}" = "gpt" ]; then
|
||||
gdisk "${USB_DEST}" <<EOF > /dev/null
|
||||
r
|
||||
h
|
||||
1
|
||||
n
|
||||
0c
|
||||
n
|
||||
n
|
||||
w
|
||||
y
|
||||
EOF
|
||||
fi
|
||||
partprobe &> /dev/null
|
||||
PARTUUID_1="$(blkid "${USB_BOOT}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
PARTUUID_2="$(blkid "${USB_ROOT}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
if [ "${USESDC}" = "TRUE" ]; then
|
||||
if [ -b /dev/mmcblk0 ]; then
|
||||
mntdev "/dev/mmcblk0p"
|
||||
sed -i "/^[[:space:]]*#/!s|^\(.*root=\)\S\+\(\s\+.*\)$|\1PARTUUID=${PARTUUID_2}\2|" "${MNTPATH}/boot/cmdline.txt"
|
||||
umntdev
|
||||
else
|
||||
errexit "No SD card present"
|
||||
fi
|
||||
fi
|
||||
mntdev "${USB_DEST}"
|
||||
sed -i "/^[[:space:]]*#/!s|^\(.*root=\)\S\+\(\s\+.*\)$|\1PARTUUID=${PARTUUID_2}\2|" "${MNTPATH}/boot/cmdline.txt"
|
||||
sed -i "/^[[:space:]]*#/!s|^\S\+\(\s\+/\s\+.*\)$|PARTUUID=${PARTUUID_2}\1|" "${MNTPATH}/etc/fstab"
|
||||
if [ "${USESDC}" = "TRUE" ]; then
|
||||
sed -i "/^[[:space:]]*#/!s|^\S\+\(\s\+/boot\s\+.*\)$|/dev/mmcblk0p1\1|" "${MNTPATH}/etc/fstab"
|
||||
if [ $(grep -v '^[[:space:]]*#' "${MNTPATH}/etc/rc.local" | grep -c 'usb-boot-init') -eq 0 ]; then
|
||||
cat <<\EOF1 > "${MNTPATH}/etc/usb-boot-init"
|
||||
#!/bin/bash
|
||||
|
||||
MNTBOOT="/tmp/usb-boot-init-mnt"
|
||||
|
||||
REBOOT=FALSE
|
||||
ROOT_PART="$(mount | sed -n 's|^\(/dev/.*\) on / .*|\1|p')"
|
||||
ROOT_DEV="$(sed 's/[0-9]\+$//' <<< "${ROOT_PART}")"
|
||||
if [ "${ROOT_DEV}" = "/dev/mmcblk0p" ]; then
|
||||
ROOT_DEV="${ROOT_DEV:0:(${#ROOT_DEV} - 1)}"
|
||||
fi
|
||||
mkdir -p "${MNTBOOT}/"
|
||||
mount "${ROOT_DEV}1" "${MNTBOOT}/"
|
||||
if [ "$(find "${MNTBOOT}/" -type f -iregex "${MNTBOOT}/ssh\(\.txt\)?" -print -delete)" != "" ]; then
|
||||
update-rc.d ssh enable && invoke-rc.d ssh start
|
||||
fi
|
||||
if [ -f "${MNTBOOT}/wpa_supplicant.conf" ]; then
|
||||
mv "${MNTBOOT}/wpa_supplicant.conf" /etc/wpa_supplicant/wpa_supplicant.conf
|
||||
REBOOT=TRUE
|
||||
fi
|
||||
if [[ $(grep -v '^[[:space:]]*#' "${MNTBOOT}/cmdline.txt" | grep -c 'init=/usr/lib/raspi-config/init_resize.sh') -ne 0 ]]; then
|
||||
sed -i '/^[[:space:]]*#/!s| init=/usr/lib/raspi-config/init_resize\.sh||' "${MNTBOOT}/cmdline.txt"
|
||||
START2=$(sfdisk -d "${ROOT_DEV}" | sed -n "s|^${ROOT_PART}\s\+:.*start=\s*\([0-9]\+\).*$|\1|p")
|
||||
PTTYPE="$(blkid "${ROOT_DEV}" | sed -n 's|^.*PTTYPE="\(\S\+\)".*|\1|p')"
|
||||
if [ "${PTTYPE}" = "dos" ]; then
|
||||
sfdisk --delete "${ROOT_DEV}" 2 > /dev/null
|
||||
echo "${START2},+" | sfdisk --no-reread --no-tell-kernel -N2 "${ROOT_DEV}" &> /dev/null
|
||||
else
|
||||
PARTUUID="$(blkid "${ROOT_PART}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
sgdisk -d 2 "${ROOT_DEV}" > /dev/null
|
||||
sgdisk -n 2:${START2}:0 "${ROOT_DEV}" > /dev/null
|
||||
sgdisk -u 2:${PARTUUID} "${ROOT_DEV}" > /dev/null
|
||||
fi
|
||||
cat <<\EOF2 > /etc/init.d/resize_root_fs
|
||||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: resize_root_fs
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Default-Start: 3
|
||||
# Default-Stop:
|
||||
# Short-Description: Resize root filesystem
|
||||
# Description:
|
||||
### END INIT INFO
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
resize2fs "$(mount | sed -n 's|^\(/dev/.*\) on / .*|\1|p')"
|
||||
update-rc.d resize_root_fs remove
|
||||
rm /etc/init.d/resize_root_fs
|
||||
;;
|
||||
*)
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
EOF2
|
||||
chmod +x /etc/init.d/resize_root_fs
|
||||
update-rc.d resize_root_fs defaults
|
||||
REBOOT=TRUE
|
||||
fi
|
||||
umount "${MNTBOOT}/"
|
||||
rm -r "${MNTBOOT}/"
|
||||
sed -i '/usb-boot-init/d' /etc/rc.local
|
||||
rm /etc/usb-boot-init
|
||||
if [ "${REBOOT}" = "TRUE" ]; then
|
||||
shutdown --no-wall -r now
|
||||
fi
|
||||
EOF1
|
||||
chmod +x "${MNTPATH}/etc/usb-boot-init"
|
||||
sed -i 's|^exit 0$|/etc/usb-boot-init\nexit 0|' "${MNTPATH}/etc/rc.local"
|
||||
fi
|
||||
else
|
||||
sed -i "/^[[:space:]]*#/!s|^\S\+\(\s\+/boot\s\+.*\)$|PARTUUID=${PARTUUID_1}\1|" "${MNTPATH}/etc/fstab"
|
||||
fi
|
||||
umntdev
|
||||
DEV_LIST=()
|
||||
if [ -b /dev/mmcblk0 ]; then
|
||||
DEV_LIST+=/dev/mmcblk0p2
|
||||
fi
|
||||
DEV_LIST+=($(ls -l /dev/sd?2 2> /dev/null | sed -n 's|^.*\(/dev/.*\)|\1|p'))
|
||||
if [ ${#DEV_LIST[@]} -gt 1 ]; then
|
||||
for i in ${!DEV_LIST[@]}; do
|
||||
if [ ${i} -lt $((${#DEV_LIST[@]} - 1)) ]; then
|
||||
j=$((i + 1))
|
||||
while [ ${j} -lt ${#DEV_LIST[@]} ]; do
|
||||
if [ "$(blkid "${DEV_LIST[i]}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" = "$(blkid "${DEV_LIST[j]}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')" ]; then
|
||||
if [[ "${DEV_LIST[i]}" != "/dev/mmcblk0p2" || "${DEV_LIST[j]}" != "${USB_DEST}2" ]]; then
|
||||
echo ""
|
||||
echo "WARNING : ${DEV_LIST[i]} and ${DEV_LIST[j]} have the same PARTUUID : $(blkid "${DEV_LIST[i]}" | sed -n 's|^.*PARTUUID="\(\S\+\)".*|\1|p')"
|
||||
fi
|
||||
fi
|
||||
((j += 1))
|
||||
done
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ "${USESDC}" = "TRUE" ]; then
|
||||
echo ""
|
||||
echo "SD card must remain in place to boot the USB device"
|
||||
else
|
||||
if [ -b /dev/mmcblk0 ]; then
|
||||
echo ""
|
||||
echo "SD card must be removed to boot the USB device"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
89
utilities/usb-boot/usb-boot.txt
Normal file
89
utilities/usb-boot/usb-boot.txt
Normal file
@ -0,0 +1,89 @@
|
||||
Running Raspbian on USB Devices : Made Easy
|
||||
|
||||
A recurring topic of discussion is how to configure and reliably run Raspbian on a USB flash drive, USB hard drive, or USB SSD instead of an SD card.
|
||||
|
||||
A Raspberry Pi 3B+ has a native USB boot mode (this mode has to be manually enabled by setting an OTP bit on a Raspberry Pi 3B). This native USB boot mode has serious compatibility issues. A bootcode.bin file is available for older Raspberry Pi models. Unfortunately, both of these approaches have serious limitations and once working, can easily be broken by simply plugging in an additional USB storage device.
|
||||
|
||||
The easiest and most reliable way to run Raspbian on a USB device with any Raspberry Pi is to leave an SD card containing Raspbian in place, but use it only for starting Raspbian that is residing on a USB device. While setting up such a configuration is not rocket science, it can be confusing to a newcomer or someone unfamiliar with Linux internals. In an effort to simplify the task, I've created the attached script named 'usb-boot' to automate the process.
|
||||
|
||||
If usb-boot is running on a Raspberry Pi 4, usb-boot first prompts: 'Use SD card to boot the USB device?'
|
||||
|
||||
If 'No' is selected, the SD card will not be altered and the direct USB boot capability of the Raspberry Pi 4 will be used.
|
||||
|
||||
[NOTE: The direct USB boot capability of the Raspberry Pi 4 requires an updated bootloader and firmware: https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711_bootloader_config.md]
|
||||
|
||||
If usb-boot is running on a Raspberry Pi 3B+ or a Raspberry Pi 3B with its OTP bit set, usb-boot first prompts: 'Use SD card to boot the USB device (recommended)?'
|
||||
|
||||
If 'No' is selected, the SD card will not be altered, but booting the USB device may be limited and/or unreliable as described above.
|
||||
|
||||
usb-boot then presents a list of available USB mass storage devices and prompts: 'Select the USB mass storage device to boot'
|
||||
|
||||
Use the arrow keys on your keyboard to navigate to the desired device and press the spacebar to select it. Then use the tab key to navigate to the 'Ok' or 'Cancel' button and press the return key.
|
||||
|
||||
usb-boot will then prompt: 'Replicate BOOT/ROOT contents from /dev/mmcblk0 to /dev/sdX?'
|
||||
|
||||
/dev/mmcblk0 is the SD card and /dev/sdX is the USB device.
|
||||
|
||||
Select 'No' if the USB device already has Raspbian on it and you wish to use it (nothing will be copied).
|
||||
|
||||
Select 'Yes' if you want to copy the Raspbian on your SD card to the USB device (everything will be copied).
|
||||
|
||||
If you select 'Yes', usb-boot will then prompt: 'Select the partition table type to use (MBR = 2TB Maximum)'
|
||||
|
||||
usb-boot will then prompt: 'All existing data on USB device /dev/sdX will be destroyed!' and ask: 'Do you wish to continue?'
|
||||
|
||||
If you select 'Yes', the copy will begin. The time required for this process will depend on the amount of data on your SD card and the speed of your storage devices.
|
||||
|
||||
usb-boot will then complete the configuration process and warn you of any potential conflicts it detects.
|
||||
|
||||
When usb-boot has finished, you should be able to reboot and be running Raspbian on the USB device (first power off and remove the SD card if not using the SD card to boot the USB device).
|
||||
|
||||
=====
|
||||
|
||||
sdc-boot provides a convenient way to select which attached device will be booted.
|
||||
|
||||
Usage syntax is:
|
||||
|
||||
sdc-boot [ /dev/sdX2 | /dev/mmcblk0p2 | hhhhhhhh-02 | hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh ]
|
||||
|
||||
/dev/sdX2 is a USB device
|
||||
|
||||
/dev/mmcblk0p2 is the SD card
|
||||
|
||||
hhhhhhhh-02 | hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh is a device identified by its PARTUUID
|
||||
|
||||
If no device is specified, the currently selected boot device will be displayed.
|
||||
|
||||
=====
|
||||
|
||||
GPT partition tables are necessary for devices whose size is over 2TB.
|
||||
|
||||
mbr2gpt converts an MBR partition table on a USB device to a GPT partition table, as well as optionally expanding the ROOT partition and enabling booting via an SD card.
|
||||
mbr2gpt converts any size USB device, including SD cards placed in a USB adapter.
|
||||
|
||||
!!! DO NOT PROCEED UNLESS YOU HAVE A RELIABLE BACKUP OF THE DEVICE BEING CONVERTED !!!
|
||||
!!! INITIAL TESTING SHOULD BE PERFORMED ON A USB DEVICE CONTAINING EXPENDABLE DATA !!!
|
||||
|
||||
Usage syntax is:
|
||||
|
||||
mbr2gpt /dev/sdX
|
||||
|
||||
mbr2gpt will prompt for permission to perform the following optional functions:
|
||||
|
||||
1. Convert the USB device to use GPT partition tables
|
||||
|
||||
2. Expand the ROOT partition to use all available space
|
||||
|
||||
3. Set the SD card to boot the USB device
|
||||
|
||||
=====
|
||||
|
||||
set-partuuid displays or changes the ROOT partition PARTUUID on a device.
|
||||
|
||||
Usage syntax is:
|
||||
|
||||
set-partuuid device [ hhhhhhhh-02 | hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh | random ]
|
||||
|
||||
device may be /dev/sdX2 or /dev/mmcblk0p2
|
||||
|
||||
If no partuuid is specified, the current ROOT partition PARTUUID will be displayed.
|
Reference in New Issue
Block a user