First Commit

This commit is contained in:
leeboby
2020-10-30 09:50:39 +08:00
commit e5f9bb65ac
845 changed files with 177861 additions and 0 deletions

305
scripts/build-all-ng.sh Executable file
View File

@@ -0,0 +1,305 @@
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
# pack_upload
# build_main
# array_contains
# build_all
[[ -z $START ]] && START="0"
[[ -z $BSP_BUILD ]] && BSP_BUILD="no"
[[ -z $MULTITHREAD ]] && MULTITHREAD="0"
[[ -z $STABILITY ]] && STABILITY="stable"
[[ -z $BUILD_OPT ]] && BUILD_OPT="image"
[[ -z $BRANCH_OVER ]] && BRANCH_OVER=""
[[ -z $RELEASE_OVER ]] && RELEASE_OVER=""
[[ -z $CLEAN_LEVEL ]] && CLEAN_LEVEL="oldcache"
[[ -z $KERNEL_CONFIGURE ]] && KERNEL_CONFIGURE="no"
# cleanup
rm -f /run/orangepi/*.pid
mkdir -p /run/orangepi
# read user defined targets if exits
if [[ -f $USERPATCHES_PATH/targets.conf ]]; then
display_alert "Adding user provided targets configuration"
BUILD_TARGETS="${USERPATCHES_PATH}/targets.conf"
else
BUILD_TARGETS="${EXTER}/config/targets.conf"
fi
unset_all ()
{
unset LINUXFAMILY LINUXCONFIG KERNELDIR KERNELSOURCE KERNELBRANCH BOOTDIR BOOTSOURCE BOOTBRANCH ARCH UBOOT_USE_GCC \
KERNEL_USE_GCC CPUMIN CPUMAX UBOOT_VER KERNEL_VER GOVERNOR BOOTSIZE BOOTFS_TYPE UBOOT_TOOLCHAIN KERNEL_TOOLCHAIN \
DEBOOTSTRAP_LIST PACKAGE_LIST_EXCLUDE KERNEL_IMAGE_TYPE write_uboot_platform family_tweaks family_tweaks_bsp \
setup_write_uboot_platform uboot_custom_postprocess atf_custom_postprocess family_tweaks_s BOOTSCRIPT \
UBOOT_TARGET_MAP LOCALVERSION UBOOT_COMPILER KERNEL_COMPILER BOOTCONFIG_VAR_NAME INITRD_ARCH BOOTENV_FILE BOOTDELAY \
ATF_TOOLCHAIN2 MOUNT SDCARD BOOTPATCHDIR KERNELPATCHDIR RELEASE IMAGE_TYPE OVERLAY_PREFIX ASOUND_STATE ATF_COMPILER \
ATF_USE_GCC ATFSOURCE ATFDIR ATFBRANCH ATFSOURCEDIR PACKAGE_LIST_RM NM_IGNORE_DEVICES DISPLAY_MANAGER \
family_tweaks_bsp_s CRYPTROOT_ENABLE CRYPTROOT_PASSPHRASE CRYPTROOT_SSH_UNLOCK CRYPTROOT_SSH_UNLOCK_PORT \
CRYPTROOT_SSH_UNLOCK_KEY_NAME ROOT_MAPPER NETWORK HDMI USB WIRELESS ARMBIANMONITOR FORCE_BOOTSCRIPT_UPDATE \
UBOOT_TOOLCHAIN2 toolchain2 BUILD_REPOSITORY_URL BUILD_REPOSITORY_COMMIT BUILD_TARGET HOST BUILD_IMAGE \
DEB_STORAGE REPO_STORAGE REPO_CONFIG REPOSITORY_UPDATE PACKAGE_LIST_RELEASE LOCAL_MIRROR COMPILE_ATF \
PACKAGE_LIST_BOARD PACKAGE_LIST_FAMILY PACKAGE_LIST_DESKTOP_BOARD PACKAGE_LIST_DESKTOP_FAMILY ATF_COMPILE ATFPATCHDIR OFFSET BOOTSOURCEDIR BOOT_USE_BLOBS \
BOOT_SOC DDR_BLOB MINILOADER_BLOB BL31_BLOB BOOT_RK3328_USE_AYUFAN_ATF BOOT_USE_BLOBS BOOT_RK3399_LEGACY_HYBRID \
BOOT_USE_MAINLINE_ATF BOOT_USE_TPL_SPL_BLOB OFFLINE_WORK IMAGE_PARTITION_TABLE BOOT_LOGO
}
pack_upload ()
{
# pack and upload to server or just pack
local version="${BOARD^}_${REVISION}_${RELEASE}_${BRANCH}_${VER/-$LINUXFAMILY/}"
local subdir=""
cd "${DESTIMG}" || exit
if [[ -n "${SEND_TO_SERVER}" ]]; then
ssh "${SEND_TO_SERVER}" "mkdir -p ${SEND_TO_LOCATION}${BOARD}/{archive,nightly}" &
display_alert "Uploading" "Please wait!" "info"
nice -n 19 bash -c "rsync -arP --info=progress2 --prune-empty-dirs $DESTIMG/ -e 'ssh -T -c aes128-ctr -o Compression=no -x -p 22' ${SEND_TO_SERVER}:${SEND_TO_LOCATION}${BOARD}/${subdir}; rm -rf ${DESTIMG}/*" &
fi
}
build_main ()
{
# build images which we do pack or kernel
#local upload_image="${BOARD^}_$(cat ${SRC}/VERSION)_${RELEASE}_${BRANCH}_*${VER/-$LINUXFAMILY/}"
#local upload_subdir="archive"
[[ $BUILD_DESKTOP == yes ]] && upload_image=${upload_image}_desktop
[[ $BUILD_MINIMAL == yes ]] && upload_image=${upload_image}_minimal
touch "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid";
if [[ $BUILD_OPT == image ]]; then
#if ssh ${SEND_TO_SERVER} stat ${SEND_TO_LOCATION}${BOARD}/${upload_subdir}/${upload_image}* \> /dev/null 2\>\&1; then
# echo "$n exists $upload_image"
#else
#shellcheck source=main.sh
source "${SRC}"/scripts/main.sh
#[[ $BSP_BUILD != yes ]] && pack_upload
#fi
else
source "${SRC}"/scripts/main.sh
fi
echo -e "\n"
rm "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid"
}
array_contains ()
{
# utility snippet
local array="$1[@]"
local seeking=$2
local in=1
for element in "${!array}"; do
if [[ "${element}" == "${seeking}" ]]; then
in=0
break
fi
done
return $in
}
function build_all()
{
# main routine
buildall_start=$(date +%s)
n=0
ARRAY=()
buildlist="cat "
if [[ -f $USERPATCHES_PATH/build_all.config ]]; then
source $USERPATCHES_PATH/build_all.config
elif [[ -f $EXTER/config/templates/build_all.config ]]; then
cp $EXTER/config/templates/build_all.config $USERPATCHES_PATH/
source $USERPATCHES_PATH/build_all.config
fi
# building selected ones
if [[ -n ${REBUILD_IMAGES} ]]; then
buildlist="grep -w '"
filter="'"
for build in $(tr ',' ' ' <<< "${REBUILD_IMAGES}"); do
buildlist=$buildlist"$build\|"
filter=$filter"$build\|"
done
buildlist=${buildlist::-2}"'"
filter=${filter::-2}"'"
fi
# find unique boards - we will build debs for all variants
sorted_unique_ids=($(echo "${ids[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
unique_boards=$(eval "${buildlist}" ${EXTER}/config/targets.conf | sed '/^#/ d' | awk '{print $1}')
read -a unique_boards <<< $(echo "${unique_boards[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')
while read -r line; do
[[ "${line}" =~ ^#.*$ ]] && continue
[[ -n "${REBUILD_IMAGES}" ]] && [[ -z $(echo "${line}" | eval grep -w "${filter}") ]] && continue
#[[ $n -lt $START ]] && ((n+=1)) && continue
unset_all
# unset also board related variables
unset BOARDFAMILY DESKTOP_AUTOLOGIN DEFAULT_CONSOLE FULL_DESKTOP MODULES_CURRENT MODULES_LEGACY MODULES_DEV \
BOOTCONFIG MODULES_BLACKLIST_LEGACY MODULES_BLACKLIST_CURRENT MODULES_BLACKLIST_DEV DEFAULT_OVERLAYS SERIALCON \
BUILD_MINIMAL RELEASE ATFBRANCH BOOT_FDT_FILE BOOTCONFIG_DEV
read -r BOARD BRANCH RELEASE BUILD_TARGET BUILD_STABILITY BUILD_IMAGE <<< "${line}"
# read all possible configurations
source ${EXTER}"/config/boards/${BOARD}".conf 2> /dev/null
# override branch to build selected branches if defined
[[ -n "${BRANCH_OVER}" ]] && [[ ${BRANCH} != ${BRANCH_OVER} ]] && continue
# override release to build selected release if defined
[[ -n "${RELEASE_OVER}" ]] && [[ "$RELEASE" != ${RELEASE_OVER} ]] && continue
# override board to build selected board if defined
[[ -n "${BOARD_OVER}" ]] && [[ "$BOARD" != ${BOARD_OVER} ]] && continue
# small optimisation. we only (try to) build needed kernels
if [[ $BUILD_OPT == kernel ]]; then
source "${EXTER}/config/sources/families/${BOARDFAMILY}.conf" 2> /dev/null
array_contains ARRAY "${LINUXFAMILY}${BRANCH}${BUILD_STABILITY}" && continue
ARRAY+=("${LINUXFAMILY}${BRANCH}${BUILD_STABILITY}")
BOARDFAMILY=${LINUXFAMILY}
elif [[ $BUILD_OPT == u-boot ]]; then
source "${EXTER}/config/sources/families/${BOARDFAMILY}.conf" 2> /dev/null
array_contains ARRAY "${BOARD}${BRANCH}${BUILD_STABILITY}" && continue
ARRAY+=("${BOARD}${BRANCH}${BUILD_STABILITY}")
elif [[ $BUILD_IMAGE == no ]] ; then
continue
fi
BUILD_DESKTOP="no"
BUILD_MINIMAL="no"
[[ ${BUILD_TARGET} == "desktop" ]] && BUILD_DESKTOP="yes"
[[ ${BUILD_TARGET} == "minimal" ]] && BUILD_MINIMAL="yes"
# create beta or stable
if [[ "${BUILD_STABILITY}" == "${STABILITY}" ]]; then
((n+=1))
if [[ $1 != "dryrun" ]] && [[ $n -ge $START ]]; then
while :
do
[[ $(find /run/orangepi/*.pid 2>/dev/null | wc -l) -le ${MULTITHREAD} || -z ${MULTITHREAD} ]] && break
sleep 5
done
display_alert "Building ${n}."
(build_main)
# create BSP for all boards
elif [[ "${BSP_BUILD}" == yes ]]; then
for BOARD in "${unique_boards[@]}"
do
source ${EXTER}"/config/boards/${BOARD}".conf 2> /dev/null
IFS=',' read -a RELBRANCH <<< $KERNEL_TARGET
for BRANCH in "${RELBRANCH[@]}"
do
RELTARGETS=(xenial buster bionic focal)
for RELEASE in "${RELTARGETS[@]}"
do
display_alert "BSP for ${BOARD} ${BRANCH} ${RELEASE}."
build_main
# unset non board related stuff
unset_all
done
done
done
display_alert "Done building all BSP images"
exit
else
# In dryrun it only prints out what will be build
printf "%s\t%-32s\t%-8s\t%-14s\t%-6s\t%-6s\t%-6s\n" "${n}." \
"$BOARD (${BOARDFAMILY})" "${BRANCH}" "${RELEASE}" "${BUILD_DESKTOP}" "${BUILD_MINIMAL}"
fi
fi
done < "${BUILD_TARGETS}"
}
# display what will be build
echo ""
display_alert "Building all targets" "$STABILITY - $BUILD_OPT"
printf "\n%s\t%-32s\t%-8s\t%-14s\t%-6s\t%-6s\t%-6s\n\n" "" "board" "branch" "release" "XFCE" "minimal"
# display what we will build
build_all "dryrun"
if [[ $BUILD_ALL != demo ]] ; then
echo ""
# build
build_all
fi
# wait until they are not finshed
sleep 5
while :
do
if [[ $(df | grep -c .tmp) -lt 1 ]]; then
break
fi
sleep 5
done
while :
do
if [[ -z $(ps -uax | grep 7z | grep OrangePi) ]]; then
break
fi
sleep 5
done
buildall_end=$(date +%s)
buildall_runtime=$(((buildall_end - buildall_start) / 60))
display_alert "Runtime in total" "${buildall_runtime} min" "info"

374
scripts/chroot-buildpackages.sh Executable file
View File

@@ -0,0 +1,374 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
# create_chroot
# chroot_prepare_distccd
# chroot_build_packages
# chroot_installpackages_local
# chroot_installpackages
# create_chroot <target_dir> <release> <arch>
#
create_chroot()
{
local target_dir="$1"
local release=$2
local arch=$3
declare -A qemu_binary apt_mirror components
qemu_binary['armhf']='qemu-arm-static'
qemu_binary['arm64']='qemu-aarch64-static'
apt_mirror['stretch']="$DEBIAN_MIRROR"
apt_mirror['buster']="$DEBIAN_MIRROR"
apt_mirror['bullseye']="$DEBIAN_MIRROR"
apt_mirror['xenial']="$UBUNTU_MIRROR"
apt_mirror['bionic']="$UBUNTU_MIRROR"
apt_mirror['focal']="$UBUNTU_MIRROR"
apt_mirror['eoan']="$UBUNTU_MIRROR"
components['stretch']='main,contrib'
components['buster']='main,contrib'
components['bullseye']='main,contrib'
components['xenial']='main,universe,multiverse'
components['bionic']='main,universe,multiverse'
components['focal']='main,universe,multiverse'
components['eoan']='main,universe,multiverse'
display_alert "Creating build chroot" "$release/$arch" "info"
local includes="ccache,locales,git,ca-certificates,devscripts,libfile-fcntllock-perl,debhelper,rsync,python3,distcc"
# perhaps a temporally workaround
[[ $release == buster || $release == bullseye || $release == focal || $release == eoan ]] && includes=${includes}",perl-openssl-defaults,libnet-ssleay-perl"
if [[ $NO_APT_CACHER != yes ]]; then
local mirror_addr="http://localhost:3142/${apt_mirror[${release}]}"
else
local mirror_addr="http://${apt_mirror[${release}]}"
fi
debootstrap --variant=buildd --components="${components[${release}]}" --arch="${arch}" --foreign --include="${includes}" "${release}" "${target_dir}" "${mirror_addr}"
[[ $? -ne 0 || ! -f "${target_dir}"/debootstrap/debootstrap ]] && exit_with_error "Create chroot first stage failed"
cp /usr/bin/${qemu_binary[$arch]} "${target_dir}"/usr/bin/
[[ ! -f "${target_dir}"/usr/share/keyrings/debian-archive-keyring.gpg ]] && \
mkdir -p "${target_dir}"/usr/share/keyrings/ && \
cp /usr/share/keyrings/debian-archive-keyring.gpg "${target_dir}"/usr/share/keyrings/
chroot "${target_dir}" /bin/bash -c "/debootstrap/debootstrap --second-stage"
[[ $? -ne 0 || ! -f "${target_dir}"/bin/bash ]] && exit_with_error "Create chroot second stage failed"
create_sources_list "$release" "${target_dir}"
[[ $NO_APT_CACHER != yes ]] && \
echo 'Acquire::http { Proxy "http://localhost:3142"; };' > "${target_dir}"/etc/apt/apt.conf.d/02proxy
cat <<-EOF > "${target_dir}"/etc/apt/apt.conf.d/71-no-recommends
APT::Install-Recommends "0";
APT::Install-Suggests "0";
EOF
[[ -f "${target_dir}"/etc/locale.gen ]] && sed -i "s/^# en_US.UTF-8/en_US.UTF-8/" "${target_dir}"/etc/locale.gen
chroot "${target_dir}" /bin/bash -c "locale-gen; update-locale LANG=en_US:en LC_ALL=en_US.UTF-8"
printf '#!/bin/sh\nexit 101' > "${target_dir}"/usr/sbin/policy-rc.d
chmod 755 "${target_dir}"/usr/sbin/policy-rc.d
rm "${target_dir}"/etc/resolv.conf 2>/dev/null
echo "nameserver $NAMESERVER" > "${target_dir}"/etc/resolv.conf
rm "${target_dir}"/etc/hosts 2>/dev/null
echo "127.0.0.1 localhost" > "${target_dir}"/etc/hosts
mkdir -p "${target_dir}"/root/{build,overlay,sources} "${target_dir}"/selinux
if [[ -L "${target_dir}"/var/lock ]]; then
rm -rf "${target_dir}"/var/lock 2>/dev/null
mkdir -p "${target_dir}"/var/lock
fi
chroot "${target_dir}" /bin/bash -c "/usr/sbin/update-ccache-symlinks"
[[ $release == focal ]] && chroot "${target_dir}" /bin/bash -c "ln -s /usr/bin/python3 /usr/bin/python"
touch "${target_dir}"/root/.debootstrap-complete
display_alert "Debootstrap complete" "${release}/${arch}" "info"
} #############################################################################
# chroot_prepare_distccd <release> <arch>
#
chroot_prepare_distccd()
{
local release=$1
local arch=$2
local dest=/tmp/distcc/${release}-${arch}
declare -A gcc_version gcc_type
gcc_version['stretch']='6.3'
gcc_version['buster']='8.3'
gcc_version['bullseye']='9.2'
gcc_version['xenial']='5.4'
gcc_version['bionic']='5.4'
gcc_version['focal']='9.2'
gcc_version['eoan']='9.2'
gcc_type['armhf']='arm-linux-gnueabihf-'
gcc_type['arm64']='aarch64-linux-gnu-'
rm -f "${dest}"/cmdlist
mkdir -p "${dest}"
#local toolchain_path=$(find_toolchain "${gcc_type[$arch]}" "== ${gcc_version[$release]}")
local toolchain_path
toolchain_path=${toolchain}
ln -sf "${toolchain_path}/${gcc_type[${arch}]}gcc" "${dest}"/cc
echo "${dest}/cc" >> "${dest}"/cmdlist
for compiler in gcc cpp g++ c++; do
echo "${dest}/$compiler" >> "${dest}"/cmdlist
echo "${dest}/${gcc_type[$arch]}${compiler}" >> "${dest}"/cmdlist
ln -sf "${toolchain_path}/${gcc_type[${arch}]}${compiler}" "${dest}/${compiler}"
ln -sf "${toolchain_path}/${gcc_type[${arch}]}${compiler}" "${dest}/${gcc_type[${arch}]}${compiler}"
done
mkdir -p /var/run/distcc/
touch /var/run/distcc/"${release}-${arch}".pid
chown -R distccd /var/run/distcc/
chown -R distccd /tmp/distcc
}
# chroot_build_packages
#
chroot_build_packages()
{
local built_ok=()
local failed=()
if [[ $IMAGE_TYPE == user-built ]]; then
# if user-built image compile only for selected arch/release
target_release="${RELEASE}"
target_arch="${ARCH}"
else
# only make packages for recent releases. There are no changes on older
target_release="stretch bionic buster bullseye eoan focal"
target_arch="armhf arm64"
fi
for release in $target_release; do
for arch in $target_arch; do
display_alert "Starting package building process" "$release/$arch" "info"
local target_dir
target_dir="${DEST}/buildpkg/${release}-${arch}-v${CHROOT_CACHE_VERSION}"
local distcc_bindaddr="127.0.0.2"
[[ ! -f "${target_dir}"/root/.debootstrap-complete ]] && create_chroot "${target_dir}" "${release}" "${arch}"
[[ ! -f "${target_dir}"/root/.debootstrap-complete ]] && exit_with_error "Creating chroot failed" "${release}/${arch}"
[[ -f /var/run/distcc/"${release}-${arch}".pid ]] && kill "$(<"/var/run/distcc/${release}-${arch}.pid")" > /dev/null 2>&1
chroot_prepare_distccd "${release}" "${arch}"
# DISTCC_TCP_DEFER_ACCEPT=0
DISTCC_CMDLIST=/tmp/distcc/${release}-${arch}/cmdlist TMPDIR=/tmp/distcc distccd --daemon \
--pid-file "/var/run/distcc/${release}-${arch}.pid" --listen $distcc_bindaddr --allow 127.0.0.0/24 \
--log-file "/tmp/distcc/${release}-${arch}.log" --user distccd
local t=$target_dir/root/.update-timestamp
if [[ ! -f ${t} || $(( ($(date +%s) - $(<"${t}")) / 86400 )) -gt 7 ]]; then
display_alert "Upgrading packages" "$release/$arch" "info"
systemd-nspawn -a -q -D "${target_dir}" /bin/bash -c "apt-get -q update; apt-get -q -y upgrade; apt-get clean"
date +%s > "${t}"
fi
for plugin in "${EXTER}"/packages/extras-buildpkgs/*.conf; do
unset package_name package_repo package_ref package_builddeps package_install_chroot package_install_target \
package_upstream_version needs_building plugin_target_dir package_component "package_builddeps_${release}"
source "${plugin}"
# check build condition
if [[ $(type -t package_checkbuild) == function ]] && ! package_checkbuild; then
display_alert "Skipping building $package_name for" "$release/$arch" >/dev/null 2>&1
continue
fi
local plugin_target_dir=${DEB_STORAGE}/extra/$package_component/
mkdir -p "${plugin_target_dir}"
# check if needs building
local needs_building=no
if [[ -n $package_install_target ]]; then
for f in $package_install_target; do
if [[ -z $(find "${plugin_target_dir}" -name "${f}_*$REVISION*_$arch.deb") ]]; then
needs_building=yes
break
fi
done
else
needs_building=yes
fi
if [[ $needs_building == no ]]; then
display_alert "Packages are up to date" "$package_name $release/$arch" "info" >/dev/null 2>&1
continue
fi
display_alert "Building packages" "$package_name $release/$arch" "ext"
local dist_builddeps_name="package_builddeps_${release}"
[[ -v $dist_builddeps_name ]] && package_builddeps="${package_builddeps} ${!dist_builddeps_name}"
# create build script
cat <<-EOF > "${target_dir}"/root/build.sh
#!/bin/bash
export PATH="/usr/lib/ccache:\$PATH"
export HOME="/root"
export DEBIAN_FRONTEND="noninteractive"
export DEB_BUILD_OPTIONS="nocheck noautodbgsym"
export CCACHE_TEMPDIR="/tmp"
# distcc is disabled to prevent compilation issues due to different host and cross toolchain configurations
#export CCACHE_PREFIX="distcc"
# uncomment for debug
#export CCACHE_RECACHE="true"
#export CCACHE_DISABLE="true"
export DISTCC_HOSTS="$distcc_bindaddr"
export DEBFULLNAME="$MAINTAINER"
export DEBEMAIL="$MAINTAINERMAIL"
$(declare -f display_alert)
cd /root/build
if [[ -n "${package_builddeps}" ]]; then
# can be replaced with mk-build-deps
deps=()
installed=\$(dpkg-query -W -f '\${db:Status-Abbrev}|\${binary:Package}\n' '*' 2>/dev/null | grep '^ii' | awk -F '|' '{print \$2}' | cut -d ':' -f 1)
for packet in $package_builddeps; do grep -q -x -e "\$packet" <<< "\$installed" || deps+=("\$packet"); done
if [[ \${#deps[@]} -gt 0 ]]; then
display_alert "Installing build dependencies"
apt-get -y -q update
apt-get -y -q --no-install-recommends --show-progress -o DPKG::Progress-Fancy=1 install "\${deps[@]}"
fi
fi
display_alert "Copying sources"
rsync -aq /root/sources/"${package_name}" /root/build/
cd /root/build/"${package_name}"
# copy overlay / "debianization" files
[[ -d "/root/overlay/${package_name}/" ]] && rsync -aq /root/overlay/"${package_name}" /root/build/
# set upstream version
[[ -n "${package_upstream_version}" ]] && debchange --preserve --newversion "${package_upstream_version}" "Import from upstream"
# set local version
# debchange -l~orangepi${REVISION}-${builddate}+ "New Orange Pi release"
debchange -l~orangepi${REVISION}+ "New Orange Pi release"
display_alert "Building package"
dpkg-buildpackage -b -uc -us -j2
if [[ \$? -eq 0 ]]; then
cd /root/build
# install in chroot if other libraries depend on them
if [[ -n "$package_install_chroot" ]]; then
display_alert "Installing packages"
for p in $package_install_chroot; do
dpkg -i \${p}_*.deb
done
fi
display_alert "Done building" "$package_name $release/$arch" "ext"
ls *.deb 2>/dev/null
mv *.deb /root 2>/dev/null
exit 0
else
display_alert "Failed building" "$package_name $release/$arch" "err"
exit 2
fi
EOF
chmod +x "${target_dir}"/root/build.sh
fetch_from_repo "$package_repo" "${EXTER}/cache/sources/extra/$package_name" "$package_ref"
eval systemd-nspawn -a -q --capability=CAP_MKNOD -D $target_dir --tmpfs=/root/build --tmpfs=/tmp:mode=777 --bind-ro $EXTER/packages/extras-buildpkgs/:/root/overlay \
--bind-ro $EXTER/cache/sources/extra/:/root/sources /bin/bash -c "/root/build.sh" 2>&1 \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/buildpkg.log'}
if [[ ${PIPESTATUS[0]} -eq 2 ]]; then
failed+=("$package_name:$release/$arch")
else
built_ok+=("$package_name:$release/$arch")
fi
mv "${target_dir}"/root/*.deb "${plugin_target_dir}" 2>/dev/null
done
# cleanup for distcc
kill "$(<"/var/run/distcc/${release}-${arch}.pid")"
done
done
if [[ ${#built_ok[@]} -gt 0 ]]; then
display_alert "Following packages were built without errors" "" "info"
for p in ${built_ok[@]}; do
display_alert "$p"
done
fi
if [[ ${#failed[@]} -gt 0 ]]; then
display_alert "Following packages failed to build" "" "wrn"
for p in ${failed[@]}; do
display_alert "$p"
done
fi
} #############################################################################
# chroot_installpackages_local
#
chroot_installpackages_local()
{
local conf=$EXTER/config/aptly-temp.conf
rm -rf /tmp/aptly-temp/
mkdir -p /tmp/aptly-temp/
echo -e "\n\t== Starting chroot_installpackages_local process ==\n" >>$DEST/debug/install.log
aptly -config=$conf repo create temp >> "${DEST}"/debug/install.log 2>&1
# NOTE: this works recursively
if [[ $EXTERNAL_NEW == prebuilt ]]; then
aptly -config=$conf repo add temp ${DEB_ORANGEPI}/extra/${RELEASE}-desktop/ >> "${DEST}"/debug/install.log 2>&1
aptly -config=$conf repo add temp ${DEB_ORANGEPI}/extra/${RELEASE}-utils/ >> "${DEST}"/debug/install.log 2>&1
else
aptly -config=$conf repo add temp ${DEB_STORAGE}/extra/${RELEASE}-desktop/ >> "${DEST}"/debug/install.log 2>&1
aptly -config=$conf repo add temp ${DEB_STORAGE}/extra/${RELEASE}-utils/ >> "${DEST}"/debug/install.log 2>&1
fi
# -gpg-key="925644A6"
aptly -keyring="$EXTER/packages/extras-buildpkgs/buildpkg-public.gpg" -secret-keyring="$EXTER/packages/extras-buildpkgs/buildpkg.gpg" -batch=true -config=$conf \
-gpg-key="925644A6" -passphrase="testkey1234" -component=temp -distribution=$RELEASE publish repo temp >> "${DEST}"/debug/install.log 2>&1
aptly -config=$conf -listen=":8189" serve >> "${DEST}"/debug/install.log 2>&1 &
local aptly_pid=$!
cp $EXTER/packages/extras-buildpkgs/buildpkg.key $SDCARD/tmp/buildpkg.key
cat <<-'EOF' > $SDCARD/etc/apt/preferences.d/90-orangepi-temp.pref
Package: *
Pin: origin "localhost"
Pin-Priority: 550
EOF
cat <<-EOF > "${SDCARD}"/etc/apt/sources.list.d/orangepi-temp.list
deb http://localhost:8189/ $RELEASE temp
EOF
chroot_installpackages
echo -e "\n\t== Finished chroot_installpackages_local process ==\n" >>$DEST/debug/install.log
kill "${aptly_pid}"
} #############################################################################
# chroot_installpackages
#
chroot_installpackages()
{
local install_list=""
for plugin in "${EXTER}"/packages/extras-buildpkgs/*.conf; do
source "$plugin"
if [[ $(type -t package_checkinstall) == function ]] && package_checkinstall; then
install_list="$install_list $package_install_target"
fi
unset package_install_target package_checkinstall
done
[[ $NO_APT_CACHER != yes ]] && local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\""
display_alert "Installing additional packages" "${install_list}"
cat <<-EOF > "${SDCARD}"/tmp/install.sh
#!/bin/bash
apt-key add /tmp/buildpkg.key
apt-get $apt_extra -q update
apt-get -q $apt_extra --show-progress -o DPKG::Progress-Fancy=1 install -y $install_list
apt-get clean
apt-key del "925644A6"
rm /etc/apt/sources.list.d/orangepi-temp.list
rm /etc/apt/preferences.d/90-orangepi-temp.pref
rm /tmp/buildpkg.key
rm -- "\$0"
EOF
chmod +x "${SDCARD}"/tmp/install.sh
chroot "${SDCARD}" /bin/bash -c "/tmp/install.sh" >> "${DEST}"/debug/install.log 2>&1
} #############################################################################

865
scripts/compilation.sh Executable file
View File

@@ -0,0 +1,865 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
# compile_atf
# compile_uboot
# compile_kernel
# compile_firmware
# compile_orangepi-config
# compile_sunxi_tools
# install_rkbin_tools
# grab_version
# find_toolchain
# advanced_patch
# process_patch_file
# userpatch_create
# overlayfs_wrapper
compile_atf()
{
if [[ $CLEAN_LEVEL == *make* ]]; then
display_alert "Cleaning" "$ATFSOURCEDIR" "info"
(cd "${EXTER}/cache/sources/${ATFSOURCEDIR}"; make distclean > /dev/null 2>&1)
fi
if [[ $USE_OVERLAYFS == yes ]]; then
local atfdir
atfdir=$(overlayfs_wrapper "wrap" "$EXTER/cache/sources/$ATFSOURCEDIR" "atf_${LINUXFAMILY}_${BRANCH}")
else
local atfdir="$EXTER/cache/sources/$ATFSOURCEDIR"
fi
cd "$atfdir" || exit
display_alert "Compiling ATF" "" "info"
local toolchain
toolchain=$(find_toolchain "$ATF_COMPILER" "$ATF_USE_GCC")
[[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${ATF_COMPILER}gcc $ATF_USE_GCC"
if [[ -n $ATF_TOOLCHAIN2 ]]; then
local toolchain2_type toolchain2_ver toolchain2
toolchain2_type=$(cut -d':' -f1 <<< "${ATF_TOOLCHAIN2}")
toolchain2_ver=$(cut -d':' -f2 <<< "${ATF_TOOLCHAIN2}")
toolchain2=$(find_toolchain "$toolchain2_type" "$toolchain2_ver")
[[ -z $toolchain2 ]] && exit_with_error "Could not find required toolchain" "${toolchain2_type}gcc $toolchain2_ver"
fi
display_alert "Compiler version" "${ATF_COMPILER}gcc $(eval env PATH="${toolchain}:${PATH}" "${ATF_COMPILER}gcc" -dumpversion)" "info"
local target_make target_patchdir target_files
target_make=$(cut -d';' -f1 <<< "${ATF_TARGET_MAP}")
target_patchdir=$(cut -d';' -f2 <<< "${ATF_TARGET_MAP}")
target_files=$(cut -d';' -f3 <<< "${ATF_TARGET_MAP}")
advanced_patch "atf" "${ATFPATCHDIR}" "$BOARD" "$target_patchdir" "$BRANCH" "${LINUXFAMILY}-${BOARD}-${BRANCH}"
# create patch for manual source changes
[[ $CREATE_PATCHES == yes ]] && userpatch_create "atf"
echo -e "\n\t== atf ==\n" >> "${DEST}"/debug/compilation.log
# ENABLE_BACKTRACE="0" has been added to workaround a regression in ATF.
# Check: https://github.com/armbian/build/issues/1157
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${toolchain2}:${PATH}" \
'make ENABLE_BACKTRACE="0" $target_make $CTHREADS \
CROSS_COMPILE="$CCACHE $ATF_COMPILER"' 2>> "${DEST}"/debug/compilation.log \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/compilation.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Compiling ATF..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "ATF compilation failed"
[[ $(type -t atf_custom_postprocess) == function ]] && atf_custom_postprocess
local atftempdir=$SRC/.tmp/atf-${LINUXFAMILY}-${BOARD}-${BRANCH}
mkdir -p "${atftempdir}"
# copy files to temp directory
for f in $target_files; do
local f_src
f_src=$(cut -d':' -f1 <<< "${f}")
if [[ $f == *:* ]]; then
local f_dst
f_dst=$(cut -d':' -f2 <<< "${f}")
else
local f_dst
f_dst=$(basename "${f_src}")
fi
[[ ! -f $f_src ]] && exit_with_error "ATF file not found" "$(basename "${f_src}")"
cp "${f_src}" "${atftempdir}/${f_dst}"
done
# copy license file to pack it to u-boot package later
[[ -f license.md ]] && cp license.md "${atftempdir}"/
}
compile_uboot()
{
# not optimal, but extra cleaning before overlayfs_wrapper should keep sources directory clean
if [[ $CLEAN_LEVEL == *make* ]]; then
display_alert "Cleaning" "$BOOTSOURCEDIR" "info"
(cd $BOOTSOURCEDIR; make clean > /dev/null 2>&1)
fi
if [[ $USE_OVERLAYFS == yes ]]; then
local ubootdir
ubootdir=$(overlayfs_wrapper "wrap" "$BOOTSOURCEDIR" "u-boot_${LINUXFAMILY}_${BRANCH}")
else
local ubootdir="$BOOTSOURCEDIR"
fi
cd "${ubootdir}" || exit
# read uboot version
local version hash
version=$(grab_version "$ubootdir")
hash=$(git --git-dir="$ubootdir"/.git rev-parse HEAD)
display_alert "Compiling u-boot" "v$version" "info"
local toolchain
toolchain=$(find_toolchain "$UBOOT_COMPILER" "$UBOOT_USE_GCC")
[[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${UBOOT_COMPILER}gcc $UBOOT_USE_GCC"
if [[ -n $UBOOT_TOOLCHAIN2 ]]; then
local toolchain2_type toolchain2_ver toolchain2
toolchain2_type=$(cut -d':' -f1 <<< "${UBOOT_TOOLCHAIN2}")
toolchain2_ver=$(cut -d':' -f2 <<< "${UBOOT_TOOLCHAIN2}")
toolchain2=$(find_toolchain "$toolchain2_type" "$toolchain2_ver")
[[ -z $toolchain2 ]] && exit_with_error "Could not find required toolchain" "${toolchain2_type}gcc $toolchain2_ver"
fi
display_alert "Compiler version" "${UBOOT_COMPILER}gcc $(eval env PATH="${toolchain}:${toolchain2}:${PATH}" "${UBOOT_COMPILER}gcc" -dumpversion)" "info"
[[ -n $toolchain2 ]] && display_alert "Additional compiler version" "${toolchain2_type}gcc $(eval env PATH="${toolchain}:${toolchain2}:${PATH}" "${toolchain2_type}gcc" -dumpversion)" "info"
# create directory structure for the .deb package
local uboot_name=${CHOSEN_UBOOT}_${REVISION}_${ARCH}
rm -rf $SRC/.tmp/$uboot_name
mkdir -p $SRC/.tmp/$uboot_name/usr/lib/{u-boot,$uboot_name} $SRC/.tmp/$uboot_name/DEBIAN
# process compilation for one or multiple targets
while read -r target; do
local target_make target_patchdir target_files
target_make=$(cut -d';' -f1 <<< "${target}")
target_patchdir=$(cut -d';' -f2 <<< "${target}")
target_files=$(cut -d';' -f3 <<< "${target}")
if [[ $CLEAN_LEVEL == *make* ]]; then
display_alert "Cleaning" "$BOOTSOURCEDIR" "info"
(cd "$BOOTSOURCEDIR"; make clean > /dev/null 2>&1)
fi
advanced_patch "u-boot" "$BOOTPATCHDIR" "$BOARD" "$target_patchdir" "$BRANCH" "${LINUXFAMILY}-${BOARD}-${BRANCH}"
# create patch for manual source changes
[[ $CREATE_PATCHES == yes ]] && userpatch_create "u-boot"
if [[ -n $ATFSOURCE ]]; then
local atftempdir=$SRC/.tmp/atf-${LINUXFAMILY}-${BOARD}-${BRANCH}
cp -Rv "${atftempdir}"/*.bin .
fi
echo -e "\n\t== u-boot ==\n" >> "${DEST}"/debug/compilation.log
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${toolchain2}:${PATH}" \
'make $CTHREADS $BOOTCONFIG \
CROSS_COMPILE="$CCACHE $UBOOT_COMPILER"' 2>> "${DEST}"/debug/compilation.log \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/compilation.log'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
if [[ "${version}" != 2014.07 ]]; then
# orangepi specifics u-boot settings
[[ -f .config ]] && sed -i 's/CONFIG_LOCALVERSION=""/CONFIG_LOCALVERSION="-orangepi"/g' .config
[[ -f .config ]] && sed -i 's/CONFIG_LOCALVERSION_AUTO=.*/# CONFIG_LOCALVERSION_AUTO is not set/g' .config
# for modern kernel and non spi targets
if [[ ${BOOTBRANCH} =~ ^tag:v201[8-9](.*) && ${target} != "spi" && -f .config ]]; then
sed -i 's/^.*CONFIG_ENV_IS_IN_FAT.*/# CONFIG_ENV_IS_IN_FAT is not set/g' .config
sed -i 's/^.*CONFIG_ENV_IS_IN_EXT4.*/CONFIG_ENV_IS_IN_EXT4=y/g' .config
sed -i 's/^.*CONFIG_ENV_IS_IN_MMC.*/# CONFIG_ENV_IS_IN_MMC is not set/g' .config
sed -i 's/^.*CONFIG_ENV_IS_NOWHERE.*/# CONFIG_ENV_IS_NOWHERE is not set/g' .config | echo \
"# CONFIG_ENV_IS_NOWHERE is not set" >> .config
echo 'CONFIG_ENV_EXT4_INTERFACE="mmc"' >> .config
echo 'CONFIG_ENV_EXT4_DEVICE_AND_PART="0:auto"' >> .config
echo 'CONFIG_ENV_EXT4_FILE="/boot/boot.env"' >> .config
fi
[[ -f tools/logos/udoo.bmp ]] && cp "${EXTER}"/packages/blobs/splash/udoo.bmp tools/logos/udoo.bmp
touch .scmversion
# $BOOTDELAY can be set in board family config, ensure autoboot can be stopped even if set to 0
[[ $BOOTDELAY == 0 ]] && echo -e "CONFIG_ZERO_BOOTDELAY_CHECK=y" >> .config
[[ -n $BOOTDELAY ]] && sed -i "s/^CONFIG_BOOTDELAY=.*/CONFIG_BOOTDELAY=${BOOTDELAY}/" .config || [[ -f .config ]] && echo "CONFIG_BOOTDELAY=${BOOTDELAY}" >> .config
fi
# workaround when two compilers are needed
cross_compile="CROSS_COMPILE=$CCACHE $UBOOT_COMPILER";
[[ -n $UBOOT_TOOLCHAIN2 ]] && cross_compile="ORANGEPI=foe"; # empty parameter is not allowed
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${toolchain2}:${PATH}" \
'make $target_make $CTHREADS \
"${cross_compile}"' 2>>"${DEST}"/debug/compilation.log \
${PROGRESS_LOG_TO_FILE:+' | tee -a "${DEST}"/debug/compilation.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Compiling u-boot..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "U-boot compilation failed"
[[ $(type -t uboot_custom_postprocess) == function ]] && uboot_custom_postprocess
# copy files to build directory
for f in $target_files; do
local f_src
f_src=$(cut -d':' -f1 <<< "${f}")
if [[ $f == *:* ]]; then
local f_dst
f_dst=$(cut -d':' -f2 <<< "${f}")
else
local f_dst
f_dst=$(basename "${f_src}")
fi
[[ ! -f $f_src ]] && exit_with_error "U-boot file not found" "$(basename "${f_src}")"
cp "${f_src}" "${SRC}/.tmp/${uboot_name}/usr/lib/${uboot_name}/${f_dst}"
done
done <<< "$UBOOT_TARGET_MAP"
if [[ $PACK_UBOOT == "yes" ]];then
pack_uboot
cp ${SRC}/.tmp/packout/{boot0_sdcard.fex,boot_package.fex} "${SRC}/.tmp/${uboot_name}/usr/lib/${uboot_name}/"
cp ${SRC}/.tmp/packout/${BOARD}-u-boot.dts "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/"
cd "${ubootdir}" || exit
fi
# declare -f on non-defined function does not do anything
cat <<-EOF > "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/platform_install.sh"
DIR=/usr/lib/$uboot_name
$(declare -f write_uboot_platform)
$(declare -f write_uboot_platform_mtd)
$(declare -f setup_write_uboot_platform)
EOF
# set up control file
cat <<-EOF > "${SRC}/.tmp/${uboot_name}/DEBIAN/control"
Package: linux-u-boot-${BOARD}-${BRANCH}
Version: $REVISION
Architecture: $ARCH
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Installed-Size: 1
Section: kernel
Priority: optional
Provides: orangepi-u-boot
Replaces: orangepi-u-boot
Conflicts: orangepi-u-boot, u-boot-sunxi
Description: Uboot loader $version
EOF
# copy config file to the package
# useful for FEL boot with overlayfs_wrapper
[[ -f .config && -n $BOOTCONFIG ]] && cp .config "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/${BOOTCONFIG}"
# copy license files from typical locations
[[ -f COPYING ]] && cp COPYING "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/LICENSE"
[[ -f Licenses/README ]] && cp Licenses/README "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/LICENSE"
[[ -n $atftempdir && -f $atftempdir/license.md ]] && cp "${atftempdir}/license.md" "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/LICENSE.atf"
display_alert "Building deb" "${uboot_name}.deb" "info"
fakeroot dpkg-deb -b "${SRC}/.tmp/${uboot_name}" "${SRC}/.tmp/${uboot_name}.deb" >> "${DEST}"/debug/output.log 2>&1
rm -rf "${SRC}/.tmp/${uboot_name}"
[[ -n $atftempdir ]] && rm -rf "${atftempdir}"
[[ ! -f $SRC/.tmp/${uboot_name}.deb ]] && exit_with_error "Building u-boot package failed"
mv "${SRC}/.tmp/${uboot_name}.deb" "${DEB_STORAGE}/u-boot/"
}
compile_kernel()
{
if [[ $CLEAN_LEVEL == *make* ]]; then
display_alert "Cleaning" "$LINUXSOURCEDIR" "info"
(cd ${LINUXSOURCEDIR}; make ARCH="${ARCHITECTURE}" clean >/dev/null 2>&1)
fi
if [[ $USE_OVERLAYFS == yes ]]; then
local kerneldir
kerneldir=$(overlayfs_wrapper "wrap" "$LINUXSOURCEDIR" "kernel_${LINUXFAMILY}_${BRANCH}")
else
local kerneldir="$LINUXSOURCEDIR"
fi
cd "${kerneldir}" || exit
if ! grep -qoE '^-rc[[:digit:]]+' <(grep "^EXTRAVERSION" Makefile | head -1 | awk '{print $(NF)}'); then
sed -i 's/EXTRAVERSION = .*/EXTRAVERSION = /' Makefile
fi
rm -f localversion
# read kernel version
local version hash
version=$(grab_version "$kerneldir")
# read kernel git hash
hash=$(git --git-dir="$kerneldir"/.git rev-parse HEAD)
# build 3rd party drivers
# compilation_prepare
advanced_patch "kernel" "$KERNELPATCHDIR" "$BOARD" "" "$BRANCH" "$LINUXFAMILY-$BRANCH"
# create patch for manual source changes in debug mode
[[ $CREATE_PATCHES == yes ]] && userpatch_create "kernel"
# re-read kernel version after patching
local version
version=$(grab_version "$kerneldir")
# create linux-source package - with already patched sources
local sources_pkg_dir=$SRC/.tmp/${CHOSEN_KSRC}_${REVISION}_all
rm -rf "${sources_pkg_dir}"
mkdir -p "${sources_pkg_dir}"/usr/src/ "${sources_pkg_dir}/usr/share/doc/linux-source-${version}-${LINUXFAMILY}" "${sources_pkg_dir}"/DEBIAN
if [[ $BUILD_KSRC == yes ]]; then
display_alert "Cleaning" "$LINUXSOURCEDIR" "info"
(cd $LINUXSOURCEDIR; make ARCH=$ARCHITECTURE clean >/dev/null 2>&1)
display_alert "Compressing sources for the linux-source package"
tar cp --directory="$kerneldir" --exclude='./.git/' --owner=root . \
| pv -p -b -r -s "$(du -sb "$kerneldir" --exclude=='./.git/' | cut -f1)" \
| pixz -4 > "${sources_pkg_dir}/usr/src/linux-source-${version}-${LINUXFAMILY}.tar.xz"
cp COPYING "${sources_pkg_dir}/usr/share/doc/linux-source-${version}-${LINUXFAMILY}/LICENSE"
fi
display_alert "Compiling $BRANCH kernel" "$version" "info"
local toolchain
toolchain=$(find_toolchain "$KERNEL_COMPILER" "$KERNEL_USE_GCC")
[[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${KERNEL_COMPILER}gcc $KERNEL_USE_GCC"
display_alert "Compiler version" "${KERNEL_COMPILER}gcc $(eval env PATH="${toolchain}:${PATH}" "${KERNEL_COMPILER}gcc" -dumpversion)" "info"
# copy kernel config
if [[ $KERNEL_KEEP_CONFIG == yes && -f "${DEST}"/config/$LINUXCONFIG.config ]]; then
display_alert "Using previous kernel config" "${DEST}/config/$LINUXCONFIG.config" "info"
cp "${DEST}/config/${LINUXCONFIG}.config" .config
else
if [[ -f $USERPATCHES_PATH/$LINUXCONFIG.config ]]; then
display_alert "Using kernel config provided by user" "userpatches/$LINUXCONFIG.config" "info"
cp "${USERPATCHES_PATH}/${LINUXCONFIG}.config" .config
else
display_alert "Using kernel config file" "config/kernel/$LINUXCONFIG.config" "info"
cp "${EXTER}/config/kernel/${LINUXCONFIG}.config" .config
fi
fi
# hack for deb builder. To pack what's missing in headers pack.
cp $EXTER/patch/misc/headers-debian-byteshift.patch /tmp
if [[ $KERNEL_CONFIGURE != yes ]]; then
if [[ $BRANCH == legacy ]]; then
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${PATH}" \
'make ARCH=$ARCHITECTURE CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" silentoldconfig'
else
# TODO: check if required
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${PATH}" \
'make ARCH=$ARCHITECTURE CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" olddefconfig'
fi
else
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${PATH}" \
'make $CTHREADS ARCH=$ARCHITECTURE CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" oldconfig'
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${PATH}" \
'make $CTHREADS ARCH=$ARCHITECTURE CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" ${KERNEL_MENUCONFIG:-menuconfig}'
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Error kernel menuconfig failed"
# store kernel config in easily reachable place
display_alert "Exporting new kernel config" "$DEST/config/$LINUXCONFIG.config" "info"
cp .config "${DEST}/config/${LINUXCONFIG}.config"
# export defconfig too if requested
if [[ $KERNEL_EXPORT_DEFCONFIG == yes ]]; then
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${PATH}" \
'make ARCH=$ARCHITECTURE CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" savedefconfig'
[[ -f defconfig ]] && cp defconfig "${DEST}/config/${LINUXCONFIG}.defconfig"
fi
fi
xz < .config > "${sources_pkg_dir}/usr/src/${LINUXCONFIG}_${version}_${REVISION}_config.xz"
echo -e "\n\t== kernel ==\n" >> "${DEST}"/debug/compilation.log
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${PATH}" \
'make $CTHREADS ARCH=$ARCHITECTURE \
CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" \
$SRC_LOADADDR \
LOCALVERSION="-$LINUXFAMILY" \
$KERNEL_IMAGE_TYPE modules dtbs 2>>$DEST/debug/compilation.log' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/compilation.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" \
--progressbox "Compiling kernel..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
if [[ ${PIPESTATUS[0]} -ne 0 || ! -f arch/$ARCHITECTURE/boot/$KERNEL_IMAGE_TYPE ]]; then
exit_with_error "Kernel was not built" "@host"
fi
# different packaging for 4.3+
if linux-version compare "${version}" ge 4.3; then
local kernel_packing="bindeb-pkg"
else
local kernel_packing="deb-pkg"
fi
display_alert "Creating packages"
# produce deb packages: image, headers, firmware, dtb
echo -e "\n\t== deb packages: image, headers, firmware, dtb ==\n" >> "${DEST}"/debug/compilation.log
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${PATH}" \
'make -j1 $kernel_packing \
KDEB_PKGVERSION=$REVISION \
BRANCH=$BRANCH \
LOCALVERSION="-${LINUXFAMILY}" \
KBUILD_DEBARCH=$ARCH \
ARCH=$ARCHITECTURE \
DEBFULLNAME="$MAINTAINER" \
DEBEMAIL="$MAINTAINERMAIL" \
CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" 2>>$DEST/debug/compilation.log' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/compilation.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Creating kernel packages..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
cat <<-EOF > "${sources_pkg_dir}"/DEBIAN/control
Package: linux-source-${version}-${BRANCH}-${LINUXFAMILY}
Version: ${version}-${BRANCH}-${LINUXFAMILY}+${REVISION}
Architecture: all
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Section: kernel
Priority: optional
Depends: binutils, coreutils
Provides: linux-source, linux-source-${version}-${LINUXFAMILY}
Recommends: gcc, make
Description: This package provides the source code for the Linux kernel $version
EOF
if [[ $BUILD_KSRC == yes ]]; then
fakeroot dpkg-deb -z0 -b "${sources_pkg_dir}" "${sources_pkg_dir}.deb"
mv "${sources_pkg_dir}.deb" "${DEB_STORAGE}/"
fi
rm -rf "${sources_pkg_dir}"
cd .. || exit
# remove firmare image packages here - easier than patching ~40 packaging scripts at once
rm -f linux-firmware-image-*.deb
mv ./*.deb "${DEB_STORAGE}/" || exit_with_error "Failed moving kernel DEBs"
# store git hash to the file
echo "${hash}" > "${EXTER}/cache/hash/linux-image-${BRANCH}-${LINUXFAMILY}.githash"
[[ -z ${KERNELPATCHDIR} ]] && KERNELPATCHDIR=$LINUXFAMILY-$BRANCH
[[ -z ${LINUXCONFIG} ]] && LINUXCONFIG=linux-$LINUXFAMILY-$BRANCH
hash_watch_1=$(find "${EXTER}/patch/kernel/${KERNELPATCHDIR}" -maxdepth 1 -printf '%s %P\n' 2> /dev/null | sort)
hash_watch_2=$(cat "${EXTER}/config/kernel/${LINUXCONFIG}.config")
echo "${hash_watch_1}${hash_watch_2}" | git hash-object --stdin >> "${EXTER}/cache/hash/linux-image-${BRANCH}-${LINUXFAMILY}.githash"
}
compile_firmware()
{
display_alert "Merging and packaging linux firmware" "@host" "info"
if [[ $USE_MAINLINE_GOOGLE_MIRROR == yes ]]; then
plugin_repo="https://kernel.googlesource.com/pub/scm/linux/kernel/git/firmware/linux-firmware.git"
else
plugin_repo="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git"
[[ $DOWNLOAD_MIRROR == china ]] && plugin_repo="${GIT_SERVER}/linux-firmware.git"
fi
local plugin_dir="orangepi-firmware${FULL}"
[[ -d "${EXTER}/cache/sources/${plugin_dir}" ]] && rm -rf "${EXTER}/cache/sources/${plugin_dir}"
mkdir -p "${EXTER}/cache/sources/${plugin_dir}/lib/firmware"
fetch_from_repo "${GIT_SERVER}/firmware" "${EXTER}/cache/sources/orangepi-firmware-git" "branch:master"
if [[ -n $FULL ]]; then
fetch_from_repo "$plugin_repo" "${EXTER}/cache/sources/linux-firmware-git" "branch:master"
# cp : create hardlinks
#cp -alf "${EXTER}"/cache/sources/linux-firmware-git/* "${EXTER}/cache/sources/${plugin_dir}/lib/firmware/"
fi
# overlay our firmware
# cp : create hardlinks
if [[ -n $FULL ]]; then
cp -alf "${EXTER}"/cache/sources/linux-firmware-git/* "${EXTER}/cache/sources/${plugin_dir}/lib/firmware/"
else
cp -alf "${EXTER}"/cache/sources/orangepi-firmware-git/* "${EXTER}/cache/sources/${plugin_dir}/lib/firmware/"
fi
# cleanup what's not needed for sure
rm -rf "${EXTER}/cache/sources/${plugin_dir}"/lib/firmware/{amdgpu,amd-ucode,radeon,nvidia,matrox,.git}
cd "${EXTER}/cache/sources/${plugin_dir}" || exit
# set up control file
mkdir -p DEBIAN
cat <<-END > DEBIAN/control
Package: orangepi-firmware${FULL}
Version: $REVISION
Architecture: all
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Installed-Size: 1
Replaces: linux-firmware, firmware-brcm80211, firmware-ralink, firmware-samsung, firmware-realtek, orangepi-firmware${REPLACE}
Section: kernel
Priority: optional
Description: Linux firmware${FULL}
END
cd "${EXTER}"/cache/sources || exit
# pack
mv "orangepi-firmware${FULL}" "orangepi-firmware${FULL}_${REVISION}_all"
fakeroot dpkg -b "orangepi-firmware${FULL}_${REVISION}_all" >> "${DEST}"/debug/install.log 2>&1
mv "orangepi-firmware${FULL}_${REVISION}_all" "orangepi-firmware${FULL}"
mv "orangepi-firmware${FULL}_${REVISION}_all.deb" "${DEB_STORAGE}/"
}
compile_orangepi-config()
{
local tmpdir=${SRC}/.tmp/orangepi-config_${REVISION}_all
display_alert "Building deb" "orangepi-config" "info"
mkdir -p "${tmpdir}"/{DEBIAN,usr/bin/,usr/sbin/,usr/lib/orangepi-config/}
# set up control file
cat <<-END > "${tmpdir}"/DEBIAN/control
Package: orangepi-config
Version: $REVISION
Architecture: all
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Replaces: orangepi-bsp
Depends: bash, iperf3, psmisc, curl, bc, expect, dialog, pv, \
debconf-utils, unzip, build-essential, html2text, apt-transport-https, html2text, dirmngr, software-properties-common
Recommends: orangepi-bsp
Suggests: libpam-google-authenticator, qrencode, network-manager, sunxi-tools
Section: utils
Priority: optional
Description: Orange Pi configuration utility
END
install -m 755 $EXTER/cache/sources/orangepi-config/scripts/tv_grab_file $tmpdir/usr/bin/tv_grab_file
install -m 755 $EXTER/cache/sources/orangepi-config/debian-config $tmpdir/usr/sbin/orangepi-config
install -m 644 $EXTER/cache/sources/orangepi-config/debian-config-jobs $tmpdir/usr/lib/orangepi-config/jobs.sh
install -m 644 $EXTER/cache/sources/orangepi-config/debian-config-submenu $tmpdir/usr/lib/orangepi-config/submenu.sh
install -m 644 $EXTER/cache/sources/orangepi-config/debian-config-functions $tmpdir/usr/lib/orangepi-config/functions.sh
install -m 644 $EXTER/cache/sources/orangepi-config/debian-config-functions-network $tmpdir/usr/lib/orangepi-config/functions-network.sh
install -m 755 $EXTER/cache/sources/orangepi-config/softy $tmpdir/usr/sbin/softy
# fallback to replace orangepi-config in BSP
ln -sf /usr/sbin/orangepi-config $tmpdir/usr/bin/orangepi-config
ln -sf /usr/sbin/softy "${tmpdir}"/usr/bin/softy
fakeroot dpkg -b "${tmpdir}" >/dev/null
mv "${tmpdir}.deb" "${DEB_STORAGE}/"
rm -rf "${tmpdir}"
}
compile_sunxi_tools()
{
# Compile and install only if git commit hash changed
cd $EXTER/cache/sources/sunxi-tools || exit
# need to check if /usr/local/bin/sunxi-fexc to detect new Docker containers with old cached sources
if [[ ! -f .commit_id || $(git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/sunxi-fexc ]]; then
display_alert "Compiling" "sunxi-tools" "info"
make -s clean >/dev/null
make -s tools >/dev/null
mkdir -p /usr/local/bin/
make install-tools >/dev/null 2>&1
git rev-parse @ 2>/dev/null > .commit_id
fi
}
install_rkbin_tools()
{
# install only if git commit hash changed
cd "${EXTER}"/cache/sources/rkbin-tools || exit
# need to check if /usr/local/bin/sunxi-fexc to detect new Docker containers with old cached sources
if [[ ! -f .commit_id || $(git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/loaderimage ]]; then
display_alert "Installing" "rkbin-tools" "info"
mkdir -p /usr/local/bin/
install -m 755 tools/loaderimage /usr/local/bin/
install -m 755 tools/trust_merger /usr/local/bin/
git rev-parse @ 2>/dev/null > .commit_id
fi
}
grab_version()
{
local ver=()
ver[0]=$(grep "^VERSION" "${1}"/Makefile | head -1 | awk '{print $(NF)}' | grep -oE '^[[:digit:]]+')
ver[1]=$(grep "^PATCHLEVEL" "${1}"/Makefile | head -1 | awk '{print $(NF)}' | grep -oE '^[[:digit:]]+')
ver[2]=$(grep "^SUBLEVEL" "${1}"/Makefile | head -1 | awk '{print $(NF)}' | grep -oE '^[[:digit:]]+')
ver[3]=$(grep "^EXTRAVERSION" "${1}"/Makefile | head -1 | awk '{print $(NF)}' | grep -oE '^-rc[[:digit:]]+')
echo "${ver[0]:-0}${ver[1]:+.${ver[1]}}${ver[2]:+.${ver[2]}}${ver[3]}"
}
# find_toolchain <compiler_prefix> <expression>
#
# returns path to toolchain that satisfies <expression>
#
find_toolchain()
{
local compiler=$1
local expression=$2
local dist=10
local toolchain=""
# extract target major.minor version from expression
local target_ver
target_ver=$(grep -oE "[[:digit:]]+\.[[:digit:]]" <<< "$expression")
for dir in "${SRC}"/toolchains/*/; do
# check if is a toolchain for current $ARCH
[[ ! -f ${dir}bin/${compiler}gcc ]] && continue
# get toolchain major.minor version
local gcc_ver
gcc_ver=$("${dir}bin/${compiler}gcc" -dumpversion | grep -oE "^[[:digit:]]+\.[[:digit:]]")
# check if toolchain version satisfies requirement
awk "BEGIN{exit ! ($gcc_ver $expression)}" >/dev/null || continue
# check if found version is the closest to target
# may need different logic here with more than 1 digit minor version numbers
# numbers: 3.9 > 3.10; versions: 3.9 < 3.10
# dpkg --compare-versions can be used here if operators are changed
local d
d=$(awk '{x = $1 - $2}{printf "%.1f\n", (x > 0) ? x : -x}' <<< "$target_ver $gcc_ver")
if awk "BEGIN{exit ! ($d < $dist)}" >/dev/null ; then
dist=$d
toolchain=${dir}bin
fi
done
echo "$toolchain"
# logging a stack of used compilers.
if [[ -f "${DEST}"/debug/compiler.log ]]; then
if ! grep -q "$toolchain" "${DEST}"/debug/compiler.log; then
echo "$toolchain" >> "${DEST}"/debug/compiler.log;
fi
else
echo "$toolchain" >> "${DEST}"/debug/compiler.log;
fi
}
# advanced_patch <dest> <family> <board> <target> <branch> <description>
#
# parameters:
# <dest>: u-boot, kernel, atf
# <family>: u-boot: u-boot; kernel: sunxi-next, ...
# <board>: orangepipcplus, orangepizero ...
# <target>: optional subdirectory
# <description>: additional description text
#
# priority:
# $USERPATCHES_PATH/<dest>/<family>/target_<target>
# $USERPATCHES_PATH/<dest>/<family>/board_<board>
# $USERPATCHES_PATH/<dest>/<family>/branch_<branch>
# $USERPATCHES_PATH/<dest>/<family>
# $EXTER/patch/<dest>/<family>/target_<target>
# $EXTER/patch/<dest>/<family>/board_<board>
# $EXTER/patch/<dest>/<family>/branch_<branch>
# $EXTER/patch/<dest>/<family>
#
advanced_patch()
{
local dest=$1
local family=$2
local board=$3
local target=$4
local branch=$5
local description=$6
display_alert "Started patching process for" "$dest $description" "info"
display_alert "Looking for user patches in" "userpatches/$dest/$family" "info"
local names=()
local dirs=(
"$USERPATCHES_PATH/$dest/$family/target_${target}:[\e[33mu\e[0m][\e[34mt\e[0m]"
"$USERPATCHES_PATH/$dest/$family/board_${board}:[\e[33mu\e[0m][\e[35mb\e[0m]"
"$USERPATCHES_PATH/$dest/$family/branch_${branch}:[\e[33mu\e[0m][\e[33mb\e[0m]"
"$USERPATCHES_PATH/$dest/$family:[\e[33mu\e[0m][\e[32mc\e[0m]"
"$EXTER/patch/$dest/$family/target_${target}:[\e[32ml\e[0m][\e[34mt\e[0m]"
"$EXTER/patch/$dest/$family/board_${board}:[\e[32ml\e[0m][\e[35mb\e[0m]"
"$EXTER/patch/$dest/$family/branch_${branch}:[\e[32ml\e[0m][\e[33mb\e[0m]"
"$EXTER/patch/$dest/$family:[\e[32ml\e[0m][\e[32mc\e[0m]"
)
local links=()
# required for "for" command
shopt -s nullglob dotglob
# get patch file names
for dir in "${dirs[@]}"; do
for patch in ${dir%%:*}/*.patch; do
names+=($(basename "${patch}"))
done
# add linked patch directories
if [[ -d ${dir%%:*} ]]; then
local findlinks
findlinks=$(find "${dir%%:*}" -maxdepth 1 -type l -print0 2>&1 | xargs -0)
[[ -n $findlinks ]] && readarray -d '' links < <(find "${findlinks}" -maxdepth 1 -type f -follow -print -iname "*.patch" -print | grep "\.patch$" | sed "s|${dir%%:*}/||g" 2>&1)
fi
done
# merge static and linked
names=("${names[@]}" "${links[@]}")
# remove duplicates
local names_s=($(echo "${names[@]}" | tr ' ' '\n' | LC_ALL=C sort -u | tr '\n' ' '))
# apply patches
for name in "${names_s[@]}"; do
for dir in "${dirs[@]}"; do
if [[ -f ${dir%%:*}/$name ]]; then
if [[ -s ${dir%%:*}/$name ]]; then
process_patch_file "${dir%%:*}/$name" "${dir##*:}"
else
display_alert "* ${dir##*:} $name" "skipped"
fi
break # next name
fi
done
done
}
# process_patch_file <file> <description>
#
# parameters:
# <file>: path to patch file
# <status>: additional status text
#
process_patch_file()
{
local patch=$1
local status=$2
# detect and remove files which patch will create
lsdiff -s --strip=1 "${patch}" | grep '^+' | awk '{print $2}' | xargs -I % sh -c 'rm -f %'
echo "Processing file $patch" >> "${DEST}"/debug/patching.log
patch --batch --silent -p1 -N < "${patch}" >> "${DEST}"/debug/patching.log 2>&1
if [[ $? -ne 0 ]]; then
display_alert "* $status $(basename "${patch}")" "failed" "wrn"
[[ $EXIT_PATCHING_ERROR == yes ]] && exit_with_error "Aborting due to" "EXIT_PATCHING_ERROR"
else
display_alert "* $status $(basename "${patch}")" "" "info"
fi
echo >> "${DEST}"/debug/patching.log
}
userpatch_create()
{
# create commit to start from clean source
git add .
git -c user.name='Orange Pi User' -c user.email='user@example.org' commit -q -m "Cleaning working copy"
local patch="$DEST/patch/$1-$LINUXFAMILY-$BRANCH.patch"
# apply previous user debug mode created patches
if [[ -f $patch ]]; then
display_alert "Applying existing $1 patch" "$patch" "wrn" && patch --batch --silent -p1 -N < "${patch}"
# read title of a patch in case Git is configured
if [[ -n $(git config user.email) ]]; then
COMMIT_MESSAGE=$(cat "${patch}" | grep Subject | sed -n -e '0,/PATCH/s/.*PATCH]//p' | xargs)
display_alert "Patch name extracted" "$COMMIT_MESSAGE" "wrn"
fi
fi
# prompt to alter source
display_alert "Make your changes in this directory:" "$(pwd)" "wrn"
display_alert "Press <Enter> after you are done" "waiting" "wrn"
read -r </dev/tty
tput cuu1
git add .
# create patch out of changes
if ! git diff-index --quiet --cached HEAD; then
# If Git is configured, create proper patch and ask for a name
if [[ -n $(git config user.email) ]]; then
display_alert "Add / change patch name" "$COMMIT_MESSAGE" "wrn"
read -e -p "Patch description: " -i "$COMMIT_MESSAGE" COMMIT_MESSAGE
[[ -z "$COMMIT_MESSAGE" ]] && COMMIT_MESSAGE="Patching something"
git commit -s -m "$COMMIT_MESSAGE"
git format-patch -1 HEAD --stdout --signature="Created with Armbian build tools https://github.com/armbian/build" > "${patch}"
PATCHFILE=$(git format-patch -1 HEAD)
rm $PATCHFILE # delete the actual file
# create a symlink to have a nice name ready
find $DEST/patch/ -type l -delete # delete any existing
ln -sf $patch $DEST/patch/$PATCHFILE
else
git diff --staged > "${patch}"
fi
display_alert "You will find your patch here:" "$patch" "info"
else
display_alert "No changes found, skipping patch creation" "" "wrn"
fi
git reset --soft HEAD~
for i in {3..1..1}; do echo -n "$i." && sleep 1; done
}
# overlayfs_wrapper <operation> <workdir> <description>
#
# <operation>: wrap|cleanup
# <workdir>: path to source directory
# <description>: suffix for merged directory to help locating it in /tmp
# return value: new directory
#
# Assumptions/notes:
# - Ubuntu Xenial host
# - /tmp is mounted as tmpfs
# - there is enough space on /tmp
# - UB if running multiple compilation tasks in parallel
# - should not be used with CREATE_PATCHES=yes
#
overlayfs_wrapper()
{
local operation="$1"
if [[ $operation == wrap ]]; then
local srcdir="$2"
local description="$3"
mkdir -p /tmp/overlay_components/ /tmp/orangepi_build/
local tempdir workdir mergeddir
tempdir=$(mktemp -d --tmpdir="/tmp/overlay_components/")
workdir=$(mktemp -d --tmpdir="/tmp/overlay_components/")
mergeddir=$(mktemp -d --suffix="_$description" --tmpdir="/tmp/orangepi_build/")
mount -t overlay overlay -o lowerdir="$srcdir",upperdir="$tempdir",workdir="$workdir" "$mergeddir"
# this is executed in a subshell, so use temp files to pass extra data outside
echo "$tempdir" >> /tmp/.overlayfs_wrapper_cleanup
echo "$mergeddir" >> /tmp/.overlayfs_wrapper_umount
echo "$mergeddir" >> /tmp/.overlayfs_wrapper_cleanup
echo "$mergeddir"
return
fi
if [[ $operation == cleanup ]]; then
if [[ -f /tmp/.overlayfs_wrapper_umount ]]; then
for dir in $(</tmp/.overlayfs_wrapper_umount); do
[[ $dir == /tmp/* ]] && umount -l "$dir" > /dev/null 2>&1
done
fi
if [[ -f /tmp/.overlayfs_wrapper_cleanup ]]; then
for dir in $(</tmp/.overlayfs_wrapper_cleanup); do
[[ $dir == /tmp/* ]] && rm -rf "$dir"
done
fi
rm -f /tmp/.overlayfs_wrapper_umount /tmp/.overlayfs_wrapper_cleanup
fi
}

370
scripts/configuration.sh Executable file
View File

@@ -0,0 +1,370 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
[[ -z $ROOTPWD ]] && ROOTPWD="orangepi" # Must be changed @first login
[[ -z $OPI_USERNAME ]] && OPI_USERNAME="orangepi"
[[ -z $OPI_PWD ]] && OPI_PWD="orangepi"
[[ -z $MAINTAINER ]] && MAINTAINER="Orange Pi" # deb signature
[[ -z $MAINTAINERMAIL ]] && MAINTAINERMAIL="leeboby@aliyun.com" # deb signature
TZDATA=$(cat /etc/timezone) # Timezone for target is taken from host or defined here.
USEALLCORES=yes # Use all CPU cores for compiling
EXIT_PATCHING_ERROR="" # exit patching if failed
[[ -z $HOST ]] && HOST="$BOARD" # set hostname to the board
cd "${SRC}" || exit
ROOTFSCACHE_VERSION=38
CHROOT_CACHE_VERSION=7
cd ${SRC}/scripts
BUILD_REPOSITORY_URL=$(git remote get-url $(git remote 2>/dev/null) 2>/dev/null)
BUILD_REPOSITORY_COMMIT=$(git describe --match=d_e_a_d_b_e_e_f --always --dirty 2>/dev/null)
ROOTFS_CACHE_MAX=42 # max number of rootfs cache, older ones will be cleaned up
DEB_STORAGE=$DEST/debs
DEB_ORANGEPI=$EXTER/cache/debs
# TODO: fixed name can't be used for parallel image building
ROOT_MAPPER="orangepi-root"
[[ -z $ROOTFS_TYPE ]] && ROOTFS_TYPE=ext4 # default rootfs type is ext4
[[ "ext4 f2fs btrfs nfs fel" != *$ROOTFS_TYPE* ]] && exit_with_error "Unknown rootfs type" "$ROOTFS_TYPE"
[[ -z $BTRFS_COMPRESSION ]] && BTRFS_COMPRESSION=zlib # default btrfs filesystem compression method is zlib
[[ ! $BTRFS_COMPRESSION =~ zlib|lzo|zstd|none ]] && exit_with_error "Unknown btrfs compression method" "$BTRFS_COMPRESSION"
# Fixed image size is in 1M dd blocks (MiB)
# to get size of block device /dev/sdX execute as root:
# echo $(( $(blockdev --getsize64 /dev/sdX) / 1024 / 1024 ))
[[ "f2fs" == *$ROOTFS_TYPE* && -z $FIXED_IMAGE_SIZE ]] && exit_with_error "Please define FIXED_IMAGE_SIZE"
# a passphrase is mandatory if rootfs encryption is enabled
if [[ $CRYPTROOT_ENABLE == yes && -z $CRYPTROOT_PASSPHRASE ]]; then
exit_with_error "Root encryption is enabled but CRYPTROOT_PASSPHRASE is not set"
fi
# small SD card with kernel, boot script and .dtb/.bin files
[[ $ROOTFS_TYPE == nfs ]] && FIXED_IMAGE_SIZE=64
# used by multiple sources - reduce code duplication
[[ $USE_MAINLINE_GOOGLE_MIRROR == yes ]] && MAINLINE_MIRROR=google
case $MAINLINE_MIRROR in
google) MAINLINE_KERNEL_SOURCE='https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable' ;;
tuna) MAINLINE_KERNEL_SOURCE='https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git' ;;
*) MAINLINE_KERNEL_SOURCE='git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git' ;;
esac
MAINLINE_KERNEL_DIR="$SRC/kernel"
if [[ $USE_GITHUB_UBOOT_MIRROR == yes ]]; then
MAINLINE_UBOOT_SOURCE='https://github.com/RobertCNelson/u-boot'
else
MAINLINE_UBOOT_SOURCE='https://github.com/orangepi-xunlong/u-boot-orangepi.git'
fi
MAINLINE_UBOOT_DIR="$SRC/u-boot"
# Let's set default data if not defined in board configuration above
[[ -z $OFFSET ]] && OFFSET=4 # offset to 1st partition (we use 4MiB boundaries by default)
ARCH=armhf
KERNEL_IMAGE_TYPE=zImage
CAN_BUILD_STRETCH=yes
ATF_COMPILE=yes
[[ -z $CRYPTROOT_SSH_UNLOCK ]] && CRYPTROOT_SSH_UNLOCK=yes
[[ -z $CRYPTROOT_SSH_UNLOCK_PORT ]] && CRYPTROOT_SSH_UNLOCK_PORT=2022
# Default to pdkdf2, this used to be the default with cryptroot <= 2.0, however
# cryptroot 2.1 changed that to Argon2i. Argon2i is a memory intensive
# algorithm which doesn't play well with SBCs (need 1GiB RAM by default !)
# https://gitlab.com/cryptsetup/cryptsetup/-/issues/372
[[ -z $CRYPTROOT_PARAMETERS ]] && CRYPTROOT_PARAMETERS="--pbkdf pbkdf2"
[[ -z $WIREGUARD ]] && WIREGUARD="no"
[[ -z $EXTRAWIFI ]] && EXTRAWIFI="yes"
[[ -z $AUFS ]] && AUFS="yes"
[[ -z $IMAGE_PARTITION_TABLE ]] && IMAGE_PARTITION_TABLE="msdos"
[[ -z $BUILD_KSRC ]] && BUILD_KSRC="no"
# single ext4 partition is the default and preferred configuration
#BOOTFS_TYPE=''
#BOOTFS_TYPE="fat"
[[ $BOOTFS_TYPE == fat && $ARCHITECTURE == arm ]] && BOOTSCRIPT="boot-sunxi-fat.cmd:boot.cmd"
[[ $BOOTFS_TYPE == fat && $ARCHITECTURE == arm64 ]] && BOOTSCRIPT='boot-sun50i-next-fat.cmd:boot.cmd'
# set unique mounting directory
SDCARD="${SRC}/.tmp/rootfs-${BRANCH}-${BOARD}-${RELEASE}-${BUILD_DESKTOP}-${BUILD_MINIMAL}"
MOUNT="${SRC}/.tmp/mount-${BRANCH}-${BOARD}-${RELEASE}-${BUILD_DESKTOP}-${BUILD_MINIMAL}"
DESTIMG="${SRC}/.tmp/image-${BRANCH}-${BOARD}-${RELEASE}-${BUILD_DESKTOP}-${BUILD_MINIMAL}"
[[ ! -f ${EXTER}/config/sources/families/$LINUXFAMILY.conf ]] && \
exit_with_error "Sources configuration not found" "$LINUXFAMILY"
source "${EXTER}/config/sources/families/${LINUXFAMILY}.conf"
if [[ -f $USERPATCHES_PATH/sources/families/$LINUXFAMILY.conf ]]; then
display_alert "Adding user provided $LINUXFAMILY overrides"
source "$USERPATCHES_PATH/sources/families/${LINUXFAMILY}.conf"
fi
# load architecture defaults
source "${EXTER}/config/sources/${ARCH}.conf"
# dropbear needs to be configured differently
[[ $CRYPTROOT_ENABLE == yes && $RELEASE == xenial ]] && exit_with_error "Encrypted rootfs is not supported in Xenial"
[[ $RELEASE == stretch && $CAN_BUILD_STRETCH != yes ]] && exit_with_error "Building Debian Stretch images with selected kernel is not supported"
[[ $RELEASE == bionic && $CAN_BUILD_STRETCH != yes ]] && exit_with_error "Building Ubuntu Bionic images with selected kernel is not supported"
[[ $RELEASE == bionic && $(lsb_release -sc) == xenial ]] && exit_with_error "Building Ubuntu Bionic images requires a Bionic build host. Please upgrade your host or select a different target OS"
[[ -n $ATFSOURCE && -z $ATF_USE_GCC ]] && exit_with_error "Error in configuration: ATF_USE_GCC is unset"
[[ -z $UBOOT_USE_GCC ]] && exit_with_error "Error in configuration: UBOOT_USE_GCC is unset"
[[ -z $KERNEL_USE_GCC ]] && exit_with_error "Error in configuration: KERNEL_USE_GCC is unset"
BOOTCONFIG_VAR_NAME=BOOTCONFIG_${BRANCH^^}
[[ -n ${!BOOTCONFIG_VAR_NAME} ]] && BOOTCONFIG=${!BOOTCONFIG_VAR_NAME}
[[ -z $LINUXCONFIG ]] && LINUXCONFIG="linux-${LINUXFAMILY}-${BRANCH}"
[[ -z $BOOTPATCHDIR ]] && BOOTPATCHDIR="u-boot-$LINUXFAMILY"
[[ -z $ATFPATCHDIR ]] && ATFPATCHDIR="atf-$LINUXFAMILY"
[[ -z $KERNELPATCHDIR ]] && KERNELPATCHDIR="$LINUXFAMILY-$BRANCH"
if [[ $RELEASE == xenial || $RELEASE == bionic || $RELEASE == focal || $RELEASE == eoan ]]; then
DISTRIBUTION="Ubuntu"
else
DISTRIBUTION="Debian"
fi
# Base system dependencies. Since adding MINIMAL_IMAGE we rely on "variant=minbase" which has very basic package set
DEBOOTSTRAP_LIST="locales gnupg ifupdown apt-utils apt-transport-https ca-certificates bzip2 console-setup cpio cron \
dbus init initramfs-tools iputils-ping isc-dhcp-client kmod less libpam-systemd \
linux-base logrotate netbase netcat-openbsd rsyslog systemd sudo ucf udev whiptail \
wireless-regdb crda dmsetup rsync tzdata"
[[ $BUILD_DESKTOP == yes ]] && DEBOOTSTRAP_LIST+=" libgtk2.0-bin"
# tab cleanup is mandatory
DEBOOTSTRAP_LIST=$(echo $DEBOOTSTRAP_LIST | sed -e 's,\\[trn],,g')
# For minimal build different set of packages is needed
# Essential packages for minimal build
PACKAGE_LIST="bc cpufrequtils device-tree-compiler fping fake-hwclock psmisc chrony parted dialog \
ncurses-term sysfsutils toilet figlet u-boot-tools usbutils openssh-server \
nocache debconf-utils python3-apt"
# Non-essential packages for minimal build
PACKAGE_LIST_ADDITIONAL="network-manager wireless-tools lsof htop mmc-utils wget nano sysstat net-tools resolvconf iozone3 jq libcrack2 cracklib-runtime curl"
[[ $RELEASE == xenial ]] && PACKAGE_LIST_ADDITIONAL="network-manager wireless-tools lsof htop wget nano sysstat net-tools resolvconf iozone3 jq libcrack2 cracklib-runtime curl"
if [[ "$BUILD_MINIMAL" != "yes" ]]; then
# Essential packages
PACKAGE_LIST="$PACKAGE_LIST bridge-utils build-essential fbset \
iw wpasupplicant sudo linux-base crda \
wireless-regdb unattended-upgrades \
console-setup unicode-data initramfs-tools \
ca-certificates expect iptables automake html2text \
bison flex libwrap0-dev libssl-dev libnl-3-dev libnl-genl-3-dev keyboard-configuration"
# Non-essential packages
PACKAGE_LIST_ADDITIONAL="$PACKAGE_LIST_ADDITIONAL alsa-utils btrfs-progs dosfstools iotop stress screen \
ntfs-3g vim pciutils evtest pv libfuse2 libdigest-sha-perl \
libproc-processtable-perl aptitude dnsutils f3 haveged hdparm rfkill vlan bash-completion \
hostapd git ethtool unzip ifenslave libpam-systemd iperf3 \
software-properties-common libnss-myhostname f2fs-tools avahi-autoipd iputils-arping qrencode sunxi-tools"
fi
# Dependent desktop packages
PACKAGE_LIST_DESKTOP="xserver-xorg xserver-xorg-video-fbdev gvfs-backends gvfs-fuse xfonts-base xinit \
x11-xserver-utils xfce4 lxtask xfce4-terminal thunar-volman gtk2-engines gtk2-engines-murrine gtk2-engines-pixbuf \
libgtk2.0-bin network-manager-gnome xfce4-notifyd gnome-keyring gcr libgck-1-0 p11-kit pasystray pavucontrol \
pulseaudio pavumeter bluez bluez-tools pulseaudio-module-bluetooth blueman libpam-gnome-keyring \
libgl1-mesa-dri policykit-1 profile-sync-daemon gnome-orca numix-gtk-theme synaptic apt-xapian-index lightdm lightdm-gtk-greeter"
# Recommended desktop packages
PACKAGE_LIST_DESKTOP_RECOMMENDS="galculator hexchat xfce4-screenshooter network-manager-openvpn-gnome mpv fbi \
cups-pk-helper cups geany atril xarchiver"
# Full desktop packages
PACKAGE_LIST_DESKTOP_FULL="libreoffice libreoffice-style-tango meld remmina kazam avahi-daemon transmission"
# Packages installed before desktop.
PACKAGE_LIST_PREDEPENDS=""
# Release specific packages
case $RELEASE in
xenial)
# Dependent desktop packages
PACKAGE_LIST_DESKTOP="xserver-xorg xserver-xorg-video-fbdev gvfs-backends gvfs-fuse xfonts-base xinit \
x11-xserver-utils xfce4 lxtask xfce4-terminal thunar-volman gtk2-engines gtk2-engines-murrine gtk2-engines-pixbuf \
libgtk2.0-bin network-manager-gnome xfce4-notifyd gnome-keyring gcr libgck-1-0 p11-kit pasystray pavucontrol \
pulseaudio pavumeter bluez bluez-tools pulseaudio-module-bluetooth blueman libpam-gnome-keyring \
libgl1-mesa-dri policykit-1 gnome-orca numix-gtk-theme synaptic apt-xapian-index lightdm lightdm-gtk-greeter"
DEBOOTSTRAP_COMPONENTS="main"
DEBOOTSTRAP_LIST+=" btrfs-tools"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db sysbench command-not-found"
PACKAGE_LIST_DESKTOP+=" paman libgcr-3-common gcj-jre-headless paprefs libgnome2-perl \
pulseaudio-module-gconf onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" chromium-browser language-selector-gnome system-config-printer-common \
system-config-printer-gnome leafpad mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
;;
stretch)
DEBOOTSTRAP_COMPONENTS="main"
DEBOOTSTRAP_LIST+=" rng-tools"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr sysbench command-not-found"
PACKAGE_LIST_DESKTOP+=" paman libgcr-3-common gcj-jre-headless paprefs dbus-x11 libgnome2-perl pulseaudio-module-gconf onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" chromium system-config-printer-common system-config-printer leafpad mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
;;
bionic)
DEBOOTSTRAP_COMPONENTS="main,universe"
DEBOOTSTRAP_LIST+=" rng-tools fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher command-not-found"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && [[ $ARCH == armhf ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher command-not-found"
PACKAGE_LIST_DESKTOP+=" xserver-xorg-input-all paprefs dbus-x11 libgnome2-perl pulseaudio-module-gconf onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" chromium-browser system-config-printer-common system-config-printer \
language-selector-gnome leafpad mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
;;
buster)
DEBOOTSTRAP_COMPONENTS="main"
DEBOOTSTRAP_LIST+=" rng-tools fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher command-not-found"
PACKAGE_LIST_DESKTOP+=" paprefs dbus-x11 numix-icon-theme onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" chromium system-config-printer-common system-config-printer mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
;;
bullseye)
DEBOOTSTRAP_COMPONENTS="main"
DEBOOTSTRAP_LIST+=" haveged fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher command-not-found"
PACKAGE_LIST_DESKTOP+=" paprefs dbus-x11 numix-icon-theme"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" firefox-esr system-config-printer-common system-config-printer"
PACKAGE_LIST_DESKTOP_FULL+=""
;;
focal)
DEBOOTSTRAP_COMPONENTS="main,universe"
DEBOOTSTRAP_LIST+=" rng-tools fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher"
PACKAGE_LIST_DESKTOP+=" xserver-xorg-input-all paprefs dbus-x11 pulseaudio-module-gsettings onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" firefox system-config-printer-common system-config-printer \
language-selector-gnome viewnior"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
PACKAGE_LIST_PREDEPENDS="policykit-1-gnome notification-daemon"
;;
eoan)
DEBOOTSTRAP_COMPONENTS="main,universe"
DEBOOTSTRAP_LIST+=" rng-tools fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher"
PACKAGE_LIST_DESKTOP+=" xserver-xorg-input-all paprefs dbus-x11 pulseaudio-module-gsettings onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" firefox system-config-printer-common system-config-printer \
language-selector-gnome mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
PACKAGE_LIST_PREDEPENDS="policykit-1-gnome notification-daemon"
;;
esac
DEBIAN_MIRROR='deb.debian.org/debian'
DEBIAN_SECURTY='security.debian.org/'
UBUNTU_MIRROR='ports.ubuntu.com/'
if [[ $DOWNLOAD_MIRROR == china ]] ; then
DEBIAN_MIRROR='mirrors.tuna.tsinghua.edu.cn/debian'
DEBIAN_SECURTY='mirrors.tuna.tsinghua.edu.cn/debian-security'
UBUNTU_MIRROR='mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/'
fi
# For user override
if [[ -f $USERPATCHES_PATH/lib.config ]]; then
display_alert "Using user configuration override" "$USERPATCHES_PATH/lib.config" "info"
source "$USERPATCHES_PATH"/lib.config
fi
if [[ "$(type -t user_config)" == "function" ]]; then
display_alert "Invoke function with user override" "user_config" "info"
user_config
fi
# apt-cacher-ng mirror configurarion
if [[ $DISTRIBUTION == Ubuntu ]]; then
APT_MIRROR=$UBUNTU_MIRROR
else
APT_MIRROR=$DEBIAN_MIRROR
fi
[[ -n $APT_PROXY_ADDR ]] && display_alert "Using custom apt-cacher-ng address" "$APT_PROXY_ADDR" "info"
# Build final package list after possible override
PACKAGE_LIST="$PACKAGE_LIST $PACKAGE_LIST_RELEASE $PACKAGE_LIST_ADDITIONAL"
[[ $BUILD_DESKTOP == yes ]] && PACKAGE_LIST="$PACKAGE_LIST $PACKAGE_LIST_DESKTOP $PACKAGE_LIST_DESKTOP_RECOMMENDS"
# remove any packages defined in PACKAGE_LIST_RM in lib.config
if [[ -n $PACKAGE_LIST_RM ]]; then
PACKAGE_LIST=$(sed -r "s/\b($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\b//g" <<< "${PACKAGE_LIST}")
fi
# Give the option to configure DNS server used in the chroot during the build process
[[ -z $NAMESERVER ]] && NAMESERVER="1.0.0.1" # default is cloudflare alternate
# debug
cat <<-EOF >> "${DEST}"/debug/output.log
## BUILD SCRIPT ENVIRONMENT
Repository: $REPOSITORY_URL
Version: $REPOSITORY_COMMIT
Host OS: $(lsb_release -sc)
Host arch: $(dpkg --print-architecture)
Host system: $(uname -a)
Virtualization type: $(systemd-detect-virt)
## Build script directories
Build directory is located on:
$(findmnt -o TARGET,SOURCE,FSTYPE,AVAIL -T "${SRC}")
Build directory permissions:
$(getfacl -p "${SRC}")
Temp directory permissions:
$(getfacl -p "${SRC}"/.tmp 2> /dev/null)
## BUILD CONFIGURATION
Build target:
Board: $BOARD
Branch: $BRANCH
Minimal: $BUILD_MINIMAL
Desktop: $BUILD_DESKTOP
Kernel configuration:
Repository: $KERNELSOURCE
Branch: $KERNELBRANCH
Config file: $LINUXCONFIG
U-boot configuration:
Repository: $BOOTSOURCE
Branch: $BOOTBRANCH
Config file: $BOOTCONFIG
Partitioning configuration:
Root partition type: $ROOTFS_TYPE
Boot partition type: ${BOOTFS_TYPE:-(none)}
User provided boot partition size: ${BOOTSIZE:-0}
Offset: $OFFSET
CPU configuration:
$CPUMIN - $CPUMAX with $GOVERNOR
EOF

714
scripts/debootstrap.sh Executable file
View File

@@ -0,0 +1,714 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
# debootstrap_ng
# create_rootfs_cache
# prepare_partitions
# update_initramfs
# create_image
# debootstrap_ng
#
debootstrap_ng()
{
display_alert "Starting rootfs and image building process for" "$BOARD $BRANCH $RELEASE" "info"
[[ $ROOTFS_TYPE != ext4 ]] && display_alert "Assuming $BOARD $BRANCH kernel supports $ROOTFS_TYPE" "" "wrn"
# trap to unmount stuff in case of error/manual interruption
trap unmount_on_exit INT TERM EXIT
# stage: clean and create directories
rm -rf $SDCARD $MOUNT
mkdir -p $SDCARD $MOUNT $DEST/images $EXTER/cache/rootfs
# stage: verify tmpfs configuration and mount
# default maximum size for tmpfs mount is 1/2 of available RAM
# CLI needs ~1.2GiB+ (Xenial CLI), Desktop - ~2.8GiB+ (Xenial Desktop w/o HW acceleration)
# calculate and set tmpfs mount to use 2/3 of available RAM
local phymem=$(( $(awk '/MemTotal/ {print $2}' /proc/meminfo) / 1024 * 2 / 3 )) # MiB
if [[ $BUILD_DESKTOP == yes ]]; then local tmpfs_max_size=3500; else local tmpfs_max_size=1500; fi # MiB
if [[ $FORCE_USE_RAMDISK == no ]]; then local use_tmpfs=no
elif [[ $FORCE_USE_RAMDISK == yes || $phymem -gt $tmpfs_max_size ]]; then
local use_tmpfs=yes
fi
[[ -n $FORCE_TMPFS_SIZE ]] && phymem=$FORCE_TMPFS_SIZE
[[ $use_tmpfs == yes ]] && mount -t tmpfs -o size=${phymem}M tmpfs $SDCARD
# stage: prepare basic rootfs: unpack cache or create from scratch
create_rootfs_cache
# stage: install kernel and u-boot packages
# install distribution and board specific applications
install_distribution_specific
install_common
# install locally built packages or install pre-built packages from orangepi
[[ $EXTERNAL_NEW == compile || $EXTERNAL_NEW == prebuilt ]] && chroot_installpackages_local
# stage: user customization script
# NOTE: installing too many packages may fill tmpfs mount
customize_image
# create list of installed packages for debug purposes
chroot $SDCARD /bin/bash -c "dpkg --get-selections" | grep -v deinstall | awk '{print $1}' | cut -f1 -d':' > $DEST/debug/installed-packages-${RELEASE}$([[ ${BUILD_MINIMAL} == yes ]] && echo "-minimal")$([[ ${BUILD_DESKTOP} == yes ]] && echo "-desktop").list 2>&1
# clean up / prepare for making the image
umount_chroot "$SDCARD"
post_debootstrap_tweaks
if [[ $ROOTFS_TYPE == fel ]]; then
FEL_ROOTFS=$SDCARD/
display_alert "Starting FEL boot" "$BOARD" "info"
source $SRC/scripts/fel-load.sh
else
prepare_partitions
create_image
fi
# stage: unmount tmpfs
umount $SDCARD 2>&1
if [[ $use_tmpfs = yes ]]; then
while grep -qs "$SDCARD" /proc/mounts
do
umount $SDCARD
sleep 5
done
fi
rm -rf $SDCARD
# remove exit trap
trap - INT TERM EXIT
} #############################################################################
# create_rootfs_cache
#
# unpacks cached rootfs for $RELEASE or creates one
#
create_rootfs_cache()
{
local packages_hash=$(get_package_list_hash "$ROOTFSCACHE_VERSION")
local cache_type=$(if [[ ${BUILD_DESKTOP} == yes ]]; then echo "desktop"; elif [[ ${BUILD_MINIMAL} == yes ]]; then echo "minimal"; else echo "cli";fi)
local cache_name=${RELEASE}-${cache_type}-${ARCH}.$packages_hash.tar.lz4
local cache_fname=${EXTER}/cache/rootfs/${cache_name}
local display_name=${RELEASE}-${cache_type}-${ARCH}.${packages_hash:0:3}...${packages_hash:29}.tar.lz4
if [[ -f $cache_fname && "$ROOT_FS_CREATE_ONLY" != "force" ]]; then
local date_diff=$(( ($(date +%s) - $(stat -c %Y $cache_fname)) / 86400 ))
display_alert "Extracting $display_name" "$date_diff days old" "info"
pv -p -b -r -c -N "[ .... ] $display_name" "$cache_fname" | lz4 -dc | tar xp --xattrs -C $SDCARD/
[[ $? -ne 0 ]] && rm $cache_fname && exit_with_error "Cache $cache_fname is corrupted and was deleted. Restart."
rm $SDCARD/etc/resolv.conf
echo "nameserver $NAMESERVER" >> $SDCARD/etc/resolv.conf
create_sources_list "$RELEASE" "$SDCARD/"
else
display_alert "local not found" "Creating new rootfs cache for $RELEASE" "info"
# stage: debootstrap base system
if [[ $NO_APT_CACHER != yes ]]; then
# apt-cacher-ng apt-get proxy parameter
local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\""
local apt_mirror="http://${APT_PROXY_ADDR:-localhost:3142}/$APT_MIRROR"
else
local apt_mirror="http://$APT_MIRROR"
fi
# fancy progress bars
[[ -z $OUTPUT_DIALOG ]] && local apt_extra_progress="--show-progress -o DPKG::Progress-Fancy=1"
display_alert "Installing base system" "Stage 1/2" "info"
eval 'debootstrap --variant=minbase --include=${DEBOOTSTRAP_LIST// /,} ${PACKAGE_LIST_EXCLUDE:+ --exclude=${PACKAGE_LIST_EXCLUDE// /,}} \
--arch=$ARCH --components=${DEBOOTSTRAP_COMPONENTS} --foreign $RELEASE $SDCARD/ $apt_mirror' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Debootstrap (stage 1/2)..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
[[ ${PIPESTATUS[0]} -ne 0 || ! -f $SDCARD/debootstrap/debootstrap ]] && exit_with_error "Debootstrap base system first stage failed"
cp /usr/bin/$QEMU_BINARY $SDCARD/usr/bin/
mkdir -p $SDCARD/usr/share/keyrings/
cp /usr/share/keyrings/*-archive-keyring.gpg $SDCARD/usr/share/keyrings/
display_alert "Installing base system" "Stage 2/2" "info"
eval 'chroot $SDCARD /bin/bash -c "/debootstrap/debootstrap --second-stage"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Debootstrap (stage 2/2)..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
[[ ${PIPESTATUS[0]} -ne 0 || ! -f $SDCARD/bin/bash ]] && exit_with_error "Debootstrap base system second stage failed"
mount_chroot "$SDCARD"
# policy-rc.d script prevents starting or reloading services during image creation
printf '#!/bin/sh\nexit 101' > $SDCARD/usr/sbin/policy-rc.d
chroot $SDCARD /bin/bash -c "dpkg-divert --quiet --local --rename --add /sbin/initctl"
chroot $SDCARD /bin/bash -c "dpkg-divert --quiet --local --rename --add /sbin/start-stop-daemon"
printf '#!/bin/sh\necho "Warning: Fake start-stop-daemon called, doing nothing"' > $SDCARD/sbin/start-stop-daemon
printf '#!/bin/sh\necho "Warning: Fake initctl called, doing nothing"' > $SDCARD/sbin/initctl
chmod 755 $SDCARD/usr/sbin/policy-rc.d
chmod 755 $SDCARD/sbin/initctl
chmod 755 $SDCARD/sbin/start-stop-daemon
# stage: configure language and locales
display_alert "Configuring locales" "$DEST_LANG" "info"
[[ -f $SDCARD/etc/locale.gen ]] && sed -i "s/^# $DEST_LANG/$DEST_LANG/" $SDCARD/etc/locale.gen
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "locale-gen $DEST_LANG"' ${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "update-locale LANG=$DEST_LANG LANGUAGE=$DEST_LANG LC_MESSAGES=$DEST_LANG"' \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
if [[ -f $SDCARD/etc/default/console-setup ]]; then
sed -e 's/CHARMAP=.*/CHARMAP="UTF-8"/' -e 's/FONTSIZE=.*/FONTSIZE="8x16"/' \
-e 's/CODESET=.*/CODESET="guess"/' -i $SDCARD/etc/default/console-setup
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "setupcon --save"'
fi
# stage: create apt-get sources list
create_sources_list "$RELEASE" "$SDCARD/"
# add armhf arhitecture to arm64
[[ $ARCH == arm64 ]] && eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "dpkg --add-architecture armhf"'
# this should fix resolvconf installation failure in some cases
chroot $SDCARD /bin/bash -c 'echo "resolvconf resolvconf/linkify-resolvconf boolean false" | debconf-set-selections'
# stage: update packages list
display_alert "Updating package list" "$RELEASE" "info"
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "apt -q -y $apt_extra update"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Updating package lists..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
#[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Updating package lists failed"
# stage: upgrade base packages from xxx-updates and xxx-backports repository branches
display_alert "Upgrading base packages" "Orange Pi" "info"
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -y -q \
$apt_extra $apt_extra_progress upgrade"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Upgrading base packages..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Upgrading base packages failed"
# stage: install additional packages
display_alert "Installing packages for" "Orange Pi" "info"
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -y -q \
$apt_extra $apt_extra_progress --no-install-recommends install $PACKAGE_LIST"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Installing Orange Pi system..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Installation of Orange Pi packages failed"
# stage: remove downloaded packages
chroot $SDCARD /bin/bash -c "apt clean"
# DEBUG: print free space
#echo -e "\nFree space:"
#eval 'df -h' ${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'}
# create list of installed packages for debug purposes
chroot $SDCARD /bin/bash -c "dpkg --get-selections" | grep -v deinstall | awk '{print $1}' | cut -f1 -d':' > ${cache_fname}.list 2>&1
# creating xapian index that synaptic runs faster
if [[ $BUILD_DESKTOP == yes ]]; then
display_alert "Recreating Synaptic search index" "Please wait" "info"
chroot $SDCARD /bin/bash -c "/usr/sbin/update-apt-xapian-index -u"
fi
# this is needed for the build process later since resolvconf generated file in /run is not saved
rm $SDCARD/etc/resolv.conf
echo "nameserver $NAMESERVER" >> $SDCARD/etc/resolv.conf
# stage: make rootfs cache archive
display_alert "Ending debootstrap process and preparing cache" "$RELEASE" "info"
sync
# the only reason to unmount here is compression progress display
# based on rootfs size calculation
umount_chroot "$SDCARD"
tar cp --xattrs --directory=$SDCARD/ --exclude='./dev/*' --exclude='./proc/*' --exclude='./run/*' --exclude='./tmp/*' \
--exclude='./sys/*' . | pv -p -b -r -s $(du -sb $SDCARD/ | cut -f1) -N "$display_name" | lz4 -c > $cache_fname
# sign rootfs cache archive that it can be used for web cache once. Internal purposes
if [[ -n $GPG_PASS ]]; then
echo $GPG_PASS | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes $cache_fname
fi
fi
# used for internal purposes. Faster rootfs cache rebuilding
if [[ -n "$ROOT_FS_CREATE_ONLY" || $BUILD_OPT == rootfs ]]; then
[[ $use_tmpfs = yes ]] && umount $SDCARD
rm -rf $SDCARD
if [[ -f "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid" ]];then
rm "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid"
fi
display_alert "Rootfs build done" "@host" "info"
display_alert "Target directory" "${EXTER}/cache/rootfs" "info"
display_alert "File name" "${cache_name}" "info"
end=$(date +%s)
runtime=$(((end-start)/60))
display_alert "Runtime" "$runtime min" "info"
display_alert "Repeat Build Options" "sudo ./build.sh ${BUILD_CONFIG} BOARD=${BOARD} BRANCH=${BRANCH} $([[ -n $BUILD_OPT ]] && echo "BUILD_OPT=${BUILD_OPT} ")$([[ -n $RELEASE ]] && echo "RELEASE=${RELEASE} ") $([[ -n $BUILD_MINIMAL ]] && echo "BUILD_MINIMAL=${BUILD_MINIMAL} ") $([[ -n $BUILD_DESKTOP ]] && echo "BUILD_DESKTOP=${BUILD_DESKTOP} ") $([[ -n $KERNEL_CONFIGURE ]] && echo "KERNEL_CONFIGURE=${KERNEL_CONFIGURE}") " "info"
# remove exit trap
trap - INT TERM EXIT
exit
fi
mount_chroot "$SDCARD"
} #############################################################################
# prepare_partitions
#
# creates image file, partitions and fs
# and mounts it to local dir
# FS-dependent stuff (boot and root fs partition types) happens here
#
prepare_partitions()
{
display_alert "Preparing image file for rootfs" "$BOARD $RELEASE" "info"
# possible partition combinations
# /boot: none, ext4, ext2, fat (BOOTFS_TYPE)
# root: ext4, btrfs, f2fs, nfs (ROOTFS_TYPE)
# declare makes local variables by default if used inside a function
# NOTE: mountopts string should always start with comma if not empty
# array copying in old bash versions is tricky, so having filesystems as arrays
# with attributes as keys is not a good idea
declare -A parttype mkopts mkfs mountopts
parttype[ext4]=ext4
parttype[ext2]=ext2
parttype[fat]=fat16
parttype[f2fs]=ext4 # not a copy-paste error
parttype[btrfs]=btrfs
# parttype[nfs] is empty
# metadata_csum and 64bit may need to be disabled explicitly when migrating to newer supported host OS releases
if [[ $(lsb_release -sc) =~ bionic|buster|bullseye|cosmic|eoan|focal ]]; then
mkopts[ext4]='-q -m 2 -O ^64bit,^metadata_csum'
elif [[ $(lsb_release -sc) == xenial ]]; then
mkopts[ext4]='-q -m 2'
fi
mkopts[fat]='-n BOOT'
mkopts[ext2]='-q'
# mkopts[f2fs] is empty
mkopts[btrfs]='-m dup'
# mkopts[nfs] is empty
mkfs[ext4]=ext4
mkfs[ext2]=ext2
mkfs[fat]=vfat
mkfs[f2fs]=f2fs
mkfs[btrfs]=btrfs
# mkfs[nfs] is empty
mountopts[ext4]=',commit=600,errors=remount-ro'
# mountopts[ext2] is empty
# mountopts[fat] is empty
# mountopts[f2fs] is empty
mountopts[btrfs]=',commit=600'
# mountopts[nfs] is empty
# default BOOTSIZE to use if not specified
DEFAULT_BOOTSIZE=96 # MiB
# stage: determine partition configuration
if [[ -n $BOOTFS_TYPE ]]; then
# 2 partition setup with forced /boot type
local bootfs=$BOOTFS_TYPE
local bootpart=1
local rootpart=2
[[ -z $BOOTSIZE || $BOOTSIZE -le 8 ]] && BOOTSIZE=${DEFAULT_BOOTSIZE}
elif [[ $ROOTFS_TYPE != ext4 && $ROOTFS_TYPE != nfs ]]; then
# 2 partition setup for non-ext4 local root
local bootfs=ext4
local bootpart=1
local rootpart=2
[[ -z $BOOTSIZE || $BOOTSIZE -le 8 ]] && BOOTSIZE=${DEFAULT_BOOTSIZE}
elif [[ $ROOTFS_TYPE == nfs ]]; then
# single partition ext4 /boot, no root
local bootfs=ext4
local bootpart=1
[[ -z $BOOTSIZE || $BOOTSIZE -le 8 ]] && BOOTSIZE=${DEFAULT_BOOTSIZE} # For cleanup processing only
elif [[ $CRYPTROOT_ENABLE == yes ]]; then
# 2 partition setup for encrypted /root and non-encrypted /boot
local bootfs=ext4
local bootpart=1
local rootpart=2
[[ -z $BOOTSIZE || $BOOTSIZE -le 8 ]] && BOOTSIZE=${DEFAULT_BOOTSIZE}
else
# single partition ext4 root
local rootpart=1
BOOTSIZE=0
fi
# stage: calculate rootfs size
local rootfs_size=$(du -sm $SDCARD/ | cut -f1) # MiB
display_alert "Current rootfs size" "$rootfs_size MiB" "info"
if [[ -n $FIXED_IMAGE_SIZE && $FIXED_IMAGE_SIZE =~ ^[0-9]+$ ]]; then
display_alert "Using user-defined image size" "$FIXED_IMAGE_SIZE MiB" "info"
local sdsize=$FIXED_IMAGE_SIZE
# basic sanity check
if [[ $ROOTFS_TYPE != nfs && $sdsize -lt $rootfs_size ]]; then
exit_with_error "User defined image size is too small" "$sdsize <= $rootfs_size"
fi
else
local imagesize=$(( $rootfs_size + $OFFSET + $BOOTSIZE )) # MiB
case $ROOTFS_TYPE in
btrfs)
# Used for server images, currently no swap functionality, so disk space
if [[ $BTRFS_COMPRESSION == none ]]; then
local sdsize=$(bc -l <<< "scale=0; (($imagesize * 1.25) / 4 + 1) * 4")
else
# requirements are rather low since rootfs gets filled with compress-force=zlib
local sdsize=$(bc -l <<< "scale=0; (($imagesize * 0.8) / 4 + 1) * 4")
fi
;;
*)
# Hardcoded overhead +25% is needed for desktop images,
# for CLI it could be lower. Align the size up to 4MiB
if [[ $BUILD_DESKTOP == yes ]]; then
local sdsize=$(bc -l <<< "scale=0; ((($imagesize * 1.30) / 1 + 0) / 4 + 1) * 4")
else
local sdsize=$(bc -l <<< "scale=0; ((($imagesize * 1.25) / 1 + 0) / 4 + 1) * 4")
fi
;;
esac
fi
# stage: create blank image
display_alert "Creating blank image for rootfs" "$sdsize MiB" "info"
# truncate --size=${sdsize}M ${SDCARD}.raw # sometimes results in fs corruption, revert to previous know to work solution
dd if=/dev/zero bs=1M status=none count=$sdsize | pv -p -b -r -s $(( $sdsize * 1024 * 1024 )) -N "[ .... ] dd" | dd status=none of=${SDCARD}.raw
# stage: calculate boot partition size
local bootstart=$(($OFFSET * 2048))
local rootstart=$(($bootstart + ($BOOTSIZE * 2048)))
local bootend=$(($rootstart - 1))
# stage: create partition table
display_alert "Creating partitions" "${bootfs:+/boot: $bootfs }root: $ROOTFS_TYPE" "info"
parted -s ${SDCARD}.raw -- mklabel ${IMAGE_PARTITION_TABLE}
if [[ $ROOTFS_TYPE == nfs ]]; then
# single /boot partition
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$bootfs]} ${bootstart}s 100%
elif [[ $BOOTSIZE == 0 ]]; then
# single root partition
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s 100%
else
# /boot partition + root partition
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$bootfs]} ${bootstart}s ${bootend}s
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s 100%
fi
# stage: mount image
# lock access to loop devices
exec {FD}>/var/lock/orangepi-debootstrap-losetup
flock -x $FD
LOOP=$(losetup -f)
[[ -z $LOOP ]] && exit_with_error "Unable to find free loop device"
check_loop_device "$LOOP"
# NOTE: losetup -P option is not available in Trusty
losetup $LOOP ${SDCARD}.raw
# loop device was grabbed here, unlock
flock -u $FD
partprobe $LOOP
# stage: create fs, mount partitions, create fstab
rm -f $SDCARD/etc/fstab
if [[ -n $rootpart ]]; then
local rootdevice="${LOOP}p${rootpart}"
if [[ $CRYPTROOT_ENABLE == yes ]]; then
display_alert "Encrypting root partition with LUKS..." "cryptsetup luksFormat $rootdevice" ""
echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksFormat $CRYPTROOT_PARAMETERS $rootdevice -
echo -n $CRYPTROOT_PASSPHRASE | cryptsetup luksOpen $rootdevice $ROOT_MAPPER -
display_alert "Root partition encryption complete." "" "ext"
# TODO: pass /dev/mapper to Docker
rootdevice=/dev/mapper/$ROOT_MAPPER # used by `mkfs` and `mount` commands
fi
check_loop_device "$rootdevice"
display_alert "Creating rootfs" "$ROOTFS_TYPE on $rootdevice"
mkfs.${mkfs[$ROOTFS_TYPE]} ${mkopts[$ROOTFS_TYPE]} $rootdevice
[[ $ROOTFS_TYPE == ext4 ]] && tune2fs -o journal_data_writeback $rootdevice > /dev/null
if [[ $ROOTFS_TYPE == btrfs && $BTRFS_COMPRESSION != none ]]; then
local fscreateopt="-o compress-force=${BTRFS_COMPRESSION}"
fi
mount ${fscreateopt} $rootdevice $MOUNT/
# create fstab (and crypttab) entry
if [[ $CRYPTROOT_ENABLE == yes ]]; then
# map the LUKS container partition via its UUID to be the 'cryptroot' device
echo "$ROOT_MAPPER UUID=$(blkid -s UUID -o value ${LOOP}p${rootpart}) none luks" >> $SDCARD/etc/crypttab
local rootfs=$rootdevice # used in fstab
else
local rootfs="UUID=$(blkid -s UUID -o value $rootdevice)"
fi
echo "$rootfs / ${mkfs[$ROOTFS_TYPE]} defaults,noatime,nodiratime${mountopts[$ROOTFS_TYPE]} 0 1" >> $SDCARD/etc/fstab
fi
if [[ -n $bootpart ]]; then
display_alert "Creating /boot" "$bootfs"
check_loop_device "${LOOP}p${bootpart}"
mkfs.${mkfs[$bootfs]} ${mkopts[$bootfs]} ${LOOP}p${bootpart}
mkdir -p $MOUNT/boot/
mount ${LOOP}p${bootpart} $MOUNT/boot/
echo "UUID=$(blkid -s UUID -o value ${LOOP}p${bootpart}) /boot ${mkfs[$bootfs]} defaults${mountopts[$bootfs]} 0 2" >> $SDCARD/etc/fstab
fi
[[ $ROOTFS_TYPE == nfs ]] && echo "/dev/nfs / nfs defaults 0 0" >> $SDCARD/etc/fstab
echo "tmpfs /tmp tmpfs defaults,nosuid 0 0" >> $SDCARD/etc/fstab
# stage: adjust boot script or boot environment
if [[ -f $SDCARD/boot/orangepiEnv.txt ]]; then
if [[ $CRYPTROOT_ENABLE == yes ]]; then
echo "rootdev=$rootdevice cryptdevice=UUID=$(blkid -s UUID -o value ${LOOP}p${rootpart}):$ROOT_MAPPER" >> $SDCARD/boot/orangepiEnv.txt
else
echo "rootdev=$rootfs" >> $SDCARD/boot/orangepiEnv.txt
fi
echo "rootfstype=$ROOTFS_TYPE" >> $SDCARD/boot/orangepiEnv.txt
elif [[ $rootpart != 1 ]]; then
local bootscript_dst=${BOOTSCRIPT##*:}
sed -i 's/mmcblk0p1/mmcblk0p2/' $SDCARD/boot/$bootscript_dst
sed -i -e "s/rootfstype=ext4/rootfstype=$ROOTFS_TYPE/" \
-e "s/rootfstype \"ext4\"/rootfstype \"$ROOTFS_TYPE\"/" $SDCARD/boot/$bootscript_dst
fi
# if we have boot.ini = remove orangepiEnv.txt and add UUID there if enabled
if [[ -f $SDCARD/boot/boot.ini ]]; then
sed -i -e "s/rootfstype \"ext4\"/rootfstype \"$ROOTFS_TYPE\"/" $SDCARD/boot/boot.ini
if [[ $CRYPTROOT_ENABLE == yes ]]; then
local rootpart="UUID=$(blkid -s UUID -o value ${LOOP}p${rootpart})"
sed -i 's/^setenv rootdev .*/setenv rootdev "\/dev\/mapper\/'$ROOT_MAPPER' cryptdevice='$rootpart':'$ROOT_MAPPER'"/' $SDCARD/boot/boot.ini
else
sed -i 's/^setenv rootdev .*/setenv rootdev "'$rootfs'"/' $SDCARD/boot/boot.ini
fi
[[ -f $SDCARD/boot/orangepiEnv.txt ]] && rm $SDCARD/boot/orangepiEnv.txt
fi
# if we have a headless device, set console to DEFAULT_CONSOLE
if [[ -n $DEFAULT_CONSOLE && -f $SDCARD/boot/orangepiEnv.txt ]]; then
if grep -lq "^console=" $SDCARD/boot/orangepiEnv.txt; then
sed -i "s/console=.*/console=$DEFAULT_CONSOLE/" $SDCARD/boot/orangepiEnv.txt
else
echo "console=$DEFAULT_CONSOLE" >> $SDCARD/boot/orangepiEnv.txt
fi
fi
# recompile .cmd to .scr if boot.cmd exists
[[ -f $SDCARD/boot/boot.cmd ]] && \
mkimage -C none -A arm -T script -d $SDCARD/boot/boot.cmd $SDCARD/boot/boot.scr > /dev/null 2>&1
} #############################################################################
# update_initramfs
#
# this should be invoked as late as possible for any modifications by
# customize_image (userpatches) and prepare_partitions to be reflected in the
# final initramfs
#
# especially, this needs to be invoked after /etc/crypttab has been created
# for cryptroot-unlock to work:
# https://serverfault.com/questions/907254/cryproot-unlock-with-dropbear-timeout-while-waiting-for-askpass
#
# since Debian buster, it has to be called within create_image() on the $MOUNT
# path instead of $SDCARD (which can be a tmpfs and breaks cryptsetup-initramfs).
# see: https://github.com/armbian/build/issues/1584
#
update_initramfs()
{
local chroot_target=$1
update_initramfs_cmd="update-initramfs -uv -k ${VER}-${LINUXFAMILY}"
display_alert "Updating initramfs..." "$update_initramfs_cmd" ""
cp /usr/bin/$QEMU_BINARY $chroot_target/usr/bin/
mount_chroot "$chroot_target/"
chroot $chroot_target /bin/bash -c "$update_initramfs_cmd" >> $DEST/debug/install.log 2>&1
display_alert "Updated initramfs." "for details see: $DEST/debug/install.log" "ext"
umount_chroot "$chroot_target/"
rm $chroot_target/usr/bin/$QEMU_BINARY
} #############################################################################
# create_image
#
# finishes creation of image from cached rootfs
#
create_image()
{
# stage: create file name
local version="${BOARD^}_${REVISION}_${DISTRIBUTION,}_${RELEASE}_${IMAGETYPE}_linux"$(grab_version "$LINUXSOURCEDIR")""
[[ $BUILD_MINIMAL == yes ]] && version=${version}_minimal
[[ $ROOTFS_TYPE == nfs ]] && version=${version}_nfsboot
destimg=$DEST/images/${version}
rm -rf $destimg
mkdir -p $destimg
if [[ $ROOTFS_TYPE != nfs ]]; then
display_alert "Copying files to root directory"
rsync -aHWXh --exclude="/boot/*" --exclude="/dev/*" --exclude="/proc/*" --exclude="/run/*" --exclude="/tmp/*" \
--exclude="/sys/*" --info=progress2,stats1 $SDCARD/ $MOUNT/
else
display_alert "Creating rootfs archive" "rootfs.tgz" "info"
tar cp --xattrs --directory=$SDCARD/ --exclude='./boot/*' --exclude='./dev/*' --exclude='./proc/*' --exclude='./run/*' --exclude='./tmp/*' \
--exclude='./sys/*' . | pv -p -b -r -s $(du -sb $SDCARD/ | cut -f1) -N "rootfs.tgz" | gzip -c > $destimg/${version}-rootfs.tgz
fi
# stage: rsync /boot
display_alert "Copying files to /boot directory"
if [[ $(findmnt --target $MOUNT/boot -o FSTYPE -n) == vfat ]]; then
# fat32
rsync -rLtWh --info=progress2,stats1 $SDCARD/boot $MOUNT
else
# ext4
rsync -aHWXh --info=progress2,stats1 $SDCARD/boot $MOUNT
fi
# stage: create final initramfs
[[ $ROOTFS_TYPE != nfs ]] && update_initramfs $MOUNT
# DEBUG: print free space
#display_alert "Free space:" "SD card" "info"
#eval 'df -h' ${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'}
# stage: write u-boot
write_uboot $LOOP
# fix wrong / permissions
chmod 755 $MOUNT
# unmount /boot first, rootfs second, image file last
sync
[[ $BOOTSIZE != 0 ]] && umount -l $MOUNT/boot
[[ $ROOTFS_TYPE != nfs ]] && umount -l $MOUNT
[[ $CRYPTROOT_ENABLE == yes ]] && cryptsetup luksClose $ROOT_MAPPER
# to make sure its unmounted
while grep -Eq '(${MOUNT}|${DESTIMG})' /proc/mounts
do
display_alert "Unmounting" "${MOUNT}" "info"
sleep 5
done
losetup -d $LOOP
rm -rf --one-file-system $DESTIMG $MOUNT
mv ${SDCARD}.raw $destimg/${version}.img
if [[ $BUILD_ALL != yes ]]; then
if [[ $COMPRESS_OUTPUTIMAGE == "" || $COMPRESS_OUTPUTIMAGE == no ]]; then
COMPRESS_OUTPUTIMAGE="sha,gpg,img"
elif [[ $COMPRESS_OUTPUTIMAGE == yes ]]; then
COMPRESS_OUTPUTIMAGE="sha,gpg,7z"
fi
if [[ $COMPRESS_OUTPUTIMAGE == *gz* ]]; then
display_alert "Compressing" "$destimg/${version}.img.gz" "info"
pigz -3 < $destimg/${version}.img > $destimg/${version}.img.gz
compression_type=".gz"
fi
if [[ $COMPRESS_OUTPUTIMAGE == *xz* ]]; then
display_alert "Compressing" "$destimg/${version}.img.xz" "info"
pixz -3 < $destimg/${version}.img > $destimg/${version}.img.xz
compression_type=".xz"
fi
if [[ $COMPRESS_OUTPUTIMAGE == *img* || $COMPRESS_OUTPUTIMAGE == *7z* ]]; then
compression_type=""
fi
if [[ $COMPRESS_OUTPUTIMAGE == *sha* ]]; then
cd $destimg
display_alert "SHA256 calculating" "${version}.img${compression_type}" "info"
sha256sum -b ${version}.img${compression_type} > ${version}.img${compression_type}.sha
fi
if [[ $COMPRESS_OUTPUTIMAGE == *gpg* ]]; then
cd $destimg
if [[ -n $GPG_PASS ]]; then
display_alert "GPG signing" "${version}.img${compression_type}" "info"
echo $GPG_PASS | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes $destimg/${version}.img${compression_type} || exit 1
else
display_alert "GPG signing skipped - no GPG_PASS" "${version}.img" "wrn"
fi
fi
#fingerprint_image "$destimg/${version}.img${compression_type}.txt" "${version}"
if [[ $COMPRESS_OUTPUTIMAGE == *7z* ]]; then
display_alert "Compressing" "$destimg/${version}.7z" "info"
7za a -t7z -bd -m0=lzma2 -mx=3 -mfb=64 -md=32m -ms=on \
$destimg/${version}.7z ${version}.key ${version}.img{,.sha,.txt} >/dev/null 2>&1
#find $destimg/ -type \
#f \( -name "${version}.img" -o -name "${version}.img.asc" -o -name "${version}.img.txt" -o -name "${version}.img.sha" \) -print0 \
#| xargs -0 rm >/dev/null 2>&1
fi
fi
display_alert "Done building" "$destimg/${version}.img" "info"
# call custom post build hook
[[ $(type -t post_build_image) == function ]] && post_build_image "$destimg/${version}.img"
# write image to SD card
if [[ $(lsblk "$CARD_DEVICE" 2>/dev/null) && -f $destimg/${version}.img ]]; then
# make sha256sum if it does not exists. we need it for comparisson
if [[ -f "$destimg/${version}".img.sha ]]; then
local ifsha=$(cat $destimg/${version}.img.sha | awk '{print $1}')
else
local ifsha=$(sha256sum -b "$destimg/${version}".img | awk '{print $1}')
fi
display_alert "Writing image" "$CARD_DEVICE ${readsha}" "info"
# write to SD card
pv -p -b -r -c -N "[ .... ] dd" $destimg/${version}.img | dd of=$CARD_DEVICE bs=1M iflag=fullblock oflag=direct status=none
# read and compare
display_alert "Verifying. Please wait!"
local ofsha=$(dd if=$CARD_DEVICE count=$(du -b $destimg/${version}.img | cut -f1) status=none iflag=count_bytes oflag=direct | sha256sum | awk '{print $1}')
if [[ $ifsha == $ofsha ]]; then
display_alert "Writing verified" "${version}.img" "info"
else
display_alert "Writing failed" "${version}.img" "err"
fi
elif [[ `systemd-detect-virt` == 'docker' && -n $CARD_DEVICE ]]; then
# display warning when we want to write sd card under Docker
display_alert "Can't write to $CARD_DEVICE" "Enable docker privileged mode in config-docker.conf" "wrn"
fi
} #############################################################################

