Newer
Older
#!/bin/bash
arg=$1
arr_index=0
declare -a command_array
declare -a help_array
# Check if we should clone feeds with ssh or http
developer=0
which git >/dev/null && git remote -v 2>/dev/null | grep -qE '(git@|ssh://)' && developer=1
# Utility functions
function register_command {
command_array[$arr_index]=$1
help_array[$arr_index]=$2
arr_index=$((arr_index+1))
}
output+=("${command_array[$i]}" "${help_array[$i]}")
printf "Available commands:\n"
printf " %-25s%s\n" "${output[@]}" | sort
printf "\n"
# Parse yaml file, look for specified feed definition and create feeds.conf-like output
function parse_yaml_feed() {
local yaml_file="$1"
local feed="$2"
local yaml_content=$(cat "$yaml_file")
# Extract the values
local names=($(echo "$yaml_content" | grep -oP '(?<=name: ).*'))
local urls=($(echo "$yaml_content" | grep -oP '(?<=uri: ).*'))
local revisions=($(echo "$yaml_content" | grep -oP '(?<=revision: ).*'))
# Create the output string
local output=""
for ((i=0; i<${#names[@]}; i++)); do
if [ ${names[i]} == ${feed} ]; then
output+="src-git-full ${names[i]} ${urls[i]}^${revisions[i]}\n"
fi
done
echo -e "$output"
}
function has_profiles_feed() {
# regex taken from ./scripts/feeds
grep -qP '^src-([\w\-]+)((?:\s+--\w+(?:=\S+)?)*)\s+(profiles)' feeds.conf
}
# Register bootstrap command that installs other commands from feeds
cp feeds.conf.io feeds.conf
parse_yaml_feed "profiles/include/iop_feed.yml" iopsys >> feeds.conf
feeds=(iopsys)
if has_profiles_feed; then
feeds+=(profiles)
fi
if [ "$developer" == 1 ]; then
./scripts/feeds update -g "${feeds[@]}" || exit 1
./scripts/feeds update "${feeds[@]}" || exit 1
./scripts/feeds install -p iopsys iop || exit 1
}
register_command "bootstrap" "Initial command to run to install other commands"
function install_locales()
{
sudo locale-gen en_US.UTF-8
}
function install_pkgs()
{
local packages_misc="
device-tree-compiler
python3
python3-cryptography
"
local packages_perl="libconvert-binary-c-perl libdigest-crc-perl"
# do we need 32 bit compatibility libs ?
if [ "$(uname -m | awk '{print$1}')" == "x86_64" ]; then
local packages_x64="libc6-dev-i386 lib32z1 libncurses5:i386"
fi
local packages_all="$packages_misc $packages_perl $packages_x64"
for pkg in $packages_all
do
if ! dpkg -s $pkg >/dev/null 2>/dev/null
then
needed="$needed $pkg"
fi
done
# install needed packages
if [ -n "$needed" ]
then
echo "Need to install dpkg packages [$needed]"
read -p "Do you approve installation of these packages (y/n): " ans
if [ "$ans" == "y" ]; then
sudo apt-get update && sudo apt-get install $needed || exit $?
else
echo "can't continue. aborting!"
exit 1
fi
fi
}
check_bash()
{
local mysh=$(ls -hl /bin/sh | awk -F'[ ,/]' '{print$NF}')
if [ "$mysh" != "bash" ]; then
echo "On Debian based systems, e.g. Ubuntu, /bin/sh must point to bash instead of $mysh"
read -p "Do you approve this change (y/n): " ans
if [ "$ans" == "y" ]; then
sudo rm -f /bin/sh
sudo ln -s bash /bin/sh
else
echo "Warning! You haven't pointed /bin/sh to bash."
exit 1
fi
fi
}
download_check_hash() {
local url="$1"
local sha256="$2"
local tarball="$(mktemp iop_brcm_tar.XXXXXXX)"
wget -nv "$url" -O "$tarball" || return 1
if ! sha256sum --quiet -c <(echo "${sha256} *${tarball}") >&2; then
echo "Hash mismatch of tarball $url (expected: $sha256)" >&2
sha256sum "$tarball" >&2
return 1
fi
printf "%s" "$tarball"
}
download_extract_bcm() {
local type="$1"
local url="$2"
local sha256="$3"
local path="$4"
local path_strip_no=0
if [ ! -z "$5" ]; then
path_strip_no="$5"
fi
local tarball="$(download_check_hash "$url" "$sha256")"
if [ -z "$tarball" ]; then
echo "Error: Error occurred during download or hash verification for $url"
case "$type" in
toolchain)
# current 10.3/4.19/2.30/2.32 BCM toolchain has owner of files set to some employee who created the tar
# Change to root during extraction
sudo tar --owner=root --group=root -C "$path" --strip-components=$path_strip_no -Pxf "$tarball"
;;
hnd_toolchain)
sudo mkdir -p "$path" && \
sudo tar --owner=root --group=root -C "$path" -xf "$tarball" --strip-components=1
;;
wlan_fw_tools)
(
set -e
sudo mkdir -p "$path"
sudo unzip -j \
"$tarball" \
bcawlan-fw-build-post-process-tools/post-process-tools/\* \
-d "$path/bin"
sudo find "$path/bin" -type f -not -name '*.ini' -execdir chmod +x '{}' ';'
)
;;
*)
echo "Error: Unknown type $type" >&2
false
;;
esac
local ret=$?
check_brcm_tools(){
local install_arm=0
local install_arm_softfp=0
local install_arm_hf=0
local install_wlan_fw_tools=0
local TOOLCHAIN_DIR="/opt/toolchains/"
if [ ! -d ${TOOLCHAIN_DIR}/crosstools-arm-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
install_arm=1
echo "Need to install Broadcom ARM toolchain"
if [ ! -d ${TOOLCHAIN_DIR}/crosstools-arm_softfp-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
install_arm_softfp=1
echo "Need to install Broadcom ARM-softfp toolchain"
fi
if [ ! -d ${TOOLCHAIN_DIR}crosstools-arm_hf-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
install_arm_hf=1
echo "Need to install Broadcom ARM-hf toolchain"
fi
if [ ! -d ${TOOLCHAIN_DIR}crosstools-aarch64-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
install_aarch64=1
echo "Need to install Broadcom aarch64 toolchain"
fi
if [ ! -d /opt/bcawlan-fw-build-post-process-tools ]; then
install_wlan_fw_tools=1
echo "Need to install bcawlan-fw-build-post-process-tools"
fi
if [ "$install_arm" -eq 1 \
-o "$install_arm_softfp" -eq 1 \
-o "$install_arm_hf" -eq 1 \
-o "$install_aarch64" -eq 1 \
read -p "Do you approve installation of the aforementioned missing toolchains and tools (y/n): " ans
echo "Downloading toolchain/tools"
else
echo "can't continue. aborting"
exit 1
fi
# create install dir
sudo mkdir -p ${TOOLCHAIN_DIR}
if [ $install_arm -eq 1 ]; then
echo "Installing ARM toolchain"
download_extract_bcm \
toolchain \
https://download.iopsys.eu/iopsys/toolchain/crosstools-arm-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
38657d72a7726db3e13621784d3e1ad65e2721c0538e87cc38cf3266bde26d6f \
${TOOLCHAIN_DIR}
fi
if [ $install_arm_softfp -eq 1 ]; then
download_extract_bcm \
toolchain \
https://download.iopsys.eu/iopsys/toolchain/crosstools-arm_softfp-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
9af29bac2ba6cbe51ee09467dbe97dc76a47bbf00df1fffafa1433817d2a147b \
${TOOLCHAIN_DIR}
fi
if [ $install_arm_hf -eq 1 ]; then
download_extract_bcm \
toolchain \
https://download.iopsys.eu/iopsys/toolchain/crosstools-arm_hf-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
3e57bbbb5e0b832813aa93274dfa937260833af645c2bc03cb1c88d4e98def92 \
${TOOLCHAIN_DIR}
fi
if [ $install_aarch64 -eq 1 ]; then
echo "Installing aarch64 toolchain"
download_extract_bcm \
toolchain \
https://download.iopsys.eu/iopsys/toolchain/crosstools-aarch64-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
aed8c327951a5a7bfd67f9d2e92f844923a216994764e0aa32903bd40ea8945a \
${TOOLCHAIN_DIR}
if [ $install_wlan_fw_tools -eq 1 ]; then
echo "Installing bcawlan-fw-build-post-process-tools"
download_extract_bcm \
wlan_fw_tools \
https://download.iopsys.eu/iopsys/toolchain/bcawlan-fw-build-post-process-tools.zip \
1082d631317aef900ab2bfe549830bfbc76da87f21ff78cd3129f369f3f92101 \
/opt/bcawlan-fw-build-post-process-tools
fi
}
check_gcc_version(){
gcc_ver=$(ls -l $(which gcc) | awk '{ print $NF }')
# if /usr/bin/gcc -> /etc/alternatives/cc
if [ -L $gcc_ver ]; then
gcc_ver=$(ls -l $gcc_ver | awk '{ print $NF }')
fi
# transform gcc-* to just a number.
gcc_ver=$(echo $gcc_ver | cut -d- -f2)
if [ "$gcc_ver" != 4.8 ]; then
echo "Your current gcc version is $gcc_ver, but it must be changed to 4.8"
read -p "Do you approve this change (y/n): " ans
if [ "$ans" == "y" ]; then
if ! dpkg -s gcc-4.8 >/dev/null 2>/dev/null ;then
sudo apt-get install gcc-4.8
fi
if ! dpkg -s g++-4.8 >/dev/null 2>/dev/null ;then
sudo apt-get install g++-4.8
fi
if ! dpkg -s gcc-4.8-multilib >/dev/null 2>/dev/null ;then
sudo apt-get install gcc-4.8-multilib
fi
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
sudo update-alternatives --install /usr/bin/g++ c++ /usr/bin/g++-4.8 100
sudo update-alternatives --install /usr/bin/g++ c++ /usr/bin/g++-$gcc_ver 90
sudo update-alternatives --install /usr/bin/gcc cc /usr/bin/gcc-4.8 100
sudo update-alternatives --install /usr/bin/gcc cc /usr/bin/gcc-$gcc_ver 90
sudo update-alternatives --install /usr/bin/cpp cpp /usr/bin/cpp-4.8 100
sudo update-alternatives --install /usr/bin/cpp cpp /usr/bin/cpp-$gcc_ver 90
sudo update-alternatives --set c++ /usr/bin/g++-4.8
sudo update-alternatives --set cc /usr/bin/gcc-4.8
sudo update-alternatives --set cpp /usr/bin/cpp-4.8
sudo ln -s /etc/alternatives/cc /usr/bin/cc
echo "The deafult gcc version has now been changed from $gcc_ver to 4.8"
fi
fi
}
restore_gcc() {
if dpkg -s gcc-5 >/dev/null 2>/dev/null
then
gcc_ver=$(ls -l $(which gcc) | awk '{ print $NF }')
# if /usr/bin/gcc -> /etc/alternatives/cc
if [ -L $gcc_ver ]; then
gcc_ver=$(ls -l $gcc_ver | awk '{ print $NF }')
fi
# transform gcc-* to just a number.
gcc_ver=$(echo $gcc_ver | cut -d- -f2)
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# is 4.8 the default reset back to 5
if [ "$gcc_ver" = "4.8" ]; then
echo "Your current gcc version is $gcc_ver that is not the distro default. set it back to default ?"
read -p "Do you approve this change (y/n): " ans
if [ "$ans" == "y" ]; then
sudo update-alternatives --set c++ /usr/bin/g++-5
sudo update-alternatives --set cc /usr/bin/gcc-5
sudo update-alternatives --set cpp /usr/bin/cpp-5
# force a reinstall of default version
# yes it needs to be done twice.
sudo apt-get install --reinstall gcc cpp g++
sudo apt-get install --reinstall gcc cpp g++
fi
fi
fi
}
# Compare modification date of two files
# return 0 (true) if first file is older, 1 (false) otherwise
is_older() {
local target=$(stat -c %Y $1 2> /dev/null)
local ref=$(stat -c %Y $2 2> /dev/null)
[ -z "$target" -o -z "$ref" ] && return 1
[ $target -lt $ref ] && return 0
return 1
}
install_iop_completion() {
local instloc=/usr/share/bash-completion/completions/iop
local srcloc=./feeds/iopsys/iop/iop.completion
local inst=0
if [ ! -e $instloc ]; then
echo "Bash completion for './iop' utility not found"
inst=1
elif is_older $instloc $srcloc ; then
echo "Bash completion for './iop' utility is outdated"
inst=1
fi
if [ $inst -eq 1 ]; then
read -p "Install latest version to '$instloc' (y/n): " ans
if [ "$ans" == "y" ]; then
sudo cp $srcloc $instloc
echo "Start a new shell to enable ./iop command completion!"
fi
fi
}
function setup_host {
#===============#
# Prerequisites #
#===============#
install_locales
install_pkgs
check_bash
check_brcm_tools
#check_gcc_version
restore_gcc
install_iop_completion
echo ""
echo ""
echo "You have successfully installed and configred prerequisites to be able to build an iopsys firmware"
echo ""
echo ""
}
register_command "setup_host" "Install needed packets to host machine"
# Plugin scripts call register command to export their interface
if [ -d package/feeds/iopsys/iop/scripts ]; then
for f in package/feeds/iopsys/iop/scripts/*; do
source $f
done
fi
function feeds_update {
# Call bootstrap to update feeds/iopsys for transiton in old/new genconfig state
echo "Calling bootstrap to update required feeds"
bootstrap
# always return true
exit 0
}
register_command "feeds_update" "Compatibility function only"
function set-feed-rev() {
./scripts/set-feed-rev "$@"
}
register_command "set-feed-rev" "Update feeds revisions in feeds.conf.io and profiles"
# Register commands from external files
source ./scripts/genconfig_wrap.sh
source ./scripts/iopupgrade.sh
if [ -z $arg ] || [ $arg == "--help" ]; then
printf "Usage: iop <command> [<args>]\n\n"
dump_commands
exit -1
fi
# Check all registered commands for a match
for i in $(seq 0 $arr_index); do
if [ $arg == "${command_array[$i]}" ]; then
# Run the command and pass all args
# except for the first to it
$arg "${@:2}"
exit 0
fi
done
# No registered command for the passed input arg
printf "Error: no such command $arg\n\n"
dump_commands
exit -1