1863 lines
58 KiB
Bash
1863 lines
58 KiB
Bash
#!/usr/bin/env zsh
|
|
# shellcheck shell=bash
|
|
# Copyright (c) 2016-2021 Ivan J. <parazyd@dyne.org>
|
|
# This file is part of libdevuansdk
|
|
#
|
|
# This source code is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This software is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this source code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
build_metal_dist() {
|
|
fn build_metal_dist
|
|
req=(arch)
|
|
req+=(workdir strapdir disk_name)
|
|
ckreq || return 1
|
|
|
|
notice "installing complete dist"
|
|
act "add release symlink to debootstrap scripts."
|
|
if [[ ! -f /usr/share/debootstrap/scripts/${release} ]]; then
|
|
ln -sf /usr/share/debootstrap/scripts/ceres \
|
|
/usr/share/debootstrap/scripts/${release}
|
|
fi
|
|
|
|
image_partition_disk_zfs || { zerr; wrapup }
|
|
image_format_partitions_zfs || { zerr; wrapup }
|
|
bootstrap_complete_base-wrapper || { zerr; wrapup }
|
|
blend_preinst || { zerr; wrapup }
|
|
blend_postinst || { zerr; wrapup }
|
|
}
|
|
|
|
build_image_dist() {
|
|
fn build_image_dist
|
|
req=(arch size parted_type)
|
|
case "$parted_type" in
|
|
gpt) req+=(gpt_boot gpt_root) ;;
|
|
dos) req+=(parted_boot parted_root) ;;
|
|
*) die "Unknown parted_type: $parted_type. Supported is gpt|dos."
|
|
zerr; return 1
|
|
;;
|
|
esac
|
|
req+=(workdir strapdir image_name)
|
|
ckreq || return 1
|
|
|
|
notice "building complete dist image"
|
|
act "$image_name"
|
|
|
|
bootstrap_complete_base || { zerr; wrapup }
|
|
blend_preinst || { zerr; wrapup }
|
|
image_prepare_raw || { zerr; wrapup }
|
|
image_partition_raw_${parted_type} || { zerr; wrapup }
|
|
build_kernel_${arch} || { zerr; wrapup }
|
|
blend_postinst || { zerr; wrapup }
|
|
rsync_to_raw_image || { zerr; wrapup }
|
|
image_pack_dist || { zerr; wrapup }
|
|
}
|
|
|
|
build_arm_dist()
|
|
{
|
|
fn build_arm_dist
|
|
req=(workdir strapdir os arch size parted_type)
|
|
case "$parted_type" in
|
|
gpt) req+=(gpt_boot gpt_root) ;;
|
|
dos) req+=(parted_boot parted_root) ;;
|
|
*) die "Unknown parted_type: $parted_type. Supported is gpt|dos."
|
|
zerr; return 1
|
|
;;
|
|
esac
|
|
ckreq || return 1
|
|
|
|
notice "Building complete Arm image(s)"
|
|
|
|
bootstrap_complete_base-wrapper || { zerr; return 1; }
|
|
blend_preinst || { zerr; return 1; }
|
|
image_prepare_raw || { zerr; return 1; }
|
|
image_connect_raw || { zerr; return 1; }
|
|
image_partition_raw_${parted_type} || { zerr; return 1; }
|
|
image_format_partitions || { zerr; return 1; }
|
|
build_kernel_${arch} || { zerr; return 1; }
|
|
image_mount || { zerr; return 1; }
|
|
strapdir_to_image || { zerr; return 1; }
|
|
blend_postinst || { zerr; return 1; }
|
|
image_umount || { zerr; return 1; }
|
|
image_disconnect_raw || { zerr; return 1; }
|
|
image_pack_dist || { zerr; return 1; }
|
|
clean_strapdir || { zerr; return 1; }
|
|
}
|
|
|
|
|
|
copy-root-overlay() {
|
|
fn copy-root-overlay "(override)"
|
|
req=(strapdir device_name bootpart_partuuid R)
|
|
ckreq || return 1
|
|
|
|
[[ -d $R/extra/generic-root ]] &&
|
|
notice "copying generic-root" && \
|
|
sudo cp -rfv $R/extra/generic-root/* $strapdir
|
|
|
|
sudo sed -e "s/{{{BOOTFS}}}/$bootfs/" -i "$strapdir/etc/fstab"
|
|
sudo sed -e "s/\/dev\/mmcblk0p1/PARTUUID=$bootpart_partuuid/" -i "$strapdir/etc/fstab"
|
|
|
|
[[ -d $R/extra/$device_name ]] && \
|
|
notice "copying ${device_name}-root" && \
|
|
sudo cp -rfv $R/extra/$device_name/* $strapdir
|
|
|
|
return 0
|
|
}
|
|
|
|
# Overide the post 'debootstrap stage 2' placeholder function of zlib/debootstrap
|
|
# bootstrap_complete_base.
|
|
# The default is just to return 0
|
|
blend_bootstrap_setup() {
|
|
fn blend_bootstrap_setup "noop"
|
|
return 0
|
|
}
|
|
|
|
|
|
# the local bootstrap wrapper just adds an options variable
|
|
# via an alias to the debootstrap command
|
|
bootstrap_complete_base-wrapper() {
|
|
mkdir -p "$debootstrap_cache"
|
|
alias debootstrap='debootstrap \
|
|
--cache-dir="$debootstrap_cache" \
|
|
--exclude="$debootstrap_purge_packages" \
|
|
${debootstrap_options}'
|
|
bootstrap_complete_base
|
|
}
|
|
|
|
image_partition_raw_gpt() {
|
|
fn image_partition_raw_gpt
|
|
req=(workdir image_name gpt_boot gpt_root bootpart_partuuid rootpart_partuuid)
|
|
ckreq || return 1
|
|
|
|
notice "partitioning raw gpt image..."
|
|
notice "workdir: $workdir"
|
|
notice "image_name: $image_name"
|
|
notice "gpt_boot: $gpt_boot"
|
|
notice "gpt_root: $gpt_root"
|
|
|
|
parted $workdir/${image_name}.img --script -- mklabel gpt || zerr
|
|
cgpt repair $workdir/${image_name}.img
|
|
cgpt create -z $workdir/${image_name}.img || zerr
|
|
cgpt create $workdir/${image_name}.img || zerr
|
|
|
|
notice 'cgpt add -i 1 -t kernel -b ${gpt_boot[1]} \
|
|
-s ${gpt_boot[2]} \
|
|
-l kernel -S 1 -T 5 -P 10 $workdir/${image_name}.img'
|
|
|
|
notice "cgpt add -i 1 -t kernel -b ${gpt_boot[1]} \
|
|
-s ${gpt_boot[2]} \
|
|
-l kernel -S 1 -T 5 -P 10 $workdir/${image_name}.img"
|
|
|
|
cgpt add -i 1 -t kernel -b ${gpt_boot[1]} \
|
|
-s ${gpt_boot[2]} \
|
|
-l kernel -S 1 -T 5 -P 10 $workdir/${image_name}.img
|
|
|
|
notice 'cgpt add -i 2 -t data -b ${gpt_root[1]} \
|
|
-s $(expr $(cgpt show $workdir/${image_name}.img | \
|
|
awk "/Sec GPT table/ {print $1}") - ${gpt_root[1]}) \
|
|
-l Root $workdir/${image_name}.img'
|
|
|
|
notice "cgpt add -i 2 -t data -b ${gpt_root[1]} \
|
|
-s $(expr $(cgpt show $workdir/${image_name}.img | \
|
|
awk '/Sec GPT table/ {print $1}') - ${gpt_root[1]}) \
|
|
-l Root $workdir/${image_name}.img"
|
|
|
|
cgpt add -i 2 -t data -b ${gpt_root[1]} \
|
|
-s $(expr $(cgpt show $workdir/${image_name}.img | \
|
|
awk '/Sec GPT table/ {print $1}') - ${gpt_root[1]}) \
|
|
-l Root $workdir/${image_name}.img
|
|
|
|
findloopdev
|
|
|
|
bootpart="${loopdevice}p1"
|
|
rootpart="${loopdevice}p2"
|
|
bootpart_partuuid=$(blkid -s PARTUUID -o value ${bootpart})
|
|
rootpart_partuuid=$(blkid -s PARTUUID -o value ${rootpart})
|
|
|
|
image_format_partitions
|
|
}
|
|
|
|
## Override the helper function:
|
|
# takes the 'apt-get -f' out of the loop so that dependency provided by other
|
|
# debs can be resolved.
|
|
# inside the loop it just uninstalls the deb because of unfullfilled deps.
|
|
install-custdebs() {
|
|
fn install-custdebs "(override)"
|
|
req=(R strapdir custom_deb_packages)
|
|
ckreq || return 1
|
|
|
|
sudo mkdir -p ${strapdir}/debs
|
|
sudo cp $R/extra/custom-packages/*.deb ${strapdir}/debs/
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/install-debs >/dev/null
|
|
#!/bin/sh
|
|
cd /debs
|
|
for deb in ${custom_deb_packages}; do
|
|
dpkg -i \$deb
|
|
done
|
|
apt-get --yes --force-yes -f install
|
|
cd /
|
|
apt-get --yes --force-yes autoremove
|
|
#rm -rf /debs
|
|
EOF
|
|
chroot-script -d install-debs
|
|
}
|
|
|
|
## Added function:
|
|
# In the style of install-custdebs above but for a collection of arbitrary
|
|
# scripts placed in a # directory alongside the blend custom debs called automate.
|
|
# The scripts are copied from the blends scripts directory to extra/custom-scripts
|
|
# in blend_preinst() above.
|
|
# Called after install-customdebs because some need checkinstall which disappears
|
|
# from archives.
|
|
install-custscripts() {
|
|
fn install-custscripts
|
|
req=(R strapdir custom_scripts)
|
|
ckreq || return 1
|
|
|
|
sudo mkdir -p ${strapdir}/var/tmp/automate
|
|
sudo cp $R/extra/custom-scripts/*.sh ${strapdir}/var/tmp/automate/
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/install-scripts >/dev/null
|
|
#!/bin/sh
|
|
cd /var/tmp/automate
|
|
for script in ${custom_scripts}; do
|
|
touch \${script}.log
|
|
bash \$script
|
|
done
|
|
apt-get --yes --force-yes -f install
|
|
cd /
|
|
apt-get --yes --force-yes autoremove
|
|
#rm -rf /var/tmp/automate
|
|
EOF
|
|
chroot-script -d install-scripts
|
|
}
|
|
|
|
copy-kernel-config() {
|
|
fn copy-kernel-config "(override)"
|
|
req=(device_name gitbranch)
|
|
ckreq || return 1
|
|
|
|
notice "copying available ${gitbranch} kernel config for ${device_name}"
|
|
notice "cp -f $R/boards/kernel-configs/${device_name}.config_${gitbranch} \
|
|
$R/tmp/kernels/$device_name/${device_name}-linux_$gitbranch/.config"
|
|
cp -f $R/boards/kernel-configs/${device_name}.config_${gitbranch} \
|
|
$R/tmp/kernels/$device_name/${device_name}-linux_$gitbranch/.config
|
|
}
|
|
|
|
## Override the helper function:
|
|
# Allow an alternative skel directory, defaults to /etc/skel
|
|
add-user() {
|
|
fn add-user
|
|
req=(strapdir username userpass user_shell)
|
|
ckreq || return 1
|
|
|
|
notice "adding user $user:$pass using $skel and shell $default_shell"
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/add-user >/dev/null
|
|
#!/bin/sh
|
|
set -x
|
|
if [ $(id -u ${username} 2>&1 >/dev/null) ]; then
|
|
echo "user not present, creating account."
|
|
|
|
sudo useradd --create-home \
|
|
--shell $usershell \
|
|
--groups $usergroups \
|
|
--password $(openssl passwd -1 $userpass) \
|
|
--skel ${user_skel:-/etc/skel} \
|
|
$username
|
|
|
|
echo "${username}:${userpass}" | chpasswd
|
|
usermod -a -G ${user_groups} ${username}
|
|
|
|
if grep -q "${user_shell}" /etc/shells; then
|
|
usermod --shell "${user_shell}" "${username}"
|
|
else
|
|
echo "${user_shell} is not available, leaving unchanged."
|
|
fi
|
|
fi
|
|
EOF
|
|
chroot-script add-user || { zerr; return 0; }
|
|
}
|
|
|
|
|
|
## apt related functions
|
|
# point apt at a local apt-proxy like apt-cacher-ng
|
|
enable_apt-proxy() {
|
|
fn enable_apt-proxy
|
|
req=(strapdir apt_proxy)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/add_apt-proxy
|
|
#!/bin/sh
|
|
|
|
cat > '/etc/apt/apt.conf.d/02proxy' << 'FOE'
|
|
Acquire::http { Proxy "${apt_proxy}"; };
|
|
FOE
|
|
EOF
|
|
chroot-script add_apt-proxy || zerr
|
|
}
|
|
|
|
disable_apt-proxy() {
|
|
fn disable_apt-proxy
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/del_apt-proxy
|
|
#!/bin/sh
|
|
rm -f /etc/apt/apt.conf.d/02proxy
|
|
EOF
|
|
chroot-script del_apt-proxy || zerr
|
|
}
|
|
|
|
|
|
|
|
# When the release changes its suite (ie. from stable to oldstable) by default
|
|
# apt asks for explicite acceptance, which you might not want in your image, turn
|
|
# this on and off.
|
|
enable_apt-allow-releaseinfo-change() {
|
|
fn enable_apt-allow-releaseinfo-change
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/add_apt-releaseinfo-change
|
|
#!/bin/sh
|
|
|
|
cat > '/etc/apt/apt.conf.d/10no-check-valid-until' << 'FOE'
|
|
Acquire::AllowReleaseInfoChange::Suite "true";
|
|
FOE
|
|
EOF
|
|
chroot-script add_apt-releaseinfo-change || zerr
|
|
}
|
|
|
|
disable_apt-allow-releaseinfo-change() {
|
|
fn disable_apt-allow-releaseinfo-change
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/del_apt-allow-releaseinfo-change
|
|
#!/bin/sh
|
|
#
|
|
rm -f /etc/apt/apt.conf.d/10no-check-valid-until
|
|
EOF
|
|
chroot-script del_apt-allow-releaseinfo-change || zerr
|
|
}
|
|
|
|
# apt checks the valid-util and refuses to install from repositories that are too
|
|
# old, which you might not want if building an old release, turn this on or off.
|
|
disable_apt-valid-until() {
|
|
fn disable_apt-valid-until
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/add_apt-check-valid
|
|
#!/bin/sh
|
|
|
|
cat > '/etc/apt/apt.conf.d/10no-check-valid-until' << 'FOE'
|
|
Acquire::Check-Valid-Until "false";
|
|
FOE
|
|
EOF
|
|
chroot-script add_apt-check-valid || zerr
|
|
}
|
|
|
|
enable_apt-valid-until() {
|
|
fn enable_apt-valid-until
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/del_apt-check-valid
|
|
#!/bin/sh
|
|
rm -f /etc/apt/apt.conf.d/10no-check-valid-until
|
|
EOF
|
|
chroot-script del_apt-check-valid || zerr
|
|
}
|
|
|
|
# Overide the sdk version of this function to prevent deletion prior to unpacking
|
|
# the cpio as we have mountpoints in place when installing to hardrive.
|
|
bootstrap_cpio_unpack()
|
|
{
|
|
fn bootstrap_cpio_unpack "$*"
|
|
req=(_bootstrap_cpio strapdir)
|
|
local _bootstrap_cpio="$1"
|
|
ckreq || return 1
|
|
|
|
notice "Unpacking bootstrap cpio archive: $_bootstrap_cpio"
|
|
|
|
#sudo rm -rf "${strapdir}"/*
|
|
|
|
pushd "$strapdir" || { zerr; return 1; }
|
|
zcat "$_bootstrap_cpio" | sudo cpio -idmn --format=newc || { zerr; return 1; }
|
|
popd
|
|
|
|
sudo mkdir -p "$strapdir"/{boot,dev,proc,sys}
|
|
}
|
|
|
|
image_partition_disk_zfs() {
|
|
fn image_partition_disk_zfs
|
|
req=(strapdir disk_name efi_start efi_part_size swap_part_size boot_part_size available_disks)
|
|
ckreq || return 1
|
|
|
|
notice "partitioning disks"
|
|
|
|
# See: https://didrocks.fr/2020/06/11/zfs-focus-on-ubuntu-20.04-lts-zsys-partition-layout/
|
|
for disk in "${available_disks[@]}"; do
|
|
local TARGET="/dev/disk/by-id/${disk}"
|
|
|
|
act "partitioning ${TARGET}"
|
|
/sbin/sgdisk --zap-all ${TARGET}
|
|
|
|
act "Partition 1 - Create partition using start and end values for partitioning the 'Bios boot' partition."
|
|
FIRST_USABLE_SECTOR=34
|
|
((ENDSECTOR = ${efi_start} - 1))
|
|
/sbin/sgdisk --print --set-alignment=1 --new=1:${FIRST_USABLE_SECTOR}:${ENDSECTOR} ${TARGET}
|
|
/sbin/sgdisk --print --change-name=1:"BIOS_Boot_Partition" --typecode=1:EF02 ${TARGET}
|
|
|
|
act "Partition 2 - Create partition using start and end values for partitioning the 'EFI' partition."
|
|
STARTSECTOR=${efi_start}
|
|
/sbin/sgdisk --print --set-alignment=${STARTSECTOR} --mbrtogpt --new=2:${STARTSECTOR}:+${efi_part_size} ${TARGET}
|
|
/sbin/sgdisk --print --change-name=2:"EFI_System_Partition" --typecode=2:EF00 ${TARGET}
|
|
|
|
act "Partition 3 - Create partition using start and end values for partitioning the 'swap' partition."
|
|
STARTSECTOR=`/sbin/sgdisk --first-in-largest ${TARGET}|sed -sn 2p`
|
|
/sbin/sgdisk --print --new=3:${STARTSECTOR}:+${swap_part_size} ${TARGET}
|
|
/sbin/sgdisk --print --change-name=3:"Linux_swap" --typecode=3:8200 ${TARGET}
|
|
|
|
act "Partition 4 - upto 2GB partition for boot."
|
|
STARTSECTOR=`/sbin/sgdisk --first-in-largest ${TARGET}|sed -sn 2p`
|
|
/sbin/sgdisk --print --new=4:${STARTSECTOR}:+${boot_part_size} ${TARGET}
|
|
/sbin/sgdisk --print --change-name=4:boot --typecode=4:BE00 ${TARGET}
|
|
|
|
act "Partition 5 - the main partition for root."
|
|
/sbin/sgdisk --print --largest-new=5 ${TARGET}
|
|
/sbin/sgdisk --print --change-name=5:root --typecode=5:BF00 ${TARGET}
|
|
|
|
act "Reread the current partition tables with partprobe."
|
|
# the second drive fails to update the kernel until reboot so added 2>
|
|
partprobe ${TARGET} 2>/dev/null || true
|
|
#partx --update ${TARGET}
|
|
#kpartx -a ${TARGET}
|
|
#hdparm -z ${TARGET}
|
|
#blockdev --rereadept ${TARGET}
|
|
#udevadm trigger --subsystem-match=block; udevadm settle --exit-if-exists=/dev/${TARGET}-part5
|
|
#echo 1 > /sys/block/sdX/device/rescan
|
|
done
|
|
}
|
|
|
|
image_format_partitions_zfs() {
|
|
fn image_format_partitions_zfs
|
|
req=(disk_name available_disks efi_partitions swap_partitions root_part_number boot_part_number rpool_name bpool_name zpool_cache_dir strapdir)
|
|
ckreq || return 1
|
|
|
|
act "format available efi partitions to vfat."
|
|
for efi_partition in "${efi_partitions[@]}"; do
|
|
act "format the efi partition to vfat."
|
|
mkfs.fat -F32 ${efi_partition}
|
|
done
|
|
|
|
act "mkswap on available swap partitions."
|
|
for swap_partition in "${swap_partitions[@]}"; do
|
|
notice "making swap on ${swap_partition}"
|
|
mkswap ${swap_partition}
|
|
done
|
|
|
|
notice "formatting zfs partitions..."
|
|
|
|
# for disk in "${available_disks[@]}"; do
|
|
# gdisk -l /dev/disk/by-id/${disk}
|
|
# done
|
|
|
|
act "udev is slow recognizing new partitions so trigger sleep for 10 seconds"
|
|
sleep 10
|
|
|
|
|
|
# create a separate boot pool for /boot with the features limited to only
|
|
# those that GRUB supports allowing the root pool to use any/all features.
|
|
|
|
if [[ ${raid} == "mirror" ]]; then
|
|
mirror_disk=${available_disks[2]};
|
|
fi
|
|
|
|
act "create the zfs boot pool"
|
|
#zpool create -f -m none \
|
|
zpool create -f \
|
|
-o cachefile=${zpool_cache_dir}/zpool.cache \
|
|
-o ashift=${ashift} -d \
|
|
-o feature@async_destroy=enabled \
|
|
-o feature@bookmarks=enabled \
|
|
-o feature@embedded_data=enabled \
|
|
-o feature@empty_bpobj=enabled \
|
|
-o feature@enabled_txg=enabled \
|
|
-o feature@extensible_dataset=enabled \
|
|
-o feature@filesystem_limits=enabled \
|
|
-o feature@hole_birth=enabled \
|
|
-o feature@large_blocks=enabled \
|
|
-o feature@lz4_compress=enabled \
|
|
-o feature@spacemap_histogram=enabled \
|
|
-o feature@zpool_checkpoint=enabled \
|
|
-O acltype=posixacl \
|
|
-O canmount=off \
|
|
-O compression=lz4 \
|
|
-O devices=off \
|
|
-O normalization=formD \
|
|
-O relatime=on \
|
|
-O xattr=sa \
|
|
-O mountpoint=legacy -o altroot=${strapdir} \
|
|
${bpool_name} ${raid} /dev/disk/by-id/${disk_name}-part${boot_part_number} /dev/disk/by-id/${mirror_disk}-part${boot_part_number}
|
|
|
|
|
|
act "create the zfs root pool"
|
|
|
|
zpool create -f \
|
|
-o cachefile=${zpool_cache_dir}/zpool.cache \
|
|
-o ashift=${ashift} \
|
|
-O acltype=posixacl \
|
|
-O canmount=off \
|
|
-O compression=lz4 \
|
|
-O dnodesize=auto \
|
|
-O normalization=formD \
|
|
-O relatime=on \
|
|
-O xattr=sa \
|
|
-O mountpoint=/ -o altroot=${strapdir} \
|
|
${rpool_name} ${raid} /dev/disk/by-id/${disk_name}-part${root_part_number} /dev/disk/by-id/${mirror_disk}-part${root_part_number}
|
|
|
|
|
|
## Physical swap used instead.
|
|
# act "create the zfs zvol for swap"
|
|
# zfs create -V ${swap_part_size} -b $(getconf PAGESIZE) \
|
|
# -o compression=zle \
|
|
# -o logbias=throughput \
|
|
# -o sync=always \
|
|
# -o primarycache=metadata \
|
|
# -o secondarycache=none \
|
|
# -o com.sun:auto-snapshot=false \
|
|
# ${rpool_name}/swap
|
|
# mkswap -f -L "Linux swap" /dev/zvol/${rpool_name}/swap
|
|
|
|
notice "zfs system installation"
|
|
act "create filesystem datasets to act as containers"
|
|
zfs create -o canmount=off -o mountpoint=none ${rpool_name}/ROOT
|
|
zfs create -o canmount=off -o mountpoint=none ${bpool_name}/BOOT
|
|
|
|
act "create filesystem datasets for the root and boot filesystems"
|
|
# Create the initial boot environment and mount ${rpool_name} at /${rpool_name}
|
|
zfs create -o canmount=noauto -o mountpoint=/ ${rpool_name}/ROOT/${root_name}
|
|
zfs mount ${rpool_name}/ROOT/${root_name}
|
|
|
|
#zfs create -o canmount=noauto -o mountpoint=/boot ${bpool_name}/BOOT/${root_name}
|
|
zfs create -o mountpoint=/boot ${bpool_name}/BOOT/${root_name}
|
|
|
|
## At this point rpool directory is created in the workdir
|
|
# zfs set mountpoint=/${rpool_name} ${rpool_name}
|
|
|
|
TMP_EXEC_STATE=on
|
|
VAR_TMP_EXEC_STATE=on
|
|
|
|
notice "create datasets"
|
|
act "create zfs datasets for $rpool_name"
|
|
zfs create -o mountpoint=/home ${rpool_name}/home
|
|
zfs create -o mountpoint=/root ${rpool_name}/home/root
|
|
zfs create -o mountpoint=/space ${rpool_name}/space
|
|
zfs create -o mountpoint=/opt ${rpool_name}/opt
|
|
zfs create -o mountpoint=/srv ${rpool_name}/srv
|
|
|
|
zfs create -o mountpoint=/usr \
|
|
-o canmount=off \
|
|
${rpool_name}/usr
|
|
|
|
zfs create -o mountpoint=/usr/share ${rpool_name}/usr/share
|
|
zfs create -o mountpoint=/usr/local ${rpool_name}/usr/local
|
|
|
|
zfs create -o mountpoint=/tmp \
|
|
-o setuid=off \
|
|
-o exec=${TMP_EXEC_STATE} \
|
|
-o com.sun:autosnapshot=false \
|
|
${rpool_name}/tmp
|
|
|
|
zfs create -o mountpoint=/var \
|
|
-o canmount=off \
|
|
${rpool_name}/var
|
|
|
|
zfs create -o mountpoint=/var/lib ${rpool_name}/var/lib
|
|
|
|
zfs create -o mountpoint=/var/lib/virt ${rpool_name}/var/lib/virt
|
|
|
|
zfs create -o mountpoint=/var/tmp \
|
|
-o setuid=off \
|
|
-o com.sun:auto-snapshot=false \
|
|
-o exec=${VAR_TMP_EXEC_STATE} \
|
|
${rpool_name}/var/tmp
|
|
|
|
zfs create -o mountpoint=/var/cache \
|
|
-o com.sun:auto-snapshot=false \
|
|
${rpool_name}/var/cache
|
|
|
|
zfs create \
|
|
-o mountpoint=/var/lib/docker \
|
|
-o com.sun:autosnapshot=false \
|
|
${rpool_name}/docker
|
|
|
|
zfs create -o mountpoint=/var/log ${rpool_name}/var/log
|
|
zfs create -o mountpoint=/var/snap ${rpool_name}/var/snap
|
|
zfs create -o mountpoint=/var/spool ${rpool_name}/var/spool
|
|
zfs create -o mountpoint=/var/www ${rpool_name}/var/www
|
|
|
|
|
|
zfs list -t all -o name,type,mountpoint,compress,exec,setuid,atime,relatime
|
|
|
|
chmod 700 ${strapdir}/root
|
|
chmod 1777 ${strapdir}/tmp
|
|
#chmod 1777 ${strapdir}/var/tmp
|
|
|
|
act "mount the efi partition on ${grub_mount} before debootstrap."
|
|
mkdir -p ${strapdir}${grub_mount}
|
|
mount /dev/disk/by-id/${disk_name}-part${efi_part_number} -t vfat ${strapdir}${grub_mount}
|
|
|
|
act "create zpool cache file"
|
|
mkdir -p ${strapdir}/etc/zfs
|
|
cp ${zpool_cache_dir}/zpool.cache ${strapdir}/etc/zfs/
|
|
}
|
|
|
|
use_swap_partition() {
|
|
fn use_swap_partition
|
|
req=(swap_partitions)
|
|
ckreq || return 1
|
|
|
|
for swap_partition in "${swap_partitions[@]}"; do
|
|
act "Using swapon on ${swap_partition}"
|
|
swapon ${swap_partition}
|
|
done
|
|
}
|
|
|
|
image_zfs_mount() {
|
|
fn image_zfs_mount
|
|
req=(strapdir disk_name rpool_name bpool_name grub_mount)
|
|
ckreq || return 1
|
|
|
|
notice "image_zfs_mount"
|
|
|
|
act "importing zfs pools without mounting the filesystem"
|
|
zpool import -N -R ${strapdir} ${rpool_name}
|
|
zpool import -N -R ${strapdir} ${bpool_name}
|
|
|
|
if [[ -n $encrypt ]]; then
|
|
act "loading encryption keys of ZFS datasets from imported pools"
|
|
zfs load-key -a
|
|
fi
|
|
|
|
act "mounting zfs datasets"
|
|
zfs mount -v ${rpool_name}/ROOT/${root_name}
|
|
zfs mount -v ${bpool_name}/BOOT/${root_name}
|
|
zfs mount -v -a
|
|
|
|
act "mount efi partition to /boot/grub"
|
|
mkdir -p ${strapdir}${grub_mount}
|
|
mount /dev/disk/by-id/${disk_name}-part${efi_part_number} -t vfat ${strapdir}${grub_mount}
|
|
|
|
act "mount system directories"
|
|
devprocsys mount ${strapdir}
|
|
}
|
|
|
|
image_zfs_umount() {
|
|
fn image_zfs_umount
|
|
req=(workdir strapdir rpool_name bpool_name)
|
|
ckreq || return 1
|
|
|
|
notice "umount system directories"
|
|
devprocsys umount ${strapdir}
|
|
|
|
act "reaping chroot processes"
|
|
PREFIX=${strapdir}
|
|
FOUND=0
|
|
|
|
reap() {
|
|
for ROOT in /proc/*/root; do
|
|
LINK=$(readlink $ROOT)
|
|
if [[ "x${LINK}" != "x" ]]; then
|
|
if [[ "x${LINK:0:${#PREFIX}}" = "x${PREFIX}" ]]; then
|
|
PID=$(basename $(dirname "$ROOT"))
|
|
act "this process is in the chroot... $PID"
|
|
kill -9 "$PID"
|
|
FOUND=1
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
reap
|
|
|
|
if [[ "x$FOUND" = "x1" ]]; then
|
|
reap
|
|
fi
|
|
|
|
act "umount efi partition"
|
|
efi_path=/dev/disk/by-id/${disk_name}-part${efi_part_number}
|
|
if [[ $(/bin/mountpoint -q -- ${efi_path}) ]]; then
|
|
umount --lazy ${efi_path}
|
|
fi
|
|
|
|
act "umount zfs partitions"
|
|
COUNT=0
|
|
|
|
while grep -q "$PREFIX" /proc/mounts; do
|
|
COUNT=$(($COUNT+1))
|
|
if [ $COUNT -ge 20 ]; then
|
|
echo "failed to umount $PREFIX"
|
|
if [ -x /usr/bin/lsof ]; then
|
|
/usr/bin/lsof "$PREFIX"
|
|
fi
|
|
exit 1
|
|
fi
|
|
grep "$PREFIX" /proc/mounts | \
|
|
cut -d\ -f2 | LANG=C sort -r | xargs -r -n 1 umount || sleep 1
|
|
done
|
|
|
|
act "export zfs pools."
|
|
zpool export ${bpool_name}
|
|
zpool export ${rpool_name}
|
|
}
|
|
|
|
get_selections() {
|
|
fn get_selections
|
|
req=(strapdir blend_release_path)
|
|
ckreq || return 1
|
|
|
|
notice "generating package list files to ${blend_release_path}"
|
|
pushd "${blend_release_path}"
|
|
dpkg --get-selections > packages.list
|
|
debconf-get-selections > debconf-settings.list
|
|
update-alternatives --get-selections > /var/tmp/alternatives-settings.list
|
|
/usr/bin/apt-mark showauto > pkgs_auto.lst
|
|
/usr/bin/apt-mark showmanual > pkgs_manual.lst
|
|
popd
|
|
}
|
|
|
|
set_selections() {
|
|
fn set_selections
|
|
req=(strapdir blend_release_path)
|
|
ckreq || return 1
|
|
pushd "${blend_release_path}"
|
|
notice "copying set selections related files to ${strapdir}/var/tmp"
|
|
if [[ -f ./packages.list ]]; then
|
|
cp ./packages.list ${strapdir}/var/tmp
|
|
else
|
|
act "no package.list found in ${blend_release_path} "
|
|
exit 0
|
|
fi
|
|
if [[ -f ./debconf-settings.list ]]; then
|
|
cp ./debconf-settings.list ${strapdir}/var/tmp
|
|
else
|
|
act "no debconf-settings.list found in ${blend_release_path} "
|
|
exit 0
|
|
fi
|
|
if [[ -f ./alternatives-settings.list ]]; then
|
|
cp ./alternatives-settings.list ${strapdir}/var/tmp
|
|
else
|
|
act "no alternatives-settings.list found in ${blend_release_path} "
|
|
exit 0
|
|
fi
|
|
if [[ -f ./pkgs_auto.lst ]]; then
|
|
cp ./pkgs_auto.lst ${strapdir}/var/tmp
|
|
else
|
|
act "no pkgs_auto.lst found in ${blend_release_path}"
|
|
fi
|
|
if [[ -f ./pkgs_auto.lst ]]; then
|
|
cp ./pkgs_manual.lst ${strapdir}/var/tmp
|
|
else
|
|
act "no pkgs_manual.lst found in ${blend_release_path}"
|
|
fi
|
|
popd
|
|
|
|
notice "upgrading using dselect"
|
|
cat <<-EOF | sudo tee "$strapdir/install-set-selections" >/dev/null
|
|
#!/bin/sh
|
|
dpkg --set-selections 2>&1 < /var/tmp/packages.list
|
|
debconfig-set-selections 2>&1 < /var/tmp/debconf-settings.list
|
|
update-alternatives --set-selections 2>&1 < /var/tmp/alternatives-settings.list
|
|
apt-get -y -u dselect-upgrade
|
|
|
|
if [[ -f /var/tmp/pkgs_auto.lst ]]; then
|
|
apt-mark auto $(cat /var/tmp/pkgs_auto.lst)
|
|
fi
|
|
if [[ -f /var/tmp/pkgs_manual.lst ]]; then
|
|
apt-mark manual $(cat /var/tmp/pkgs_manual.lst)
|
|
fi
|
|
EOF
|
|
chroot-script -d install-set-selections || { zerr; return 1; }
|
|
}
|
|
|
|
enablessh() {
|
|
fn enablessh
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
notice "enabling ssh access without password."
|
|
act "Use ssh-copy-id default@192.168.1.x to login on reboot."
|
|
|
|
act "adding or creating keys (place keys in /etc/ssh/ssh_host_rsa_key.pub)"
|
|
cat <<-EOF | sudo tee "$strapdir/etc/rc.local" >/dev/null
|
|
#!/bin/sh
|
|
# rc.local for base images
|
|
|
|
[ -f /etc/ssh/ssh_host_rsa_key.pub ] || ssh-keygen -A
|
|
|
|
exit 0
|
|
EOF
|
|
|
|
sudo chmod +x "$strapdir/etc/rc.local"
|
|
|
|
cat <<-EOF | sudo tee "$strapdir/enablessh" >/dev/null
|
|
#!/usr/bin/env zsh
|
|
set -x ; exec 2>${PWD}/enablessh.log
|
|
|
|
config_file="/etc/ssh/sshd_config"
|
|
|
|
typeset -A rules
|
|
rules=(
|
|
"LoginGraceTime" "1m"
|
|
"PermitRootLogin" "yes"
|
|
"PasswordAuthentication" "no"
|
|
"AllowUsers" "${username}"
|
|
)
|
|
EOF
|
|
|
|
cat <<-'EOF' | sudo tee -a "$strapdir/enablessh" >/dev/null
|
|
|
|
for rule in "${(@k)rules}"; do
|
|
regex="s/^#\?\(${rule}\s*\).*$/\1 ${rules[${rule}]}/"
|
|
sed -i "${regex}" ${config_file};
|
|
done
|
|
EOF
|
|
chroot-script -d enablessh || { zerr; return 1; }
|
|
}
|
|
|
|
install_kernel_headers() {
|
|
fn install_kernel_headers
|
|
req=(strapdir kernel_version arch)
|
|
ckreq || return 1
|
|
|
|
# could go in blends/devuan-desktop-live/config $extra_packages and
|
|
# remove headers in blends/devuan-desktop-live/chimaera/config $purge_packages
|
|
|
|
notice "install kernel headers"
|
|
cat <<-EOF | sudo tee "$strapdir/install-kernel-headers" >/dev/null
|
|
#!/bin/sh
|
|
apt-get install -y linux-image-${kernel_version}-${arch}
|
|
apt-get install -y linux-headers-${kernel_version}-${arch}
|
|
apt-get -y -f install
|
|
EOF
|
|
chroot-script -d install-kernel-headers || { zerr; return 1; }
|
|
}
|
|
|
|
install_zfs() {
|
|
fn install_zfs
|
|
req=(strapdir rpool_name bpool_name root_name grubversion)
|
|
ckreq || return 1
|
|
|
|
act "install zfs to the $strapdir"
|
|
act "install the zfs packages in the correct order before dselect upgrade"
|
|
cat <<-EOF | sudo tee "$strapdir/install-zfs" >/dev/null
|
|
#!/bin/sh
|
|
apt-get remove -y live-config && apt-get -y autoremove
|
|
apt-get install -y dh-autoreconf
|
|
apt-get install -y zfs-dkms zfs-initramfs zfsnap zfsutils-linux ${grubversion} busybox console-setup
|
|
apt-get -y -f install
|
|
|
|
# add nouveau graphics setting before updating initramfs: add to the grub commandline with
|
|
update-initramfs -u
|
|
|
|
# zfs_autoimport_disable is now compiled as set to 1/true by default
|
|
# At module load 0=read zpool.cache 1=do not read zpool.cache
|
|
#echo '# https://openzfs.github.io/openzfs-docs/Performance and Tuning/Module Parameters.html' > /etc/modprobe.d/zfs.conf
|
|
#echo 'options zfs zfs_autoimport_disable=0' >> /etc/modprobe.d/zfs.conf
|
|
|
|
echo 'options zfs l2arc_write_max=50331648' >> /etc/modprobe.d/zfs.conf
|
|
echo 'options zfs l2arc_write_boost=100663296' >> /etc/modprobe.d/zfs.conf
|
|
|
|
# Additional datasets to /etc/default/zfs not created under ROOT
|
|
sed -i "s/#ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\"/" /etc/default/zfs
|
|
#
|
|
sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/home\"/" /etc/default/zfs
|
|
sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/space\"/" /etc/default/zfs
|
|
sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/tmp\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/opt\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/usr_share\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/usr_local\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var_lib\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var_lib_docker\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var_lib_virt\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var_tmp\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/usr\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var\"/" /etc/default/zfs
|
|
EOF
|
|
chroot-script -d install-zfs || { zerr; return 1; }
|
|
}
|
|
|
|
install_grub(){
|
|
fn install_grub
|
|
req=(strapdir disk_name efi_partitions swap_part_number rpool_name bpool_name root_name grub_mount grub_theme grub_gfxmode)
|
|
ckreq || return 1
|
|
|
|
notice "installing grub."
|
|
|
|
act "move the grub theme to the grub partition, stops 'update-alternatives desktop-grub-theme' from working."
|
|
mkdir -p /boot/grub/grub-themes
|
|
cp -a /usr/share/desktop-base/grub-themes/${grub_theme} /boot/grub/grub-themes/
|
|
|
|
|
|
act "replace the pool name detection with zdb command in /etc/grub.d/10_linux."
|
|
sed -i "s|rpool=.*|rpool=\`zdb -l \${GRUB_DEVICE} \| grep -E '[[:blank:]]name' \| cut -d\\\' -f 2\`|" $strapdir/etc/grub.d/10_linux
|
|
|
|
|
|
act "change the grub kernel commandline"
|
|
cat <<-EOF | sudo tee "$strapdir/write-default-grub" >/dev/null
|
|
#!/bin/sh
|
|
set -x
|
|
# GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=/dev/zvol/rpool/swap radeon:modeset=1 i915:modeset=1 cgroup_enable=memory swapaccount=1 net.ifnames=0
|
|
|
|
# set boot filesystem - duplicated by grub but misses rpool_name when grub-probe fails to read filesystem type.
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 zfs=${rpool_name}\"|" /etc/default/grub
|
|
|
|
# set swap as the resume partition.
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 resume=/dev/disk/by-id/${disk_name}-part${swap_part_number}\"|" /etc/default/grub
|
|
|
|
# set root - Not needed as the kernel and root are set before /etc/default/grub is added
|
|
#sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 root=ZFS=${rpool_name}\/ROOT\/${root_name}\"|" /etc/default/grub
|
|
|
|
# init_on_alloc=1 is a security hardening mechanism preventing a class of security issues from being exploitable.
|
|
# init_on_alloc=1 causes big performance regression for zfs: ubuntu +bug/1862822
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 init_on_alloc=0\"|" /etc/default/grub
|
|
|
|
# enable udev "info" logging for block devices
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 rd.log.block=info\"|" /etc/default/grub
|
|
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 cgroup_enable=memory\"|" /etc/default/grub
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 swapaccount=1\"|" /etc/default/grub
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 net.ifnames=0\"|" /etc/default/grub
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 nouveau.modeset=1\"|" /etc/default/grub
|
|
#sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 i915.modeset=1\"|" /etc/default/grub
|
|
#sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 radeon.modeset=1\"|" /etc/default/grub
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 noplymouth nosplash\"|" /etc/default/grub
|
|
sed -i '/^#GRUB_DISABLE_LINUX_UUID=.*/ s/.*/&\nGRUB_DISABLE_LINUX_UUID=true/' /etc/default/grub
|
|
sed -i '/^#GRUB_TIMEOUT=.*/ s/.*/&\nGRUB_RECORDFAIL_TIMEOUT=5/' /etc/default/grub
|
|
#sed -i "s|^#GRUB_DISABLE_LINUX_UUID=\"\(.*\)\"|GRUB_DISABLE_LINUX_UUID=\"\1 true\"|" /etc/default/grub
|
|
echo "" >> /etc/default/grub
|
|
echo "# Preload modules so that they are not missed." >> /etc/default/grub
|
|
echo "GRUB_PRELOAD_MODULES=part_gpt" >> /etc/default/grub
|
|
|
|
sed -i "s|^\(GRUB_GFXMODE=\).*|\1\"$grub_gfxmode\"|" /etc/default/grub
|
|
sed -i '/^GRUB_GFXMODE=.*/ s/.*/&\nGRUB_GFXPAYLOAD_LINUX=\"keep\"/' /etc/default/grub
|
|
|
|
sed -i "s|^\(GRUB_THEME=\).&|\1\"/boot/grub/grub-themes/${grub_theme}/theme.txt\"|" /etc/default/grub
|
|
|
|
# debug grub
|
|
sed -i "s/quiet//" /etc/default/grub
|
|
#sed -i "s/#GRUB_TERMINAL/GRUB_TERMINAL/" /etc/default/grub
|
|
EOF
|
|
chroot-script -d write-default-grub || { zerr; return 1; }
|
|
|
|
#umount -q ${strapdir}${grub_mount}
|
|
if [[ -v $efi ]]; then
|
|
mkdir -p ${grub_mount}
|
|
act "write grub-efi to available efi partitions."
|
|
for efi_partition in "${efi_partitions[@]}"; do
|
|
notice "writing to efi partitions: ${efi_partitions}"
|
|
if ! /bin/mountpoint -q "${strapdir}${grub_mount}"; then
|
|
act "mount the primary disks efi partition under ${grub_mount}"
|
|
mount ${disk_path}/${disk_name}-part${efi_part_number} ${strapdir}${grub_mount}
|
|
else
|
|
notice "the mountpoint ${grub_mount} already in use. Skipping mount operation."
|
|
fi
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/update-grub_${disk_name} > /dev/null
|
|
#!/bin/sh
|
|
|
|
echo "populate the ${grub_mount} with update-grub."
|
|
grub-mkconfig -o ${grub_mount}/grub.cfg
|
|
|
|
echo "install grub to disk name ${disk_name}, efi partition ${efi_partition}"
|
|
grub-install --target=${grub_efi_target} \
|
|
--no-uefi-secure-boot \
|
|
--efi-directory=${grub_mount} \
|
|
--bootloader-id="Devuan ${release} (RAID disk ${disk_name})" \
|
|
--recheck \
|
|
--no-floppy
|
|
EOF
|
|
chroot-script -d update-grub_${disk_name} || { zerr; return 1; }
|
|
umount ${strapdir}${grub_mount}
|
|
done
|
|
else
|
|
mkdir -p ${grub_mount}
|
|
act "write grub to available efi partitions."
|
|
for disk_name in "${available_disks[@]}"; do
|
|
notice "writing grub to available ${disk_name}:"
|
|
if ! /bin/mountpoint -q "${strapdir}${grub_mount}"; then
|
|
act "mount the primary disks efi partition under ${grub_mount}"
|
|
mount ${disk_path}/${disk_name}-part${efi_part_number} ${strapdir}${grub_mount}
|
|
else
|
|
notice "The mount point ${grub_mount} is already in use. Skipping mount operation."
|
|
fi
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/update-grub_${disk_name} > /dev/null
|
|
#!/bin/sh
|
|
|
|
echo "populate the ${grub_mount} with update-grub."
|
|
grub-mkconfig -o ${grub_mount}/grub.cfg
|
|
|
|
echo "install grub-pc to ${disk_name}"
|
|
grub-install --target=i386-pc /dev/disk/by-id/${disk_name}
|
|
EOF
|
|
chroot-script -d update-grub_${disk_name} || { zerr; return 1; }
|
|
umount ${strapdir}${grub_mount}
|
|
done
|
|
|
|
fi
|
|
}
|
|
|
|
|
|
dpkg-version() {
|
|
fn dpkg--version
|
|
req=(R strapdir)
|
|
ckreq || return 1
|
|
|
|
chroot-script bash -c "dpkg-query --show --showformat "\${Version}\n" dpkg"
|
|
}
|
|
|
|
|
|
apt-version() {
|
|
fn apt-version
|
|
req=(R strapdir)
|
|
ckreq || return 1
|
|
|
|
chroot-script bash -c "dpkg-query --show --showformat "\${Version}\n" apt"
|
|
}
|
|
|
|
|
|
install_u-boot(){
|
|
fn install_u-boot
|
|
req=(strapdir disk_name efi_partitions swap_part_number rpool_name bpool_name root_name grub_mount)
|
|
ckreq || return 1
|
|
|
|
# When installing to metal we will install the os plus grub as usual and
|
|
# then boot grub from u-boot written to SPI.
|
|
# u-boot gets build as a part of the board definition in arm-sdk. We add
|
|
# zfs support there in case we wish to boot the kernel directly later.
|
|
|
|
# https://github.com/sigmaris/u-boot/wiki/RockPro64-boot-sequence
|
|
|
|
# notice "installing u-boot to SPI."
|
|
|
|
# The RK3399 Boot ROM will look for code with an ID block header for:
|
|
# SPI flash at offset 0 bytes
|
|
# eMMC at offset 0x8000 bytes (64 sectors, a sector is 0x200 bytes)
|
|
# SDcard at offset 0x8000 bytes (64 sectors, a sector is 0x200 bytes)
|
|
|
|
# this is where we write the idbloader.img (containing U-Boot TPL & SPL)
|
|
|
|
# For SPI it must be written in rkspi format using the U-Boot mkimage tool.
|
|
|
|
cat /proc/device-tree/model # Pine64 RockPro64 v2.0
|
|
cat /proc/device-tree/compatible # pine64,rockpro64-v2.0pine64,rockpro64rockchip,rk3399
|
|
|
|
cat /proc/mtd
|
|
# dev: size erasesize name
|
|
# mtd0: 00060000 00001000 "u-boot-spl"
|
|
# mtd1: 00398000 00001000 "u-boot"
|
|
# mtd2: 00008000 00001000 "u-boot-env"
|
|
# mtd3: 00c00000 00001000 "user"
|
|
|
|
lsmtd
|
|
# DEVICE MAJ:MIN NAME TYPE SIZE
|
|
# mtd0 90:0 u-boot-spl nor 384K
|
|
# mtd1 90:2 u-boot nor 3.6M
|
|
# mtd2 90:4 u-boot-env nor 32K
|
|
# mtd3 90:6 user nor 12M
|
|
|
|
mtdinfo
|
|
# Count of MTD devices: 4
|
|
# Present MTD devices: mtd0, mtd1, mtd2, mtd3
|
|
# Sysfs interface supported: yes
|
|
|
|
sudo mtdinfo /dev/mtd0
|
|
# mtd0
|
|
# Name: u-boot-spl
|
|
# Type: nor
|
|
# Eraseblock size: 4096 bytes, 4.0 KiB
|
|
# Amount of eraseblocks: 96 (393216 bytes, 384.0 KiB)
|
|
# Minimum input/output unit size: 1 byte
|
|
# Sub-page size: 1 byte
|
|
# Character device major/minor: 90:0
|
|
# Bad blocks are allowed: false
|
|
# Device is writable: true
|
|
|
|
sudo mtd_debug info /dev/mtd0
|
|
# mtd.type = MTD_NORFLASH
|
|
# mtd.flags = MTD_CAP_NORFLASH
|
|
# mtd.size = 393216 (384K)
|
|
# mtd.erasesize = 4096 (4K)
|
|
# mtd.writesize = 1
|
|
# mtd.oobsize = 0
|
|
# regions = 0
|
|
|
|
|
|
build_atf(){
|
|
fn build_atf
|
|
req=(strapdir atf_branch atfgit compiler)
|
|
ckreq || return 1
|
|
|
|
notice "Build arm-trusted-firmware bl31.elf for rk3399."
|
|
|
|
git config --global user.name 'Build Robot'
|
|
git config --global user.email 'noemail@example.com'
|
|
git clone --depth 1 -b "$atf_branch" "$atfgit" "$R/tmp/kernels/arm-trusted-firmware" || zerr
|
|
pushd "$R/tmp/kernels/arm-trusted-firmware"
|
|
#git am ../atf-rk3399-baudrate.patch
|
|
make realclean
|
|
make -j$(nproc) CROSS_COMPILE=$compile PLAT=rk3399 DEBUG=1 bl31 || zerr
|
|
popd
|
|
|
|
act "Publish arm-trusted-firmware bl31.elf"
|
|
mkdir -p "$R/dist"
|
|
cp "$R/tmp/kernels/arm-trusted-firmware/build/rk3399/debug/bl31/bl31.elf" "$R/dist"
|
|
}
|
|
|
|
build_uboot(){
|
|
fn build_u-boot
|
|
req=(strapdir ubootgit uboot_branch MAKEOPTS)
|
|
ckreq || return 1
|
|
|
|
defconfig=rockpro64-rk3399_defconfig
|
|
img1type=rksd # Rockchip SD Boot Image
|
|
img1name=idbloader.img
|
|
img2name=u-boot.itb
|
|
artifact=u-boot
|
|
|
|
notice "Build u-boot"
|
|
"FIXME: AUTOBOOT was too chatty at the configure stage with these entries do its disabled for now."
|
|
git clone --depth 1 "$ubootgit" -b "$uboot_branch" "$R/tmp/kernels/u-boot-rockpro64" || zer
|
|
pushd "$R/tmp/kernels/u-boot-rockpro64"
|
|
make mrproper
|
|
make $(defconfig)
|
|
act "apply local changes to defconfig."
|
|
"$R/tmp/kernels/rockpro64/rockpro64-linux/scripts/config" --file .config \
|
|
--enable CONFIG_CMD_ZFS \
|
|
--enable CONFIG_CMD_BOOTMENU \
|
|
--enable CONFIG_MENU \
|
|
--enable CONFIG_MENU_SHOW \
|
|
--enable CONFIG_CFB_CONSOLE_ANSI \
|
|
--enable CONFIG_CMD_BOOTEFI \
|
|
--enable CONFIG_EFI_LOADER \
|
|
--enable CONFIG_EFI_SECURE_BOOT \
|
|
--enable CONFIG_CMD_BOOTM \
|
|
--enable CONFIG_BOOTM_EFI \
|
|
--enable CONFIG_BOOTM_LINUX \
|
|
--enable CONFIG_BOOTM_NETBSD \
|
|
--enable CONFIG_BLK \
|
|
--enable CONFIG_VERSION_VARIABLE \
|
|
--enable CONFIG_PARTITIONS \
|
|
--enable CONFIG_DM_VIDEO
|
|
#--enable CONFIG_AUTOBOOT_KEYED \
|
|
#--set-val CONFIG_BOOTDELAY 30
|
|
|
|
act "apply sigmaris changes to defconfig."
|
|
"$R/tmp/kernels/rockpro64/rockpro64-linux/scripts/config" --file .config \
|
|
--enable CONFIG_OF_BOARD_SETUP \
|
|
--enable CONFIG_MTD \
|
|
--enable CONFIG_CMD_MTDPARTS \
|
|
--enable CONFIG_SPL_MMC \
|
|
--enable CONFIG_SPL_SPI \
|
|
--enable CONFIG_SPI_FLASH_MTD \
|
|
--enable CONFIG_SPL_SPI_FLASH_SUPPORT \
|
|
--enable CONFIG_NVME \
|
|
--enable CONFIG_SCSI \
|
|
--enable CONFIG_DM_SCSI \
|
|
--enable CONFIG_OF_LIBFDT_OVERLAY \
|
|
--enable CONFIG_FDT_FIXUP_PARTITIONS \
|
|
--enable CONFIG_SERVERIP_FROM_PROXYDHCP \
|
|
--enable CONFIG_AHCI \
|
|
--enable CONFIG_SCSI_AHCI \
|
|
--enable CONFIG_AHCI_PCI \
|
|
--enable CONFIG_DM_KEYBOARD \
|
|
--enable CONFIG_LED \
|
|
--enable CONFIG_LED_GPIO \
|
|
--set-val CONFIG_DEFAULT_DEVICE_TREE "rk3399-rockpro64" \
|
|
--set-val CONFIG_SERVERIP_FROM_PROXYDHCP_DELAY_MS 100 \
|
|
--set-val CONFIG_MTDIDS_DEFAULT "nor0=spi0.0" \
|
|
--set-val CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:384k(u-boot-spl),3680k(u-boot),32k(u-boot-env),-(user)"
|
|
|
|
|
|
make -j$(nproc) $MAKEOPTS ARCH=arm CROSS_COMPILE=$compiler || zerr
|
|
export BL31="$R/tmp/kernels/arm-trusted-firmware/build/rk3399/debug/bl31/bl31.elf"
|
|
mkdir -p "$R/dist"
|
|
|
|
act "create ${img1type}_${img1name} image file."
|
|
"$R/tmp/kernels/u-boot-rockpro64/tools/mkimage" \
|
|
-n rk3399 \ # set image name
|
|
-T $(img1type) \ # set image type
|
|
-d tpl/u-boot-tpl.bin:spl/u-boot-spl.bin \ # use image data from
|
|
${img1type}_$(img1name) # idbloader.img
|
|
act "Publish ${img1type}_${image1name}"
|
|
cp ${img1type}_$(img1name) "$R/dist"
|
|
|
|
img1type=rkspi # Rockchip SPI Boot Image
|
|
act "create ${img1type}_${img1name} image file."
|
|
"$R/tmp/kernels/u-boot-rockpro64/tools/mkimage" \
|
|
-n rk3399 \ # set image name
|
|
-T $(img1type) \ # set image type
|
|
-d tpl/u-boot-tpl.bin:spl/u-boot-spl.bin \ # use image data from
|
|
${img1type}_$(img1name) # idbloader.img
|
|
act "Publish ${img1type}_${image1name}"
|
|
cp ${img1type}_$(img1name) "$R/dist"
|
|
|
|
act "Publish ${image2name}"
|
|
cp u-boot.itb "$R/dist"/$(img2name) # u-boot.itb
|
|
popd
|
|
}
|
|
|
|
create_spi_image(){
|
|
act "Create single SPI image with u-boot.itb at 0x60000"
|
|
|
|
padsize=$((0x60000 - 1))
|
|
img1size=$(wc -c <"$(img1name)")
|
|
[ $img1size -le $padsize ] || exit 1
|
|
dd \
|
|
if=/dev/zero \
|
|
of=$(img1name) \
|
|
conv=notrunc \
|
|
bs=1 \
|
|
count=1 \
|
|
seek=$padsize
|
|
cat $(img1name) u-boot.itb > "$R/dist"/spi_combined.img
|
|
create-u-boot-spi-scripts
|
|
"$R/tmp/kernels/u-boot-rockpro64/tools/mkimage" \
|
|
-C none \ # set compression
|
|
-A arm \ # set architecture
|
|
-T script \ # set image type
|
|
-d scripts/flash_spi.cmd \ # use image data fro
|
|
"$R/dist/flash_spi.scr"
|
|
}
|
|
|
|
spi_flash_img(){
|
|
fn spi_flash_img
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
notice "Create SD card image to flash u-boot to SPI"
|
|
|
|
cp "$R/dist/flash_spi.scr boot.scr"
|
|
cp "$R/dist/spi_combined.img spi_combined.img"
|
|
dd \
|
|
if=/dev/zero \
|
|
of=boot.tmp \
|
|
bs=1M \
|
|
count=16
|
|
mkfs.vfat -n u-boot-script boot.tmp
|
|
mcopy -sm -i boot.tmp boot.scr ::
|
|
mcopy -sm -i boot.tmp spi_combined.img ::
|
|
dd \
|
|
if=/dev/zero \
|
|
of=flash_spi.img \
|
|
bs=1M \
|
|
count=32
|
|
parted -s flash_spi.img mklabel gpt
|
|
parted -s flash_spi.img unit s mkpart loader1 64 8063
|
|
parted -s flash_spi.img unit s mkpart loader2 16384 24575
|
|
parted -s flash_spi.img unit s mkpart boot fat16 24576 100%
|
|
parted -s flash_spi.img set 3 legacy_boot on
|
|
dd \
|
|
if= "$R/tmp/kernels/u-boot-rockpro64/idbloader.img" \
|
|
of=flash_spi.img \
|
|
conv=notrunc \
|
|
seek=64
|
|
dd \
|
|
if="$R/tmp/kernels/u-boot-rockpro6/u-boot.itb" \
|
|
of=flash_spi.img \
|
|
conv=notrunc \
|
|
seek=16384
|
|
dd \
|
|
if=boot.tmp \
|
|
of=flash_spi.img \
|
|
conv=notrunc \
|
|
seek=24576
|
|
gzip flash_spi.img
|
|
}
|
|
|
|
set-bootloader(){
|
|
fn set-bootloader
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
case "$1" in
|
|
*-rockchip-rock64-*)
|
|
SD_LOADER="$R/dist/rksd_loader.img"
|
|
SPI_LOADER="$R/dist/rksd_loader.img"
|
|
BOARD=rock64
|
|
;;
|
|
|
|
*-rockchip-rockpro64-*)
|
|
SD_LOADER="$R/dist/rksd_loader.img"
|
|
SPI_LOADER="$R/dist/rkspi_loader.img"
|
|
BOARD=rockpro64
|
|
;;
|
|
|
|
*-rockchip-pinebookpro-*)
|
|
SD_LOADER="$R/dist/rksd_loader.img"
|
|
SPI_LOADER="$R/dist/rkspi_loader.img"
|
|
BOARD=pinebookpro
|
|
;;
|
|
|
|
*-rockchip-rockpi4b-*)
|
|
SD_LOADER="$R/dist/rksd_loader.img"
|
|
SPI_LOADER="$R/dist/rkspi_loader.img"
|
|
BOARD=rockpi4b
|
|
;;
|
|
|
|
*)
|
|
echo "Cannot detect board from $1."
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if ! grep -qi "$BOARD" /proc/device-tree/compatible; then
|
|
echo "You are currently running on different board:"
|
|
echo "$(tr -d '\0' < /proc/device-tree/model || true)"
|
|
echo "It may brick your device or the system unless"
|
|
echo "you know what are you doing."
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
bootloader-version(){
|
|
fn bootloader-version
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
# FIXME: Assumes partitions number p1 or p6 and uses p1 for both
|
|
version() {
|
|
local DEVICE="${1/p6/p1}"
|
|
|
|
echo -n "Current version: "
|
|
if strings "$DEVICE" | grep "^U-Boot [a-z0-9.-]*$"; then
|
|
echo -n "Board: "
|
|
strings "$DEVICE" | grep -E "^board="
|
|
echo -n "FDT: "
|
|
strings "$DEVICE" | grep -E "^fdtfile="
|
|
else
|
|
echo "not installed on $DEVICE."
|
|
fi
|
|
echo
|
|
}
|
|
}
|
|
|
|
upgrade-sd-bootloader(){
|
|
fn upgrade-sd-bootloader
|
|
req=(strapdir SD_LOADER)
|
|
ckreq || return 1
|
|
|
|
notice "Upgrading pre-existing bootloader."
|
|
# FIXME:
|
|
# extlinux, u-boot, grub, EFI
|
|
# Assumes u-boot written to a mounted efi partion
|
|
# Writes the rksd image only to a specific partition number on sd devices. Uses p1
|
|
if [[ $(findmnt -M /boot/efi) ]]; then
|
|
MNT_DEV=$(findmnt /boot/efi -n -o SOURCE)
|
|
else
|
|
echo "Error: efi partition not mounted."
|
|
exit 1
|
|
fi
|
|
|
|
|
|
# report current version
|
|
bootloader-version "$MNT_DEV"
|
|
|
|
write_sd() {
|
|
case "$1" in
|
|
/dev/mmcblk*p6|/dev/sd*p6|/dev/mapper/loop*p6|/dev/mapper/nvme*p6)
|
|
dd if="$2" of="${1/p6/p1}"
|
|
;;
|
|
|
|
*)
|
|
echo "Cannot detect boot device ($MNT_DEV)."
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
write_sd "$MNT_DEV" "$SD_LOADER"
|
|
|
|
sync
|
|
}
|
|
|
|
erase-sd-bootloader(){
|
|
fn erase-sd-bootloader
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
notice "Erasing pre-existing bootloader."
|
|
# FIXME: Writes/erases a specific partition number on sd devices. Uses p1
|
|
MNT_DEV=$(findmnt /boot/efi -n -o SOURCE)
|
|
|
|
# report current version
|
|
bootloader-version "$MNT_DEV"
|
|
|
|
write_sd() {
|
|
case "$1" in
|
|
/dev/mmcblk*p6|/dev/sd*p6|/dev/mapper/loop*p6|/dev/mapper/nvme*p6)
|
|
dd \
|
|
if="$2" \
|
|
of="${1/p6/p1}"
|
|
;;
|
|
|
|
*)
|
|
echo "Cannot detect boot device ($MNT_DEV)."
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
write_sd "$MNT_DEV" "/dev/zero"
|
|
|
|
sync
|
|
}
|
|
|
|
write-emmc-flash(){
|
|
fn write-emmc-flash
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
notice "Writing u-boot to emmc."
|
|
for blkdevice in $(ls -d /dev/mmcblk* | sed -n -E '/mmcblk[0-9]+$/ p' ); do
|
|
if [[ -f /sys/block/${blkdevice##*/}/device/type ]]; then
|
|
if [[ $(< /sys/block/${blkdevice##*/}/device/type) == MMC ]]; then
|
|
emmc_blkdevice=${blkdevice}
|
|
fi
|
|
fi
|
|
done
|
|
|
|
MNT_DEV=$(findmnt / -n -o SOURCE)
|
|
MNT_DEV=${MNT_DEV%p[0-9]*}
|
|
if [[ "$MNT_DEV" == $emmc_blkdevice* ]]; then
|
|
echo "Cannot write when running from eMMC, use: $0 --force."
|
|
exit 1
|
|
fi
|
|
|
|
# When booting from sdcard:
|
|
# the card appears as /dev/mmcblk1 and
|
|
# the emmc appears as /dev/mmcblk2
|
|
pushd "$R/tmp/kernels/u-boot-rockpro64"
|
|
dd \
|
|
if="$R/dist/rksd_idbloader.img" \
|
|
of=/dev/${emmc_blkdevice} \
|
|
seek=64
|
|
dd \
|
|
if="$R/dist/u-boot.itb" \
|
|
of=/dev/${emmc_blkdevice} \
|
|
seek=16384
|
|
popd
|
|
}
|
|
|
|
erase-spi-flash(){
|
|
fn erase-spi-flash
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
notice "Erasing spi flash."
|
|
# FIXME: Assumes contents of spi labels, we don't have 'loader' so fails.
|
|
# mtd0: 00060000 00001000 "u-boot-spl"
|
|
# mtd1: 00398000 00001000 "u-boot"
|
|
# mtd2: 00008000 00001000 "u-boot-env"
|
|
# mtd3: 00c00000 00001000 "user"
|
|
|
|
if ! MTD=$(grep \"loader\" /proc/mtd | cut -d: -f1); then
|
|
echo "loader partition on MTD is not found"
|
|
return 1
|
|
fi
|
|
|
|
# report current version
|
|
bootloader-version "/dev/${MTD/mtd/mtdblock}"
|
|
|
|
flash_erase "/dev/$MTD" 0 0
|
|
}
|
|
|
|
write-spi-flash(){
|
|
fn write-spi-flash
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
notice "Writing spi flash."
|
|
|
|
version "/dev/${MTD/mtd/mtdblock}"
|
|
confirm
|
|
|
|
write_nand() {
|
|
if ! MTD=$(grep \"${1}\" /proc/mtd | cut -d: -f1); then
|
|
echo "${1} partition on MTD is not found"
|
|
exit 1
|
|
fi
|
|
echo "Writing /dev/$MTD with content of $2"
|
|
flash_erase "/dev/$MTD" 0 0
|
|
nandwrite "/dev/$MTD" < "$2"
|
|
}
|
|
write_nand u-boot-spl "$SPI_LOADER"
|
|
}
|
|
|
|
|
|
}
|
|
|
|
# u-boot menu has been deprecated, extlinux.conf is used instead and uutomatically
|
|
# updated with u-boot-update from u-boot-menu. see ARM-sdk/BOARDs/rockpro64-ayunfan.
|
|
create-u-boot-menu(){
|
|
fn create-u-boot-menu
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
# FIXME: Need to choose a default and fix the other calls
|
|
cat <<-EOF | tee scripts/boot.cmd > /dev/null
|
|
setenv bootmenu_0 Boot 1. kernel=bootm 0x82000000 # Set first menu entry
|
|
setenv bootmenu_1 Boot 2. kernel=bootm 0x83000000 # Set second menu entry
|
|
setenv bootmenu_2 Reset board=reset # Set third menu entry
|
|
setenv bootmenu_3 U-Boot boot order=boot # Set fourth menu entry
|
|
bootmenu 20 # Run bootmenu with autoboot delay 20s
|
|
|
|
u-boot console command sequence:
|
|
from a android phone
|
|
setenv bootmenu_0 "Boot LNX ARCH =
|
|
setenv bootargs 'root=/dev/mmcblk0p7 rootfstype=ext4 rootwait'; \
|
|
ext2load mmc 0:2 0x1000000 /boot/zImage;
|
|
ext2load mmc 0:2 0x2000000 /boot/tegra20-paz00.dtb;
|
|
bootz 0x1000000 - 0x2000000;"
|
|
pastbin example
|
|
setenv bootargs 'mem=214M root=/dev/mmcblk0p2 noinitrd rw rootfstype=ext2 console=ttyS0,115200n8 rootwait'
|
|
setenv kernelargs 'mem=214M root=/dev/mmcblk0p2 noinitrd rw rootfstype=ext2 console=ttyS0,115200n8 rootwait'
|
|
saveenv
|
|
display init force
|
|
mmcinit 0
|
|
fatload mmc 0 0 uzImage.bin
|
|
textout -1 -1 \"Commands finished. Trying to boot...\" FFFFFF
|
|
bootm 0
|
|
|
|
from fat partition
|
|
fatload mmc 0 0x3000000 uImage
|
|
fatload mmc 0 0x2A00000 devicetree.dtb
|
|
bootm 0x3000000 - 0x2A00000
|
|
|
|
zfs support
|
|
zfsload <interface> <dev[:part]> [addr] [filename] [bytes]
|
|
zfsload mmc 2:2 0x30007fc0 /rpool/@/boot/uImage
|
|
|
|
grub from u-boot
|
|
ext4load mmc 0:1 0x43300000 /boot/grub/arm-uboot/core.img
|
|
bootm 0x43300000
|
|
|
|
raspberrypi example
|
|
setenv kernel_addr_r 2000000
|
|
setenv fdt_addr_r 1000000
|
|
setenv bootargs 'root=/dev/mmcblk0p7 rootfstype=ext4 rootwait'; \
|
|
load mmc 0:2 \$kernel_addr_r /boot/image
|
|
load mmc 0:2 \$fdt_addr_r boot/dtb/bcm2837-rpi-3-b.dtb
|
|
|
|
from the current spi
|
|
setenv fdt_addr_r 0x01f00000
|
|
setenv kernel_addr_r 0x02080000
|
|
setenv devtype scsi
|
|
setenv devnum 0
|
|
setenv distro_bootpart 2
|
|
|
|
devuan-sdk version - variables set in arm-sdk-boards/(boardname>)
|
|
setenv kernel_addr_z 0x44080000
|
|
setenv kernel_addr_r 0x43000000
|
|
setenv fdt_addr_r 0x42000000
|
|
setenv ramdisk_addr_r 0x43300000
|
|
setenv rootfsaddr 0x43300000
|
|
setenv devtype mmc
|
|
setenv devnum 0
|
|
setenv distro_bootpart 1
|
|
qemu changes
|
|
setenv console /dev/ttyS2
|
|
setenv root /dev/mmcblk0p2
|
|
setenv root /dev/vda2
|
|
setenv bootargs "consoleblank=0 root=${root} rw rootwait console=${console},1500000n8 earlycon=uart8250,mmio32,0xff1a0000 console=tty1"
|
|
setenv bootargs "console=tty0 console=${console} root=/dev/mmcblk0p2 rw rootwait rootfstype=ext4 fbcon=rotate:1"
|
|
setenv bootargs "console=${console} root=/dev/vda2 mem=128M rdinit=/sbin/init"
|
|
setenv fdt_addr_r 0xf5f17000
|
|
setenv devtype virtio
|
|
|
|
if load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_z} Image.gz; then
|
|
unzip ${kernel_addr_z} ${kernel_addr_r}
|
|
if load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} rk3399-rockpro64.dtb; then
|
|
booti ${kernel_addr_r} - ${fdt_addr_r};
|
|
fi;
|
|
fi
|
|
|
|
armbian: https://github.com/armbian/build/blob/master/config/bootscripts/boot-rockchip64.cmd
|
|
|
|
efi: https://github.com/ARM-software/u-boot/blob/master/doc/README.uefi
|
|
https://u-boot.readthedocs.io/en/latest/develop/uefi/uefi.html
|
|
# the efi fat32 partition is mounted under /boot/efi
|
|
load mmc 0:1 ${fdt_addr_r} rk3399-rockpro64.dtb
|
|
load mmc 0:1 ${kernel_addr_r} \
|
|
/EFI/Devuan\ daedalus\ \(RAID\ disk\ ata-WDC_WD30EZRZ-00WN9B0_WD-WCC4E6RKKRVX\)/grubaa64.efi
|
|
bootefi ${kernel_addr_r} ${fdt_addr_r}
|
|
|
|
# u-boot, extlinux.conf
|
|
label linux-5.0.0-rc3
|
|
kernel /Image
|
|
devicetree /sun50i-a64-amarula-relic.dtb
|
|
append console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw
|
|
|
|
=> load mmc 0:2 ${fdt_addr_r} boot/dtb
|
|
29830 bytes read in 14 ms (2 MiB/s)
|
|
=> load mmc 0:1 ${kernel_addr_r} efi/debian/grubaa64.efi
|
|
reading efi/debian/grubaa64.efi
|
|
120832 bytes read in 7 ms (16.5 MiB/s)
|
|
=> bootefi ${kernel_addr_r} ${fdt_addr_r}
|
|
|
|
efi FIT:
|
|
=> load mmc 0:1 ${kernel_addr_r} image.fit
|
|
4620426 bytes read in 83 ms (53.1 MiB/s)
|
|
=> bootm ${kernel_addr_r}#config-grub-nofdt
|
|
## Loading kernel from FIT Image at 40400000 ...
|
|
Using 'config-grub-nofdt' configuration
|
|
Verifying Hash Integrity ... sha256,rsa2048:dev+ OK
|
|
Trying 'efi-grub' kernel subimage
|
|
Description: GRUB EFI Firmware
|
|
Created: 2019-11-20 8:18:16 UTC
|
|
Type: Kernel Image (no loading done)
|
|
Compression: uncompressed
|
|
Data Start: 0x404000d0
|
|
Data Size: 450560 Bytes = 440 KiB
|
|
Hash algo: sha256
|
|
Hash value: 4dbee00021112df618f58b3f7cf5e1595533d543094064b9ce991e8b054a9eec
|
|
Verifying Hash Integrity ... sha256+ OK
|
|
XIP Kernel Image (no loading done)
|
|
## Transferring control to EFI (at address 404000d0) ...
|
|
Welcome to GRUB!
|
|
|
|
initramfs example https://armtix.artixlinux.org/info/firefly-rk3399.html
|
|
mkimage -A arm -T ramdisk -d <path to initramfs> mkinitramfs-linux.uimg
|
|
|
|
Next, you have to create u-boot script u-boot.cmd with following contents:
|
|
|
|
setenv bootargs "consoleblank=0 root=${console} rw rootwait console=ttyS2,1500000n8 earlycon=uart8250,mmio32,0xff1a0000 console=tty1"
|
|
load mmc 1:1 ${fdt_addr_r} /dtbs/rockchip/rk3399-firefly.dtb
|
|
load mmc 1:1 ${kernel_addr_r} /Image
|
|
load mmc 1:1 ${ramdisk_addr_r} /initramfs-linux.uimg
|
|
booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}
|
|
|
|
mkimage -A arm -T ramdisk -d boot.cmd boot.scr
|
|
|
|
EOF
|
|
|
|
"$R/tmp/kernels/u-boot-rockpro64/tools/mkimage" \
|
|
-A arm \ # set architechture
|
|
-O linux \ # set operating system
|
|
-T script \ # set image type
|
|
-C none \ # set compression type
|
|
-a 0 \ # set load address
|
|
-e 0 \ # set entry point
|
|
-n "ubootscript" \ # set image name
|
|
-d scripts/boot.cmd \ # use image data from
|
|
"$R/dist/boot.scr"
|
|
|
|
}
|
|
|
|
create-u-boot-spi-scripts(){
|
|
fn create-u-boot-spi-scripts
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-'EOF' | tee "$R/tmp/kernels/u-boot-rockpro64/scripts/erase_spi.cmd" > /dev/null
|
|
setenv blink_work 'led work on; sleep 0.1; led work off; sleep 0.1'
|
|
setenv blink_diy 'led diy on; sleep 0.1; led diy off; sleep 0.1'
|
|
|
|
echo "Enable SPI Flash now."
|
|
|
|
run blink_work
|
|
sleep 2
|
|
run blink_work
|
|
sleep 2
|
|
run blink_work
|
|
sleep 2
|
|
run blink_work
|
|
sleep 2
|
|
run blink_work
|
|
sleep 2
|
|
|
|
if sf probe; then
|
|
|
|
# erase all mtd partitions containing u-boot
|
|
run blink_work
|
|
run blink_work
|
|
run blink_work
|
|
mtd erase u-boot-spl
|
|
run blink_work
|
|
run blink_work
|
|
run blink_work
|
|
mtd erase u-boot
|
|
run blink_work
|
|
run blink_work
|
|
run blink_work
|
|
mtd erase u-boot-env
|
|
|
|
led work on
|
|
echo "Erased U-Boot from SPI Flash."
|
|
while true; do sleep 1; done
|
|
else
|
|
echo "Error: No SPI flash."
|
|
# blink both LEDs forever
|
|
while true; do run blink_diy; run blink_work; done
|
|
fi
|
|
EOF
|
|
|
|
cat <<-'EOF' | tee "$R/tmp/kernels/u-boot-rockpro64/scripts/flash-spi.cmd" > /dev/null
|
|
setenv blink_work 'led work on; sleep 0.1; led work off; sleep 0.1'
|
|
setenv blink_diy 'led diy on; sleep 0.1; led diy off; sleep 0.1'
|
|
|
|
run blink_work
|
|
if sf probe; then
|
|
run blink_work
|
|
|
|
if size ${devtype} ${devnum}:${distro_bootpart} spi_combined.img; then
|
|
run blink_work
|
|
load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} spi_combined.img
|
|
|
|
# write flash
|
|
run blink_work
|
|
run blink_work
|
|
run blink_work
|
|
sf update ${kernel_addr_r} 0 ${filesize}
|
|
run blink_work
|
|
run blink_work
|
|
run blink_work
|
|
|
|
led work on
|
|
echo "Wrote U-Boot to SPI Flash successfully."
|
|
while true; do sleep 1; done
|
|
else
|
|
echo "Error: Missing spi_combined.img"
|
|
# blink red LED forever
|
|
while true; do run blink_diy; sleep 0.1; done
|
|
fi
|
|
else
|
|
echo "Error: No SPI flash."
|
|
# blink both LEDs forever
|
|
while true; do run blink_diy; run blink_work; done
|
|
fi
|
|
EOF
|
|
|
|
# The procedure if you have idbloader.img and u-boot.itb on an sdcard.
|
|
cat <<-'EOF' | tee tee "$R/tmp/kernels/u-boot-rockpro64/scripts/load-spi-from-usb.cmd" > /dev/null
|
|
if ls usb 0:1; then
|
|
if sf probe; then
|
|
load usb 0:1 ${fdt_addr_r} idbloader.img
|
|
sf update ${fdt_addr_r} 0 ${filesize}
|
|
load usb 0:1 ${fdt_addr_r} u-boot.itb
|
|
sf update ${fdt_addr_r} 60000 ${filesize}
|
|
else
|
|
echo "Error: No SPI flash."
|
|
# blink both LEDs forever
|
|
while true; do run blink_diy; run blink_work; done
|
|
fi
|
|
else
|
|
echo "Error: No USB available."
|
|
fi
|
|
EOF
|
|
}
|
|
|
|
create-rockpro64-scripts(){
|
|
cat <<-'EOF' | tee /usr/local/sbin/rockpro64_enable_eth_gadget.sh > /dev/null
|
|
#!/bin/bash
|
|
|
|
set -xe
|
|
|
|
# enable peripheral mode
|
|
enable_dtoverlay usb0_dwc3_peripheral usb0/dwc3@fe800000 okay \
|
|
'dr_mode="peripheral"'
|
|
|
|
# reload dwc3
|
|
echo fe800000.dwc3 > /sys/bus/platform/drivers/dwc3/unbind
|
|
echo fe800000.dwc3 > /sys/bus/platform/drivers/dwc3/bind
|
|
|
|
# install eth gadget
|
|
install_gadget RockPro64 fe800000.dwc3 ecm
|
|
EOF
|
|
|
|
cat <<-'EOF' | tee /usr/local/sbin/rockpro64_disable_otg.sh > /dev/null
|
|
#!/bin/bash
|
|
|
|
set -x
|
|
|
|
# enable peripheral mode
|
|
disable_dtoverlay dwc3_peripheral
|
|
|
|
# reload dwc3
|
|
echo fe800000.dwc3 > /sys/bus/platform/drivers/dwc3/unbind
|
|
echo fe800000.dwc3 > /sys/bus/platform/drivers/dwc3/bind
|
|
|
|
# install eth gadget
|
|
uninstall_gadgets
|
|
EOF
|
|
|
|
cat <<-'EOF' | tee /usr/local/sbin/rockpro64_reset_emmc.sh > /dev/null
|
|
#!/bin/bash
|
|
|
|
if [[ "$1" != "--force" ]]; then
|
|
MNT_DEV=$(findmnt / -n -o SOURCE)
|
|
if [[ "$MNT_DEV" == /dev/mmcblk1* ]]; then
|
|
echo "Cannot reset when running from eMMC, use: $0 --force."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [[ -d /sys/bus/platform/drivers/sdhci-arasan/fe330000.sdhci ]]; then
|
|
echo "Unbinding..."
|
|
echo fe330000.sdhci > /sys/bus/platform/drivers/sdhci-arasan/unbind
|
|
fi
|
|
|
|
echo "Binding..."
|
|
echo fe330000.sdhci > /sys/bus/platform/drivers/sdhci-arasan/bind
|
|
|
|
echo "Finished"
|
|
EOF
|
|
|
|
cat <<-'EOF' | tee /usr/local/sbin/rockpro64_reset_spi_flash.sh > /dev/null
|
|
#!/bin/bash
|
|
|
|
if [[ -d /sys/bus/platform/drivers/rockchip-spi/ff1d0000.spi ]]; then
|
|
echo "Unbinding..."
|
|
echo ff1d0000.spi > /sys/bus/platform/drivers/rockchip-spi/unbind
|
|
fi
|
|
|
|
echo "Binding..."
|
|
echo ff1d0000.spi > /sys/bus/platform/drivers/rockchip-spi/bind
|
|
|
|
echo "Finished"
|
|
EOF
|
|
}
|
|
|
|
#-----------
|
|
#zfs specific commands can be seen in the boot loader prompt using
|
|
# UBOOT #help
|
|
#
|
|
# zfsls - list files in a directory (default /)
|
|
# zfsload- load binary file from a ZFS file system
|
|
#
|
|
#2. To list the files in zfs pool, device or partition, execute
|
|
# zfsls <interface> <dev[:part]> [POOL/@/dir/file]
|
|
# For example:
|
|
# UBOOT #zfsls mmc 0:5 /rpool/@/usr/bin/
|
|
#
|
|
#3. To read and load a file from an ZFS formatted partition to RAM, execute
|
|
# zfsload <interface> <dev[:part]> [addr] [filename] [bytes]
|
|
# For example:
|
|
# UBOOT #zfsload mmc 2:2 0x30007fc0 /rpool/@/boot/uImage
|
|
#:
|