154
scripts/desktop.sh Executable file
View File

@@ -0,0 +1,154 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
create_desktop_package ()
{
# join and cleanup package list
PACKAGE_LIST_DESKTOP+=" "${PACKAGE_LIST_DESKTOP_RECOMMENDS}
PACKAGE_LIST_DESKTOP=${PACKAGE_LIST_DESKTOP// /,};
PACKAGE_LIST_DESKTOP=${PACKAGE_LIST_DESKTOP//[[:space:]]/}
PACKAGE_LIST_PREDEPENDS=${PACKAGE_LIST_PREDEPENDS// /,};
PACKAGE_LIST_PREDEPENDS=${PACKAGE_LIST_PREDEPENDS//[[:space:]]/}
local destination=${SRC}/.tmp/${RELEASE}/${BOARD}/${CHOSEN_DESKTOP}_${REVISION}_all
rm -rf "${destination}"
mkdir -p "${destination}"/DEBIAN
# set up control file
cat <<-EOF > "${destination}"/DEBIAN/control
Package: ${CHOSEN_DESKTOP}
Version: $REVISION
Architecture: all
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Installed-Size: 1
Section: xorg
Priority: optional
Recommends: ${PACKAGE_LIST_DESKTOP//[:space:]+/,}
Provides: ${CHOSEN_DESKTOP}
Pre-Depends: ${PACKAGE_LIST_PREDEPENDS//[:space:]+/,}
Description: Orange Pi desktop for ${DISTRIBUTION} ${RELEASE}
EOF
cat <<-EOF > "${destination}"/DEBIAN/postinst
#!/bin/sh -e
# overwrite stock chromium and firefox configuration
if [ -d /etc/chromium-browser/ ]; then ln -sf /etc/orangepi/chromium.conf /etc/chromium-browser/default; fi
if [ -d /etc/chromium.d/ ]; then ln -sf /etc/orangepi/chromium.conf /etc/chromium.d/chromium.conf; fi
cp -R /etc/orangepi/chromium /usr/share
# overwrite stock lightdm greeter configuration
if [ -d /etc/orangepi/lightdm ]; then cp -R /etc/orangepi/lightdm /etc/; fi
if [ -d /usr/lib/firefox-esr/ ]; then
ln -sf /etc/orangepi/firefox.conf /usr/lib/firefox-esr/mozilla.cfg
echo 'pref("general.config.obscure_value", 0);' > /usr/lib/firefox-esr/defaults/pref/local-settings.js
echo 'pref("general.config.filename", "mozilla.cfg");' >> /usr/lib/firefox-esr/defaults/pref/local-settings.js
fi
# Adjust menu
#if [ -f /etc/xdg/menus/xfce-applications.menu ]; then
#sed -i -n '/<Menuname>Settings<\/Menuname>/{p;:a;N;/<Filename>xfce4-session-logout.desktop<\/Filename>/!ba;s/.*\n/\
#\t<Separator\/>\n\t<Merge type="all"\/>\n <Separator\/>\n <Filename>orangepi-donate.desktop<\/Filename>\
#\n <Filename>orangepi-support.desktop<\/Filename>\n/};p' /etc/xdg/menus/xfce-applications.menu
#fi
# Hide few items
if [ -f /usr/share/applications/display-im6.q16.desktop ]; then mv /usr/share/applications/display-im6.q16.desktop /usr/share/applications/display-im6.q16.desktop.hidden; fi
if [ -f /usr/share/applications/display-im6.desktop ]]; then mv /usr/share/applications/display-im6.desktop /usr/share/applications/display-im6.desktop.hidden; fi
if [ -f /usr/share/applications/vim.desktop ]]; then mv /usr/share/applications/vim.desktop /usr/share/applications/vim.desktop.hidden; fi
if [ -f /usr/share/applications/libreoffice-startcenter.desktop ]]; then mv /usr/share/applications/libreoffice-startcenter.desktop /usr/share/applications/libreoffice-startcenter.desktop.hidden; fi
# Disable Pulseaudio timer scheduling which does not work with sndhdmi driver
if [ -f /etc/pulse/default.pa ]; then sed "s/load-module module-udev-detect$/& tsched=0/g" -i /etc/pulse/default.pa; fi
exit 0
EOF
chmod 755 "${destination}"/DEBIAN/postinst
# add loading desktop splash service
mkdir -p "${destination}"/etc/systemd/system/
cp "${EXTER}"/packages/blobs/desktop/desktop-splash/desktop-splash.service "${destination}"/etc/systemd/system/desktop-splash.service
# install optimized browser configurations
mkdir -p "${destination}"/etc/orangepi
cp "${EXTER}"/packages/blobs/desktop/chromium.conf "${destination}"/etc/orangepi
cp "${EXTER}"/packages/blobs/desktop/firefox.conf "${destination}"/etc/orangepi
cp -R "${EXTER}"/packages/blobs/desktop/chromium "${destination}"/etc/orangepi
# install lightdm greeter
cp -R "${EXTER}"/packages/blobs/desktop/lightdm "${destination}"/etc/orangepi
# install default desktop settings
mkdir -p "${destination}"/etc/skel
cp -R "${EXTER}"/packages/blobs/desktop/skel/. "${destination}"/etc/skel
# using different icon pack. Workaround due to this bug https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=867779
if [[ ${RELEASE} == bionic || ${RELEASE} == stretch || ${RELEASE} == buster || ${RELEASE} == bullseye || ${RELEASE} == focal || ${RELEASE} == eoan ]]; then
sed -i 's/<property name="IconThemeName" type="string" value=".*$/<property name="IconThemeName" type="string" value="LoginIcons"\/>/g' \
"${destination}"/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml
fi
# install dedicated startup icons
mkdir -p "${destination}"/usr/share/pixmaps "${destination}"/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/
cp "${EXTER}/packages/blobs/desktop/icons/${DISTRIBUTION,,}.png" "${destination}"/usr/share/pixmaps
sed 's/xenial.png/'"${DISTRIBUTION,,}"'.png/' -i "${destination}"/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml
# install logo for login screen
cp "${EXTER}"/packages/blobs/desktop/icons/orangepi.png "${destination}"/usr/share/pixmaps
# install wallpapers
mkdir -p "${destination}"/usr/share/backgrounds/xfce/
cp "${EXTER}"/packages/blobs/desktop/wallpapers/orangepi*.jpg "${destination}"/usr/share/backgrounds/xfce/
# create board DEB file
display_alert "Building desktop package" "${CHOSEN_DESKTOP}_${REVISION}_all" "info"
fakeroot dpkg-deb -b "${destination}" "${destination}.deb" >/dev/null
mkdir -p "${DEB_STORAGE}/${RELEASE}"
mv "${destination}.deb" "${DEB_STORAGE}/${RELEASE}"
# cleanup
rm -rf "${destination}"
}
desktop_postinstall ()
{
# disable display manager for first run
#chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload disable lightdm.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt update" >> "${DEST}"/debug/install.log 2>&1
if [[ ${FULL_DESKTOP} == yes ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_FULL" >> "${DEST}"/debug/install.log 2>&1
fi
if [[ -n ${PACKAGE_LIST_DESKTOP_BOARD} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_BOARD" >> "${DEST}"/debug/install.log 2>&1
fi
if [[ -n ${PACKAGE_LIST_DESKTOP_FAMILY} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_FAMILY" >> "${DEST}"/debug/install.log 2>&1
fi
# Compile Turbo Frame buffer for sunxi
if [[ $LINUXFAMILY == sun* && $BRANCH == legacy && $BOARD != orangepizero2 ]]; then
sed 's/name="use_compositing" type="bool" value="true"/name="use_compositing" type="bool" value="false"/' -i "${SDCARD}"/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml
# enable memory reservations
echo "disp_mem_reserves=on" >> "${SDCARD}"/boot/orangepiEnv.txt
echo "extraargs=cma=96M" >> "${SDCARD}"/boot/orangepiEnv.txt
fi
mkdir -p ${SDCARD}/etc/lightdm/lightdm.conf.d
cat <<-EOF > ${SDCARD}/etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
[Seat:*]
autologin-user=$OPI_USERNAME
autologin-user-timeout=0
user-session=xfce
EOF
}

618
scripts/distributions.sh Executable file
View File

@@ -0,0 +1,618 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
# install_common
# install_rclocal
# install_distribution_specific
# post_debootstrap_tweaks
install_common()
{
display_alert "Applying common tweaks" "" "info"
# install rootfs encryption related packages separate to not break packages cache
if [[ $CRYPTROOT_ENABLE == yes ]]; then
display_alert "Installing rootfs encryption related packages" "cryptsetup" "info"
chroot "${SDCARD}" /bin/bash -c "apt -y -qq --no-install-recommends install cryptsetup" \
>> "${DEST}"/debug/install.log 2>&1
if [[ $CRYPTROOT_SSH_UNLOCK == yes ]]; then
display_alert "Installing rootfs encryption related packages" "dropbear-initramfs" "info"
chroot "${SDCARD}" /bin/bash -c "apt -y -qq --no-install-recommends install dropbear-initramfs cryptsetup-initramfs" \
>> "${DEST}"/debug/install.log 2>&1
fi
fi
# add dummy fstab entry to make mkinitramfs happy
echo "/dev/mmcblk0p1 / $ROOTFS_TYPE defaults 0 1" >> "${SDCARD}"/etc/fstab
# required for initramfs-tools-core on Stretch since it ignores the / fstab entry
echo "/dev/mmcblk0p2 /usr $ROOTFS_TYPE defaults 0 2" >> "${SDCARD}"/etc/fstab
# adjust initramfs dropbear configuration
# needs to be done before kernel installation, else it won't be in the initrd image
if [[ $CRYPTROOT_ENABLE == yes && $CRYPTROOT_SSH_UNLOCK == yes ]]; then
# Set the port of the dropbear ssh deamon in the initramfs to a different one if configured
# this avoids the typical 'host key changed warning' - `WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!`
[[ -f "${SDCARD}"/etc/dropbear-initramfs/config ]] && \
sed -i 's/^#DROPBEAR_OPTIONS=/DROPBEAR_OPTIONS="-p '"${CRYPTROOT_SSH_UNLOCK_PORT}"'"/' \
"${SDCARD}"/etc/dropbear-initramfs/config
# setup dropbear authorized_keys, either provided by userpatches or generated
if [[ -f $USERPATCHES_PATH/dropbear_authorized_keys ]]; then
cp "$USERPATCHES_PATH"/dropbear_authorized_keys "${SDCARD}"/etc/dropbear-initramfs/authorized_keys
else
# generate a default ssh key for login on dropbear in initramfs
# this key should be changed by the user on first login
display_alert "Generating a new SSH key pair for dropbear (initramfs)" "" ""
ssh-keygen -t ecdsa -f "${SDCARD}"/etc/dropbear-initramfs/id_ecdsa \
-N '' -O force-command=cryptroot-unlock -C 'AUTOGENERATED_BY_ARMBIAN_BUILD' >> "${DEST}"/debug/install.log 2>&1
# /usr/share/initramfs-tools/hooks/dropbear will automatically add 'id_ecdsa.pub' to authorized_keys file
# during mkinitramfs of update-initramfs
#cat "${SDCARD}"/etc/dropbear-initramfs/id_ecdsa.pub > "${SDCARD}"/etc/dropbear-initramfs/authorized_keys
# The version of the Linux kernel
CRYPTROOT_SSH_UNLOCK_KEY_NAME="${BOARD^}_${REVISION}_${DISTRIBUTION,}_${RELEASE}_${IMAGETYPE}_linux"$(grab_version "$LINUXSOURCEDIR")"".key
# copy dropbear ssh key to image output dir for convenience
cp "${SDCARD}"/etc/dropbear-initramfs/id_ecdsa "${DEST}/images/${CRYPTROOT_SSH_UNLOCK_KEY_NAME}"
display_alert "SSH private key for dropbear (initramfs) has been copied to:" \
"$DEST/images/$CRYPTROOT_SSH_UNLOCK_KEY_NAME" "info"
fi
fi
# create modules file
local modules=MODULES_${BRANCH^^}
if [[ -n "${!modules}" ]]; then
tr ' ' '\n' <<< "${!modules}" > "${SDCARD}"/etc/modules
elif [[ -n "${MODULES}" ]]; then
tr ' ' '\n' <<< "${MODULES}" > "${SDCARD}"/etc/modules
fi
# create blacklist files
local blacklist=MODULES_BLACKLIST_${BRANCH^^}
if [[ -n "${!blacklist}" ]]; then
tr ' ' '\n' <<< "${!blacklist}" | sed -e 's/^/blacklist /' > "${SDCARD}/etc/modprobe.d/blacklist-${BOARD}.conf"
elif [[ -n "${MODULES_BLACKLIST}" ]]; then
tr ' ' '\n' <<< "${MODULES_BLACKLIST}" | sed -e 's/^/blacklist /' > "${SDCARD}/etc/modprobe.d/blacklist-${BOARD}.conf"
fi
# configure MIN / MAX speed for cpufrequtils
cat <<-EOF > "${SDCARD}"/etc/default/cpufrequtils
ENABLE=true
MIN_SPEED=$CPUMIN
MAX_SPEED=$CPUMAX
GOVERNOR=$GOVERNOR
EOF
# remove default interfaces file if present
# before installing board support package
rm -f "${SDCARD}"/etc/network/interfaces
# disable selinux by default
mkdir -p "${SDCARD}"/selinux
[[ -f "${SDCARD}"/etc/selinux/config ]] && sed "s/^SELINUX=.*/SELINUX=disabled/" -i "${SDCARD}"/etc/selinux/config
# remove Ubuntu's legal text
[[ -f "${SDCARD}"/etc/legal ]] && rm "${SDCARD}"/etc/legal
# Prevent loading paralel printer port drivers which we don't need here.
# Suppress boot error if kernel modules are absent
if [[ -f "${SDCARD}"/etc/modules-load.d/cups-filters.conf ]]; then
sed "s/^lp/#lp/" -i "${SDCARD}"/etc/modules-load.d/cups-filters.conf
sed "s/^ppdev/#ppdev/" -i "${SDCARD}"/etc/modules-load.d/cups-filters.conf
sed "s/^parport_pc/#parport_pc/" -i "${SDCARD}"/etc/modules-load.d/cups-filters.conf
fi
# console fix due to Debian bug
sed -e 's/CHARMAP=".*"/CHARMAP="'$CONSOLE_CHAR'"/g' -i "${SDCARD}"/etc/default/console-setup
# add the /dev/urandom path to the rng config file
echo "HRNGDEVICE=/dev/urandom" >> "${SDCARD}"/etc/default/rng-tools
# ping needs privileged action to be able to create raw network socket
# this is working properly but not with (at least) Debian Buster
chroot "${SDCARD}" /bin/bash -c "chmod u+s /bin/ping"
# change time zone data
echo "${TZDATA}" > "${SDCARD}"/etc/timezone
chroot "${SDCARD}" /bin/bash -c "dpkg-reconfigure -f noninteractive tzdata >/dev/null 2>&1"
# set root password
chroot "${SDCARD}" /bin/bash -c "(echo $ROOTPWD;echo $ROOTPWD;) | passwd root >/dev/null 2>&1"
# enable automated login to console(s)
#mkdir -p "${SDCARD}"/etc/systemd/system/getty@.service.d/
#mkdir -p "${SDCARD}"/etc/systemd/system/serial-getty@.service.d/
#cat <<-EOF > "${SDCARD}"/etc/systemd/system/serial-getty@.service.d/override.conf
#[Service]
#ExecStartPre=/bin/sleep 6
#ExecStart=
#ExecStart=-/sbin/agetty --noclear --autologin root %I $TERM
#Type=idle
#EOF
#cp "${SDCARD}"/etc/systemd/system/serial-getty@.service.d/override.conf "${SDCARD}"/etc/systemd/system/getty@.service.d/override.conf
# force change root password at first login
#chroot "${SDCARD}" /bin/bash -c "chage -d 0 root"
# change console welcome text
echo -e "Orange Pi ${REVISION} ${RELEASE^} \\l \n" > "${SDCARD}"/etc/issue
echo "Orange Pi ${REVISION} ${RELEASE^}" > "${SDCARD}"/etc/issue.net
sed -i "s/^PRETTY_NAME=.*/PRETTY_NAME=\"Orange Pi $REVISION "${RELEASE^}"\"/" "${SDCARD}"/etc/os-release
# enable few bash aliases enabled in Ubuntu by default to make it even
sed "s/#alias ll='ls -l'/alias ll='ls -l'/" -i "${SDCARD}"/etc/skel/.bashrc
sed "s/#alias la='ls -A'/alias la='ls -A'/" -i "${SDCARD}"/etc/skel/.bashrc
sed "s/#alias l='ls -CF'/alias l='ls -CF'/" -i "${SDCARD}"/etc/skel/.bashrc
# root user is already there. Copy bashrc there as well
cp "${SDCARD}"/etc/skel/.bashrc "${SDCARD}"/root
# display welcome message at first root login
touch "${SDCARD}"/root/.not_logged_in_yet
if [[ ${DESKTOP_AUTOLOGIN} != no ]]; then
# set desktop autologin
touch "${SDCARD}"/root/.desktop_autologin
fi
# NOTE: this needs to be executed before family_tweaks
local bootscript_src=${BOOTSCRIPT%%:*}
local bootscript_dst=${BOOTSCRIPT##*:}
cp "${EXTER}/config/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
if [[ -n $BOOTENV_FILE ]]; then
if [[ -f $USERPATCHES_PATH/bootenv/$BOOTENV_FILE ]]; then
cp "$USERPATCHES_PATH/bootenv/${BOOTENV_FILE}" "${SDCARD}"/boot/orangepiEnv.txt
elif [[ -f $EXTER/config/bootenv/$BOOTENV_FILE ]]; then
cp "${EXTER}/config/bootenv/${BOOTENV_FILE}" "${SDCARD}"/boot/orangepiEnv.txt
fi
fi
if [[ $ROOTFS_TYPE == nfs ]]; then
display_alert "Copying NFS boot script template"
if [[ -f $USERPATCHES_PATH/nfs-boot.cmd ]]; then
cp "$USERPATCHES_PATH"/nfs-boot.cmd "${SDCARD}"/boot/boot.cmd
else
cp "${EXTER}"/config/templates/nfs-boot.cmd.template "${SDCARD}"/boot/boot.cmd
if [[ -z $NFS_LOCAL_IP ]]; then
NFS_LOCAL_IP=$(ifconfig "${NET_IFNAME}" | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
fi
sed -i "s#BRANCH#$BRANCH#" "${SDCARD}"/boot/boot.cmd
sed -i "s#NFS_LOCAL_IP#$NFS_LOCAL_IP#" "${SDCARD}"/boot/boot.cmd
sed -i "s#NFS_ROOTFS#$NFS_ROOTFS#" "${SDCARD}"/boot/boot.cmd
fi
fi
[[ -n $OVERLAY_PREFIX && -f $SDCARD/boot/orangepiEnv.txt ]] && \
echo "overlay_prefix=$OVERLAY_PREFIX" >> "${SDCARD}"/boot/orangepiEnv.txt
[[ -n $DEFAULT_OVERLAYS && -f $SDCARD/boot/orangepiEnv.txt ]] && \
echo "overlays=${DEFAULT_OVERLAYS//,/ }" >> "${SDCARD}"/boot/orangepiEnv.txt
[[ -n $BOOT_FDT_FILE && -f $SDCARD/boot/orangepiEnv.txt ]] && \
echo "fdtfile=${BOOT_FDT_FILE}" >> "${SDCARD}/boot/orangepiEnv.txt"
# initial date for fake-hwclock
date -u '+%Y-%m-%d %H:%M:%S' > "${SDCARD}"/etc/fake-hwclock.data
echo "${HOST}" > "${SDCARD}"/etc/hostname
# set hostname in hosts file
cat <<-EOF > "${SDCARD}"/etc/hosts
127.0.0.1 localhost $HOST
::1 localhost $HOST ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
EOF
# install family packages
if [[ -n ${PACKAGE_LIST_FAMILY} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install $PACKAGE_LIST_FAMILY" >> "${DEST}"/debug/install.log 2>&1
fi
# install family packages
if [[ -n ${PACKAGE_LIST_BOARD} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install $PACKAGE_LIST_BOARD" >> "${DEST}"/debug/install.log 2>&1
fi
# remove family packages
if [[ -n ${PACKAGE_LIST_FAMILY_REMOVE} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq remove --auto-remove $PACKAGE_LIST_FAMILY_REMOVE" >> "${DEST}"/debug/install.log 2>&1
fi
# remove board packages
if [[ -n ${PACKAGE_LIST_BOARD_REMOVE} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq remove --auto-remove $PACKAGE_LIST_BOARD_REMOVE" >> "${DEST}"/debug/install.log 2>&1
fi
# install u-boot
if [[ "${REPOSITORY_INSTALL}" != *u-boot* ]]; then
UBOOT_VER=$(dpkg --info "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
install_deb_chroot "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb"
else
UBOOT_VER=$(dpkg --info "${DEB_ORANGEPI}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
install_deb_chroot "${DEB_ORANGEPI}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" "orangepi"
fi
# install kernel
if [[ "${REPOSITORY_INSTALL}" != *kernel* ]]; then
VER=$(dpkg --info "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
VER="${VER/-$LINUXFAMILY/}"
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb"
if [[ -f ${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb ]]; then
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb"
fi
if [[ $INSTALL_HEADERS == yes ]]; then
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/headers}_${REVISION}_${ARCH}.deb"
fi
else
VER=$(dpkg --info "${DEB_ORANGEPI}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
VER="${VER/-$LINUXFAMILY/}"
install_deb_chroot "${DEB_ORANGEPI}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" "orangepi"
if [[ -f ${DEB_ORANGEPI}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb ]]; then
install_deb_chroot "${DEB_ORANGEPI}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb" "orangepi"
fi
if [[ $INSTALL_HEADERS == yes ]]; then
install_deb_chroot "${DEB_ORANGEPI}/${CHOSEN_KERNEL/image/headers}_${REVISION}_${ARCH}.deb" "orangepi"
fi
fi
# install board support packages
if [[ "${REPOSITORY_INSTALL}" != *bsp* ]]; then
install_deb_chroot "${DEB_STORAGE}/$RELEASE/${CHOSEN_ROOTFS}_${REVISION}_${ARCH}.deb"
else
install_deb_chroot "${DEB_ORANGEPI}/$RELEASE/${CHOSEN_ROOTFS}_${REVISION}_${ARCH}.deb" "orangepi"
fi
# install orangepi-desktop
if [[ "${REPOSITORY_INSTALL}" != *orangepi-desktop* ]]; then
if [[ $BUILD_DESKTOP == yes ]]; then
install_deb_chroot "${DEB_STORAGE}/$RELEASE/orangepi-${RELEASE}-desktop_${REVISION}_all.deb"
# install display manager and PACKAGE_LIST_DESKTOP_FULL packages if enabled per board
desktop_postinstall
fi
else
if [[ $BUILD_DESKTOP == yes ]]; then
install_deb_chroot "${DEB_ORANGEPI}/$RELEASE/orangepi-${RELEASE}-desktop_${REVISION}_all.deb" "orangepi"
# install display manager and PACKAGE_LIST_DESKTOP_FULL packages if enabled per board
desktop_postinstall
fi
fi
# install orangepi-firmware
if [[ "${REPOSITORY_INSTALL}" != *orangepi-firmware* ]]; then
if [[ -f ${DEB_STORAGE}/orangepi-firmware_${REVISION}_all.deb ]]; then
install_deb_chroot "${DEB_STORAGE}/orangepi-firmware_${REVISION}_all.deb"
fi
else
if [[ -f ${DEB_STORAGE}/orangepi-firmware_${REVISION}_all.deb ]]; then
install_deb_chroot "${DEB_ORANGEPI}/orangepi-firmware_${REVISION}_all.deb" "orangepi"
fi
fi
# install orangepi-config
if [[ "${REPOSITORY_INSTALL}" != *orangepi-config* ]]; then
if [[ $BUILD_MINIMAL != yes ]]; then
install_deb_chroot "${DEB_STORAGE}/orangepi-config_${REVISION}_all.deb"
fi
else
if [[ $BUILD_MINIMAL != yes ]]; then
install_deb_chroot "${DEB_ORANGEPI}/orangepi-config_${REVISION}_all.deb" "orangepi"
fi
fi
# install kernel sources
if [[ -f ${DEB_STORAGE}/${CHOSEN_KSRC}_${REVISION}_all.deb && $INSTALL_KSRC == yes ]]; then
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KSRC}_${REVISION}_all.deb"
elif [[ $INSTALL_KSRC == yes ]]; then
display_alert "Please set BUILD_KSRC=yes to generate the kernel source package" "" "wrn"
fi
# install wireguard tools
if [[ $WIREGUARD == yes ]]; then
chroot "${SDCARD}" /bin/bash -c "apt -y -qq install wireguard-tools --no-install-recommends" >> "${DEST}"/debug/install.log 2>&1
fi
# freeze orangepi packages
if [[ $BSPFREEZE == yes ]]; then
display_alert "Freezing Orange Pi packages" "$BOARD" "info"
chroot "${SDCARD}" /bin/bash -c "apt-mark hold ${CHOSEN_KERNEL} ${CHOSEN_KERNEL/image/headers} \
linux-u-boot-${BOARD}-${BRANCH} ${CHOSEN_KERNEL/image/dtb}" >> "${DEST}"/debug/install.log 2>&1
fi
# add orangepi user
chroot "${SDCARD}" /bin/bash -c "adduser --quiet --disabled-password --shell /bin/bash --home /home/${OPI_USERNAME} --gecos ${OPI_USERNAME} ${OPI_USERNAME}"
chroot "${SDCARD}" /bin/bash -c "(echo ${OPI_PWD};echo ${OPI_PWD};) | passwd "${OPI_USERNAME}" >/dev/null 2>&1"
for additionalgroup in sudo netdev audio video disk tty users games dialout plugdev input bluetooth systemd-journal ssh; do
chroot "${SDCARD}" /bin/bash -c "usermod -aG ${additionalgroup} ${OPI_USERNAME} 2>/dev/null"
done
# fix for gksu in Xenial
touch ${SDCARD}/home/${OPI_USERNAME}/.Xauthority
chroot "${SDCARD}" /bin/bash -c "chown ${OPI_USERNAME}:${OPI_USERNAME} /home/${OPI_USERNAME}/.Xauthority"
# set up profile sync daemon on desktop systems
chroot "${SDCARD}" /bin/bash -c "which psd >/dev/null 2>&1"
if [ $? -eq 0 ]; then
echo -e "${OPI_USERNAME} ALL=(ALL) NOPASSWD: /usr/bin/psd-overlay-helper" >> ${SDCARD}/etc/sudoers
touch ${SDCARD}/home/${OPI_USERNAME}/.activate_psd
chroot "${SDCARD}" /bin/bash -c "chown $OPI_USERNAME:$OPI_USERNAME /home/${OPI_USERNAME}/.activate_psd"
fi
# remove deb files
rm -f "${SDCARD}"/root/*.deb
# copy boot splash images
cp "${EXTER}"/packages/blobs/splash/orangepi-u-boot.bmp "${SDCARD}"/boot/boot.bmp
# execute $LINUXFAMILY-specific tweaks
[[ $(type -t family_tweaks) == function ]] && family_tweaks
# enable additional services
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable orangepi-firstrun.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable orangepi-firstrun-config.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable orangepi-zram-config.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable orangepi-hardware-optimize.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable orangepi-ramlog.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable orangepi-resize-filesystem.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable orangepi-hardware-monitor.service >/dev/null 2>&1"
# copy "first run automated config, optional user configured"
cp ${EXTER}/packages/bsp/orangepi_first_run.txt.template "${SDCARD}"/boot/orangepi_first_run.txt.template
## switch to beta repository at this stage if building nightly images
#[[ $IMAGE_TYPE == nightly ]] \
#&& echo "deb http://beta.orangepi.com $RELEASE main ${RELEASE}-utils ${RELEASE}-desktop" \
#> "${SDCARD}"/etc/apt/sources.list.d/orangepi.list
# Cosmetic fix [FAILED] Failed to start Set console font and keymap at first boot
[[ -f "${SDCARD}"/etc/console-setup/cached_setup_font.sh ]] \
&& sed -i "s/^printf '.*/printf '\\\033\%\%G'/g" "${SDCARD}"/etc/console-setup/cached_setup_font.sh
[[ -f "${SDCARD}"/etc/console-setup/cached_setup_terminal.sh ]] \
&& sed -i "s/^printf '.*/printf '\\\033\%\%G'/g" "${SDCARD}"/etc/console-setup/cached_setup_terminal.sh
[[ -f "${SDCARD}"/etc/console-setup/cached_setup_keyboard.sh ]] \
&& sed -i "s/-u/-x'/g" "${SDCARD}"/etc/console-setup/cached_setup_keyboard.sh
# fix for https://bugs.launchpad.net/ubuntu/+source/blueman/+bug/1542723
chroot "${SDCARD}" /bin/bash -c "chown root:messagebus /usr/lib/dbus-1.0/dbus-daemon-launch-helper"
chroot "${SDCARD}" /bin/bash -c "chmod u+s /usr/lib/dbus-1.0/dbus-daemon-launch-helper"
sed -i "s/^#kernel.printk*/kernel.printk/" "${SDCARD}"/etc/sysctl.conf
# disable repeated messages due to xconsole not being installed.
[[ -f "${SDCARD}"/etc/rsyslog.d/50-default.conf ]] && \
sed '/daemon\.\*\;mail.*/,/xconsole/ s/.*/#&/' -i "${SDCARD}"/etc/rsyslog.d/50-default.conf
# disable deprecated parameter
sed '/.*$KLogPermitNonKernelFacility.*/,// s/.*/#&/' -i "${SDCARD}"/etc/rsyslog.conf
# enable getty on multiple serial consoles
# and adjust the speed if it is defined and different than 115200
#
# example: SERIALCON="ttyS0:15000000,ttyGS1"
#
ifs=$IFS
for i in $(echo "${SERIALCON:-'ttyS0'}" | sed "s/,/ /g")
do
IFS=':' read -r -a array <<< "$i"
# add serial console to secure tty list
[ -z "$(grep -w '^${array[0]}' "${SDCARD}"/etc/securetty 2> /dev/null)" ] && \
echo "${array[0]}" >> "${SDCARD}"/etc/securetty
if [[ ${array[1]} != "115200" && -n ${array[1]} ]]; then
# make a copy, fix speed and enable
cp "${SDCARD}"/lib/systemd/system/serial-getty@.service \
"${SDCARD}/lib/systemd/system/serial-getty@${array[0]}.service"
sed -i "s/--keep-baud 115200/--keep-baud ${array[1]},115200/" \
"${SDCARD}/lib/systemd/system/serial-getty@${array[0]}.service"
fi
display_alert "Enabling serial console" "${array[0]}" "info"
chroot "${SDCARD}" /bin/bash -c "systemctl daemon-reload" >> "${DEST}"/debug/install.log 2>&1
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable serial-getty@${array[0]}.service" \
>> "${DEST}"/debug/install.log 2>&1
if [[ "${array[0]}" == "ttyGS0" && $LINUXFAMILY == sun8i && $BRANCH == default ]]; then
mkdir -p "${SDCARD}"/etc/systemd/system/serial-getty@ttyGS0.service.d
cat <<-EOF > "${SDCARD}"/etc/systemd/system/serial-getty@ttyGS0.service.d/10-switch-role.conf
[Service]
ExecStartPre=-/bin/sh -c "echo 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role"
EOF
fi
done
IFS=$ifs
[[ $LINUXFAMILY == sun*i ]] && mkdir -p "${SDCARD}"/boot/overlay-user
# to prevent creating swap file on NFS (needs specific kernel options)
# and f2fs/btrfs (not recommended or needs specific kernel options)
[[ $ROOTFS_TYPE != ext4 ]] && touch "${SDCARD}"/var/swap
# install initial asound.state if defined
mkdir -p "${SDCARD}"/var/lib/alsa/
[[ -n $ASOUND_STATE ]] && cp "${EXTER}/packages/blobs/asound.state/${ASOUND_STATE}" "${SDCARD}"/var/lib/alsa/asound.state
# save initial orangepi-release state
cp "${SDCARD}"/etc/orangepi-release "${SDCARD}"/etc/orangepi-image-release
# DNS fix. package resolvconf is not available everywhere
if [ -d /etc/resolvconf/resolv.conf.d ]; then
echo "nameserver $NAMESERVER" > "${SDCARD}"/etc/resolvconf/resolv.conf.d/head
fi
# permit root login via SSH for the first boot
sed -i 's/#\?PermitRootLogin .*/PermitRootLogin yes/' "${SDCARD}"/etc/ssh/sshd_config
# enable PubkeyAuthentication
sed -i 's/#\?PubkeyAuthentication .*/PubkeyAuthentication yes/' "${SDCARD}"/etc/ssh/sshd_config
# configure network manager
sed "s/managed=\(.*\)/managed=true/g" -i "${SDCARD}"/etc/NetworkManager/NetworkManager.conf
# remove network manager defaults to handle eth by default
rm -f "${SDCARD}"/usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf
# most likely we don't need to wait for nm to get online
chroot "${SDCARD}" /bin/bash -c "systemctl disable NetworkManager-wait-online.service" >> "${DEST}"/debug/install.log 2>&1
# avahi daemon defaults if exists
[[ -f "${SDCARD}"/usr/share/doc/avahi-daemon/examples/sftp-ssh.service ]] && \
cp "${SDCARD}"/usr/share/doc/avahi-daemon/examples/sftp-ssh.service "${SDCARD}"/etc/avahi/services/
[[ -f "${SDCARD}"/usr/share/doc/avahi-daemon/examples/ssh.service ]] && \
cp "${SDCARD}"/usr/share/doc/avahi-daemon/examples/ssh.service "${SDCARD}"/etc/avahi/services/
# Just regular DNS and maintain /etc/resolv.conf as a file
sed "/dns/d" -i "${SDCARD}"/etc/NetworkManager/NetworkManager.conf
sed "s/\[main\]/\[main\]\ndns=default\nrc-manager=file/g" -i "${SDCARD}"/etc/NetworkManager/NetworkManager.conf
if [[ -n $NM_IGNORE_DEVICES ]]; then
mkdir -p "${SDCARD}"/etc/NetworkManager/conf.d/
cat <<-EOF > "${SDCARD}"/etc/NetworkManager/conf.d/10-ignore-interfaces.conf
[keyfile]
unmanaged-devices=$NM_IGNORE_DEVICES
EOF
fi
# nsswitch settings for sane DNS behavior: remove resolve, assure libnss-myhostname support
sed "s/hosts\:.*/hosts: files mymachines dns myhostname/g" -i "${SDCARD}"/etc/nsswitch.conf
# build logo in any case
#boot_logo
}
install_rclocal()
{
cat <<-EOF > "${SDCARD}"/etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
exit 0
EOF
chmod +x "${SDCARD}"/etc/rc.local
}
install_distribution_specific()
{
display_alert "Applying distribution specific tweaks for" "$RELEASE" "info"
case $RELEASE in
xenial)
# remove legal info from Ubuntu
[[ -f "${SDCARD}"/etc/legal ]] && rm "${SDCARD}"/etc/legal
# ureadahead needs kernel tracing options that AFAIK are present only in mainline. disable
chroot "${SDCARD}" /bin/bash -c \
"systemctl --no-reload mask ondemand.service ureadahead.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c \
"systemctl --no-reload mask setserial.service etc-setserial.service >/dev/null 2>&1"
;;
stretch|buster)
# remove doubled uname from motd
[[ -f "${SDCARD}"/etc/update-motd.d/10-uname ]] && rm "${SDCARD}"/etc/update-motd.d/10-uname
# rc.local is not existing but one might need it
install_rclocal
;;
bullseye)
# remove doubled uname from motd
[[ -f "${SDCARD}"/etc/update-motd.d/10-uname ]] && rm "${SDCARD}"/etc/update-motd.d/10-uname
# rc.local is not existing but one might need it
install_rclocal
# fix missing versioning
[[ $(grep -L "VERSION_ID=" "${SDCARD}"/etc/os-release) ]] && echo 'VERSION_ID="11"' >> "${SDCARD}"/etc/os-release
[[ $(grep -L "VERSION=" "${SDCARD}"/etc/os-release) ]] && echo 'VERSION="11 (bullseye)"' >> "${SDCARD}"/etc/os-release
# remove security updates repository since it does not exists yet
sed '/security/ d' -i "${SDCARD}"/etc/apt/sources.list
;;
bionic|eoan|focal)
# by using default lz4 initrd compression leads to corruption, go back to proven method
sed -i "s/^COMPRESS=.*/COMPRESS=gzip/" "${SDCARD}"/etc/initramfs-tools/initramfs.conf
# remove doubled uname from motd
[[ -f "${SDCARD}"/etc/update-motd.d/10-uname ]] && rm "${SDCARD}"/etc/update-motd.d/10-uname
# remove motd news from motd.ubuntu.com
[[ -f "${SDCARD}"/etc/default/motd-news ]] && sed -i "s/^ENABLED=.*/ENABLED=0/" "${SDCARD}"/etc/default/motd-news
# rc.local is not existing but one might need it
install_rclocal
# Basic Netplan config. Let NetworkManager manage all devices on this system
[[ -d "${SDCARD}"/etc/netplan ]] && cat <<-EOF > "${SDCARD}"/etc/netplan/orangepi-default.yaml
network:
version: 2
renderer: NetworkManager
EOF
# DNS fix
sed -i "s/#DNS=.*/DNS=$NAMESERVER/g" "${SDCARD}"/etc/systemd/resolved.conf
# Journal service adjustements
sed -i "s/#Storage=.*/Storage=volatile/g" "${SDCARD}"/etc/systemd/journald.conf
sed -i "s/#Compress=.*/Compress=yes/g" "${SDCARD}"/etc/systemd/journald.conf
sed -i "s/#RateLimitIntervalSec=.*/RateLimitIntervalSec=30s/g" "${SDCARD}"/etc/systemd/journald.conf
sed -i "s/#RateLimitBurst=.*/RateLimitBurst=10000/g" "${SDCARD}"/etc/systemd/journald.conf
# Chrony temporal fix https://bugs.launchpad.net/ubuntu/+source/chrony/+bug/1878005
sed -i '/DAEMON_OPTS=/s/"-F -1"/"-F 0"/' "${SDCARD}"/etc/default/chrony
# disable conflicting services
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload mask ondemand.service >/dev/null 2>&1"
;;
esac
}
post_debootstrap_tweaks()
{
# remove service start blockers and QEMU binary
rm -f "${SDCARD}"/sbin/initctl "${SDCARD}"/sbin/start-stop-daemon
chroot "${SDCARD}" /bin/bash -c "dpkg-divert --quiet --local --rename --remove /sbin/initctl"
chroot "${SDCARD}" /bin/bash -c "dpkg-divert --quiet --local --rename --remove /sbin/start-stop-daemon"
rm -f "${SDCARD}"/usr/sbin/policy-rc.d "${SDCARD}/usr/bin/${QEMU_BINARY}"
}

100
scripts/fel-load.sh Executable file
View File

@@ -0,0 +1,100 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# FEL_ROOTFS should be set to path to debootstrapped root filesystem
# unless you want to kill your /etc/fstab and share your rootfs on NFS
# without any access control
fel_prepare_host()
{
# Start rpcbind for NFS if inside docker container
[ "$(systemd-detect-virt)" == 'docker' ] && service rpcbind start
# remove and re-add NFS share
rm -f /etc/exports.d/orangepi.exports
mkdir -p /etc/exports.d
echo "$FEL_ROOTFS *(rw,async,no_subtree_check,no_root_squash,fsid=root)" > /etc/exports.d/orangepi.exports
# Start NFS server if inside docker container
[ "$(systemd-detect-virt)" == 'docker' ] && service nfs-kernel-server start
exportfs -ra
}
fel_prepare_target()
{
if [[ -f $USERPATCHES_PATH/fel-boot.cmd ]]; then
display_alert "Using custom boot script" "userpatches/fel-boot.cmd" "info"
cp "$USERPATCHES_PATH"/fel-boot.cmd "${FEL_ROOTFS}"/boot/boot.cmd
else
cp "${EXTER}"/config/templates/fel-boot.cmd.template "${FEL_ROOTFS}"/boot/boot.cmd
fi
if [[ -z $FEL_LOCAL_IP ]]; then
FEL_LOCAL_IP=$(ifconfig "${NET_IFNAME}" | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
fi
sed -i "s#BRANCH#$BRANCH#" "${FEL_ROOTFS}"/boot/boot.cmd
sed -i "s#FEL_LOCAL_IP#$FEL_LOCAL_IP#" "${FEL_ROOTFS}"/boot/boot.cmd
sed -i "s#FEL_ROOTFS#$FEL_ROOTFS#" "${FEL_ROOTFS}"/boot/boot.cmd
mkimage -C none -A arm -T script -d "${FEL_ROOTFS}"/boot/boot.cmd "${FEL_ROOTFS}"/boot/boot.scr > /dev/null
# kill /etc/fstab on target
echo > "${FEL_ROOTFS}"/etc/fstab
echo "/dev/nfs / nfs defaults 0 0" >> "${FEL_ROOTFS}"/etc/fstab
echo "tmpfs /tmp tmpfs defaults,nosuid 0 0" >> "${FEL_ROOTFS}"/etc/fstab
}
fel_load()
{
# update each time in case boot/script.bin link was changed in multi-board images
local dtb_file
if [[ -n $FEL_DTB_FILE ]]; then
dtb_file=$FEL_DTB_FILE
else
if [[ $BRANCH == legacy ]]; then
# script.bin is either regular file or absolute symlink
if [[ -L $FEL_ROOTFS/boot/script.bin ]]; then
dtb_file=boot/bin/$(basename "$(readlink "${FEL_ROOTFS}"/boot/script.bin)")
else
dtb_file=boot/script.bin
fi
else
dtb_file=boot/dtb/$(grep CONFIG_DEFAULT_DEVICE_TREE "${FEL_ROOTFS}/usr/lib/u-boot/${BOOTCONFIG}" | cut -d '"' -f2).dtb
fi
fi
[[ $(type -t fel_pre_load) == function ]] && fel_pre_load
display_alert "Loading files via" "FEL USB" "info"
sunxi-fel "${FEL_EXTRA_ARGS}" -p uboot "${FEL_ROOTFS}/usr/lib/${CHOSEN_UBOOT}_${REVISION}_armhf/u-boot-sunxi-with-spl.bin" \
write 0x42000000 "${FEL_ROOTFS}"/boot/zImage \
write 0x43000000 "${FEL_ROOTFS}/${dtb_file}" \
write 0x43300000 "${FEL_ROOTFS}"/boot/uInitrd \
write 0x43100000 "${FEL_ROOTFS}"/boot/boot.scr
}
if [[ -f $USERPATCHES_PATH/fel-hooks.sh ]]; then
display_alert "Using additional FEL hooks in" "external/userpatches/fel-hooks.sh" "info"
# shellcheck source=/dev/null
source "$USERPATCHES_PATH"/fel-hooks.sh
fi
# basic sanity check
if [[ -n $FEL_ROOTFS ]]; then
fel_prepare_host
fel_prepare_target
[[ $(type -t fel_post_prepare) == function ]] && fel_post_prepare
RES=b
while [[ $RES != q ]]; do
if [[ $FEL_AUTO != yes ]]; then
display_alert "Connect device in FEL mode and press" "<Enter>" "info"
read -r
fi
fel_load
display_alert "Press any key to boot again, <q> to finish" "FEL" "info"
read -r -n 1 RES
echo
done
service nfs-kernel-server restart
fi

1044
scripts/general.sh Executable file

File diff suppressed because it is too large Load Diff

143
scripts/image-helpers.sh Executable file
View File

@@ -0,0 +1,143 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
# mount_chroot
# umount_chroot
# unmount_on_exit
# check_loop_device
# install_external_applications
# write_uboot
# customize_image
# install_deb_chroot
# mount_chroot <target>
#
# helper to reduce code duplication
#
mount_chroot()
{
local target=$1
mount -t proc chproc "${target}"/proc
mount -t sysfs chsys "${target}"/sys
mount -t devtmpfs chdev "${target}"/dev || mount --bind /dev "${target}"/dev
mount -t devpts chpts "${target}"/dev/pts
} #############################################################################
# umount_chroot <target>
#
# helper to reduce code duplication
#
umount_chroot()
{
local target=$1
display_alert "Unmounting" "$target" "info"
while grep -Eq "${target}.*(dev|proc|sys)" /proc/mounts
do
umount -l --recursive "${target}"/dev >/dev/null 2>&1
umount -l "${target}"/proc >/dev/null 2>&1
umount -l "${target}"/sys >/dev/null 2>&1
sleep 5
done
} #############################################################################
# unmount_on_exit
#
unmount_on_exit()
{
trap - INT TERM EXIT
umount_chroot "${SDCARD}/"
umount -l "${SDCARD}"/tmp >/dev/null 2>&1
umount -l "${SDCARD}" >/dev/null 2>&1
umount -l "${MOUNT}"/boot >/dev/null 2>&1
umount -l "${MOUNT}" >/dev/null 2>&1
[[ $CRYPTROOT_ENABLE == yes ]] && cryptsetup luksClose "${ROOT_MAPPER}"
losetup -d "${LOOP}" >/dev/null 2>&1
rm -rf --one-file-system "${SDCARD}"
if [[ -f "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid" ]];then
rm "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid"
fi
exit_with_error "debootstrap-ng was interrupted"
} #############################################################################
# check_loop_device <device_node>
#
check_loop_device()
{
local device=$1
if [[ ! -b $device ]]; then
if [[ $CONTAINER_COMPAT == yes && -b /tmp/$device ]]; then
display_alert "Creating device node" "$device"
mknod -m0660 "${device}" b "0x$(stat -c '%t' "/tmp/$device")" "0x$(stat -c '%T' "/tmp/$device")"
else
exit_with_error "Device node $device does not exist"
fi
fi
} #############################################################################
# write_uboot <loopdev>
#
# writes u-boot to loop device
# Parameters:
# loopdev: loop device with mounted rootfs image
#
write_uboot()
{
local loop=$1
display_alert "Writing U-boot bootloader" "$loop" "info"
mkdir -p /tmp/u-boot/
dpkg -x "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" /tmp/u-boot/
write_uboot_platform "/tmp/u-boot/usr/lib/${CHOSEN_UBOOT}_${REVISION}_${ARCH}" "$loop"
[[ $? -ne 0 ]] && exit_with_error "U-boot bootloader failed to install" "@host"
rm -r /tmp/u-boot/
sync
} #############################################################################
customize_image()
{
# for users that need to prepare files at host
[[ -f $USERPATCHES_PATH/customize-image-host.sh ]] && source "$USERPATCHES_PATH"/customize-image-host.sh
cp "$USERPATCHES_PATH"/customize-image.sh "${SDCARD}"/tmp/customize-image.sh
chmod +x "${SDCARD}"/tmp/customize-image.sh
mkdir -p "${SDCARD}"/tmp/overlay
# util-linux >= 2.27 required
mount -o bind,ro "$USERPATCHES_PATH"/overlay "${SDCARD}"/tmp/overlay
display_alert "Calling image customization script" "customize-image.sh" "info"
chroot "${SDCARD}" /bin/bash -c "/tmp/customize-image.sh $RELEASE $LINUXFAMILY $BOARD $BUILD_DESKTOP"
CUSTOMIZE_IMAGE_RC=$?
umount -i "${SDCARD}"/tmp/overlay >/dev/null 2>&1
mountpoint -q "${SDCARD}"/tmp/overlay || rm -r "${SDCARD}"/tmp/overlay
if [[ $CUSTOMIZE_IMAGE_RC != 0 ]]; then
exit_with_error "customize-image.sh exited with error (rc: $CUSTOMIZE_IMAGE_RC)"
fi
} #############################################################################
install_deb_chroot()
{
local package=$1
local type=$2
local name=$(basename "${package}")
cp "${package}" "${SDCARD}/root/${name}"
if [[ ${type} == "orangepi" ]]; then
display_alert "Installing form Orange Pi" "$name"
else
display_alert "Installing" "$name"
fi
[[ $NO_APT_CACHER != yes ]] && local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\""
LC_ALL=C LANG=C chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt -yqq \
$apt_extra --no-install-recommends install ./root/$name" >> "${DEST}"/debug/install.log 2>&1
rm -f "${SDCARD}/root/${name}"
}

482
scripts/main.sh Executable file
View File

@@ -0,0 +1,482 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Main program
#
if [[ $(basename "$0") == main.sh ]]; then
echo "Please use build.sh to start the build process"
exit 255
fi
# default umask for root is 022 so parent directories won't be group writeable without this
# this is used instead of making the chmod in prepare_host() recursive
umask 002
# destination
DEST="${SRC}"/output
REVISION="2.0.8"
[[ $DOWNLOAD_MIRROR == "china" ]] && NTP_SERVER="cn.pool.ntp.org"
if [[ $BUILD_ALL != "yes" ]]; then
# override stty size
[[ -n $COLUMNS ]] && stty cols $COLUMNS
[[ -n $LINES ]] && stty rows $LINES
TTY_X=$(($(stty size | awk '{print $2}')-6)) # determine terminal width
TTY_Y=$(($(stty size | awk '{print $1}')-6)) # determine terminal height
fi
# We'll use this title on all menus
backtitle="Orange Pi building script, http://www.orangepi.org"
titlestr="Choose an option"
# if language not set, set to english
[[ -z $LANGUAGE ]] && export LANGUAGE="en_US:en"
# default console if not set
[[ -z $CONSOLE_CHAR ]] && export CONSOLE_CHAR="UTF-8"
[[ -z $FORCE_CHECKOUT ]] && FORCE_CHECKOUT=yes
# Load libraries
# shellcheck source=debootstrap.sh
source "${SRC}"/scripts/debootstrap.sh # system specific install
# shellcheck source=image-helpers.sh
source "${SRC}"/scripts/image-helpers.sh # helpers for OS image building
# shellcheck source=distributions.sh
source "${SRC}"/scripts/distributions.sh # system specific install
# shellcheck source=desktop.sh
source "${SRC}"/scripts/desktop.sh # desktop specific install
# shellcheck source=compilation.sh
source "${SRC}"/scripts/compilation.sh # patching and compilation of kernel, uboot, ATF
# shellcheck source=compilation-prepare.sh
#source "${SRC}"/scripts/compilation-prepare.sh # kernel plugins - 3rd party drivers that are not upstreamed. Like WG, AUFS, various Wifi
# shellcheck source=makeboarddeb.sh
source "${SRC}"/scripts/makeboarddeb.sh # create board support package
# shellcheck source=general.sh
source "${SRC}"/scripts/general.sh # general functions
# shellcheck source=chroot-buildpackages.sh
source "${SRC}"/scripts/chroot-buildpackages.sh # building packages in chroot
# shellcheck source=pack.sh
source "${SRC}"/scripts/pack-uboot.sh
# compress and remove old logs
mkdir -p "${DEST}"/debug
(cd "${DEST}"/debug && tar -czf logs-"$(<timestamp)".tgz ./*.log) > /dev/null 2>&1
rm -f "${DEST}"/debug/*.log > /dev/null 2>&1
date +"%d_%m_%Y-%H_%M_%S" > "${DEST}"/debug/timestamp
# delete compressed logs older than 7 days
(cd "${DEST}"/debug && find . -name '*.tgz' -mtime +7 -delete) > /dev/null
if [[ $PROGRESS_DISPLAY == none ]]; then
OUTPUT_VERYSILENT=yes
elif [[ $PROGRESS_DISPLAY == dialog ]]; then
OUTPUT_DIALOG=yes
fi
if [[ $PROGRESS_LOG_TO_FILE != yes ]]; then unset PROGRESS_LOG_TO_FILE; fi
SHOW_WARNING=yes
if [[ $USE_CCACHE != no ]]; then
CCACHE=ccache
export PATH="/usr/lib/ccache:$PATH"
# private ccache directory to avoid permission issues when using build script with "sudo"
# see https://ccache.samba.org/manual.html#_sharing_a_cache for alternative solution
[[ $PRIVATE_CCACHE == yes ]] && export CCACHE_DIR=$DEST/cache/ccache
else
CCACHE=""
fi
if [ "$OFFLINE_WORK" == "yes" ]; then
echo -e "\n"
display_alert "* " "You are working offline."
display_alert "* " "Sources, time and host will not be checked"
echo -e "\n"
sleep 3s
else
# we need dialog to display the menu in case not installed. Other stuff gets installed later
prepare_host_basic
fi
# if BUILD_OPT, KERNEL_CONFIGURE, BOARD, BRANCH or RELEASE are not set, display selection menu
if [[ -z $BUILD_OPT ]]; then
options+=("u-boot" "U-boot package")
options+=("kernel" "Kernel package")
options+=("rootfs" "Rootfs and all deb packages")
options+=("image" "Full OS image for flashing")
menustr="Compile image | rootfs | kernel | u-boot"
BUILD_OPT=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" --notags \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $BUILD_OPT ]] && exit_with_error "No option selected"
fi
if [[ -z $BOARD ]]; then
options+=("orangepir1" "Allwinner H2+ quad core 256MB RAM WiFi SPI 2xETH")
options+=("orangepizero" "Allwinner H2+ quad core 256MB/512MB RAM WiFi SPI")
options+=("orangepipc" "Allwinner H3 quad core 1GB RAM")
options+=("orangepipcplus" "Allwinner H3 quad core 1GB RAM WiFi eMMC")
options+=("orangepione" "Allwinner H3 quad core 512MB RAM")
options+=("orangepilite" "Allwinner H3 quad core 512MB RAM WiFi")
options+=("orangepiplus" "Allwinner H3 quad core 1GB/2GB RAM WiFi GBE eMMC")
options+=("orangepiplus2e" "Allwinner H3 quad core 2GB RAM WiFi GBE eMMC")
options+=("orangepizeroplus2h3" "Allwinner H3 quad core 512MB RAM WiFi/BT eMMC")
options+=("orangepipc2" "Allwinner H5 quad core 1GB RAM GBE SPI")
options+=("orangepiprime" "Allwinner H5 quad core 2GB RAM GBE WiFi/BT")
options+=("orangepizeroplus" "Allwinner H5 quad core 512MB RAM GBE WiFi SPI")
options+=("orangepizeroplus2h5" "Allwinner H5 quad core 512MB RAM WiFi/BT eMMC")
options+=("orangepi3" "Allwinner H6 quad core 1GB/2GB RAM GBE WiFi/BT eMMC USB3")
options+=("orangepilite2" "Allwinner H6 quad core 1GB RAM WiFi/BT USB3")
options+=("orangepioneplus" "Allwinner H6 quad core 1GB RAM GBE")
options+=("orangepizero2" "Allwinner H616 quad core 512MB/1GB RAM WiFi/BT GBE SPI")
menustr="Please choose a Board."
BOARD=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $BOARD ]] && exit_with_error "No option selected"
fi
BOARD_TYPE="conf"
# shellcheck source=/dev/null
source "${EXTER}/config/boards/${BOARD}.${BOARD_TYPE}"
LINUXFAMILY="${BOARDFAMILY}"
[[ -z $KERNEL_TARGET ]] && exit_with_error "Board configuration does not define valid kernel config"
if [[ -z $BRANCH ]]; then
options=()
[[ $KERNEL_TARGET == *current* ]] && options+=("current" "Recommended. Come with best support")
[[ $KERNEL_TARGET == *legacy* ]] && options+=("legacy" "Old stable / Legacy")
[[ $KERNEL_TARGET == *dev* && $EXPERT = yes ]] && options+=("dev" "\Z1Development version (@kernel.org)\Zn")
menustr="Select the target kernel branch\nExact kernel versions depend on selected board"
# do not display selection dialog if only one kernel branch is available
if [[ "${#options[@]}" == 2 ]]; then
BRANCH="${options[0]}"
else
BRANCH=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
fi
unset options
[[ -z $BRANCH ]] && exit_with_error "No kernel branch selected"
else
[[ $KERNEL_TARGET != *$BRANCH* ]] && exit_with_error "Kernel branch not defined for this board" "$BRANCH"
fi
if [[ ${BUILD_OPT} == image || ${BUILD_OPT} == kernel ]]; then
if [[ -z $KERNEL_CONFIGURE ]]; then
options+=("no" "Do not change the kernel configuration")
options+=("yes" "Show a kernel configuration menu before compilation")
menustr="Select the kernel configuration."
KERNEL_CONFIGURE=$(whiptail --title "${titlestr}" --backtitle "$backtitle" --notags \
--menu "${menustr}" $TTY_Y $TTY_X $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $KERNEL_CONFIGURE ]] && exit_with_error "No option selected"
fi
fi
# define distribution support status
declare -A distro_name
distro_name['stretch']="Debian 9 Stretch"
distro_name['buster']="Debian 10 Buster"
distro_name['bullseye']="Debian 11 Bullseye"
distro_name['xenial']="Ubuntu Xenial 16.04 LTS"
distro_name['bionic']="Ubuntu Bionic 18.04 LTS"
distro_name['focal']="Ubuntu Focal 20.04 LTS"
distro_name['eoan']="Ubuntu Eoan 19.10"
if [[ ${BUILD_OPT} == image || ${BUILD_OPT} == rootfs ]]; then
RELEASE_TARGET="stretch buster bullseye xenial bionic eoan focal"
if [[ -z $RELEASE ]]; then
if [[ $BRANCH == legacy ]]; then
if [[ $LINUXFAMILY == sun50iw9 || $LINUXFAMILY == sun50iw6 ]]; then
RELEASE_TARGET="stretch xenial buster bionic focal"
else
RELEASE_TARGET="xenial"
fi
elif [[ $BRANCH == current || $BRANCH == dev ]]; then
RELEASE_TARGET="buster bionic focal"
else
[[ -z $BRANCH ]] && exit_with_error "No kernel branch selected"
fi
distro_menu "stretch"
distro_menu "buster"
distro_menu "bullseye"
distro_menu "xenial"
distro_menu "bionic"
distro_menu "eoan"
distro_menu "focal"
menustr="Select the target OS release package base"
RELEASE=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $RELEASE ]] && exit_with_error "No option selected"
fi
# don't show desktop option if we choose minimal build
[[ $BUILD_MINIMAL == yes ]] && BUILD_DESKTOP="no"
if [[ -z $BUILD_DESKTOP ]]; then
options+=("no" "Image with console interface (server)")
options+=("yes" "Image with desktop environment")
menustr="Select the target image type."
BUILD_DESKTOP=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" --notags \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $BUILD_DESKTOP ]] && exit_with_error "No option selected"
[[ $BUILD_DESKTOP == yes ]] && BUILD_MINIMAL="no"
fi
if [[ $BUILD_DESKTOP == "no" && -z $BUILD_MINIMAL ]]; then
options+=("no" "Standard image with console interface")
options+=("yes" "Minimal image with console interface")
menustr="Select the target image type."
BUILD_MINIMAL=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" --notags \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $BUILD_MINIMAL ]] && exit_with_error "No option selected"
fi
fi
#prevent conflicting setup
[[ $BUILD_DESKTOP == yes ]] && BUILD_MINIMAL=no
[[ $BUILD_DESKTOP == yes ]] && IMAGETYPE="desktop"
[[ $BUILD_DESKTOP == no ]] && IMAGETYPE="server"
[[ $BUILD_MINIMAL == yes ]] && EXTERNAL_NEW=no
CONTAINER_COMPAT="no"
[[ -z $COMPRESS_OUTPUTIMAGE ]] && COMPRESS_OUTPUTIMAGE="yes"
#shellcheck source=configuration.sh
source "${SRC}"/scripts/configuration.sh
# optimize build time with 100% CPU usage
CPUS=$(grep -c 'processor' /proc/cpuinfo)
if [[ $USEALLCORES != no ]]; then
CTHREADS="-j$((CPUS + CPUS/2))"
else
CTHREADS="-j1"
fi
if [[ $BUILD_ALL == yes && -n $GPG_PASS ]]; then
IMAGE_TYPE=stable
else
IMAGE_TYPE=user-built
fi
branch2dir() {
[[ "${1}" == "head" ]] && echo "HEAD" || echo "${1##*:}"
}
BOOTSOURCEDIR="${BOOTDIR}/$(branch2dir "${BOOTBRANCH}")"
LINUXSOURCEDIR="${KERNELDIR}/$(branch2dir "${KERNELBRANCH}")"
[[ -n $ATFSOURCE ]] && ATFSOURCEDIR="${ATFDIR}/$(branch2dir "${ATFBRANCH}")"
# The version of the Linux kernel
#VER=$(grab_version "$LINUXSOURCEDIR")
#KERNEL_NAME="linux${VER}"
# define package names
DEB_BRANCH=${BRANCH//default}
# if not empty, append hyphen
DEB_BRANCH=${DEB_BRANCH:+${DEB_BRANCH}-}
CHOSEN_UBOOT=linux-u-boot-${DEB_BRANCH}${BOARD}
CHOSEN_KERNEL=linux-image-${DEB_BRANCH}${LINUXFAMILY}
CHOSEN_ROOTFS=linux-${RELEASE}-root-${DEB_BRANCH}${BOARD}
CHOSEN_DESKTOP=orangepi-${RELEASE}-desktop
CHOSEN_KSRC=linux-source-${BRANCH}-${LINUXFAMILY}
do_default() {
start=$(date +%s)
# Check and install dependencies, directory structure and settings
# The OFFLINE_WORK variable inside the function
prepare_host
[[ $CLEAN_LEVEL == *sources* ]] && cleaning "sources"
# fetch_from_repo <url> <dir> <ref> <subdir_flag>
# ignore updates help on building all images - for internal purposes
if [[ $IGNORE_UPDATES != yes ]]; then
display_alert "Downloading sources" "" "info"
fetch_from_repo "$BOOTSOURCE" "$BOOTDIR" "$BOOTBRANCH" "yes"
fetch_from_repo "$KERNELSOURCE" "$KERNELDIR" "$KERNELBRANCH" "yes"
if [[ -n $ATFSOURCE ]]; then
fetch_from_repo "$ATFSOURCE" "${EXTER}/cache/sources/$ATFDIR" "$ATFBRANCH" "yes"
fi
fetch_from_repo "https://github.com/linux-sunxi/sunxi-tools" "${EXTER}/cache/sources/sunxi-tools" "branch:master"
#fetch_from_repo "https://github.com/armbian/rkbin" "${EXTER}/cache/sources/rkbin-tools" "branch:master"
fi
compile_sunxi_tools
#install_rkbin_tools
for option in $(tr ',' ' ' <<< "$CLEAN_LEVEL"); do
[[ $option != sources ]] && cleaning "$option"
done
# Compile u-boot if packed .deb does not exist or use the one from Orange Pi
if [[ $BUILD_OPT == u-boot || $BUILD_OPT == image ]]; then
if [[ ! -f "${DEB_STORAGE}"/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb ]]; then
[[ -n "${ATFSOURCE}" && "${REPOSITORY_INSTALL}" != *u-boot* ]] && compile_atf
[[ ${REPOSITORY_INSTALL} != *u-boot* ]] && compile_uboot
fi
if [[ $BUILD_OPT == "u-boot" ]]; then
display_alert "U-boot build done" "@host" "info"
display_alert "Target directory" "${DEB_STORAGE}/u-boot" "info"
display_alert "File name" "${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" "info"
fi
fi
# Compile kernel if packed .deb does not exist or use the one from Orange Pi
if [[ $BUILD_OPT == kernel || $BUILD_OPT == image ]]; then
if [[ ! -f ${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb ]]; then
[[ "${REPOSITORY_INSTALL}" != *kernel* ]] && compile_kernel
fi
if [[ $BUILD_OPT == "kernel" ]]; then
display_alert "Kernel build done" "@host" "info"
display_alert "Target directory" "${DEB_STORAGE}/" "info"
display_alert "File name" "${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" "info"
fi
fi
if [[ $BUILD_OPT == rootfs || $BUILD_OPT == image ]]; then
# Compile orangepi-config if packed .deb does not exist or use the one from Orange Pi
if [[ ! -f ${DEB_STORAGE}/orangepi-config_${REVISION}_all.deb ]]; then
[[ "${REPOSITORY_INSTALL}" != *orangepi-config* ]] && compile_orangepi-config
fi
if [[ ! -f ${DEB_STORAGE}/orangepi-firmware_${REVISION}_all.deb ]]; then
[[ "${REPOSITORY_INSTALL}" != *orangepi-firmware* ]] && compile_firmware
fi
overlayfs_wrapper "cleanup"
# create board support package
if [[ ! -f ${DEB_STORAGE}/$RELEASE/${CHOSEN_ROOTFS}_${REVISION}_${ARCH}.deb ]]; then
[[ "${REPOSITORY_INSTALL}" != *bsp* ]] && create_board_package
fi
# create desktop package
if [[ ! -f ${DEB_STORAGE}/$RELEASE/${CHOSEN_DESKTOP}_${REVISION}_all.deb ]]; then
[[ "${REPOSITORY_INSTALL}" != *orangepi-desktop* ]] && create_desktop_package
fi
# build additional packages
[[ $EXTERNAL_NEW == compile ]] && chroot_build_packages
[[ $BSP_BUILD != yes ]] && debootstrap_ng
fi
# hook for function to run after build, i.e. to change owner of $SRC
# NOTE: this will run only if there were no errors during build process
[[ $(type -t run_after_build) == function ]] && run_after_build || true
end=$(date +%s)
runtime=$(((end-start)/60))
display_alert "Runtime" "$runtime min" "info"
# Make it easy to repeat build by displaying build options used
[ "$(systemd-detect-virt)" == 'docker' ] && BUILD_CONFIG='docker'
display_alert "Repeat Build Options" "sudo ./build.sh ${BUILD_CONFIG} BOARD=${BOARD} BRANCH=${BRANCH} \
$([[ -n $BUILD_OPT ]] && echo "BUILD_OPT=${BUILD_OPT} ")\
$([[ -n $RELEASE ]] && echo "RELEASE=${RELEASE} ")\
$([[ -n $BUILD_MINIMAL ]] && echo "BUILD_MINIMAL=${BUILD_MINIMAL} ")\
$([[ -n $BUILD_DESKTOP ]] && echo "BUILD_DESKTOP=${BUILD_DESKTOP} ")\
$([[ -n $KERNEL_CONFIGURE ]] && echo "KERNEL_CONFIGURE=${KERNEL_CONFIGURE}")\
" "info"
} # end of do_default()
if [[ -z $1 ]]; then
do_default
else
eval "$@"
fi

306
scripts/makeboarddeb.sh Executable file
View File

@@ -0,0 +1,306 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Create board support packages
#
# Functions:
# create_board_package
create_board_package()
{
display_alert "Creating board support package" "$BOARD $BRANCH" "info"
local destination=$SRC/.tmp/${RELEASE}/${CHOSEN_ROOTFS}_${REVISION}_${ARCH}
rm -rf "${destination}"
mkdir -p "${destination}"/DEBIAN
# install copy of boot script & environment file
local bootscript_src=${BOOTSCRIPT%%:*}
local bootscript_dst=${BOOTSCRIPT##*:}
mkdir -p "${destination}"/usr/share/orangepi/
cp "${EXTER}/config/bootscripts/${bootscript_src}" "${destination}/usr/share/orangepi/${bootscript_dst}"
[[ -n $BOOTENV_FILE && -f ${EXTER}/config/bootenv/$BOOTENV_FILE ]] && \
cp "${EXTER}/config/bootenv/${BOOTENV_FILE}" "${destination}"/usr/share/orangepi/orangepiEnv.txt
# add configuration for setting uboot environment from userspace with: fw_setenv fw_printenv
if [[ -n $UBOOT_FW_ENV ]]; then
UBOOT_FW_ENV=($(tr ',' ' ' <<< "$UBOOT_FW_ENV"))
mkdir -p "${destination}"/etc
echo "# Device to access offset env size" > "${destination}"/etc/fw_env.config
echo "/dev/mmcblk0 ${UBOOT_FW_ENV[0]} ${UBOOT_FW_ENV[1]}" >> "${destination}"/etc/fw_env.config
fi
# Replaces: base-files is needed to replace /etc/update-motd.d/ files on Xenial
# Replaces: unattended-upgrades may be needed to replace /etc/apt/apt.conf.d/50unattended-upgrades
# (distributions provide good defaults, so this is not needed currently)
# Depends: linux-base is needed for "linux-version" command in initrd cleanup script
# Depends: fping is needed for orangepimonitor to upload orangepi-hardware-monitor.log
cat <<-EOF > "${destination}"/DEBIAN/control
Package: linux-${RELEASE}-root-${DEB_BRANCH}${BOARD}
Version: $REVISION
Architecture: $ARCH
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Installed-Size: 1
Section: kernel
Priority: optional
Depends: bash, linux-base, u-boot-tools, initramfs-tools, lsb-release, fping
Provides: orangepi-bsp
Conflicts: orangepi-bsp
Suggests: orangepi-config
Replaces: zram-config, base-files, orangepi-tools-$RELEASE
Recommends: bsdutils, parted, util-linux, toilet
Description: OrangePi tweaks for $RELEASE on $BOARD ($BRANCH branch)
EOF
# set up pre install script
cat <<-EOF > "${destination}"/DEBIAN/preinst
#!/bin/sh
# tell people to reboot at next login
[ "\$1" = "upgrade" ] && touch /var/run/.reboot_required
# convert link to file
if [ -L "/etc/network/interfaces" ]; then
cp /etc/network/interfaces /etc/network/interfaces.tmp
rm /etc/network/interfaces
mv /etc/network/interfaces.tmp /etc/network/interfaces
fi
# fixing ramdisk corruption when using lz4 compression method
sed -i "s/^COMPRESS=.*/COMPRESS=gzip/" /etc/initramfs-tools/initramfs.conf
# swap
grep -q vm.swappiness /etc/sysctl.conf
case \$? in
0)
sed -i 's/vm\.swappiness.*/vm.swappiness=100/' /etc/sysctl.conf
;;
*)
echo vm.swappiness=100 >>/etc/sysctl.conf
;;
esac
sysctl -p >/dev/null 2>&1
# disable deprecated services
[ -f "/etc/profile.d/activate_psd_user.sh" ] && rm /etc/profile.d/activate_psd_user.sh
[ -f "/etc/profile.d/check_first_login.sh" ] && rm /etc/profile.d/check_first_login.sh
[ -f "/etc/profile.d/check_first_login_reboot.sh" ] && rm /etc/profile.d/check_first_login_reboot.sh
[ -f "/etc/profile.d/ssh-title.sh" ] && rm /etc/profile.d/ssh-title.sh
[ -f "/etc/update-motd.d/10-header" ] && rm /etc/update-motd.d/10-header
[ -f "/etc/update-motd.d/30-sysinfo" ] && rm /etc/update-motd.d/30-sysinfo
[ -f "/etc/update-motd.d/35-tips" ] && rm /etc/update-motd.d/35-tips
[ -f "/etc/update-motd.d/40-updates" ] && rm /etc/update-motd.d/40-updates
[ -f "/etc/update-motd.d/98-autoreboot-warn" ] && rm /etc/update-motd.d/98-autoreboot-warn
[ -f "/etc/update-motd.d/99-point-to-faq" ] && rm /etc/update-motd.d/99-point-to-faq
[ -f "/etc/update-motd.d/80-esm" ] && rm /etc/update-motd.d/80-esm
[ -f "/etc/update-motd.d/80-livepatch" ] && rm /etc/update-motd.d/80-livepatch
[ -f "/etc/apt/apt.conf.d/50unattended-upgrades" ] && rm /etc/apt/apt.conf.d/50unattended-upgrades
[ -f "/etc/apt/apt.conf.d/02compress-indexes" ] && rm /etc/apt/apt.conf.d/02compress-indexes
[ -f "/etc/apt/apt.conf.d/02periodic" ] && rm /etc/apt/apt.conf.d/02periodic
[ -f "/etc/apt/apt.conf.d/no-languages" ] && rm /etc/apt/apt.conf.d/no-languages
[ -f "/etc/init.d/armhwinfo" ] && rm /etc/init.d/armhwinfo
[ -f "/etc/logrotate.d/armhwinfo" ] && rm /etc/logrotate.d/armhwinfo
[ -f "/etc/init.d/firstrun" ] && rm /etc/init.d/firstrun
[ -f "/etc/init.d/resize2fs" ] && rm /etc/init.d/resize2fs
[ -f "/lib/systemd/system/firstrun-config.service" ] && rm /lib/systemd/system/firstrun-config.service
[ -f "/lib/systemd/system/firstrun.service" ] && rm /lib/systemd/system/firstrun.service
[ -f "/lib/systemd/system/resize2fs.service" ] && rm /lib/systemd/system/resize2fs.service
[ -f "/usr/lib/orangepi/apt-updates" ] && rm /usr/lib/orangepi/apt-updates
[ -f "/usr/lib/orangepi/firstrun-config.sh" ] && rm /usr/lib/orangepi/firstrun-config.sh
dpkg-divert --quiet --package linux-${RELEASE}-root-${DEB_BRANCH}${BOARD} --add --rename --divert /etc/mpv/mpv-dist.conf /etc/mpv/mpv.conf
exit 0
EOF
chmod 755 "${destination}"/DEBIAN/preinst
# postrm script
cat <<-EOF > "${destination}"/DEBIAN/postrm
#!/bin/sh
if [ remove = "\$1" ] || [ abort-install = "\$1" ]; then
dpkg-divert --quiet --package linux-${RELEASE}-root-${DEB_BRANCH}${BOARD} --remove --rename --divert /etc/mpv/mpv-dist.conf /etc/mpv/mpv.conf
systemctl disable orangepi-hardware-monitor.service orangepi-hardware-optimize.service >/dev/null 2>&1
systemctl disable orangepi-zram-config.service orangepi-ramlog.service >/dev/null 2>&1
fi
exit 0
EOF
chmod 755 "${destination}"/DEBIAN/postrm
# set up post install script
cat <<-EOF > "${destination}"/DEBIAN/postinst
#!/bin/sh
#
# ${BOARD} BSP post installation script
#
systemctl --no-reload enable orangepi-ramlog.service
# check if it was disabled in config and disable in new service
if [ -n "\$(grep -w '^ENABLED=false' /etc/default/log2ram 2> /dev/null)" ]; then
sed -i "s/^ENABLED=.*/ENABLED=false/" /etc/default/orangepi-ramlog
fi
# fix boot delay "waiting for suspend/resume device"
if [ -f "/etc/initramfs-tools/initramfs.conf" ]; then
if ! grep --quiet "RESUME=none" /etc/initramfs-tools/initramfs.conf; then
echo "RESUME=none" >> /etc/initramfs-tools/initramfs.conf
fi
fi
EOF
if [[ $RELEASE == bionic ]] || [[ $RELEASE == focal && $BOARDFAMILY == sun50iw6 ]]; then
cat <<-EOF >> "${destination}"/DEBIAN/postinst
# temporally disable acceleration on some arch in Bionic due to broken mesa packages
echo 'Section "Device"
\tIdentifier \t"Default Device"
\tOption \t"AccelMethod" "none"
EndSection' >> /etc/X11/xorg.conf.d/01-orangepi-defaults.conf
EOF
fi
# install bootscripts if they are not present. Fix upgrades from old images
if [[ $FORCE_BOOTSCRIPT_UPDATE == yes ]]; then
cat <<-EOF >> "${destination}"/DEBIAN/postinst
if [ true ]; then
# this package recreate boot scripts
EOF
else
cat <<-EOF >> "${destination}"/DEBIAN/postinst
if [ ! -f /boot/$bootscript_dst ]; then
# if boot script does not exits its recreated
EOF
fi
cat <<-EOF >> "${destination}"/DEBIAN/postinst
# move bootscript to /usr/share/orangepi
# create a backup
[ -f /etc/orangepi-release ] && . /etc/orangepi-release
[ -z \${VERSION} ] && VERSION=$(echo \`date +%s\`)
if [ -f /boot/$bootscript_dst ]; then
cp /boot/$bootscript_dst /usr/share/orangepi/${bootscript_dst}-\${VERSION} >/dev/null 2>&1
echo "NOTE: You can find previous bootscript versions in /usr/share/orangepi !"
fi
# cleanup old bootscript backup
ls /usr/share/orangepi/boot.cmd-* >/dev/null 2>&1 | head -n -5 | xargs rm -f --
ls /usr/share/orangepi/boot.ini-* >/dev/null 2>&1 | head -n -5 | xargs rm -f --
echo "Recreating boot script"
cp /usr/share/orangepi/$bootscript_dst /boot >/dev/null 2>&1
rootdev=\$(sed -e 's/^.*root=//' -e 's/ .*\$//' < /proc/cmdline)
rootfstype=\$(sed -e 's/^.*rootfstype=//' -e 's/ .*$//' < /proc/cmdline)
# recreate orangepiEnv.txt only not exists
if [ ! -f /boot/orangepiEnv.txt ]; then
cp /usr/share/orangepi/orangepiEnv.txt /boot/ >/dev/null 2>&1
echo "rootdev="\$rootdev >> /boot/orangepiEnv.txt
echo "rootfstype="\$rootfstype >> /boot/orangepiEnv.txt
fi
[ -f /boot/boot.ini ] && sed -i "s/setenv rootdev.*/setenv rootdev \\"\$rootdev\\"/" /boot/boot.ini
[ -f /boot/boot.ini ] && sed -i "s/setenv rootfstype.*/setenv rootfstype \\"\$rootfstype\\"/" /boot/boot.ini
[ -f /boot/boot.cmd ] && mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr >/dev/null 2>&1
fi
[ ! -f "/etc/network/interfaces" ] && cp /etc/network/interfaces.default /etc/network/interfaces
ln -sf /var/run/motd /etc/motd
rm -f /etc/update-motd.d/00-header /etc/update-motd.d/10-help-text
if [ ! -f "/etc/default/orangepi-motd" ]; then
mv /etc/default/orangepi-motd.dpkg-dist /etc/default/orangepi-motd
fi
if [ ! -f "/etc/default/orangepi-ramlog" ]; then
mv /etc/default/orangepi-ramlog.dpkg-dist /etc/default/orangepi-ramlog
fi
if [ ! -f "/etc/default/orangepi-zram-config" ]; then
mv /etc/default/orangepi-zram-config.dpkg-dist /etc/default/orangepi-zram-config
fi
if [ -L "/usr/lib/chromium-browser/master_preferences.dpkg-dist" ]; then
mv /usr/lib/chromium-browser/master_preferences.dpkg-dist /usr/lib/chromium-browser/master_preferences
fi
systemctl --no-reload enable orangepi-hardware-monitor.service orangepi-hardware-optimize.service orangepi-zram-config.service >/dev/null 2>&1
exit 0
EOF
chmod 755 "${destination}"/DEBIAN/postinst
# won't recreate files if they were removed by user
# TODO: Add proper handling for updated conffiles
#cat <<-EOF > "${destination}"/DEBIAN/conffiles
#EOF
# copy common files from a premade directory structure
rsync -a "${EXTER}"/packages/bsp/common/* "${destination}"/
# trigger uInitrd creation after installation, to apply
# /etc/initramfs/post-update.d/99-uboot
cat <<-EOF > "${destination}"/DEBIAN/triggers
activate update-initramfs
EOF
# armhwinfo, firstrun, orangepimonitor, etc. config file
cat <<-EOF > "${destination}"/etc/orangepi-release
# PLEASE DO NOT EDIT THIS FILE
BOARD=${BOARD}
BOARD_NAME="$BOARD_NAME"
BOARDFAMILY=${BOARDFAMILY}
BUILD_REPOSITORY_URL=${BUILD_REPOSITORY_URL}
BUILD_REPOSITORY_COMMIT=${BUILD_REPOSITORY_COMMIT}
DISTRIBUTION_CODENAME=${RELEASE}
VERSION=${REVISION}
LINUXFAMILY=${LINUXFAMILY}
BRANCH=${BRANCH}
ARCH=${ARCHITECTURE}
IMAGE_TYPE=$IMAGE_TYPE
BOARD_TYPE=$BOARD_TYPE
INITRD_ARCH=${INITRD_ARCH}
KERNEL_IMAGE_TYPE=${KERNEL_IMAGE_TYPE}
EOF
# this is required for NFS boot to prevent deconfiguring the network on shutdown
sed -i 's/#no-auto-down/no-auto-down/g' "${destination}"/etc/network/interfaces.default
if [[ $LINUXFAMILY == sunxi* ]]; then
# add mpv config for x11 output - slow, but it works compared to no config at all
# TODO: Test which output driver is better with DRM
mkdir -p "${destination}"/etc/mpv/
cp "${EXTER}"/packages/bsp/mpv/mpv_mainline.conf "${destination}"/etc/mpv/mpv.conf
fi
# execute $LINUXFAMILY-specific tweaks
[[ $(type -t family_tweaks_bsp) == function ]] && family_tweaks_bsp
# add some summary to the image
fingerprint_image "${destination}/etc/orangepi.txt"
# fixing permissions (basic), reference: dh_fixperms
find "${destination}" -print0 2>/dev/null | xargs -0r chown --no-dereference 0:0
find "${destination}" ! -type l -print0 2>/dev/null | xargs -0r chmod 'go=rX,u+rw,a-s'
# create board DEB file
display_alert "Building package" "$CHOSEN_ROOTFS" "info"
fakeroot dpkg-deb -b "${destination}" "${destination}.deb" >> "${DEST}"/debug/install.log 2>&1
mkdir -p "${DEB_STORAGE}/${RELEASE}/"
mv "${destination}.deb" "${DEB_STORAGE}/${RELEASE}/"
# cleanup
rm -rf "${destination}"
}

179
scripts/pack-uboot.sh Executable file
View File

@@ -0,0 +1,179 @@
#!/bin/bash
#
# SPDX-License-Identifier: GPL-2.0
function do_prepare()
{
if [[ $BOARDFAMILY == "sun50iw6" ]]; then
configs_file_list=(
${FILE}/*.fex
${FILE}/boot_package.cfg
)
boot_file_list=(
${BOOTDIR}/boot0_sdcard_${CHIP}.bin:${PACK_OUT}/boot0_sdcard.fex
${BOOTDIR}/u-boot-${CHIP}.bin:${PACK_OUT}/u-boot.fex
${FILE}/scp.bin:${PACK_OUT}/scp.fex
${FILE}/bl31.bin:${PACK_OUT}/monitor.fex
${SYS_CONFIG}:${PACK_OUT}/sys_config.fex
)
for file in ${configs_file_list[@]} ; do
cp -f $file ${PACK_OUT}/ 2> /dev/null
done
for file in ${boot_file_list[@]} ; do
cp -rf `echo $file | awk -F: '{print $1}'` \
`echo $file | awk -F: '{print $2}'` 2>/dev/null
done
else
export PATH=$EXTER/packages/pack-uboot/${BOARDFAMILY}/tools/:$PATH
cp ${EXTER}/packages/pack-uboot/${BOARDFAMILY}/bin/* .
cp ${BOOTSOURCEDIR}/u-boot.bin u-boot.fex
[[ $BOARDFAMILY != sun50iw9 ]] && cp ${BOOTSOURCEDIR}/boot0_sdcard.bin boot0_sdcard.fex
fi
}
function do_ini_to_dts()
{
if [[ $BOARDFAMILY == "sun50iw6" ]]; then
local DTC_SRC_PATH=${LINUXSOURCEDIR}/arch/${ARCHITECTURE}/boot/dts/sunxi/
local DTC_INI_FILE_BASE=${SYS_CONFIG}
local DTC_INI_FILE=${DEST}/sys_config_fix.fex
cp $DTC_INI_FILE_BASE $DTC_INI_FILE
sed -i "s/\(\[dram\)_para\(\]\)/\1\2/g" $DTC_INI_FILE
sed -i "s/\(\[nand[0-9]\)_para\(\]\)/\1\2/g" $DTC_INI_FILE
DTC_SRC_FILE=${EXTER}/chips/${CHIP}/pack/bin/dtc_src_file
dtc_alph -O dtb -o ${DEST}/sunxi.dtb \
-b 0 \
-i $DTC_SRC_PATH \
-F $DTC_INI_FILE \
$DTC_SRC_FILE 1>/dev/null 2>&1
if [ $? -ne 0 ]; then
pack_error "Conver script to dts failed"
exit 1
fi
else
local DTC_COMPILER=$EXTER/packages/pack-uboot/${BOARDFAMILY}/tools/dtc
[[ ! -f $DTC_COMPILER ]] && exit_with_error "Script_to_dts: Can not find dtc compiler."
$DTC_COMPILER -p 2048 -W no-unit_address_vs_reg -@ -O dtb -o ${BOARD}-u-boot.dtb -b 0 ${BOARD}-u-boot.dts
[[ $? -ne 0 ]] && exit_with_error "Conver script to dts failed."
# It'is used for debug dtb
$DTC_COMPILER -W no-unit_address_vs_reg -I dtb -O dts -o .${BOARD}-u-boot.dts ${BOARD}-u-boot.dtb 1>/dev/null 2>&1
fi
}
function do_common()
{
if [[ $BOARDFAMILY == "sun50iw9" ]]; then
busybox unix2dos sys_config.fex
script sys_config.fex > /dev/null
cp ${PACKOUT_DIR}/${BOARD}-u-boot.dtb sunxi.fex
update_dtb sunxi.fex 4096
update_boot0 boot0_sdcard.fex sys_config.bin SDMMC_CARD > /dev/null
update_uboot -no_merge u-boot.fex sys_config.bin > /dev/null
[[ $? -ne 0 ]] && exit_with_error "update u-boot run error"
#pack boot package
busybox unix2dos boot_package.cfg
dragonsecboot -pack boot_package.cfg > /dev/null
[[ $? -ne 0 ]] && exit_with_error "dragon pack error"
else
unix2dos sys_config.fex 2>/dev/null
script sys_config.fex > /dev/null
cp sys_config.bin config.fex 2>/dev/null
cp ${DEST}/sunxi.dtb sunxi.fex
update_uboot_fdt u-boot.fex sunxi.fex u-boot.fex >/dev/null
update_scp scp.fex sunxi.fex >/dev/null
# Those files for Nand or Card
update_boot0 boot0_sdcard.fex sys_config.bin SDMMC_CARD > /dev/null
update_uboot u-boot.fex sys_config.bin > /dev/null
unix2dos boot_package.cfg 2>/dev/null
dragonsecboot -pack boot_package.cfg 1>/dev/null 2>&1
#Here, will check if need to used multi config.fex or not
update_uboot_v2 u-boot.fex sys_config.bin ${LINUXFAMILY} 1>/dev/null 2>&1
fi
}
do_pack_a64()
{
cp -avf ${FILE}/* ${PACK_OUT}/ > /dev/null
cp -avf $BOOTDIR/u-boot-sun50iw1p1.bin ${PACK_OUT}/u-boot.bin > /dev/null
# Build binary device tree
dtc -Odtb -o A64.dtb A64.dts 1>/dev/null 2>&1
# Build sys_config.bin
unix2dos sys_config.fex 1>/dev/null 2>&1
script sys_config.fex 1>/dev/null 2>&1
# Merge u-boot.bin infile outfile mode [secmonitor | secos | scp]
merge_uboot u-boot.bin bl31.bin u-boot-merged.bin secmonitor 1>/dev/null 2>&1
merge_uboot u-boot-merged.bin scp.bin u-boot-merged2.bin scp 1>/dev/null 2>&1
# Merge uboot and dtb
update_uboot_fdt u-boot-merged2.bin A64.dtb u-boot-with-dtb.bin 1>/dev/null 2>&1
# Merge uboot and sys_config.fex
update_uboot u-boot-with-dtb.bin sys_config.bin 1>/dev/null 2>&1
cp ${PACK_OUT}/boot0.bin ${UBOOT_BIN}/boot0_sdcard_${CHIP}.bin 1>/dev/null 2>&1
cp ${PACK_OUT}/u-boot-with-dtb.bin ${UBOOT_BIN}/u-boot-${CHIP}.bin 1>/dev/null 2>&1
cp ${PACK_OUT}/A64.dtb ${UBOOT_BIN}/ 1>/dev/null 2>&1
}
do_pack_h3()
{
cp $BOOTDIR/boot0_sdcard_${CHIP}.bin ${PACK_OUT}
cp $BOOTDIR/u-boot-${CHIP}.bin ${PACK_OUT}
cp $SYS_CONFIG ${PACK_OUT}/sys_config.fex
fex2bin sys_config.fex sys_config.bin
update_boot0 boot0_sdcard_${CHIP}.bin sys_config.bin SDMMC_CARD 1>/dev/null 2>&1
update_uboot u-boot-${CHIP}.bin sys_config.bin 1>/dev/null 2>&1
cp boot0_sdcard_${CHIP}.bin $UBOOT_BIN/boot0_sdcard_${CHIP}.bin
cp u-boot-${CHIP}.bin $UBOOT_BIN/u-boot-${CHIP}.bin
cp sys_config.bin $UBOOT_BIN/script.bin_${BOARD}
cp sys_config.bin $EXTER/chips/${CHIP}/script/script.bin_${BOARD}
}
pack_uboot()
{
PACKOUT_DIR=$SRC/.tmp/packout
rm -rf ${PACKOUT_DIR}
mkdir -p ${PACKOUT_DIR}
cd ${PACKOUT_DIR}
do_prepare
do_ini_to_dts
do_common
}