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

View File

@@ -0,0 +1,2 @@
[Service]
NoNewPrivileges=false

View File

@@ -0,0 +1,5 @@
#!/bin/sh
case "$2" in
up) /sbin/iwconfig $1 power off || true ;;
down) /sbin/iwconfig $1 power on || true ;;
esac

View File

@@ -0,0 +1,5 @@
[connection]
wifi.mac-address-randomization=1
[device]
wifi.scan-rand-mac-address=no

View File

@@ -0,0 +1,2 @@
[connection]
wifi.powersave = 2

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# With offloading enabled, Samba becomes completely useless - transfers to a Windows PC freezes randomly
# Disabling offloading should solve this - all RK3399
IFACE=$1
EVENT=$2
if [[ "$EVENT" != "up" ]]; then
exit 1
fi
if linux-version compare $(uname -r | cut -d '.' -f1,2) gt 4.4; then
exit 1
fi
ETHTOOL=/sbin/ethtool
[ -f $ETHTOOL ] || exit 2
[ -d /sys/devices/platform/fe300000.ethernet/net/$IFACE ] || exit 3
$ETHTOOL -K $IFACE rx off tx off
exit 0

View File

@@ -0,0 +1,10 @@
Section "Monitor"
Identifier "Monitor0"
Option "DPMS" "false"
EndSection
Section "ServerFlags"
Option "BlankTime" "0"
Option "StandbyTime" "0"
Option "SuspendTime" "0"
Option "OffTime" "0"
EndSection

View File

@@ -0,0 +1,2 @@
Acquire::GzipIndexes "true";
Acquire::CompressionTypes::Order:: "gz";

View File

@@ -0,0 +1,22 @@
// Enable the update/upgrade script (0=disable)
APT::Periodic::Enable "0";
// Do "apt-get update" automatically every n-days (0=disable)
APT::Periodic::Update-Package-Lists "21";
// Do "apt-get upgrade --download-only" every n-days (0=disable)
APT::Periodic::Download-Upgradeable-Packages "0";
// Run the "unattended-upgrade" security upgrade script
// every n-days (0=disabled)
// Requires the package "unattended-upgrades" and will write
// a log in /var/log/unattended-upgrades
APT::Periodic::Unattended-Upgrade "7";
// Do "apt-get autoclean" every n-days (0=disable)
APT::Periodic::AutocleanInterval "120";
// Define basic patterns
Unattended-Upgrade::Origins-Pattern {
"origin=${distro_id},codename=${distro_codename}";
};

View File

@@ -0,0 +1,2 @@
APT::Install-Recommends "0";
APT::Install-Suggests "0";

View File

@@ -0,0 +1 @@
Acquire::Languages "none";

View File

@@ -0,0 +1,4 @@
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/15 * * * * root /usr/lib/orangepi/orangepi-truncate-logs

View File

@@ -0,0 +1,2 @@
@reboot root /usr/lib/orangepi/orangepi-apt-updates
@daily root /usr/lib/orangepi/orangepi-apt-updates

View File

@@ -0,0 +1,2 @@
#!/bin/sh
/usr/lib/orangepi/orangepi-ramlog write >/dev/null 2>&1

View File

@@ -0,0 +1,6 @@
# add space-separated list of MOTD script names (without number) to exclude them from MOTD
# Example:
# MOTD_DISABLE="header tips updates"
MOTD_DISABLE=""
ONE_WIRE="" # yes = show 1-wire temperature sensor if attached

View File

@@ -0,0 +1,12 @@
# configuration values for the orangepi-ram-logging service
#
# enable the orangepi-ram-logging service?
ENABLED=true
#
# size of the tmpfs mount -- please keep in mind to adjust /etc/default/orangepi-zram-config too when increasing
SIZE=50M
#
# use rsync instead of cp -r
# requires rsync installed, may provide better performance
# due to copying only new and changed files
USE_RSYNC=true

View File

@@ -0,0 +1,34 @@
# configuration values for the orangepi-zram-config service
#
# enable the orangepi-zram-config service?
ENABLED=true
# percentage of zram used as swap compared to physically available DRAM.
# Huge overcommitment (300) is possible and sometimes desirable. See
# https://forum.armbian.com/topic/5565-zram-vs-swap/?do=findComment&comment=61082
# and don't forget to adjust $MEM_LIMIT_PERCENTAGE below too.
# ZRAM_PERCENTAGE=50
# percentage of DRAM available to zram. If this amount is exceeded the zram
# devices used for swap simply behave as if the device is full. You need to
# adjust/increase this value only if you want to work with massive memory
# overcommitment (ZRAM_PERCENTAGE exceeding 150 for example)
# MEM_LIMIT_PERCENTAGE=50
# create how many zram devices max for swap
# ZRAM_MAX_DEVICES=4
# Which algorithm for zram based swapping. Seems lzo is best choice on ARM:
# https://forum.armbian.com/topic/8161-swap-on-sbc/?do=findComment&comment=61668
# SWAP_ALGORITHM=lzo
# Which algorithm to choose for zram based ramlog partition
# RAMLOG_ALGORITHM=zstd
# Which algorithm to choose for zram based /tmp
# TMP_ALGORITHM=zstd
# If defined a separate partition will be used as zram backing device. Be CAREFUL
# which partition you assign and read starting from CONFIG_ZRAM_WRITEBACK in
# https://www.kernel.org/doc/Documentation/blockdev/zram.txt
# ZRAM_BACKING_DEV=/dev/nvme0n2

View File

@@ -0,0 +1,11 @@
#!/bin/bash
. /etc/orangepi-release
echo "update-initramfs: Converting to u-boot format" >&2
tempname="/boot/uInitrd-$1"
mkimage -A $INITRD_ARCH -O linux -T ramdisk -C gzip -n uInitrd -d $2 $tempname > /dev/null
ln -sf $(basename $tempname) /boot/uInitrd > /dev/null 2>&1 || mv $tempname /boot/uInitrd
exit 0

View File

@@ -0,0 +1 @@
options r8723bs rtw_power_mgnt=0 rtw_enusbss=0

View File

@@ -0,0 +1,4 @@
source /etc/network/interfaces.d/*
# Network is managed by Network manager
auto lo
iface lo inet loopback

View File

@@ -0,0 +1,31 @@
#!/bin/sh
#
# 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.
# acticate profile sync daemon
if [ -f "${HOME}/.activate_psd" ]; then
rm -f ${HOME}/.activate_psd
/usr/bin/psd >/dev/null 2>&1
config_file="${HOME}/.config/psd/psd.conf"
if [ -f "${config_file}" ]; then
# test for overlayfs
# TODO: don't enable on btrfs
sed -i 's/#USE_OVERLAYFS=.*/USE_OVERLAYFS="yes"/' "${config_file}"
case $(/usr/bin/psd p 2>/dev/null | grep Overlayfs) in
*active*)
echo -e "\nConfigured profile sync daemon with overlayfs."
;;
*)
echo -e "\nConfigured profile sync daemon."
sed -i 's/USE_OVERLAYFS="yes"/#USE_OVERLAYFS="no"/' "${config_file}"
;;
esac
fi
systemctl --user enable psd.service >/dev/null 2>&1
systemctl --user start psd.service >/dev/null 2>&1
fi

View File

@@ -0,0 +1,15 @@
#!/bin/sh
#
# 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.
# only do this for interactive shells
if [ "$-" != "${-#*i}" ]; then
printf "\n"
if [ -f "/var/run/.reboot_required" ]; then
printf "[\e[0;91m Kernel was updated, please reboot\x1B[0m ]\n\n"
fi
fi

View File

@@ -0,0 +1,274 @@
#!/bin/sh
#
# 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.
. /etc/orangepi-release
check_abort()
{
echo -e "\nDisabling user account creation procedure\n"
rm -f /root/.not_logged_in_yet
trap - INT
exit 0
}
function read_password()
{
unset password
prompt="$1 password: "
while IFS= read -p "$prompt" -r -s -n 1 char
do
if [[ $char == $'\0' ]]
then
break
fi
prompt='*'
password+="$char"
done
}
set_timezone_and_locales()
{
# Grab this machine's public IP address
PUBLIC_IP=`curl --max-time 5 -s https://ipinfo.io/ip`
if [ $? -eq 0 ]; then
# Call the geolocation API and capture the output
RES=$(
curl --max-time 5 -s http://ipwhois.app/json/${PUBLIC_IP} | \
jq '.timezone, .country, .country_code' | \
while read -r TIMEZONE; do
read -r COUNTRY
echo "${TIMEZONE},${COUNTRY},${COUNTRYCODE}" | tr --delete \"
done
)
TZDATA=$(echo ${RES} | cut -d"," -f1)
STATE=$(echo ${RES} | cut -d"," -f2)
LOCALES=$(grep territory /usr/share/i18n/locales/* | grep "$STATE" | cut -d ":" -f 1 | cut -d "/" -f 6 | xargs -I{} grep {} /usr/share/i18n/SUPPORTED | grep "\.UTF-8" | cut -d " " -f 1)
CCODE=$(echo ${RES} | cut -d"," -f3 | awk '{print tolower($0)}' | xargs)
options=(`echo ${LOCALES}`);
# reconfigure tzdata
timedatectl set-timezone "${TZDATA}"
dpkg-reconfigure --frontend=noninteractive tzdata > /dev/null 2>&1
echo -e "Detected timezone: \x1B[92m$(LC_ALL=C timedatectl | grep "Time zone" | cut -d":" -f2 | xargs)\x1B[0m"
echo -e "Do you want to set locales and console keyboard automatically from your location [Y/n]"
read -sn1 SetLocales
if [ "$SetLocales" != "n" ] && [ "$SetLocales" != "N" ]; then
# when having more locales, prompt for choosing one
if [[ "${#options[@]}" -gt 1 ]]; then
echo -e "\nAt your location, more locales are possible:\n"
PS3='Please enter your choice:'
select opt in "${options[@]}"
do
if [[ " ${options[@]} " =~ " ${opt} " ]]; then
LOCALES=${opt}
break
fi
done
fi
# generate locales
sed -i 's/# '"${LOCALES}"'/'"${LOCALES}"'/' /etc/locale.gen
echo -e "Generating locales: \x1B[92m${LOCALES}\x1B[0m"
locale-gen $LOCALES > /dev/null 2>&1
update-locale LANG=$LOCALES LANGUAGE=$LOCALES LC=$LOCALES LC_MESSAGES=$LOCALES
# setting up keyboard
echo -e "Console keyboard layout: \x1B[92m$CCODE\x1B[0m"
sed -i "s/XKBLAYOUT=.*/XKBLAYOUT=\"$CCODE\"/" /etc/default/keyboard
setupcon -k --force
else
echo -e "You can use \x1B[92morangepi-config\x1B[0m to set locales and console keyboard."
fi
fi
}
add_profile_sync_settings()
{
/usr/bin/psd >/dev/null 2>&1
config_file="${HOME}/.config/psd/psd.conf"
if [ -f "${config_file}" ]; then
# test for overlayfs
sed -i 's/#USE_OVERLAYFS=.*/USE_OVERLAYFS="yes"/' "${config_file}"
case $(/usr/bin/psd p 2>/dev/null | grep Overlayfs) in
*active*)
echo -e "\nConfigured profile sync daemon with overlayfs."
;;
*)
echo -e "\nConfigured profile sync daemon."
sed -i 's/USE_OVERLAYFS="yes"/#USE_OVERLAYFS="no"/' "${config_file}"
;;
esac
fi
systemctl --user enable psd.service >/dev/null 2>&1
systemctl --user start psd.service >/dev/null 2>&1
}
add_user()
{
read -t 0 temp
while [ -f "/root/.not_logged_in_yet" ]; do
echo -e "\nPlease provide a username (eg. your forename): \c"
read -e username
RealUserName="$(echo "$username" | tr '[:upper:]' '[:lower:]' | tr -d -c '[:alnum:]')"
[ -z "$RealUserName" ] && return
if ! id "$RealUserName" >/dev/null 2>&1; then break; else echo -e "Username \e[0;31m$RealUserName\x1B[0m already exists on the system."; fi
done
while [ -f "/root/.not_logged_in_yet" ]; do
read_password "Create"
first_input=$password
echo ""
read_password "Repeat"
second_input=$password
echo ""
if [[ $first_input == $second_input ]]; then
result="$(cracklib-check <<<"$password")"
okay="$(awk -F': ' '{ print $2}' <<<"$result")"
if [[ "$okay" == "OK" ]]; then
echo -e "\nPlease provide your real name (eg. John Doe): \c"
read -e RealName
adduser --quiet --disabled-password --shell /bin/bash --home /home/"$RealUserName" --gecos "$RealName" "$RealUserName"
(echo $first_input;echo $second_input;) | passwd "$RealUserName" >/dev/null 2>&1
for additionalgroup in sudo netdev audio video disk tty users games dialout plugdev input bluetooth systemd-journal ssh; do
usermod -aG ${additionalgroup} ${RealUserName} 2>/dev/null
done
# fix for gksu in Xenial
touch /home/$RealUserName/.Xauthority
chown $RealUserName:$RealUserName /home/$RealUserName/.Xauthority
RealName="$(awk -F":" "/^${RealUserName}:/ {print \$5}" </etc/passwd | cut -d',' -f1)"
[ -z "$RealName" ] && RealName=$RealUserName
echo -e "\nDear \e[0;92m${RealName}\x1B[0m, your account \e[0;92m${RealUserName}\x1B[0m has been created and is sudo enabled."
echo -e "Please use this account for your daily work from now on.\n"
rm -f /root/.not_logged_in_yet
# set up profile sync daemon on desktop systems
which psd >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "${RealUserName} ALL=(ALL) NOPASSWD: /usr/bin/psd-overlay-helper" >> /etc/sudoers
touch /home/${RealUserName}/.activate_psd
chown $RealUserName:$RealUserName /home/${RealUserName}/.activate_psd
fi
break
else
echo -e "Rejected - \e[0;31m$okay.\x1B[0m Try again."
fi
elif [[ -n $password ]]; then
echo -e "Rejected - \e[0;31mpasswords do not match.\x1B[0m Try again."
fi
done
}
if [ -f /root/.not_logged_in_yet ] && [ -n "$BASH_VERSION" ] && [ "$-" != "${-#*i}" ]; then
# disable autologin
#rm -f /etc/systemd/system/getty@.service.d/override.conf
#rm -f /etc/systemd/system/serial-getty@.service.d/override.conf
#systemctl daemon-reload
# detect lightdm
#desktop_lightdm=$(dpkg-query -W -f='${db:Status-Abbrev}\n' lightdm 2>/dev/null)
echo -e "New to Orange Pi? Support: \e[1m\e[39mhttp://www.orangepi.org\x1B[0m\n"
#trap '' 2
#while [ -f "/root/.not_logged_in_yet" ]; do
# read_password "New root"
# # only allow one login. Once you enter root password, kill others.
# loginfrom=$(who am i | awk '{print $2}')
# who -la | grep root | grep -v "$loginfrom" | awk '{print $7}' | xargs --no-run-if-empty kill -9
# first_input=$password
# echo ""
# read_password "Repeat"
# second_input=$password
# echo ""
# if [[ $first_input == $second_input ]]; then
# result="$(cracklib-check <<<"$password")"
# okay="$(awk -F': ' '{ print $2}' <<<"$result")"
# if [[ "$okay" == "OK" ]]; then
# (echo $first_input;echo $second_input;) | passwd root >/dev/null 2>&1
# set_timezone_and_locales
# break
# else
# echo -e "Rejected - \e[0;31m$okay.\x1B[0m Try again."
# fi
# elif [[ -n $password ]]; then
# echo -e "Rejected - \e[0;31mpasswords do not match.\x1B[0m Try again."
# fi
#done
#trap - INT TERM EXIT
#trap check_abort INT
#while [ -f "/root/.not_logged_in_yet" ]; do
# echo -e "\nCreating a new user account. Press <Ctrl-C> to abort"
# [ -n "$desktop_lightdm" ] && echo "Desktop environment will not be enabled if you abort the new user creation"
# add_user
#done
#trap - INT TERM EXIT
rm -f /root/.not_logged_in_yet
# check whether desktop environment has to be considered
#if [ -n "$desktop_lightdm" ]; then
# # 1st run goes without login
# mkdir -p /etc/lightdm/lightdm.conf.d
# cat <<-EOF > /etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
# [Seat:*]
# autologin-user=$RealUserName
# autologin-user-timeout=0
# user-session=xfce
# EOF
#
# ln -sf /lib/systemd/system/lightdm.service /etc/systemd/system/display-manager.service
# if [[ -f /var/run/resize2fs-reboot ]]; then
# # Let the user reboot now otherwise start desktop environment
# printf "\n\n\e[0;91mWarning: a reboot is needed to finish resizing the filesystem \x1B[0m \n"
# printf "\e[0;91mPlease reboot the system now \x1B[0m \n\n"
# elif [ -z "$ConfigureDisplay" ] || [ "$ConfigureDisplay" = "n" ] || [ "$ConfigureDisplay" = "N" ]; then
# echo -e "\n\e[1m\e[39mNow starting desktop environment...\x1B[0m\n"
# sleep 1
# service lightdm start 2>/dev/null
# if [ -f /root/.desktop_autologin ]; then
# rm /root/.desktop_autologin
# else
# (sleep 20; rm /etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf) &
# fi
# # logout if logged at console
# #[[ -n $(who -la | grep root | grep tty1) ]] && exit 1
# fi
#else
# # Display reboot recommendation if necessary
# if [[ -f /var/run/resize2fs-reboot ]]; then
# printf "\n\n\e[0;91mWarning: a reboot is needed to finish resizing the filesystem \x1B[0m \n"
# printf "\e[0;91mPlease reboot the system now \x1B[0m \n\n"
# fi
#fi
fi

View File

@@ -0,0 +1,4 @@
# This should fix
# perl: warning: Setting locale failed.
export LC_ALL=$LANG

View File

@@ -0,0 +1,14 @@
#!/bin/sh
#
# 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.
if [ -n "$PS1" ] && ( [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] ); then
tput tsl > /dev/null
if [ "$?" -eq 0 ]; then
echo `tput tsl` `whoami`@`hostname` `tput fsl`
fi
fi

View File

@@ -0,0 +1,40 @@
# Beware! This file is rewritten by htop when settings are changed in the interface.
# The parser is also very primitive, and not human-friendly.
fields=0 48 17 18 38 39 40 2 46 47 49 1
sort_key=1
sort_direction=1
hide_threads=0
hide_kernel_threads=1
hide_userland_threads=0
shadow_other_users=0
show_thread_names=0
show_program_path=1
highlight_base_name=0
highlight_megabytes=1
highlight_threads=1
tree_view=0
header_margin=1
detailed_cpu_time=0
cpu_count_from_zero=0
update_process_names=0
account_guest_in_cpu_meter=0
color_scheme=0
delay=15
left_meters=AllCPUs Memory Swap CpuTemp
left_meter_modes=1 1 1 2
right_meters=OrangePiversion Hostname Tasks LoadAverage Uptime CpuFreq Eth0 Eth0stat
right_meter_modes=2 2 2 2 2 2 2 2
# SBC hardware and Kernel specific path.
# Editable manually.
BoardName=
CpuFreq_handler=
CpuTemp_handler=
CpuVCore_l_handler=
CpuVCore_b_handler=
GpuVCore_handler=
GpuTemp_handler=
# Wlan / Eth alias
eth0_alias=
eth1_alias=
wlan0_alias=
wlan1_alias=

View File

@@ -0,0 +1,28 @@
[Unit]
Description=Rotate log files
Documentation=man:logrotate(8) man:logrotate.conf(5)
ConditionACPower=true
[Service]
Type=oneshot
ExecStartPre=/usr/lib/orangepi/orangepi-ramlog write
ExecStart=/usr/sbin/logrotate /etc/logrotate.conf
ExecStartPost=/usr/lib/orangepi/orangepi-ramlog postrotate
# performance options
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
# hardening options
# details: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
# no ProtectHome for userdir logs
# no PrivateNetwork for mail deliviery
# no ProtectKernelTunables for working SELinux with systemd older than 235
# no MemoryDenyWriteExecute for gzip on i686
PrivateDevices=true
PrivateTmp=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectSystem=full
RestrictRealtime=true

View File

@@ -0,0 +1 @@
KERNEL=="wlan*", ACTION=="add", RUN+="/sbin/iwconfig wlan0 power off"

View File

@@ -0,0 +1,26 @@
#!/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.
# DO NOT EDIT THIS FILE but add config options to /etc/default/orangepi-motd
# any changes will be lost on board support package update
THIS_SCRIPT="header"
MOTD_DISABLE=""
[[ -f /etc/default/orangepi-motd ]] && . /etc/default/orangepi-motd
for f in $MOTD_DISABLE; do
[[ $f == $THIS_SCRIPT ]] && exit 0
done
. /etc/os-release
. /etc/orangepi-release
KERNELID=$(uname -r)
TERM=linux toilet -f standard -F metal $(echo $BOARD_NAME | sed 's/Orange Pi/OPi/')
echo -e "Welcome to \e[0;91mOrange Pi \x1B[0m$(if [[ $ID == debian ]]; then echo ${PRETTY_NAME##*\(} | sed -e 's/^.*Linux //' | sed "s/\/.*//" | sed 's|)||'; else echo -n ${VERSION_CODENAME^};fi) with \e[0;91mLinux $KERNELID\x1B[0m\n"

View File

@@ -0,0 +1,207 @@
#!/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.
#
# DO NOT EDIT THIS FILE but add config options to /etc/default/orangepi-motd
# generate system information
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
THIS_SCRIPT="sysinfo"
MOTD_DISABLE=""
STORAGE=/dev/sda1
SHOW_IP_PATTERN="^bond.*|^[ewr].*|^br.*|^lt.*|^umts.*|^lan.*"
CPU_TEMP_LIMIT=45
AMB_TEMP_LIMIT=40
[[ -f /etc/default/orangepi-motd ]] && . /etc/default/orangepi-motd
for f in $MOTD_DISABLE; do
[[ $f == $THIS_SCRIPT ]] && exit 0
done
# don't edit below here
function display() {
# $1=name $2=value $3=red_limit $4=minimal_show_limit $5=unit $6=after $7=acs/desc{
# battery red color is opposite, lower number
if [[ "$1" == "Battery" ]]; then local great="<"; else local great=">"; fi
if [[ -n "$2" && "$2" > "0" && (( "${2%.*}" -ge "$4" )) ]]; then
printf "%-14s%s" "$1:"
if awk "BEGIN{exit ! ($2 $great $3)}"; then echo -ne "\e[0;91m $2"; else echo -ne "\e[0;92m $2"; fi
printf "%-1s%s\x1B[0m" "$5"
printf "%-11s%s\t" "$6"
return 1
fi
} # display
function getboardtemp() {
if [ -f /etc/orangepimonitor/datasources/soctemp ]; then
read raw_temp </etc/orangepimonitor/datasources/soctemp 2>/dev/null
if [ ! -z $(echo "$raw_temp" | grep -o "^[1-9][0-9]*\.\?[0-9]*$") ] && (( $(echo "${raw_temp} < 200" |bc -l) )); then
# Allwinner legacy kernels output degree C
board_temp=${raw_temp}
else
board_temp=$(awk '{printf("%d",$1/1000)}' <<<${raw_temp})
fi
elif [ -f /etc/orangepimonitor/datasources/pmictemp ]; then
# fallback to PMIC temperature
board_temp=$(awk '{printf("%d",$1/1000)}' </etc/orangepimonitor/datasources/pmictemp)
fi
} # getboardtemp
function batteryinfo() {
# Battery info for Allwinner
mainline_dir="/sys/power/axp_pmu"
legacy_dir="/sys/class/power_supply"
if [[ -e "$mainline_dir" ]]; then
read status_battery_connected < $mainline_dir/battery/connected 2>/dev/null
if [[ "$status_battery_connected" == "1" ]]; then
read status_battery_charging < $mainline_dir/charger/charging
read status_ac_connect < $mainline_dir/ac/connected
read battery_percent< $mainline_dir/battery/capacity
# dispay charging / percentage
if [[ "$status_ac_connect" == "1" && "$battery_percent" -lt "100" ]]; then
status_battery_text=" charging"
elif [[ "$status_ac_connect" == "1" && "$battery_percent" -eq "100" ]]; then
status_battery_text=" charged"
else
status_battery_text=" discharging"
fi
fi
elif [[ -e "$legacy_dir/axp813-ac" ]]; then
read status_battery_connected < $legacy_dir/axp20x-battery/present
if [[ "$status_battery_connected" == "1" ]]; then
status_battery_text=" "$(awk '{print tolower($0)}' < $legacy_dir/axp20x-battery/status)
read status_ac_connect < $legacy_dir/axp813-ac/present
read battery_percent< $legacy_dir/axp20x-battery/capacity
fi
elif [[ -e "$legacy_dir/battery" ]]; then
if [[ (("$(cat $legacy_dir/battery/voltage_now)" -gt "5" )) ]]; then
status_battery_text=" "$(awk '{print tolower($0)}' < $legacy_dir/battery/status)
read battery_percent <$legacy_dir/battery/capacity
fi
fi
} # batteryinfo
function ambienttemp() {
# define where w1 usually shows up
W1_DIR="/sys/devices/w1_bus_master1/"
if [ -f /etc/orangepimonitor/datasources/ambienttemp ]; then
read raw_temp </etc/orangepimonitor/datasources/ambienttemp 2>/dev/null
amb_temp=$(awk '{printf("%d",$1/1000)}' <<<${raw_temp})
echo $amb_temp
elif [[ -d $W1_DIR && $ONE_WIRE == yes ]]; then
device=$(ls -1 $W1_DIR | grep -Eo '^[0-9]{1,4}' | head -1)
if [[ -n $device ]]; then
if [[ -d ${W1_DIR}${device}/hwmon/hwmon0 ]]; then hwmon=0; else hwmon=1; fi
read raw_temp < ${W1_DIR}${device}/hwmon/hwmon${hwmon}/temp1_input 2>/dev/null
amb_temp=$(awk '{printf("%d",$1/1000)}' <<<${raw_temp})
echo $amb_temp
fi
else
# read ambient temperature from USB device if available
if [[ ! -f /usr/bin/temper ]]; then
echo ""
return
fi
amb_temp=$(temper -c 2>/dev/null)
case ${amb_temp} in
*"find the USB device"*)
echo ""
;;
*)
amb_temp=$(awk '{print $NF}' <<<$amb_temp | sed 's/C//g')
echo -n "scale=1;${amb_temp}/1" | grep -oE "\-?[[:digit:]]+\.[[:digit:]]"
esac
fi
} # ambienttemp
#function get_ip_addresses() {
# # return up to 2 IPv4 address(es) comma separated
# hostname -I | tr " " "\n" | \
# grep -E "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" | \
# tail -n2 | sed ':a;N;$!ba;s/\n/,/g'
#} # get_ip_addresses
function get_ip_addresses() {
local ips=()
for f in /sys/class/net/*; do
local intf=$(basename $f)
# match only interface names starting with e (Ethernet), br (bridge), w (wireless), r (some Ralink drivers use ra<number> format)
if [[ $intf =~ $SHOW_IP_PATTERN ]]; then
local tmp=$(ip -4 addr show dev $intf | awk '/inet/ {print $2}' | cut -d'/' -f1)
# add both name and IP - can be informative but becomes ugly with long persistent/predictable device names
#[[ -n $tmp ]] && ips+=("$intf: $tmp")
# add IP only
[[ -n $tmp ]] && ips+=("$tmp")
fi
done
echo "${ips[@]}"
} # get_ip_addresses
function storage_info() {
# storage info
RootInfo=$(df -h /)
root_usage=$(awk '/\// {print $(NF-1)}' <<<${RootInfo} | sed 's/%//g')
root_total=$(awk '/\// {print $(NF-4)}' <<<${RootInfo})
StorageInfo=$(df -h $STORAGE 2>/dev/null | grep $STORAGE)
if [[ -n "${StorageInfo}" && ${RootInfo} != *$STORAGE* ]]; then
storage_usage=$(awk '/\// {print $(NF-1)}' <<<${StorageInfo} | sed 's/%//g')
storage_total=$(awk '/\// {print $(NF-4)}' <<<${StorageInfo})
fi
} # storage_info
# query various systems and send some stuff to the background for overall faster execution.
# Works only with ambienttemp and batteryinfo since A20 is slow enough :)
amb_temp=$(ambienttemp &)
ip_address=$(get_ip_addresses &)
batteryinfo
storage_info
getboardtemp
critical_load=$(( 1 + $(grep -c processor /proc/cpuinfo) / 2 ))
# get uptime, logged in users and load in one take
UPTIME=$(LC_ALL=C uptime)
UPT1=${UPTIME#*'up '}
UPT2=${UPT1%'user'*}
users=${UPT2//*','}
users=${users//' '}
time=${UPT2%','*}
time=${time//','}
load=${UPTIME#*'load average: '}
load=${load//','}
# memory and swap
mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
memory_usage=$(awk '{printf("%.0f",(($2-($4+$6+$7))/$2) * 100)}' <<<${mem_info})
memory_total=$(awk '{printf("%d",$2/1024)}' <<<${mem_info})
swap_info=$(LC_ALL=C free -m | grep "^Swap")
swap_usage=$( (awk '/Swap/ { printf("%3.0f", $3/$2*100) }' <<<${swap_info} 2>/dev/null || echo 0) | tr -c -d '[:digit:]')
swap_total=$(awk '{print $(2)}' <<<${swap_info})
# display info
display "System load" "${load%% *}" "${critical_load}" "0" "" "${load#* }"
printf "Up time: \x1B[92m%s\x1B[0m\t\t" "$time"
display "Local users" "${users##* }" "3" "2" ""
echo "" # fixed newline
display "Memory usage" "$memory_usage" "70" "0" " %" " of ${memory_total}MB"
display "Zram usage" "$swap_usage" "75" "0" " %" " of $swap_total""Mb"
printf "IP: "
printf "\x1B[92m%s\x1B[0m" "$ip_address"
echo "" # fixed newline
a=0;b=0;c=0
display "CPU temp" "$board_temp" $CPU_TEMP_LIMIT "0" "°C" "" ; a=$?
display "Ambient temp" "$amb_temp" $AMB_TEMP_LIMIT "0" "°C" "" ; b=$?
(( ($a+$b) >0 )) && echo "" # new line only if some value is displayed
display "Usage of /" "$root_usage" "90" "1" "%" " of $root_total"
display "storage/" "$storage_usage" "90" "1" "%" " of $storage_total"
display "Battery" "$battery_percent" "20" "1" "%" "$status_battery_text"
echo ""
echo ""

View File

@@ -0,0 +1,30 @@
#!/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.
# DO NOT EDIT THIS FILE but add config options to /etc/default/orangepi-motd
# any changes will be lost on board support package update
THIS_SCRIPT="config"
MOTD_DISABLE=""
[[ -f /etc/default/orangepi-motd ]] && . /etc/default/orangepi-motd
for f in $MOTD_DISABLE; do
[[ $f == $THIS_SCRIPT ]] && exit 0
done
if [[ $(( $RANDOM % 2 )) == 0 ]]; then
if [[ -f /usr/sbin/orangepi-config ]]; then
echo -e "[\e[31m General system configuration (beta)\e[0m: \e[1morangepi-config\e[0m ]\n"
else
echo -e "[\e[31m Menu-driven system configuration (beta)\e[0m: \e[1msudo dpkg -i orangepi-config.deb\e[0m ]\n"
fi
fi
exit 0

View File

@@ -0,0 +1,17 @@
[Unit]
Description=Dispatch Password Requests to Console Directory Watch when bootsplash is active
DefaultDependencies=no
Conflicts=shutdown.target
Conflicts=systemd-ask-password-console.path
Conflicts=systemd-ask-password-console.service
After=plymouth-start.service
Before=paths.target shutdown.target cryptsetup.target
ConditionPathExists=!/run/plymouth/pid
ConditionPathExists=/sys/devices/platform/bootsplash.0/enabled
[Path]
DirectoryNotEmpty=/run/systemd/ask-password
MakeDirectory=yes
[Install]
WantedBy=sysinit.target

View File

@@ -0,0 +1,16 @@
[Unit]
Description=Dispatch Password Requests to Console when bootsplash is active
DefaultDependencies=no
Conflicts=shutdown.target
Conflicts=systemd-ask-password-console.path
Conflicts=systemd-ask-password-console.service
After=plymouth-start.service systemd-vconsole-setup.service
Before=shutdown.target
ConditionPathExists=!/run/plymouth/pid
ConditionPathExists=/sys/devices/platform/bootsplash.0/enabled
[Service]
ExecStartPre=-/bin/sh -c '/bin/cat /sys/devices/platform/bootsplash.0/enabled > /run/systemd/ask-password/bootsplash-state ; exec /bin/echo off > /sys/devices/platform/bootsplash.0/enabled'
ExecStart=/usr/bin/systemd-tty-ask-password-agent --query --console
ExecStartPost=-/bin/sh -c 'exec /bin/cat /run/systemd/ask-password/bootsplash-state > /sys/devices/platform/bootsplash.0/enabled ; /bin/rm /run/systemd/ask-password/bootsplash-state'
Type=oneshot

View File

@@ -0,0 +1,14 @@
[Unit]
Description=Hide bootsplash after starting the system
After=graphical.target
DefaultDependencies=no
ConditionPathExists=/sys/devices/platform/bootsplash.0/enabled
[Service]
ExecStartPre=/bin/sh -c 'exec /bin/sleep 15'
ExecStart=/bin/sh -c 'exec /bin/echo off > /sys/devices/platform/bootsplash.0/enabled'
Restart=no
Type=oneshot
[Install]
WantedBy=graphical.target

View File

@@ -0,0 +1,19 @@
[Unit]
Description=Show bootsplash on system halt, power off, reboot, or kexec
Before=systemd-halt.service
Before=systemd-kexec.service
Before=systemd-poweroff.service
Before=systemd-reboot.service
DefaultDependencies=no
ConditionPathExists=/sys/devices/platform/bootsplash.0/enabled
[Service]
ExecStart=/bin/sh -c 'exec /bin/echo on > /sys/devices/platform/bootsplash.0/enabled'
Restart=no
Type=oneshot
[Install]
WantedBy=halt.target
WantedBy=kexec.target
WantedBy=poweroff.target
WantedBy=reboot.target

View File

@@ -0,0 +1,2 @@
[Service]
TTYVTDisallocate=no

View File

@@ -0,0 +1,18 @@
# Orange Pi firstrun configuration service
# This service will run in parallel with other services
[Unit]
Description=Orange Pi first run optional user configuration
Wants=network-online.target
After=network.target network-online.target
ConditionPathExists=/boot/orangepi_first_run.txt
ConditionPathExists=/root/.not_logged_in_yet
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/orangepi/orangepi-firstrun-config
TimeoutStartSec=2min
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,17 @@
# Orange Pi firstrun service
# Regenerates the SSH keys and performs additional first run tweaks
# This service will run in parallel with other services
[Unit]
Description=Orange Pi first run tasks
Before=getty.target system-getty.slice
[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/usr/lib/orangepi/orangepi-firstrun start
TimeoutStartSec=2min
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,19 @@
# Orange Pi hardware monitor service
# Detects and sets various features on boot
# This service may block the boot process for up to 2 minutes
[Unit]
Description=Orange Pi hardware monitoring
Before=basic.target
After=sysinit.target local-fs.target
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/usr/lib/orangepi/orangepi-hardware-monitor start
ExecStop=/usr/lib/orangepi/orangepi-hardware-monitor stop
RemainAfterExit=yes
TimeoutStartSec=2min
[Install]
WantedBy=basic.target

View File

@@ -0,0 +1,19 @@
# Orange Pi hardware optimization service
# Apply optimisations
# This service may block the boot process for up to 2 minutes
[Unit]
Description=Orange Pi hardware optimization
Before=basic.target
After=sysinit.target local-fs.target orangepi-hardware-monitor.target
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/usr/lib/orangepi/orangepi-hardware-optimization start
ExecStop=/usr/lib/orangepi/orangepi-hardware-optimization stop
RemainAfterExit=yes
TimeoutStartSec=2min
[Install]
WantedBy=basic.target

View File

@@ -0,0 +1,23 @@
# Orange Pi ramlog service
# Stores logs in (compressed) memory
# This service may block the boot process for up to 30 sec
[Unit]
Description=Orange Pi memory supported logging
DefaultDependencies=no
Before=rsyslog.service sysinit.target syslog.target
After=orangepi-zram-config.service
Conflicts=shutdown.target
RequiresMountsFor=/var/log /var/log.hdd
IgnoreOnIsolate=yes
[Service]
Type=oneshot
ExecStart=/usr/lib/orangepi/orangepi-ramlog start
ExecStop=/usr/lib/orangepi/orangepi-ramlog stop
ExecReload=/usr/lib/orangepi/orangepi-ramlog write
RemainAfterExit=yes
TimeoutStartSec=30sec
[Install]
WantedBy=sysinit.target

View File

@@ -0,0 +1,18 @@
# Orange Pi resize filesystem service
# Resizes partition and filesystem on first/second boot
# This service may block the boot process for up to 3 minutes
[Unit]
Description=Orange Pi filesystem resize
Before=basic.target
After=sysinit.target local-fs.target
DefaultDependencies=no
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/orangepi/orangepi-resize-filesystem start
TimeoutStartSec=6min
[Install]
WantedBy=basic.target

View File

@@ -0,0 +1,20 @@
# Orange Pi ZRAM configuration service
# Create 1 + number of cores compressed block devices
# This service may block the boot process for up to 30 sec
[Unit]
Description=Orange Pi ZRAM config
DefaultDependencies=no
After=local-fs.target
Before=orangepi-ramlog.target
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/lib/orangepi/orangepi-zram-config start
ExecStop=/usr/lib/orangepi/orangepi-zram-config stop
RemainAfterExit=yes
TimeoutStartSec=30sec
[Install]
WantedBy=sysinit.target

View File

@@ -0,0 +1,2 @@
[Service]
Environment=TERM=linux

View File

@@ -0,0 +1,2 @@
[Unit]
After=orangepi-ramlog.service

View File

@@ -0,0 +1,2 @@
[Service]
TimeoutStopSec=10

View File

@@ -0,0 +1,5 @@
# Handle AXP power button with systemd
ACTION=="remove", GOTO="power_switch_end"
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="axp20x-pek", TAG+="power-switch"
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="axp[12][890]-supplyer", TAG+="power-switch"
LABEL="power_switch_end"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
../../share/chromium/master_preferences

View File

@@ -0,0 +1,8 @@
/boot/*
/dev/*
/proc/*
/sys/*
/media/*
/mnt/*
/run/*
/tmp/*

View File

@@ -0,0 +1,55 @@
#!/bin/bash
#
# 40-updates - create the list of packages for update with caching
# Copyright (c) 2015 Arkadiusz Raj
#
# Author: Arkadiusz Raj arek.raj@gmail.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
lock_file='/var/run/orangepi-motd-updates.lock'
if { set -C; 2>/dev/null >${lock_file}; }; then
trap "rm -f ${lock_file}" EXIT
else
exit 0
fi
# give up if packages are broken
[[ ! $(dpkg -l | grep ^..r) ]] && exit 0
myfile="/var/cache/apt/archives/updates.number"
# update procedure
DISTRO=$(lsb_release -c | cut -d ":" -f 2 | tr -d '[:space:]') && DISTRO=${DISTRO,,}
# run around the packages
upgrades=0
security_upgrades=0
while IFS= read -r LINE; do
# increment the upgrade counter
(( upgrades++ ))
# keep another count for security upgrades
[[ ${LINE} == *"${DISTRO}-sec"* ]] && (( security_upgrades++ ))
done < <(apt-get upgrade -s -qq | sed -n '/^Inst/p')
cat >|${myfile} <<EOT
NUM_UPDATES="${upgrades}"
NUM_SECURITY_UPDATES="${security_upgrades}"
DATE="$(date +"%Y-%m-%d %H:%M")"
EOT
exit 0

View File

@@ -0,0 +1,52 @@
#!/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:
#
# show_motd_warning
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
my_name="${0##*/}"
Log=/var/log/orangepi-hardware-monitor.log
show_motd_warning() {
cat > /etc/update-motd.d/90-warning <<EOT
#!/bin/bash
echo -e "\e[0;91mAttention:\x1B[0m $1\n"
rm "\$0"
EOT
chmod +x /etc/update-motd.d/90-warning
} # show_motd_warning
get_random_mac ()
{
local prefixes=("02" "06" "0A" "0E")
local random=$(shuf -i 0-3 -n 1)
MACADDR=$(printf ${prefixes[$random]}':%02X:%02X:%02X:%02X:%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256] $[RANDOM%256] $[RANDOM%256])
}
# set fixed IP address from first randomly assigned one. If nothing is deteceted, generate one.
set_fixed_mac ()
{
CONNECTION="$(nmcli -f UUID,ACTIVE,DEVICE,TYPE connection show --active | tail -n1)"
UUID=$(awk -F" " '/ethernet/ {print $1}' <<< "${CONNECTION}")
DEVNAME=$(awk -F" " '/ethernet/ {print $3}' <<< "${CONNECTION}")
MACADDR=$(/sbin/ip link | grep -A1 ${DEVNAME} | awk -F" " '/ether / {print $2}')
[[ -z $MACADDR ]] && get_random_mac
if [[ -n $UUID ]]; then
nmcli connection modify $UUID ethernet.cloned-mac-address $MACADDR
nmcli connection modify $UUID -ethernet.mac-address ""
nmcli connection down $UUID >/dev/null 2>&1
nmcli connection up $UUID >/dev/null 2>&1
return 0
fi
} # set fixed mac to the 1st active network adapter

View File

@@ -0,0 +1,120 @@
#!/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.
. /etc/orangepi-release
. /etc/os-release
. /lib/init/vars.sh
. /lib/lsb/init-functions
. /usr/lib/orangepi/orangepi-common
case "$1" in
start)
# read number of cores needed below
cpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')
# adjust custom htop initial configuration based on CPU count https://github.com/avafinger/htop-2.1.1_enhanced-version
right_meters="Hostname Tasks LoadAverage Uptime"
right_meter_modes="2 2 2 2"
x=1
until [ $x -gt $cpu_cores ]; do
right_meters=$right_meters" CpuFreq($x)"
right_meter_modes=$right_meter_modes" 2"
let x+=1
done
sed -i 's/header_margin=.*/header_margin=1/g' /etc/skel/.config/htop/htoprc
sed -i 's/left_meters=.*/left_meters=AllCPUs Memory Swap CpuTemp/g' /etc/skel/.config/htop/htoprc
sed -i 's/left_meter_modes=.*/left_meter_modes=1 1 1 2/g' /etc/skel/.config/htop/htoprc
sed -i "s/right_meters=.*/right_meters=$right_meters/g" /etc/skel/.config/htop/htoprc
sed -i "s/right_meter_modes=.*/right_meter_modes=$right_meter_modes/g" /etc/skel/.config/htop/htoprc
# copy predefined settings for root user
cp -R /etc/skel/.config /root/
# Run a q&d benchmark to be able to identify cards way too slow easily
echo -e "\n### quick iozone test:$(cd /root; iozone -e -I -a -s 1M -r 4k -i 0 -i 1 -i 2 | grep '^ 1024' | sed 's/ 1024 //')" >> $Log
# Bluetooth tweaks
#case ${BOARD} in
# orangepizeroplus2*|orangepiwin)
# update-rc.d ap6212-bluetooth defaults
# ;;
#esac
# Debian Buster desktop bugfix https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=923289
[[ -d /etc/lightdm ]] && dpkg-reconfigure libgdk-pixbuf2.0-0 && update-mime-database /usr/share/mime
# update console info
setupcon --save
# add unique installation id to the image release file
sed '1s/^/IMAGE_UUID=/' /proc/sys/kernel/random/uuid >> /etc/orangepi-image-release
# SSH Keys creation
rm -f /etc/ssh/ssh_host*
read entropy_before </proc/sys/kernel/random/entropy_avail
dpkg-reconfigure openssh-server >/dev/null 2>&1
service sshd restart
read entropy_after </proc/sys/kernel/random/entropy_avail
echo -e "\n### [firstrun] Recreated SSH keys (entropy: ${entropy_before} ${entropy_after})" >>${Log}
# get rid of purple background color in newt apps whiptail, partimage, debconf ... Reverting to Debian look.
[[ -f /etc/newt/palette ]] && sed -e 's/magenta/blue/g' -i /etc/newt/palette
# desktop tweaks - enable show windows content on stronger boards
if [[ ${cpu_cores} -gt 2 && -f /etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml ]]; then
sed -i 's/<property name="box_move" type="bool" value=".*/<property name="box_move" type="bool" value="false"\/>/g' \
/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml
fi
# randomize mac in orangepiEnv.txt
if [[ -f /boot/orangepiEnv.txt ]]; then
get_random_mac
sed -i "s/^ethaddr=.*/ethaddr=$MACADDR/" /boot/orangepiEnv.txt
get_random_mac
sed -i "s/^eth1addr=.*/eth1addr=$MACADDR/" /boot/orangepiEnv.txt
fi
# hardware workarounds per family
case $LINUXFAMILY in
sun7i|sun8i)
# set some mac address for BT
[[ -n $(lsmod | egrep "dhd|brcmfmac" ) ]] && \
(MACADDR=$(printf '43:29:B1:%02X:%02X:%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256]) ; \
sed -i "s/^MAC_ADDR=.*/MAC_ADDR=${MACADDR}/" /etc/default/brcm40183 ;\
sed -i "s/^MAC_ADDR=.*/MAC_ADDR=${MACADDR}/" /etc/default/ap6212 \
echo -e "\n### [firstrun] Use MAC address ${MACADDR} for Bluetooth from now" >>${Log})
case $BOARD_NAME in
"Orange Pi Zero")
get_random_mac
echo "options xradio_wlan macaddr=${MACADDR}" >/etc/modprobe.d/xradio_wlan.conf
echo -e "\n### [firstrun] Use MAC address ${MACADDR} for Wi-Fi from now" >>${Log}
cd /etc/network/ && ln -sf interfaces.network-manager interfaces
(modprobe -r xradio_wlan && sleep 1 && modprobe xradio_wlan) &
;;
esac
# trigger red or blue LED as user feedback
echo heartbeat >/sys/class/leds/*red*/trigger 2>/dev/null || echo heartbeat >/sys/class/leds/*blue*/trigger 2>/dev/null
;;
*)
esac
# varios temporary hardware workarounds
[[ $LINUXFAMILY == rk3399 ]] && set_fixed_mac
systemctl disable orangepi-firstrun
exit 0
;;
*)
echo "Usage: $0 start"
exit 0
;;
esac

View File

@@ -0,0 +1,140 @@
#!/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.
# Function calculates number of bit in a netmask
#
mask2cidr() {
nbits=0
IFS=.
for dec in $1 ; do
case $dec in
255) let nbits+=8;;
254) let nbits+=7;;
252) let nbits+=6;;
248) let nbits+=5;;
240) let nbits+=4;;
224) let nbits+=3;;
192) let nbits+=2;;
128) let nbits+=1;;
0);;
*) echo "Error: $dec is not recognised"; exit 1
esac
done
echo "$nbits"
}
do_firstrun_automated_user_configuration()
{
#-----------------------------------------------------------------------------
#Notes:
# - See /boot/orangepi_first_run.txt for full list of available variables
# - Variable names here must here must match ones in packages/bsp/orangepi_first_run.txt.template
#-----------------------------------------------------------------------------
#Config FP
local fp_config='/boot/orangepi_first_run.txt'
#-----------------------------------------------------------------------------
#Grab user requested settings
if [[ -f $fp_config ]]; then
# Convert line endings to Unix from Dos
sed -i $'s/\r$//' "$fp_config"
# check syntax
bash -n "$fp_config" || return
# Load vars directly from file
source "$fp_config"
# Obtain backward configuration compatibility
FR_net_static_dns=${FR_net_static_dns// /,}
FR_net_static_mask=$(mask2cidr $FR_net_static_mask)
#-----------------------------------------------------------------------------
# - Remove configuration file
if [[ $FR_general_delete_this_file_after_completion == 1 ]]; then
dd if=/dev/urandom of="$fp_config" bs=16K count=1
sync
rm "$fp_config"
else
mv "$fp_config" "${fp_config}.old"
fi
#-----------------------------------------------------------------------------
# Set Network
if [[ $FR_net_change_defaults == 1 ]]; then
# - Get 1st index of available wlan and eth adapters
local fp_ifconfig_tmp='/tmp/.ifconfig'
ifconfig -a | sed 's/[ \t].*//;/^\(lo\|\|bond0\|sit0\|ip6tnl0\)$/d' > "$fp_ifconfig_tmp" #export to file, should be quicker in loop than calling ifconfig each time.
# find eth[0-9]
for ((i=0; i<=9; i++))
do
if (( $(cat "$fp_ifconfig_tmp" | grep -ci -m1 "eth$i") )); then
eth_index=eth${i}
break
fi
done
# Predictable Network Interface Names
[[ -z $eth_index ]] && eth_index=$(cat "$fp_ifconfig_tmp" | grep -m1 "en" | cut -f1 -d":" | head -1)
# find wlan[0-9]
for ((i=0; i<=9; i++))
do
if (( $(cat "$fp_ifconfig_tmp" | grep -ci -m1 "wlan$i") )); then
wlan_index=wlan${i}
break
fi
done
# Predictable Network Interface Names
[[ -z $wlan_index ]] && wlan_index=$(cat "$fp_ifconfig_tmp" | grep -m1 "wl" | cut -f1 -d":" | head -1)
rm "$fp_ifconfig_tmp"
# for static IP we only append settings
if [[ $FR_net_use_static == 1 ]]; then
local FIXED_IP_SETTINGS="ipv4.method manual ipv4.address ${FR_net_static_ip}/${FR_net_static_mask} ipv4.dns ${FR_net_static_dns} ipv4.gateway ${FR_net_static_gateway}"
fi
if [[ -n $eth_index || -n $wlan_index ]]; then
# delete all current connections
LC_ALL=C nmcli -t -f UUID,DEVICE connection show | awk '{print $1}' | cut -f1 -d":" | xargs nmcli connection delete
# - Wifi enable
if [[ $FR_net_wifi_enabled == 1 ]]; then
#Set wifi country code
iw reg set "$FR_net_wifi_countrycode"
nmcli con add con-name "Orange Pi wireless" type wifi ifname ${wlan_index} ssid "$FR_net_wifi_ssid" -- wifi-sec.key-mgmt wpa-psk wifi-sec.psk "$FR_net_wifi_key" ${FIXED_IP_SETTINGS}
nmcli con up "Orange Pi wireless"
#Enable Wlan, disable Eth
FR_net_ethernet_enabled=0
# - Ethernet enable
elif [[ $FR_net_ethernet_enabled == 1 ]]; then
nmcli con add con-name "Orange Pi ethernet" type ethernet ifname ${eth_index} -- ${FIXED_IP_SETTINGS}
nmcli con up "Orange Pi ethernet"
#Enable Eth, disable Wlan
FR_net_wifi_enabled=0
fi
fi
fi
fi
} #do_firstrun_automated_user_configuration
do_firstrun_automated_user_configuration
exit 0

View File

@@ -0,0 +1,180 @@
#!/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:
#
# prepare_temp_monitoring
# log_hardware_info
# get_flash_information
# check_sd_card_speed
# Read in basic OS image information
. /etc/orangepi-release
# and script configuration
. /usr/lib/orangepi/orangepi-common
prepare_temp_monitoring() {
# still an ugly hack but better do it just once at startup instead of every login
[ -d /etc/orangepimonitor/datasources ] || mkdir -p -m775 /etc/orangepimonitor/datasources
# PMIC check
if [[ -f /sys/power/axp_pmu/pmu/temp ]]; then
ln -fs /sys/power/axp_pmu/pmu/temp /etc/orangepimonitor/datasources/pmictemp
elif [[ -f /sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034//temp1_input ]]; then
ln -fs /sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input \
/etc/orangepimonitor/datasources/pmictemp
elif [[ -f /sys/devices/b0170000.i2c/i2c-0/0-0065/atc2603c-hwmon.0/ic_temperature ]]; then
ln -fs /sys/devices/b0170000.i2c/i2c-0/0-0065/atc2603c-hwmon.0/ic_temperature \
/etc/orangepimonitor/datasources/pmictemp
elif [[ -f /sys/class/axppower/ic_temp ]]; then
ln -fs /sys/class/axppower/ic_temp /etc/orangepimonitor/datasources/pmictemp
fi
# SoC temp: check sun7i legacy exception first, then standard path(s)
if [[ -d "/sys/devices/platform/a20-tp-hwmon" ]]; then
# sun7i legacy
ln -fs /sys/devices/platform/a20-tp-hwmon/temp1_input /etc/orangepimonitor/datasources/soctemp
elif [[ -f /sys/class/hwmon/hwmon0/temp1_input && ${BOARDFAMILY} != "mvebu" ]]; then
# usual convention with modern kernels
ln -fs /sys/class/hwmon/hwmon0/temp1_input /etc/orangepimonitor/datasources/soctemp
else
# all other boards/kernels use the same sysfs node except of Actions Semi S500:
[[ ${BOARDFAMILY} == s500 ]] && THERMAL_ZONE="thermal_zone1" || THERMAL_ZONE="thermal_zone0"
ln -fs /sys/devices/virtual/thermal/${THERMAL_ZONE}/temp /etc/orangepimonitor/datasources/soctemp
fi
# Ambient temp
if [[ ${BOARD} == "helios4" && -f /dev/thermal-board/temp1_input ]]; then
ln -fs /dev/thermal-board/temp1_input /etc/orangepimonitor/datasources/ambienttemp
fi
} # prepare_temp_monitoring
log_hardware_info() {
[ -f "/etc/logrotate.d/${0##*/}" ] || \
echo -e "${Log} {\n rotate 12\n weekly\n compress\n missingok\n notifempty\n}" \
> "/etc/logrotate.d/${0##*/}" ; chmod 644 "/etc/logrotate.d/${0##*/}"
CPU_ARCH=$(lscpu | awk '/Architecture/ {print $2}')
DISTRO_ARCH=$(dpkg --print-architecture)
KERNELID=$(uname -r)
echo -e "\n$(date) | ${BOARD_NAME} | ${VERSION} | ${DISTRO_ARCH} | ${CPU_ARCH} | ${KERNELID}" >>${Log}
chmod 644 ${Log}
echo -e "\n### dmesg:\n" >>${Log}
dmesg >>${Log}
echo -e "\n### orangepi-release:\n" >>${Log}
cat /etc/orangepi-release >>${Log}
echo -e "\n### boot environment:\n" >>${Log}
cat /boot/orangepiEnv.txt >>${Log} 2>/dev/null || grep -v "^#" /boot/boot.ini | sed '/^\s*$/d' >>${Log}
echo -e "\n### lsusb:\n" >>${Log}
lsusb 2>/dev/null >>${Log}
echo -e "\n### lscpu:\n" >>${Log}
lscpu >>${Log}
echo -e "\n### cpuinfo:\n" >>${Log}
cat /proc/cpuinfo >>${Log}
echo -e "\n### meminfo:\n" >>${Log}
cat /proc/meminfo >>${Log}
echo -e "\n### virtual memory:\n" >>${Log}
for sysfsnode in /proc/sys/vm/* ; do sysctl $(echo ${sysfsnode} | sed 's|/proc/sys/vm/|vm.|'); done >>${Log}
if [ -x /sbin/ip ]; then
echo -e "\n### ip addr:\n" >>${Log}
/sbin/ip r s >>${Log} ; /sbin/ip a >>${Log}
echo " " >>${Log}
else
echo -e "\n### ifconfig:\n" >>${Log}
ifconfig >>${Log}
fi
echo -e "### partitions:\n" >>${Log}
grep -v " ram" /proc/partitions >>${Log}
echo -e "\n### df:\n" >>${Log}
df -h | egrep '^udev|^tmpfs|^/dev/|log2ram|folder2ram' >>${Log}
which zpool >/dev/null 2>&1 && echo -e "\n### zpools:\n\n$(zpool list)\n\n### zfs datasets:\n\n$(zfs list)" >>${Log}
echo -e "\n### lsblk:\n" >>${Log}
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,UUID | grep -v "SWAP" >>${Log}
which zramctl >/dev/null 2>&1 && echo -e "\n### zramctl:\n\n$(zramctl)" >>${Log}
echo -e "\n### mtab:\n" >>${Log}
egrep '^/dev/|\ zfs\ ' /etc/mtab | egrep -v "log2ram|folder2ram" | sort >>${Log}
[[ -e /boot/script.bin ]] && echo -e "\n### /boot/script.bin --> $(readlink /boot/script.bin)" >>${Log}
get_flash_information >>${Log}
echo -e "\n### Boot system health:\n" >>${Log}
orangepimonitor -s | egrep "^Time|^[0-9]" >>${Log}
} # log_hardware_info
get_flash_information() {
# http://www.bunniestudios.com/blog/?page_id=1022
find /sys -name oemid | while read Device ; do
DeviceNode="${Device%/*}"
DeviceName="${DeviceNode##*/}"
echo -e "\n### ${DeviceName} info:\n"
find "${DeviceNode}" -maxdepth 1 -type f | while read ; do
NodeName="${REPLY##*/}"
echo -e "$(printf "%20s" ${NodeName}): $(cat "${DeviceNode}/${NodeName}" | tr '\n' " ")"
done
done
} # get_flash_information
check_sd_card_speed() {
# function that checks on 3rd boot whether firstrun script made a quick benchmark
# and displays a motd warning when _random_ I/O is below some tresholds.
if [ -f /var/log/orangepi-hardware-monitor.log ]; then
RebootCount=$(grep -c '^### df:' /var/log/orangepi-hardware-monitor.log)
if [ ${RebootCount} -eq 2 ]; then
# check whether iozone data has been collected
IozoneResults="$(awk -F" " '/^### quick iozone test/ {print $10"\t"$11}' </var/log/orangepi-hardware-monitor.log)"
if [ "X${IozoneResults}" != "X" ]; then
set ${IozoneResults}
Readspeed=$1
Writespeed=$2
if [ ${Readspeed} -lt 500 -o ${Writespeed} -lt 250 ]; then
show_motd_warning "Your SD card seems to be very slow. Please check performance using orangepimonitor -c"
fi
fi
fi
fi
} # check_sd_card_speed
case $1 in
*start*)
# check sd card speed once on 3rd boot too warn for too slow media
check_sd_card_speed &
# prepare correct temperature readouts
prepare_temp_monitoring &
# log hardware id to file, write log
echo $BOARD_NAME >/var/run/machine.id # we should leave this, maybe users depend on it
if [ $? -ne 0 ]; then
# most probably readonly fs. We'll try to warn the user.
show_motd_warning "It seems the rootfs is readonly at the moment. Please check your SD card for errors"
fi
# check whether auto detection override exists and if true use this for machine.id
[ -f /root/.machine.id ] && cat /root/.machine.id >/var/run/machine.id
log_hardware_info &
;;
*stop*)
case ${BOARDFAMILY} in
sun?i)
# redefine green led to blink until shutdown, try to switch OTG port to host
(echo heartbeat >/sys/class/leds/*green*/trigger) 2>/dev/null
echo 0 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role 2>/dev/null
;;
esac
# some kernel modules are known to crash the kernel on shutdown (an example
# is the mass storage gadget module at least on sun7i). We try to unload as
# much modules as possible to minimize such situations:
/sbin/modprobe -r $(cut -f1 -d' ' </proc/modules)
# shutdown logging
if [ -f /var/log.hdd/orangepi-hardware-monitor.log ]; then
echo -e "\n### shutdown:\n\n$(iostat -p zram0)\n\n$(vmstat -w)\n\n$(free -h)\n\n$(dmesg | tail -n 100)" >>/var/log.hdd/orangepi-hardware-monitor.log
else
echo -e "\n### shutdown:\n\n$(iostat -p zram0)\n\n$(vmstat -w)\n\n$(free -h)\n\n$(dmesg | tail -n 100)" >>/var/log/orangepi-hardware-monitor.log
fi
sync
;;
esac

View File

@@ -0,0 +1,227 @@
#!/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:
#
# set_io_scheduler
# prepare_board
# add_usb_storage_quirks
# Read in basic OS image information
. /etc/orangepi-release
# and script configuration
. /usr/lib/orangepi/orangepi-common
set_io_scheduler() {
# Convert kernel version to integer
KERNELID=$(uname -r | awk -F'.' '{print ($1 * 100) + $2}')
for i in $( lsblk -idn -o NAME | grep -v zram ); do
read ROTATE </sys/block/$i/queue/rotational
case ${ROTATE} in
1) # mechanical drives
[[ $KERNELID -lt 420 ]] && sched=cfq || sched=bfq
;;
0) # flash based
[[ $KERNELID -lt 420 ]] && sched=noop || sched=none
;;
*)
continue
;;
esac
echo $sched >/sys/block/$i/queue/scheduler
echo -e "[\e[0;32m ok \x1B[0m] Setting $sched I/O scheduler for $i"
done
} # set_io_scheduler
prepare_board() {
CheckDevice=$(for i in /var/log /var / ; do findmnt -n -o SOURCE $i && break ; done)
# adjust logrotate configs
if [[ "${CheckDevice}" == "/dev/zram0" || "${CheckDevice}" == "orangepi-ramlog" ]]; then
for ConfigFile in /etc/logrotate.d/* ; do sed -i -e "s/\/log\//\/log.hdd\//g" "${ConfigFile}"; done
sed -i "s/\/log\//\/log.hdd\//g" /etc/logrotate.conf
else
for ConfigFile in /etc/logrotate.d/* ; do sed -i -e "s/\/log.hdd\//\/log\//g" "${ConfigFile}"; done
sed -i "s/\/log.hdd\//\/log\//g" /etc/logrotate.conf
fi
# unlock cpuinfo_cur_freq to be accesible by a normal user
prefix="/sys/devices/system/cpu/cpufreq"
for f in $(ls -1 $prefix 2> /dev/null)
do
[[ -f $prefix/$f/cpuinfo_cur_freq ]] && chmod +r $prefix/$f/cpuinfo_cur_freq 2> /dev/null
done
# older kernels
prefix="/sys/devices/system/cpu/cpu0/cpufreq/"
[[ -f $prefix/cpuinfo_cur_freq ]] && chmod +r $prefix/cpuinfo_cur_freq 2> /dev/null
# enable compression where not exists
find /etc/logrotate.d/. -type f | xargs grep -H -c 'compress' | grep 0$ | cut -d':' -f1 | xargs -L1 sed -i '/{/ a compress'
sed -i "s/#compress/compress/" /etc/logrotate.conf
# tweak ondemand cpufreq governor settings to increase cpufreq with IO load
grep -q ondemand /etc/default/cpufrequtils
if [ $? -eq 0 ]; then
echo ondemand >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
cd /sys/devices/system/cpu
for i in cpufreq/ondemand cpu0/cpufreq/ondemand cpu4/cpufreq/ondemand ; do
if [ -d $i ]; then
echo 1 >${i}/io_is_busy
echo 25 >${i}/up_threshold
echo 10 >${i}/sampling_down_factor
echo 200000 >${i}/sampling_rate
fi
done
fi
case ${BOARDFAMILY} in
rk3399)
for i in $(awk -F':' '/gpu/{print $1}' </proc/interrupts | sed 's/\ //g'); do
echo 2 >/proc/irq/$i/smp_affinity
done
for i in $(awk -F':' '/dw-mci/{print $1}' </proc/interrupts | sed 's/\ //g'); do
echo 2 >/proc/irq/$i/smp_affinity
done
echo 2 >/proc/irq/$(awk -F":" "/ehci/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 2 >/proc/irq/$(awk -F":" "/ohci/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 4 >/proc/irq/$(awk -F":" "/xhci/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 8 >/proc/irq/$(awk -F":" "/eth0/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 7 >/sys/class/net/eth0/queues/rx-0/rps_cpus
echo 32768 >/proc/sys/net/core/rps_sock_flow_entries
echo 32768 >/sys/class/net/eth0/queues/rx-0/rps_flow_cnt
for i in $(awk -F':' 'tolower($0) ~ /pcie/{print $1}' </proc/interrupts | sed 's/\ //g'); do
echo 16 >/proc/irq/$i/smp_affinity
done
# set dmc memory governor to performance with default kernel
if [ -f /sys/bus/platform/drivers/rockchip-dmc/dmc/devfreq/dmc/governor ]; then
echo performance > /sys/bus/platform/drivers/rockchip-dmc/dmc/devfreq/dmc/governor
fi
;;
sun8i*) # H3/R40/V40 boards, try to do the best based on specific board since interfaces vary a lot
# 10 or 120 sec user feedback that the board is ready after 1st login with 3.4 kernel
SwapState="$(grep swap /etc/fstab)"
if [ "X${SwapState}" != "X" ]; then
(echo heartbeat >/sys/class/leds/*green*/trigger) 2>/dev/null
[ -f "/root/.not_logged_in_yet" ] && BlinkTime=120 || BlinkTime=10
(sleep ${BlinkTime} && (echo default-on >/sys/class/leds/*green*/trigger) 2>/dev/null) &
fi
# check kernel version for IRQ/module names
case ${KERNELID} in
3*)
# BSP kernel
GbE="gmac0"; WiFi="wlan0"; USB1="usb2"; USB2="usb3"; USB3="usb4"
;;
*)
# Mainline kernel
GbE="eth0"; WiFi="wlan0"; USB1="usb3"; USB2="usb4"; USB3="usb5"
;;
esac
# Assign 1st and 2nd USB port to cpu1 and cpu2 on every sun8i board
echo 2 >/proc/irq/$(awk -F":" "/${USB1}/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 4 >/proc/irq/$(awk -F":" "/${USB2}/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
case ${BOARD_NAME} in
"Orange Pi+"|"Orange Pi+ 2"|"Orange Pi+ 2E"|"Banana Pi M2*"|"NanoPi M1 Plus")
# Send GBit Ethernet IRQs to cpu3
echo 8 >/proc/irq/$(awk -F":" "/${GbE}/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 7 >/sys/class/net/eth0/queues/rx-0/rps_cpus
;;
"NanoPi M1"|"Orange Pi PC Plus"|"Orange Pi PC +"|"Orange Pi PC"|"NanoPi Neo"|"Orange Pi Zero")
# Send 3rd USB port's IRQs to cpu3
echo 8 >/proc/irq/$(awk -F":" "/${USB3}/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
;;
"Orange Pi Lite"|"NanoPi Air"|"Lime A33"|"Orange Pi Zero Plus 2"*)
# Send SDIO/mmc IRQs to cpu3
for i in $(awk -F':' '/sunxi-mmc/{print $1}' </proc/interrupts | sed 's/\ //g'); do
echo 8 >/proc/irq/$i/smp_affinity
done
;;
"Beelink X2"|"Orange Pi R1")
# Wifi module reload workaround / fix
[[ -n $(lsmod | grep 8189es) ]] && rmmod 8189es && modprobe 8189es
# Send SDIO to cpu1, USB to cpu2, Ethernet to cpu3
for i in $(awk -F':' '/sunxi-mmc/{print $1}' </proc/interrupts | sed 's/\ //g'); do
echo 2 >/proc/irq/$i/smp_affinity
done
for i in $(awk -F':' '/hcd:usb/{print $1}' </proc/interrupts | sed 's/\ //g'); do
echo 4 >/proc/irq/$i/smp_affinity
done
echo 8 >/proc/irq/$(awk -F":" "/${GbE}/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
;;
esac
;;
sun50i*|sunxi64*) # A64/H5 based boards like Pine64, OPi PC 2, NanoPi NEO 2
# Send IRQs for the lower real USB port (usb2) to cpu2 and for the upper (OTG/usb1) to cpu1
echo 2 >/proc/irq/$(awk -F":" "/usb1/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 4 >/proc/irq/$(awk -F":" "/usb2/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 8 >/proc/irq/$(awk -F":" "/sunxi-mmc/ {print \$1}" </proc/interrupts | sed 's/\ //g' | head -n1)/smp_affinity
echo 8 >/proc/irq/$(awk -F":" "/eth/ {print \$1}" </proc/interrupts | sed 's/\ //g' | head -n1)/smp_affinity
echo 7 >/sys/class/net/eth0/queues/rx-0/rps_cpus
# OrangePi win GMAC is very unstable on gigabit. Limit it down to 100Mb solve problems
[[ $BOARD == orangepiwin && $BRANCH == default ]] && ethtool -s eth0 speed 100 duplex full
;;
esac
} # prepare_board
add_usb_storage_quirks() {
# check for /boot/orangepiEnv.txt existence
[ -f /boot/orangepiEnv.txt ] || return
# cleanup. add LF. This prevents adding parameters to the same line
echo "" >> /boot/orangepiEnv.txt; sed -i '/^$/d;$G' /boot/orangepiEnv.txt; sed -i '/^$/d;$G' /boot/orangepiEnv.txt
# cleanup. remove empty lines in the middle
sed -i '/^$/d' /boot/orangepiEnv.txt
# preserve old contents if existent
TMPFILE=$(mktemp /tmp/${0##*/}.XXXXXX)
trap "sleep 1 ; rm \"${TMPFILE}\" ; exit 0" 0 1 2 3 15
awk -F"=" '/^usbstoragequirks/ {print $2}' </boot/orangepiEnv.txt | tr -d -c '[:graph:]' >${TMPFILE}
# UAS blacklist Norelsys NS1068X and NS1066X since broken. Can be removed once
# they're blacklisted upstream
[ -s ${TMPFILE} ] || echo "0x2537:0x1066:u,0x2537:0x1068:u" >${TMPFILE}
# check for connected Seagate or WD HDD enclosures and blacklist them all
lsusb | awk -F" " '{print "0x"$6}' | sed 's/:/:0x/' | sort | uniq | while read ; do
case ${REPLY} in
"0x0bc2:"*|"0x1058:"*)
grep -q "${REPLY}" ${TMPFILE} || sed -i "1 s/\$/,${REPLY}:u/" ${TMPFILE}
;;
esac
done
read USBQUIRKS <${TMPFILE}
sed -i '/^usbstoragequirks/d' /boot/orangepiEnv.txt
echo "usbstoragequirks=${USBQUIRKS}" >>/boot/orangepiEnv.txt
sync &
if [ -f /sys/module/usb_storage/parameters/quirks ]; then
echo ${USBQUIRKS} >/sys/module/usb_storage/parameters/quirks
fi
} # add_usb_storage_quirks
case $1 in
*start*)
# set optimal disk scheduler settings
set_io_scheduler &
# hardware preparation
prepare_board &
# add usb quirks
add_usb_storage_quirks &
;;
esac

View File

@@ -0,0 +1,129 @@
#!/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.
SIZE=50M
USE_RSYNC=true
ENABLED=false
[ -f /etc/default/orangepi-ramlog ] && . /etc/default/orangepi-ramlog
[ "$ENABLED" != true ] && exit 0
# Never touch anything below here. Only edit /etc/default/orangepi-ramlog
HDD_LOG=/var/log.hdd/
RAM_LOG=/var/log/
LOG2RAM_LOG="${HDD_LOG}orangepi-ramlog.log"
LOG_OUTPUT="tee -a $LOG2RAM_LOG"
isSafe () {
[ -d $HDD_LOG ] || (echo "ERROR: $HDD_LOG doesn't exist! Can't sync." >&2 ; exit 1)
NoCache=$(which nocache 2>/dev/null)
}
RecreateLogs (){
# in case of crash those services don't start if there are no dirs & logs
check_if_installed apache2 && [ ! -d /var/log/apache2 ] && mkdir -p /var/log/apache2
check_if_installed cron-apt && [ ! -d /var/log/cron-apt ] && \
(mkdir -p /var/log/cron-apt ; touch /var/log/cron-apt/log)
check_if_installed proftpd-basic && [ ! -d /var/log/proftpd ] && \
(mkdir -p /var/log/proftpd ; touch /var/log/proftpd/controls.log)
check_if_installed nginx && [ ! -d /var/log/nginx ] && \
(mkdir -p /var/log/nginx ; touch /var/log/nginx/access.log ; touch /var/log/nginx/error.log)
check_if_installed lighttpd && [ ! -d /var/log/lighttpd ] && \
(mkdir -p /var/log/lighttpd ; touch /var/log/lighttpd/access.log ; touch /var/log/lighttpd/error.log)
check_if_installed samba && [ ! -d /var/log/samba ] && mkdir -p /var/log/samba
check_if_installed unattended-upgrades && [ ! -d /var/log/unattended-upgrades ] && mkdir -p /var/log/unattended-upgrades
return 0
}
syncToDisk () {
isSafe
echo -e "\n\n$(date): Syncing logs to storage\n" | $LOG_OUTPUT
if [ "$USE_RSYNC" = true ]; then
${NoCache} rsync -aXWv --exclude "lost+found" --exclude orangepi-ramlog.log --links $RAM_LOG $HDD_LOG 2>&1 | $LOG_OUTPUT
else
${NoCache} cp -rfup $RAM_LOG -T $HDD_LOG 2>&1 | $LOG_OUTPUT
fi
sync /
}
syncFromDisk () {
isSafe
echo -e "\n\n$(date): Loading logs from storage\n" | $LOG_OUTPUT
if [ "$USE_RSYNC" = true ]; then
${NoCache} rsync -aXWv --delete --exclude "lost+found" --exclude orangepi-ramlog.log --exclude *.gz --exclude *.xz --exclude='*.[0-9]' --links $HDD_LOG $RAM_LOG 2>&1 | $LOG_OUTPUT
else
${NoCache} find $HDD_LOG* -maxdepth 1 -type f -not \( -name '*.[0-9]' -or -name '*.xz*' -or -name '*.gz' \) | xargs cp -ut $RAM_LOG
fi
sync /
}
check_if_installed () {
local DPKG_Status="$(dpkg -s "$1" 2>/dev/null | awk -F": " '/^Status/ {print $2}')"
if [[ "X${DPKG_Status}" = "X" || "${DPKG_Status}" = *deinstall* ]]; then
return 1
else
return 0
fi
}
case "$1" in
start)
[ -d $HDD_LOG ] || mkdir -p $HDD_LOG
mount --bind $RAM_LOG $HDD_LOG
mount --make-private $HDD_LOG
# Check whether zram device is available or we need to use tmpfs
if [ "$(blkid -s TYPE /dev/zram0 | awk ' { print $2 } ' | grep ext4)" ]; then
LOG_TYPE="zram"
else
LOG_TYPE="tmpfs"
fi
case $LOG_TYPE in
zram)
echo -e "Mounting /dev/zram0 as $RAM_LOG \c" | $LOG_OUTPUT
mount -o discard /dev/zram0 $RAM_LOG 2>&1 | $LOG_OUTPUT
;;
tmpfs)
echo -e "Setting up $RAM_LOG as tmpfs \c" | $LOG_OUTPUT
mount -t tmpfs -o nosuid,noexec,nodev,mode=0755,size=$SIZE orangepi-ramlog $RAM_LOG 2>&1 | $LOG_OUTPUT
;;
esac
syncFromDisk
RecreateLogs
;;
stop)
syncToDisk
umount -l $RAM_LOG
umount -l $HDD_LOG
;;
write)
syncToDisk
;;
postrotate)
cd /var/log.hdd/
find . -type f -print | grep -E -v "(\.gz|\.xz|\.[0-9]|orangepi-ramlog)" | while IFS= read -r file
do
dest="/var/log/$file"
cat $file > $dest
done
;;
*)
echo "Usage: ${0##*/} {start|stop|write}" >&2
exit 1
;;
esac

View File

@@ -0,0 +1,202 @@
#!/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.
. /etc/orangepi-release
. /lib/init/vars.sh
. /lib/lsb/init-functions
. /usr/lib/orangepi/orangepi-common
do_expand_partition()
{
# trim any btrfs subvolume identifier given in square brackets (e.g. /dev/mapper/orangepi-root[/@])
local rootsource=$(findmnt -n -o SOURCE / | sed 's~\[.*\]~~') # i.e. /dev/mmcblk0p1 or /dev/mapper/orangepi-root
# check for device type
local roottype=$(lsblk -n -o TYPE $rootsource) # crypt, part or disk
case ${roottype} in
crypt)
IS_CRYPTDEVICE=true
local cryptname=$(lsblk -n -o NAME $rootsource)
local parent_uuid=$(cat /etc/crypttab | awk '{if($1=="'$cryptname'"){print $2}}' | sed 's/UUID=//')
local rootpart=$(blkid -U $parent_uuid)
;;
part)
local rootpart=$rootsource # i.e. /dev/mmcblk0p1
;;
esac
local rootdevice=$(lsblk -n -o PKNAME $rootpart | head -1) # i.e. mmcblk0
# due to the bug in util-linux 2.34 which fails to show device, let's use this failover:
[[ -z $rootdevice ]] && rootdevice=$(echo $rootpart | sed -e "s/^\/dev\///" | sed "s/p.*//")
local rootdevicepath="/dev/$rootdevice" # i.e. /dev/mmcblk0
# get count of partitions and their boundaries
local partitions=$(parted $rootdevicepath print -sm | tail -1 | awk -F ':' '{print $1}')
local partstart=$(parted $rootdevicepath unit s print -sm | tail -1 | cut -d: -f2 | sed 's/s//') # start of first partition
local partend=$(parted $rootdevicepath unit s print -sm | head -3 | tail -1 | cut -d: -f3 | sed 's/s//') # end of first partition
local startfrom=$(( $partend + 1 ))
[[ $partitions == 1 ]] && startfrom=$partstart
local capacity=$(( $(lsblk -n -b -d -o SIZE $rootdevicepath) / 1024 / 1024 / 1024 )) # GiB
# check whether a resizing rule is defined. We will take this value if it's not too low. In
# this case the value will be ignored and resizing to the whole card size happens.
if [[ -f /root/.rootfs_resize ]]; then
read RESIZE_VALUE </root/.rootfs_resize
ResizeLog="Resize rule $RESIZE_VALUE defined for root partition"
case $RESIZE_VALUE in
*%)
# percentage value, we try to use 16MiB to align partitions since this is
# the erase block size of more recent SD cards (512 byte sectors, so we use 32
# as divider and substract 1)
local percentage=$(echo $RESIZE_VALUE | tr -c -d '[:digit:]')
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * $percentage / 3200))}") - 1 ))
[[ $lastsector -lt $partend ]] && unset lastsector
;;
*s)
# sector value, we use it directly
local lastsector=$(echo $RESIZE_VALUE | tr -c -d '[:digit:]')
[[ $lastsector -lt $partend ]] && unset lastsector
;;
esac
# if SD card is larger than 4GiB then create another partition behind first one(s)
if [[ $capacity -ge 5 ]]; then
local secondpartition=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * 99 / 3200))}") -1 ))
if [[ $secondpartition -lt $partend ]]; then
unset secondpartition
fi
fi
else
# check device capacity. If 4GiB or below do not use whole card but leave a 5% spare area
# to help older cards with wear leveling and garbage collection. In case this reduced card
# capacity is less than the actual image capacity this is a clear sign that someone wants
# to use Orange Pi on a card of inappropriate size so he gets what he deserves (at least he
# should know what he's doing)
if [[ $capacity -lt 5 ]]; then # 4 GiB or less
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * 95 / 3200))}") -1 ))
if [[ $lastsector -lt $partend ]]; then
unset lastsector
else
ResizeLog="4GiB or smaller media - leaving 5% spare area"
fi
elif [[ $capacity -lt 9 ]]; then # 8 GiB or less
# Leave 2 percent unpartitioned
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * 98 / 3200))}") -1 ))
if [[ $lastsector -lt $partend ]]; then
unset lastsector
else
ResizeLog="8GiB or smaller media - leaving 2% spare area"
fi
else
# Leave 1 percent unpartitioned
local lastsector=$(( 32 * $(parted $rootdevicepath unit s print -sm | grep "^$rootdevicepath" | awk -F":" "{printf (\"%0d\", ( \$2 * 99 / 3200))}") -1 ))
if [[ $lastsector -lt $partend ]]; then
unset lastsector
else
ResizeLog="Leaving 1% spare area"
fi
fi
fi
# Start resizing
echo -e "\n### [resize2fs] ${ResizeLog}. Start resizing partition $rootsource now:\n" >>${Log}
cat /proc/partitions >>${Log}
echo -e "\nExecuting fdisk, fsck and partprobe:" >>${Log}
local fdisk_version=$(fdisk --version | awk '{print $NF}' | grep -oE "^[[:digit:]]\.[[:digit:]]+")
if [[ $partitions == 1 ]] && awk "BEGIN{exit ! ($fdisk_version >= 2.27 )}"; then
# if dealing with fdisk from util-linux 2.27+ we need a workaround for just 1 partition
# though it does not break anything - just prevents an "unexpected command" to fdisk
# https://github.com/igorpecovnik/lib/issues/353#issuecomment-224728506
((echo d; echo n; echo p; echo ; echo $startfrom; echo $lastsector ; echo w;) | fdisk $rootdevicepath) >>${Log} 2>&1
else
((echo d; echo $partitions; echo n; echo p; echo ; echo $startfrom; echo $lastsector ; echo w;) | fdisk $rootdevicepath) >>${Log} 2>&1
fi
[[ -n $secondpartition ]] && \
((echo n; echo p; echo ; echo $(( $lastsector + 1 )); echo $secondpartition ; echo w;) | fdisk $rootdevicepath) >>${Log} 2>&1
local s=0
partprobe $rootdevicepath >>${Log} 2>&1 || s=$?
echo -e "New partition table:\n" >>${Log}
cat /proc/partitions >>${Log}
echo -e "\nNow trying to resize $1 filesystem on $rootsource to the limits:\n" >>${Log}
# if crypt-device, resize LUKS container first
if [[ $IS_CRYPTDEVICE ]]; then
do_resize_crypt $cryptname
fi
case $1 in
ext4)
resize2fs $rootsource >>${Log} 2>&1
# check whether reboot is necessary for resize2fs to take effect
local usedpercent=$(findmnt --target / -n -o USE% -b) # images before resize have 70-75%
if [[ $s != 0 || $usedpercent -gt 70 ]]; then
touch /var/run/resize2fs-reboot
echo -e "\n### [resize2fs] Automated reboot needed to finish the resize procedure" >>${Log}
fi
;;
btrfs)
btrfs filesystem resize max / >> ${Log} 2>&1
;;
esac
}
do_resize_crypt()
{
echo -e "\n### [resize2fs] Start resizing LUKS container now\n" >> ${Log}
cryptsetup resize $1
}
do_expand_ext4()
{
echo -e "\n### [resize2fs] Start resizing ext4 partition $1 now\n" >> ${Log}
resize2fs ${rootpart} >> ${Log} 2>&1
}
do_expand_btrfs()
{
echo -e "\n### [resize2fs] Start resizing btrfs partition $1 now\n" >> ${Log}
btrfs filesystem resize max / >> ${Log} 2>&1
}
case "$1" in
start)
# skip resizing if rootfs is neither ext4 not btrfs or if explicitly disabled
if [[ -f /root/.no_rootfs_resize ]]; then
systemctl disable orangepi-resize-filesystem
exit 0
fi
# Logging header
CPU_ARCH=$(lscpu | awk '/Architecture/ {print $2}')
DISTRO_ARCH=$(dpkg --print-architecture)
KERNELID=$(uname -r)
echo "$(date) | ${BOARD_NAME} | ${VERSION} | ${DISTRO_ARCH} | ${CPU_ARCH} | ${KERNELID}" >>${Log}
chmod 644 ${Log}
rootfstype=$(findmnt -n -o FSTYPE /)
rootpart=$(findmnt -n -o SOURCE /) # i.e. /dev/mmcblk0p1
case ${rootfstype} in
ext4)
# first stage - resize the rootfs partition
[[ ! -f /var/lib/orangepi/resize_second_stage ]] && do_expand_partition ${rootfstype}
# second stage - resize the filesystem
[[ ! -f /var/run/resize2fs-reboot ]] && do_expand_ext4 ${rootpart}
;;
btrfs)
do_expand_partition ${rootfstype} && systemctl disable orangepi-resize-filesystem
;;
esac
# disable itself
[[ ! -f /var/run/resize2fs-reboot ]] && systemctl disable orangepi-resize-filesystem
exit 0
;;
*)
echo "Usage: $0 start"
exit 0
;;
esac

View File

@@ -0,0 +1,30 @@
#!/bin/sh
#
# 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.
#
# truncate, save and clean logs if they get over 75% of the /var/log size
# working only when orangepi-ramlog is enabled
treshold=75 # %
[ -f /etc/default/orangepi-ramlog ] && . /etc/default/orangepi-ramlog
[ "$ENABLED" != true ] && exit 0
logusage=$(df /var/log/ --output=pcent | tail -1 |cut -d "%" -f 1)
if [ $logusage -ge $treshold ]; then
# write to SD
/usr/lib/orangepi/orangepi-ramlog write >/dev/null 2>&1
# rotate logs on "disk"
/usr/sbin/logrotate --force /etc/logrotate.conf
# truncate
/usr/bin/find /var/log -name '*.log' -or -name '*.xz' -or -name 'lastlog' -or -name 'messages' -or -name 'debug' -or -name 'syslog' | xargs -r truncate --size 0
/usr/bin/find /var/log -name 'btmp' -or -name 'wtmp' -or -name 'faillog' -or -name 'firewalld' | xargs -r truncate --size 0
/usr/bin/find /var/log -name 'mail.err' -or -name 'mail.info' -or -name 'mail.warning' | xargs -r truncate --size 0
# remove
/usr/bin/find /var/log -name '*.[0-9]' -or -name '*.gz' | xargs -r rm -f
fi

View File

@@ -0,0 +1,137 @@
#!/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:
#
# activate_zram_swap
# activate_ramlog_partition
# activate_compressed_tmp
# Read in basic OS image information
. /etc/orangepi-release
# and script configuration
. /usr/lib/orangepi/orangepi-common
# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,
# RAMLOG_ALGORITHM and TMP_ALGORITHM here:
[ -f /etc/default/orangepi-zram-config ] && . /etc/default/orangepi-zram-config
activate_zram_swap() {
# Do not interfere with already present config-zram package
dpkg -l | grep -q 'zram-config' && exit 0
[[ "$ENABLED" != "true" ]] && exit 0
# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES
# defines the maximum, on modern kernels we overwrite this with 1 and rely on
# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES
uname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1
cpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')
[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}
module_args="$(modinfo zram | awk -F" " '/num_devices/ {print $2}' | cut -f1 -d:)"
[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return
# Expose 50% of real memory as swap space by default
zram_percent=${ZRAM_PERCENTAGE:=50}
mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
memory_total=$(awk '{printf("%d",$2*1024)}' <<<${mem_info})
mem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))
# Limit memory available to zram to 50% by default
mem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}
mem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))
# Limit Journal size to 20Mb
sed -i "s/.*SystemMaxUse=$/SystemMaxUse=20M/" /etc/systemd/journald.conf
swap_algo=${SWAP_ALGORITHM:=lzo}
for (( i=1; i<=zram_devices; i++ )); do
if [ -f /sys/block/zram${i}/comp_algorithm ]; then
# set compression algorithm, if defined as lzo choose lzo-rle if available
# https://www.phoronix.com/scan.php?page=news_item&px=ZRAM-Linux-5.1-Better-Perform
grep -q 'lzo-rle' /sys/block/zram${i}/comp_algorithm && \
[[ "X${swap_algo}" = "Xlzo" ]] && swap_algo="lzo-rle"
echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null
fi
if [ "X${ZRAM_BACKING_DEV}" != "X" ]; then
echo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev
fi
echo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams
echo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize
echo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit
mkswap /dev/zram${i}
swapon -p 5 /dev/zram${i}
done
# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap
echo 0 > /proc/sys/vm/page-cluster
echo -e "\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\n" >>${Log}
} # activate_zram_swap
activate_ramlog_partition() {
# /dev/zram0 will be used as a compressed /var/log partition in RAM if
# ENABLED=true in /etc/default/orangepi-ramlog is set
ENABLED=$(awk -F"=" '/^ENABLED/ {print $2}' /etc/default/orangepi-ramlog)
[[ "$ENABLED" != "true" ]] && return
# read size also from /etc/default/orangepi-ramlog
ramlogsize=$(awk -F"=" '/^SIZE/ {print $2}' /etc/default/orangepi-ramlog)
disksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)
# choose RAMLOG_ALGORITHM if defined in /etc/default/orangepi-zram-config
# otherwise try to choose most efficient compression scheme available.
# See https://patchwork.kernel.org/patch/9918897/
if [ "X${RAMLOG_ALGORITHM}" = "X" ]; then
for algo in lz4 lz4hc quicklz zlib brotli zstd ; do
echo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null
done
else
echo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null
fi
echo -n ${disksize} > /sys/block/zram0/disksize
# if it fails, select $swap_algo. Workaround for some older kernels
if [[ $? == 1 ]]; then
echo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null
echo -n ${disksize} > /sys/block/zram0/disksize
fi
mkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0
algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram0/comp_algorithm)
echo -e "### Activated Orange Pi ramlog partition with ${algo} compression" >>${Log}
} # activate_ramlog_partition
activate_compressed_tmp() {
# create /tmp not as tmpfs but zram compressed if no fstab entry exists
grep -q '^tmpfs /tmp' /etc/mtab && return
tmp_device=$(( ${zram_devices} + 1 ))
if [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then
if [ "X${TMP_ALGORITHM}" = "X" ]; then
echo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
else
echo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
fi
fi
echo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize
mkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}
mount -o nosuid,discard /dev/zram${tmp_device} /tmp
chmod 777 /tmp
algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram${tmp_device}/comp_algorithm)
echo -e "\n### Activated ${algo} compressed /tmp" >>${Log}
} # activate_compressed_tmp
case $1 in
*start*)
activate_zram_swap
activate_ramlog_partition
activate_compressed_tmp
;;
esac

View File

@@ -0,0 +1,728 @@
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
#
# Tool to transfer the rootfs of an already running Orange Pi installation from SD card
# to NAND, eMMC, SATA or USB storage. In case of eMMC it's also possible to transfer
# the bootloader to eMMC in a single step so from then on running without SD card is
# possible.
# Import:
# DIR: path to u-boot directory
# write_uboot_platform: function to write u-boot to a block device
[[ -f /usr/lib/u-boot/platform_install.sh ]] && source /usr/lib/u-boot/platform_install.sh
# script configuration
CWD="/usr/lib/nand-sata-install"
EX_LIST="${CWD}/exclude.txt"
[ -f /etc/default/openmediavault ] && echo '/srv/*' >> "${EX_LIST}"
logfile="/var/log/nand-sata-install.log"
# read in board info
[[ -f /etc/orangepi-release ]] && source /etc/orangepi-release
backtitle="$BOARD_NAME install script, http://www.orangepi.org"
title="eMMC and USB Orange Pi installer v${VERSION}"
# exceptions
if grep -q 'sun4i' /proc/cpuinfo; then DEVICE_TYPE="a10";
elif grep -q 'sun5i' /proc/cpuinfo; then DEVICE_TYPE="a13";
else DEVICE_TYPE="a20"; fi
BOOTLOADER="${CWD}/${DEVICE_TYPE}/bootloader"
case ${LINUXFAMILY} in
rk3328|rk3399|rockchip64)
FIRSTSECTOR=32768
;;
*)
FIRSTSECTOR=8192
;;
esac
#recognize_root
root_uuid=$(sed -e 's/^.*root=//' -e 's/ .*$//' < /proc/cmdline)
root_partition=$(blkid | tr -d '":' | grep "${root_uuid}" | awk '{print $1}')
root_partition_device="${root_partition::-2}"
# find targets: NAND, EMMC, SATA, SPI flash, NVMe
[[ -b /dev/nand ]] && nandcheck=$(ls -d -1 /dev/nand* | grep -w 'nand' | awk '{print $NF}');
emmccheck=$(ls -d -1 /dev/mmcblk* | grep -w 'mmcblk[0-9]' | grep -v "$root_partition_device");
diskcheck=$(lsblk -l | awk -F" " '/ disk / {print $1}' | grep -E '^sd|^nvme')
spicheck=$(grep 'mtd' /proc/partitions | awk '{print $NF}')
# define makefs and mount options
declare -A mkopts mountopts
# for ARMv7 remove 64bit feature from default mke2fs format features
if [[ $LINUXFAMILY == mvebu ]]; then
mkopts[ext2]='-O ^64bit -qF'
mkopts[ext3]='-O ^64bit -qF'
mkopts[ext4]='-O ^64bit -qF'
else
mkopts[ext2]='-qF'
mkopts[ext3]='-qF'
mkopts[ext4]='-qF'
fi
mkopts[btrfs]='-f'
mkopts[f2fs]='-f'
mountopts[ext2]='defaults,noatime,nodiratime,commit=600,errors=remount-ro,x-gvfs-hide 0 1'
mountopts[ext3]='defaults,noatime,nodiratime,commit=600,errors=remount-ro,x-gvfs-hide 0 1'
mountopts[ext4]='defaults,noatime,nodiratime,commit=600,errors=remount-ro,x-gvfs-hide 0 1'
mountopts[btrfs]='defaults,noatime,nodiratime,commit=600,compress=lzo,x-gvfs-hide 0 2'
mountopts[f2fs]='defaults,noatime,nodiratime,x-gvfs-hide 0 2'
# Create boot and root file system "$1" = boot, "$2" = root (Example: create_orangepi "/dev/nand1" "/dev/sda3")
create_orangepi()
{
# create mount points, mount and clean
TempDir=$(mktemp -d /mnt/${0##*/}.XXXXXX || exit 2)
sync && mkdir -p "${TempDir}"/bootfs "${TempDir}"/rootfs
if [[ $eMMCFilesystemChoosen =~ ^(btrfs|f2fs)$ ]]; then
[[ -n $1 ]] && mount ${1::-1}"1" "${TempDir}"/bootfs
[[ -n $2 ]] && ( mount -o compress-force=zlib "$2" "${TempDir}"/rootfs 2> /dev/null || mount "$2" "${TempDir}"/rootfs )
else
[[ -n $2 ]] && ( mount -o compress-force=zlib "$2" "${TempDir}"/rootfs 2> /dev/null || mount "$2" "${TempDir}"/rootfs )
[[ -n $1 && $1 != "spi" ]] && mount "$1" "${TempDir}"/bootfs
fi
rm -rf "${TempDir}"/bootfs/* "${TempDir}"/rootfs/*
# sata root part
# UUID=xxx...
satauuid=$(blkid -o export "$2" | grep -w UUID)
# SD card boot part -- wrong since more than one entry on various platforms
# UUID=xxx...
sduuid=$(blkid -o export /dev/mmcblk*p1 | grep -w UUID | grep -v "$root_partition_device")
# write information to log
echo -e "\nOld UUID: ${root_uuid}" >> $logfile
echo "SD UUID: $sduuid" >> $logfile
echo "SATA UUID: $satauuid" >> $logfile
echo "eMMC UUID: $emmcuuid $eMMCFilesystemChoosen" >> $logfile
echo "Boot: \$1 $1 $eMMCFilesystemChoosen" >> $logfile
echo "Root: \$2 $2 $FilesystemChoosen" >> $logfile
# calculate usage and see if it fits on destination
USAGE=$(df -BM | grep ^/dev | head -1 | awk '{print $3}' | tr -cd '[0-9]. \n')
DEST=$(df -BM | grep ^/dev | grep "${TempDir}"/rootfs | awk '{print $4}' | tr -cd '[0-9]. \n')
if [[ $USAGE -gt $DEST ]]; then
dialog --title "$title" --backtitle "$backtitle" --colors --infobox\
"\n\Z1Partition too small.\Zn Needed: $USAGE MB Avaliable: $DEST MB" 5 60
umount_device "$1"; umount_device "$2"
exit 3
fi
if [[ $1 == *nand* ]]; then
# creating nand boot. Copy precompiled uboot
rsync -aqc $BOOTLOADER/* "${TempDir}"/bootfs
fi
# write information to log
echo "Usage: $USAGE" >> $logfile
echo -e "Dest: $DEST\n\n/etc/fstab:" >> $logfile
cat /etc/fstab >> $logfile
echo -e "\n/etc/mtab:" >> $logfile
grep '^/dev/' /etc/mtab | grep -E -v "log2ram|folder2ram" | sort >> $logfile
# stop running services
echo -e "\nFiles currently open for writing:" >> $logfile
lsof / | awk 'NR==1 || $4~/[0-9][uw]/' | grep -v "^COMMAND" >> $logfile
echo -e "\nTrying to stop running services to minimize open files:\c" >> $logfile
stop_running_services "nfs-|smbd|nmbd|winbind|ftpd|netatalk|monit|cron|webmin|rrdcached" >> $logfile
stop_running_services "fail2ban|ramlog|folder2ram|postgres|mariadb|mysql|postfix|mail|nginx|apache|snmpd" >> $logfile
pkill dhclient 2>/dev/null
LANG=C echo -e "\n\nChecking again for open files:" >> $logfile
lsof / | awk 'NR==1 || $4~/[0-9][uw]/' | grep -v "^COMMAND" >> $logfile
# count files is needed for progress bar
dialog --title " $title " --backtitle "$backtitle" --infobox "\n Counting files ... few seconds." 5 60
TODO=$(rsync -ahvrltDn --delete --stats --exclude-from=$EX_LIST / "${TempDir}"/rootfs | grep "Number of files:"|awk '{print $4}' | tr -d '.,')
echo -e "\nCopying ${TODO} files to $2. \c" >> $logfile
# creating rootfs
# Speed copy increased x10
# Variables for interfacing with rsync progress
nsi_conn_path="${TempDir}/nand-sata-install"
nsi_conn_done="${nsi_conn_path}/done"
nsi_conn_progress="${nsi_conn_path}/progress"
mkdir -p "${nsi_conn_path}"
echo 0 >"${nsi_conn_progress}"
echo no >"${nsi_conn_done}"
# Launch rsync in background
{ \
rsync -avrltD --delete --exclude-from=$EX_LIST / "${TempDir}"/rootfs | \
nl | awk '{ printf "%.0f\n", 100*$1/"'"$TODO"'" }' \
> "${nsi_conn_progress}" ;
# save exit code from rsync
echo ${PIPESTATUS[0]} >"${nsi_conn_done}"
} &
# while variables
rsync_copy_finish=0
rsync_progress=0
prev_progress=0
rsync_done=""
while [ "${rsync_copy_finish}" -eq 0 ]; do
# Sometimes reads the progress file while writing and only partial numbers (like 1 when is 15)
prev_progress=${rsync_progress}
rsync_progress=$(tail -n1 "${nsi_conn_progress}")
if [[ -z ${rsync_progress} ]]; then
rsync_progress=${prev_progress}
fi
if [ ${prev_progress} -gt ${rsync_progress} ]; then
rsync_progress=${prev_progress}
fi
echo "${rsync_progress}"
# finish the while if the rsync is finished
rsync_done=$(cat ${nsi_conn_done})
if [[ "${rsync_done}" != "no" ]]; then
if [[ ${rsync_done} -eq 0 ]]; then
rm -rf "${nsi_conn_path}"
rsync_copy_finish=1
else
# if rsync return error
echo "Error: could not copy rootfs files, exiting"
exit 4
fi
else
sleep 0.5
fi
done | \
dialog --backtitle "$backtitle" --title " $title " --gauge "\n\n Transferring rootfs to $2 ($USAGE MB). \n\n \
This will take approximately $(( $((USAGE/300)) * 1 )) minutes to finish. Please wait!\n\n" 11 80
# run rsync again to silently catch outstanding changes between / and "${TempDir}"/rootfs/
dialog --title "$title" --backtitle "$backtitle" --infobox "\n Cleaning up ... Almost done." 5 40
rsync -avrltD --delete --exclude-from=$EX_LIST / "${TempDir}"/rootfs >/dev/null 2>&1
# creating fstab from scratch
rm -f "${TempDir}"/rootfs/etc/fstab
mkdir -p "${TempDir}"/rootfs/etc "${TempDir}"/rootfs/media/mmcboot "${TempDir}"/rootfs/media/mmcroot
# Restore TMP and swap
echo "# <file system> <mount point> <type> <options> <dump> <pass>" > "${TempDir}"/rootfs/etc/fstab
echo "tmpfs /tmp tmpfs defaults,nosuid 0 0" >> "${TempDir}"/rootfs/etc/fstab
grep swap /etc/fstab >> "${TempDir}"/rootfs/etc/fstab
# creating fstab, kernel and boot script for NAND partition
#
if [[ $1 == *nand* ]]; then
echo "Finishing installation to NAND." >> $logfile
REMOVESDTXT="and remove SD to boot from NAND"
echo "$1 /boot vfat defaults 0 0" >> "${TempDir}"/rootfs/etc/fstab
echo "$2 / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 1" >> "${TempDir}"/rootfs/etc/fstab
dialog --title "$title" --backtitle "$backtitle" --infobox "\nConverting kernel ... few seconds." 5 60
mkimage -A arm -O linux -T kernel -C none -a "0x40008000" -e "0x40008000" -n "Linux kernel" -d \
/boot/zImage "${TempDir}"/bootfs/uImage >/dev/null 2>&1
cp /boot/script.bin "${TempDir}"/bootfs/
if [[ $DEVICE_TYPE != a13 ]]; then
# Note: Not using UUID based boot for NAND
cat <<-EOF > "${TempDir}"/bootfs/uEnv.txt
console=ttyS0,115200
root=$2 rootwait
extraargs="console=tty1 hdmi.audio=EDID:0 disp.screen0_output_mode=EDID:0 consoleblank=0 loglevel=1"
EOF
else
# Note: Not using UUID based boot for NAND
cat <<-EOF > "${TempDir}"/bootfs/uEnv.txt
console=ttyS0,115200
root=$2 rootwait
extraargs="consoleblank=0 loglevel=1"
EOF
fi
sync
[[ $DEVICE_TYPE = a20 ]] && echo "machid=10bb" >> "${TempDir}"/bootfs/uEnv.txt
# ugly hack becouse we don't have sources for A10 nand uboot
if [[ $ID == Cubieboard || $BOARD_NAME == Cubieboard || $ID == "Lime A10" || $BOARD_NAME == "Lime A10" ]]; then
cp "${TempDir}"/bootfs/uEnv.txt "${TempDir}"/rootfs/boot/uEnv.txt
cp "${TempDir}"/bootfs/script.bin "${TempDir}"/rootfs/boot/script.bin
cp "${TempDir}"/bootfs/uImage "${TempDir}"/rootfs/boot/uImage
fi
umount_device "/dev/nand"
tune2fs -o journal_data_writeback /dev/nand2 >/dev/null 2>&1
tune2fs -O ^has_journal /dev/nand2 >/dev/null 2>&1
e2fsck -f /dev/nand2 >/dev/null 2>&1
fi
# Boot from eMMC, root = eMMC or SATA / USB
#
if [[ $2 == ${emmccheck}p* || $1 == ${emmccheck}p* ]]; then
if [[ $2 == ${DISK_ROOT_PART} ]]; then
local targetuuid=$satauuid
local choosen_fs=$FilesystemChoosen
echo "Finalizing: boot from eMMC, rootfs on USB/SATA/NVMe." >> $logfile
if [[ $eMMCFilesystemChoosen =~ ^(btrfs|f2fs)$ ]]; then
echo "$emmcuuid /media/mmcroot $eMMCFilesystemChoosen ${mountopts[$eMMCFilesystemChoosen]}" >> "${TempDir}"/rootfs/etc/fstab
fi
else
local targetuuid=$emmcuuid
local choosen_fs=$eMMCFilesystemChoosen
echo "Finishing full install to eMMC." >> $logfile
fi
# fix that we can have one exlude file
cp -R /boot "${TempDir}"/bootfs
# old boot scripts
sed -e 's,root='"$root_uuid"',root='"$targetuuid"',g' -i "${TempDir}"/bootfs/boot/boot.cmd
# new boot scripts
if [[ -f "${TempDir}"/bootfs/boot/orangepiEnv.txt ]]; then
sed -e 's,rootdev=.*,rootdev='"$targetuuid"',g' -i "${TempDir}"/bootfs/boot/orangepiEnv.txt
grep -q '^rootdev' "${TempDir}"/bootfs/boot/orangepiEnv.txt || echo "rootdev=$targetuuid" >> "${TempDir}"/bootfs/boot/orangepiEnv.txt
else
sed -e 's,setenv rootdev.*,setenv rootdev '"$targetuuid"',g' -i "${TempDir}"/bootfs/boot/boot.cmd
[[ -f "${TempDir}"/bootfs/boot/boot.ini ]] && sed -e 's,^setenv rootdev.*$,setenv rootdev "'"$targetuuid"'",' -i "${TempDir}"/bootfs/boot/boot.ini
[[ -f "${TempDir}"/rootfs/boot/boot.ini ]] && sed -e 's,^setenv rootdev.*$,setenv rootdev "'"$targetuuid"'",' -i "${TempDir}"/rootfs/boot/boot.ini
fi
mkimage -C none -A arm -T script -d "${TempDir}"/bootfs/boot/boot.cmd "${TempDir}"/bootfs/boot/boot.scr >/dev/null 2>&1 || (echo 'Error while creating U-Boot loader image with mkimage' >&2 ; exit 5)
# fstab adj
if [[ "$1" != "$2" ]]; then
echo "$emmcbootuuid /media/mmcboot ext4 ${mountopts[ext4]}" >> "${TempDir}"/rootfs/etc/fstab
echo "/media/mmcboot/boot /boot none bind 0 0" >> "${TempDir}"/rootfs/etc/fstab
fi
# if the rootfstype is not defined as cmdline argument on orangepiEnv.txt
if ! grep -qE '^rootfstype=.*' "${TempDir}"/bootfs/boot/orangepiEnv.txt; then
# Add the line of type of the selected rootfstype to the file orangepiEnv.txt
echo "rootfstype=$choosen_fs" >> "${TempDir}"/bootfs/boot/orangepiEnv.txt
fi
if [[ $eMMCFilesystemChoosen =~ ^(btrfs|f2fs)$ ]]; then
echo "$targetuuid / $choosen_fs ${mountopts[$choosen_fs]}" >> "${TempDir}"/rootfs/etc/fstab
# swap file not supported under btrfs but we might have made a partition
[[ -n ${emmcswapuuid} ]] && sed -e 's,/var/swap.*,'$emmcswapuuid' none swap sw 0 0,g' -i "${TempDir}"/rootfs/etc/fstab
sed -e 's,rootfstype=.*,rootfstype='$eMMCFilesystemChoosen',g' -i "${TempDir}"/bootfs/boot/orangepiEnv.txt
else
sed -e 's,rootfstype=.*,rootfstype='$choosen_fs',g' -i "${TempDir}"/bootfs/boot/orangepiEnv.txt
echo "$targetuuid / $choosen_fs ${mountopts[$choosen_fs]}" >> "${TempDir}"/rootfs/etc/fstab
fi
if [[ $(type -t write_uboot_platform) != function ]]; then
echo "Error: no u-boot package found, exiting"
exit 6
fi
write_uboot_platform "$DIR" $emmccheck
fi
# Boot from SD card, root = SATA / USB
#
if [[ $2 == ${DISK_ROOT_PART} && -z $1 ]]; then
echo -e "Finishing transfer to disk, boot from SD/eMMC" >> $logfile
[[ -f /boot/boot.cmd ]] && sed -e 's,root='"$root_uuid"',root='"$satauuid"',g' -i /boot/boot.cmd
[[ -f /boot/boot.ini ]] && sed -e 's,^setenv rootdev.*$,setenv rootdev "'"$satauuid"'",' -i /boot/boot.ini
# new boot scripts
if [[ -f /boot/orangepiEnv.txt ]]; then
sed -e 's,rootdev=.*,rootdev='"$satauuid"',g' -i /boot/orangepiEnv.txt
grep -q '^rootdev' /boot/orangepiEnv.txt || echo "rootdev=$satauuid" >> /boot/orangepiEnv.txt
sed -e 's,rootfstype=.*,rootfstype='$FilesystemChoosen',g' -i /boot/orangepiEnv.txt
grep -q '^rootfstype' /boot/orangepiEnv.txt || echo "rootfstype=$FilesystemChoosen" >> /boot/orangepiEnv.txt
else
sed -e 's,setenv rootdev.*,setenv rootdev '"$satauuid"',' -i /boot/boot.cmd
sed -e 's,setenv rootdev.*,setenv rootdev '"$satauuid"',' -i /boot/boot.ini
sed -e 's,setenv rootfstype.*,setenv rootfstype '"$FilesystemChoosen"',' -i /boot/boot.cmd
sed -e 's,setenv rootfstype.*,setenv rootfstype '"$FilesystemChoosen"',' -i /boot/boot.ini
fi
[[ -f /boot/boot.cmd ]] && mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr >/dev/null 2>&1 || (echo 'Error while creating U-Boot loader image with mkimage' >&2 ; exit 7)
mkdir -p "${TempDir}"/rootfs/media/mmc/boot
echo "${sduuid} /media/mmcboot ext4 ${mountopts[ext4]}" >> "${TempDir}"/rootfs/etc/fstab
echo "/media/mmcboot/boot /boot none bind 0 0" >> "${TempDir}"/rootfs/etc/fstab
echo "$satauuid / $FilesystemChoosen ${mountopts[$FilesystemChoosen]}" >> "${TempDir}"/rootfs/etc/fstab
# recreate swap file if already existing (might be missing since zram only)
if [ -f /var/swap ]; then
fallocate -l 128M "${TempDir}"/rootfs/var/swap || dd if=/dev/zero of="${TempDir}"/rootfs/var/swap bs=1M count=128 status=noxfer
mkswap "${TempDir}"/rootfs/var/swap
fi
fi
# Boot from SPI, root = SATA / USB
#
if [[ $1 == *spi* ]]; then
sed -e 's,rootdev=.*,rootdev='"$satauuid"',g' -i "${TempDir}"/rootfs/boot/orangepiEnv.txt
echo "$satauuid / $FilesystemChoosen ${mountopts[$FilesystemChoosen]}" >> "${TempDir}"/rootfs/etc/fstab
fi
# recreate OMV mounts at destination if needed
grep -q ' /srv/' /etc/fstab
if [ $? -eq 0 -a -f /etc/default/openmediavault ]; then
echo -e '# >>> [openmediavault]' >> "${TempDir}"/rootfs/etc/fstab
grep ' /srv/' /etc/fstab | while read ; do
echo "${REPLY}" >> "${TempDir}"/rootfs/etc/fstab
mkdir -p -m700 "${TempDir}/rootfs$(awk -F" " '{print $2}' <<<"${REPLY}")"
done
echo -e '# <<< [openmediavault]' >> "${TempDir}"/rootfs/etc/fstab
fi
echo -e "\nChecking again for open files:" >> $logfile
lsof / | awk 'NR==1 || $4~/[0-9][uw]/' | grep -v "^COMMAND" >> $logfile
LANG=C echo -e "\n$(date): Finished\n\n" >> $logfile
cat $logfile > "${TempDir}"/rootfs${logfile}
sync
umount "${TempDir}"/rootfs
[[ $1 != "spi" ]] && umount "${TempDir}"/bootfs
} # create_orangepi
# Accept device as parameter: for example /dev/sda unmounts all their mounts
umount_device()
{
if [[ -n $1 ]]; then
device="$1";
for n in ${device}*; do
if [[ $device != "$n" ]]; then
if mount|grep -q "$n"; then
umount -l "$n" >/dev/null 2>&1
fi
fi
done
fi
} # umount_device
show_nand_warning()
{
local temp_rc=$(mktemp)
cat <<-'EOF' > $temp_rc
screen_color = (WHITE,RED,ON)
EOF
local warn_text="You are installing the system to sunxi NAND.
This is not recommended as NAND has \Z1worse performance
and reliability\Zn than a good SD card.
You have been warned."
DIALOGRC=$temp_rc dialog --title "NAND warning" --backtitle "$backtitle" --colors \
--ok-label "I understand and agree" --msgbox "$warn_text" 10 70
}
# formatting sunxi NAND - no parameters, fixed solution.
#
format_nand()
{
[[ ! -e /dev/nand ]] && echo '/dev/nand does not exist' >&2 && exit 8
show_nand_warning
dialog --title "$title" --backtitle "$backtitle" --infobox "\nFormating ... up to one minute." 5 40
if [[ $DEVICE_TYPE = a20 ]]; then
(echo y;) | sunxi-nand-part -f a20 /dev/nand 65536 'bootloader 65536' 'linux 0' >> $logfile 2>&1
else
(echo y;) | sunxi-nand-part -f a10 /dev/nand 65536 'bootloader 65536' 'linux 0' >> $logfile 2>&1
fi
mkfs.vfat /dev/nand1 >> $logfile 2>&1
mkfs.ext4 -qF /dev/nand2 >> $logfile 2>&1
}
# formatting eMMC [device] example /dev/mmcblk1 - one can select filesystem type
#
format_emmc()
{
# choose and create fs
IFS=" "
BTRFS=$(grep -o btrfs /proc/filesystems)
FilesystemTargets="1 ext4 2 ext3 3 ext2 4 f2fs"
[[ -n $BTRFS && ! `uname -r | grep '^3.' ` ]] && FilesystemTargets=$FilesystemTargets" 5 $BTRFS"
FilesystemOptions=($FilesystemTargets)
FilesystemCmd=(dialog --title "Select filesystem type for eMMC $1" --backtitle "$backtitle" --menu "\n$infos" 10 60 16)
FilesystemChoices=$("${FilesystemCmd[@]}" "${FilesystemOptions[@]}" 2>&1 >/dev/tty)
[[ $? -ne 0 ]] && exit 9
eMMCFilesystemChoosen=${FilesystemOptions[(2*$FilesystemChoices)-1]}
# deletes all partitions on eMMC drive
dd bs=1 seek=446 count=64 if=/dev/zero of="$1" >/dev/null 2>&1
# calculate capacity and reserve some unused space to ease cloning of the installation
# to other media 'of the same size' (one sector less and cloning will fail)
QUOTED_DEVICE=$(echo "$1" | sed 's:/:\\\/:g')
CAPACITY=$(parted "$1" unit s print -sm | awk -F":" "/^${QUOTED_DEVICE}/ {printf (\"%0d\", \$2 / ( 1024 / \$4 ))}")
if [[ $CAPACITY -lt 4000000 ]]; then
# Leave 2 percent unpartitioned when eMMC size is less than 4GB (unlikely)
LASTSECTOR=$(( 32 * $(parted "$1" unit s print -sm | awk -F":" "/^${QUOTED_DEVICE}/ {printf (\"%0d\", ( \$2 * 98 / 3200))}") -1 ))
else
# Leave 1 percent unpartitioned
LASTSECTOR=$(( 32 * $(parted "$1" unit s print -sm | awk -F":" "/^${QUOTED_DEVICE}/ {printf (\"%0d\", ( \$2 * 99 / 3200))}") -1 ))
fi
parted -s "$1" -- mklabel msdos
dialog --title "$title" --backtitle "$backtitle" --infobox "\nFormating $1 to $eMMCFilesystemChoosen ... please wait." 5 60
# we can't boot from btrfs or f2fs
if [[ $eMMCFilesystemChoosen =~ ^(btrfs|f2fs)$ ]]; then
local partedFsType="${eMMCFilesystemChoosen}"
if [[ $eMMCFilesystemChoosen == "f2fs" ]]; then
partedFsType=''
fi
# default boot partition size, in MiB
DEFAULT_BOOTSIZE=96
# (convert to sectors for partitioning)
DEFAULT_BOOTSIZE_SECTORS=$(((${DEFAULT_BOOTSIZE} * 1024 * 1024) / 512))
# check whether swap is currently defined and a new swap partition is needed
grep -q swap /etc/fstab
case $? in
0)
parted -s "$1" -- mkpart primary $partedFsType ${FIRSTSECTOR}s $(( ${FIRSTSECTOR} + ${DEFAULT_BOOTSIZE_SECTORS} - 1 ))s
parted -s "$1" -- mkpart primary $partedFsType $(( ${FIRSTSECTOR} + ${DEFAULT_BOOTSIZE_SECTORS} ))s $(( ${FIRSTSECTOR} + 393215 ))s
parted -s "$1" -- mkpart primary $partedFsType $(( ${FIRSTSECTOR} + 393216 ))s ${LASTSECTOR}s
partprobe "$1"
mkfs.ext4 ${mkopts[ext4]} "$1"'p1' >> $logfile 2>&1
mkswap "$1"'p2' >> $logfile 2>&1
mkfs.${eMMCFilesystemChoosen} "$1"'p3' ${mkopts[$eMMCFilesystemChoosen]} >> $logfile 2>&1
emmcbootuuid=$(blkid -o export "$1"'p1' | grep -w UUID)
emmcswapuuid=$(blkid -o export "$1"'p2' | grep -w UUID)
emmcuuid=$(blkid -o export "$1"'p3' | grep -w UUID)
dest_root=$emmccheck'p3'
;;
*)
parted -s "$1" -- mkpart primary $partedFsType ${FIRSTSECTOR}s $(( ${FIRSTSECTOR} + ${DEFAULT_BOOTSIZE_SECTORS} - 1 ))s
parted -s "$1" -- mkpart primary $partedFsType $(( ${FIRSTSECTOR} + ${DEFAULT_BOOTSIZE_SECTORS} ))s ${LASTSECTOR}s
partprobe "$1"
mkfs.ext4 ${mkopts[ext4]} "$1"'p1' >> $logfile 2>&1
mkfs.${eMMCFilesystemChoosen} "$1"'p2' ${mkopts[$eMMCFilesystemChoosen]} >> $logfile 2>&1
emmcbootuuid=$(blkid -o export "$1"'p1' | grep -w UUID)
emmcuuid=$(blkid -o export "$1"'p2' | grep -w UUID)
dest_root=$emmccheck'p2'
;;
esac
else
parted -s "$1" -- mkpart primary $eMMCFilesystemChoosen ${FIRSTSECTOR}s ${LASTSECTOR}s
partprobe "$1"
mkfs.${eMMCFilesystemChoosen} ${mkopts[$eMMCFilesystemChoosen]} "$1"'p1' >> $logfile 2>&1
emmcuuid=$(blkid -o export "$1"'p1' | grep -w UUID)
emmcbootuuid=$emmcuuid
fi
}
# formatting SATA/USB/NVMe partition, examples: /dev/sda3 or /dev/nvme0n1p1
#
format_disk()
{
# choose and create fs
IFS=" "
ROOTFSTYPE=$(lsblk -o MOUNTPOINT,FSTYPE | awk -F" " '/^\/\ / {print $2}')
case ${ROOTFSTYPE} in
btrfs)
FilesystemTargets='1 btrfs'
;;
*)
BTRFS=$(grep -o btrfs /proc/filesystems)
FilesystemTargets='1 ext4 2 ext3 3 ext2'
[[ -n $BTRFS && ! `uname -r | grep '^3.' ` && $choice != 6 ]] && FilesystemTargets=$FilesystemTargets" 4 $BTRFS"
;;
esac
FilesystemOptions=($FilesystemTargets)
FilesystemCmd=(dialog --title "Select filesystem type for $1" --backtitle "$backtitle" --menu "\n$infos" 10 60 16)
FilesystemChoices=$("${FilesystemCmd[@]}" "${FilesystemOptions[@]}" 2>&1 >/dev/tty)
[[ $? -ne 0 ]] && exit 10
FilesystemChoosen=${FilesystemOptions[(2*$FilesystemChoices)-1]}
dialog --title "$title" --backtitle "$backtitle" --infobox "\nFormating $1 to $FilesystemChoosen ... please wait." 5 60
mkfs.${FilesystemChoosen} ${mkopts[$FilesystemChoosen]} "$1" >> $logfile 2>&1
}
# choose target SATA/USB/NVMe partition.
check_partitions()
{
IFS=" "
AvailablePartitions=$(lsblk -l | awk -F" " '/ part | raid..? / {print $1}' | grep -E '^sd|^nvme|^md')
if [[ -z $AvailablePartitions ]]; then
dialog --title "$title" --backtitle "$backtitle" --colors --msgbox \
"\n\Z1There are no avaliable partitions. Please create them.\Zn" 7 60
# We need gdisk for proper partition alignment
apt-get -y -q install gdisk >/dev/null 2>&1
gdisk /dev/$diskcheck
fi
AvailablePartitions=$(lsblk -l | awk -F" " '/ part | raid..? / {print $1}' | grep -E '^sd|^nvme|^md' | uniq | sed 's|^|/dev/|' | nl | xargs echo -n)
PartitionOptions=($AvailablePartitions)
PartitionCmd=(dialog --title 'Select destination:' --backtitle "$backtitle" --menu "\n$infos" 10 60 16)
PartitionChoices=$("${PartitionCmd[@]}" "${PartitionOptions[@]}" 2>&1 >/dev/tty)
[[ $? -ne 0 ]] && exit 11
DISK_ROOT_PART=${PartitionOptions[(2*$PartitionChoices)-1]}
}
# build and update new bootscript
update_bootscript()
{
if [ -f /boot/boot.cmd.new ]; then
mv -f /boot/boot.cmd.new /boot/boot.cmd >/dev/null 2>&1
mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr >/dev/null 2>&1
elif [ -f /boot/boot.ini.new ]; then
mv -f /boot/boot.ini.new /boot/boot.ini >/dev/null 2>&1
rootdev=$(sed -e 's/^.*root=//' -e 's/ .*$//' < /proc/cmdline)
rootfstype=$(sed -e 's/^.*rootfstype=//' -e 's/ .*$//' < /proc/cmdline)
sed -i "s/setenv rootfstype.*/setenv rootfstype \"$rootfstype\"/" /boot/boot.ini
sed -i "s/setenv rootdev.*/setenv rootdev \"$rootdev\"/" /boot/boot.ini
fi
}
# show warning [TEXT]
show_warning()
{
dialog --title "$title" --backtitle "$backtitle" --cr-wrap --colors --yesno " \Z1$(toilet -W -f ascii9 WARNING)\Zn\n$1" 14 53
[[ $? -ne 0 ]] && exit 13
}
# try to stop running services
stop_running_services()
{
systemctl --state=running | awk -F" " '/.service/ {print $1}' | sort -r | \
grep -E -e "$1" | while read ; do
echo -e "\nStopping ${REPLY} \c"
systemctl stop ${REPLY} 2>&1
done
}
main()
{
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# This tool must run under root
if [[ $EUID -ne 0 ]]; then
echo 'This tool must run as root. Exiting ...' >&2
exit 14
fi
# Check if we run it from SD card
# TODO: Disable/remove this in the future
case ${root_partition_device} in
/dev/mmcblk*) # mmc device, we can continue
:
;;
*)
dialog --title "$title" --backtitle "$backtitle" --colors --infobox '\n\Z1This tool must run from SD-card! \Zn' 5 37
exit 15
;;
esac
[ -f $logfile ] && echo -e '\n\n\n' >> $logfile
LANG=C echo -e "$(date): Start ${0##*/}.\n" >> $logfile
IFS="'"
options=()
if [[ -n $emmccheck ]]; then
ichip='eMMC';
dest_boot=$emmccheck'p1'
dest_root=$emmccheck'p1'
else
ichip='NAND'
dest_boot='/dev/nand1'
dest_root='/dev/nand2'
fi
# Boot + RootFS relocation options
[[ -n $diskcheck ]] && options+=(1 'Boot from SD - system on SATA, USB or NVMe')
[[ -n $nandcheck || -n $emmccheck ]] && options+=(2 "Boot from $ichip - system on $ichip")
[[ ( -n $nandcheck || -n $emmccheck ) && -n $diskcheck ]] && options+=(3 "Boot from $ichip - system on SATA, USB or NVMe")
[[ -n $spicheck ]] && options+=(4 'Boot from SPI - system on SATA, USB or NVMe')
# U-boot install/update options
[[ -n ${root_partition_device} ]] && options+=(5 'Install/Update the bootloader on SD/eMMC')
[[ ( $LINUXFAMILY == odroidxu4 || $LINUXFAMILY == mvebu* || $LINUXFAMILY == mt7623 ) && ( -b /dev/mmcblk0boot0 || -b /dev/mmcblk1boot0 ) ]] && options+=(6 'Install/Update the bootloader on special eMMC partition')
[[ -n $spicheck && $(type -t write_uboot_platform_mtd) == function ]] && options+=(7 'Install/Update the bootloader on SPI Flash')
[[ ${#options[@]} -eq 0 || "$root_uuid" == "$emmcuuid" || "$root_uuid" == "/dev/nand2" ]] && \
dialog --ok-label 'Cancel' --title ' Warning ' --backtitle "$backtitle" --colors --no-collapse --msgbox '\n\Z1There are no targets. Please check your drives.\Zn' 7 52
cmd=(dialog --title 'Choose an option:' --backtitle "$backtitle" --menu "\nCurrent root: $root_uuid \n \n" 14 60 7)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
[[ $? -ne 0 ]] && exit 16
for choice in $choices
do
case $choice in
1)
title='MMC (SD/eMMC) boot | USB/SATA/NVMe root install'
command='Reboot'
check_partitions
show_warning "This script will erase your device $DISK_ROOT_PART. Continue?"
format_disk "$DISK_ROOT_PART"
create_orangepi "" "$DISK_ROOT_PART"
;;
2)
title="$ichip install"
command='Power off'
show_warning "This script will erase your $ichip. Continue?"
if [[ -n $emmccheck ]]; then
umount_device "$emmccheck"
format_emmc "$emmccheck"
else
umount_device '/dev/nand'
format_nand
fi
create_orangepi "$dest_boot" "$dest_root"
;;
3)
title="$ichip boot | USB/SATA/NVMe root install"
command='Power off'
check_partitions
show_warning "This script will erase your $ichip and $DISK_ROOT_PART. Continue?"
if [[ -n $emmccheck ]]; then
umount_device "$emmccheck"
format_emmc "$emmccheck"
else
umount_device '/dev/nand'
format_nand
fi
umount_device "${DISK_ROOT_PART//[0-9]*/}"
format_disk "$DISK_ROOT_PART"
create_orangepi "$dest_boot" "$DISK_ROOT_PART"
;;
4)
# Espressobin has flash boot by default
title='SPI flash boot | USB/SATA/NVMe root install'
command='Power off'
# we need to copy boot
sed -i '/boot/d' $EX_LIST
check_partitions
show_warning "This script will erase your device $DISK_ROOT_PART. Continue?"
format_disk "$DISK_ROOT_PART"
create_orangepi 'spi' "$DISK_ROOT_PART"
;;
5)
show_warning 'This script will update the bootloader on SD/eMMC. Continue?'
write_uboot_platform "$DIR" "${root_partition_device}"
update_bootscript
dialog --backtitle "$backtitle" --title 'Writing bootloader' --msgbox '\n Done.' 7 30
return
;;
6)
if [[ -b /dev/mmcblk0boot0 ]]; then
BOOTPART='/dev/mmcblk0'
elif [[ -b /dev/mmcblk1boot0 ]]; then
BOOTPART='/dev/mmcblk1'
fi
show_warning "This script will update the bootloader on $BOOTPART. Continue?"
write_uboot_platform "$DIR" $BOOTPART
echo 'Done'
return
;;
7)
MTD_BLK="/dev/${spicheck}"
show_warning "This script will update the bootloader on SPI Flash $MTD_BLK. Continue?"
write_uboot_platform_mtd "$DIR" $MTD_BLK
update_bootscript
echo 'Done'
return
;;
esac
done
dialog --title "$title" --backtitle "$backtitle" --yes-label "$command" --no-label 'Exit' --yesno "\nAll done. $command $REMOVESDTXT" 7 70
[[ $? -eq 0 ]] && "$(echo ${command,,} | sed 's/ //')"
} # main
main "$@"

View File

@@ -0,0 +1,101 @@
#!/bin/bash
# Copyright (c) 2017 The Armbian Project https://www.armbian.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.
if [[ ! -n $1 ]]; then
echo >&2 "Usage: $0 <overlay_source_file.dts>"
exit -1
fi
if [[ $EUID -ne 0 ]]; then
echo >&2 "This program must be run with superuser rights"
exit -1
fi
if [[ ! -f $1 ]]; then
echo >&2 "Can't open file $1. File does not exist?"
exit -1
fi
if [[ $1 == *.dts ]]; then
fname=$(basename $1 .dts)
else
echo >&2 "Overlay source file name should have the .dts extension"
exit -1
fi
if [[ ! -f /etc/orangepi-release || ! -f /boot/orangepiEnv.txt ]]; then
echo >&2 "Orange Pi is not installed properly. Missing orangepi-release or orangepiEnv.txt"
exit -1
fi
. /etc/orangepi-release
case "${LINUXFAMILY}" in
sunxi|sunxi64|rockchip64)
:;;
*)
echo >&2 "Overlays are not supported on ${LINUXFAMILY^} based boards."
exit -1
;;
esac
if [[ -d /lib/modules/$(uname -r)/build/scripts/dtc ]]; then
if [[ ! -x /lib/modules/$(uname -r)/build/scripts/dtc/dtc ]]; then
# Can't use distribution provided (i.e. Bionic) dtc yet
# https://git.kernel.org/pub/scm/utils/dtc/dtc.git/commit/livetree.c?id=bba26a5291c8343101e0296b0e478deb4c9b60b0
echo >&2 "Error: kernel headers are not installed properly"
echo >&2 "Can't find dtc that supports compiling overlays"
echo >&2 "Please install the headers package for kernel $(uname -r)"
exit -1
else
export PATH=/lib/modules/$(uname -r)/build/scripts/dtc/:$PATH
fi
fi
if ! type dtc > /dev/null ; then
echo "Error: dtc not found in PATH"
echo "Please try to install matching kernel headers"
exit -1
fi
if ! grep -q 'symbols' <(dtc --help) ; then
echo "Error: dtc does not support compiling overlays"
# echo "Please try to install matching kernel headers"
exit -1
fi
if [[ ! -d /boot/overlay-user ]]; then
mkdir -p /boot/overlay-user
fi
temp_dir=$(mktemp -d)
echo "Compiling the overlay"
dtc -@ -q -I dts -O dtb -o ${temp_dir}/${fname}.dtbo $1
if [[ $? -ne 0 ]]; then
echo >&2 "Error compiling the overlay"
exit -1
fi
echo "Copying the compiled overlay file to /boot/overlay-user/"
cp ${temp_dir}/${fname}.dtbo /boot/overlay-user/${fname}.dtbo
if grep -q '^user_overlays=' /boot/orangepiEnv.txt; then
line=$(grep '^user_overlays=' /boot/orangepiEnv.txt | cut -d'=' -f2)
if grep -qE "(^|[[:space:]])${fname}([[:space:]]|$)" <<< $line; then
echo "Overlay ${fname} was already added to /boot/orangepiEnv.txt, skipping"
else
sed -i -e "/^user_overlays=/ s/$/ ${fname}/" /boot/orangepiEnv.txt
fi
else
sed -i -e "\$auser_overlays=${fname}" /boot/orangepiEnv.txt
fi
echo "Reboot is required to apply the changes"

View File

@@ -0,0 +1,6 @@
[Allow setting brightness]
Identity=unix-group:sudo
Action=org.xfce.power.backlight-helper
ResultAny=yes
ResultInactive=yes
ResultActive=yes

View File

@@ -0,0 +1,6 @@
[nm-applet]
Identity=unix-group:netdev;unix-group:sudo
Action=org.freedesktop.NetworkManager.*
ResultAny=yes
ResultInactive=no
ResultActive=yes

View File

@@ -0,0 +1,6 @@
[Allow Automount]
Identity=unix-group:plugdev
Action=org.freedesktop.udisks2.filesystem-mount;org.freedesktop.udisks2.filesystem-mount-system;org.freedesktop.udisks2.filesystem-mount-other-seat;org.freedesktop.udisks2.filesystem-unmount-others;org.freedesktop.udisks2.eject-media;org.freedesktop.udisks2.eject-media-system;org.freedesktop.udisks2.power-off-drive*
ResultAny=yes
ResultInactive=yes
ResultActive=yes

View File

@@ -0,0 +1,6 @@
[Allow Desktopstuff]
Identity=unix-group:sudo
Action=org.freedesktop.login1.reboot;org.freedesktop.login1.reboot-multiple-session;org.freedesktop.login1.power-off;org.freedesktop.login1.power-off-multiple-sessions;org.freedesktop.login1.suspend;org.freedesktop.login1.suspend-multiple-sessions;org.freedesktop.login1.hibernate;org.freedesktop.login1.hibernate-multiple-sessions
ResultAny=yes
ResultInactive=yes
ResultActive=yes

View File

@@ -0,0 +1,6 @@
[printing]
Identity=unix-group:netdev;unix-group:sudo
Action=org.opensuse.cupspkhelper.mechanism.*
ResultAny=yes
ResultInactive=no
ResultActive=yes

524
external/packages/bsp/h3consumption vendored Normal file
View File

@@ -0,0 +1,524 @@
#!/bin/bash
#
# h3consumption
#
# This tool patches fex/script.bin, adds commands to /etc/rc.local and
# adjusts /etc/defaults/cpufrequtils to control board consumption. Works
# only with H3 devices running legacy kernel.
#
#############################################################################
#
# Background information:
#
# By controlling a few settings energy consumption of H3 boards can be
# influenced:
#
# - disabling GPU/HDMI on headless devices: 210 mW less idle consumption
# (memory bandwidth also increases so performance will slightly improve)
#
# - negotiate only Fast Ethernet on GbE devices: 370 mW less idle consumption
#
# - switch off Ethernet on Fast Ethernet devices: 200 mW less idle consumption
#
# - limit max cpufreq: does not affect idle consumption but peak/full load
# (using 912 mhz on NanoPi M1/NEO or Orange Pi One/Lite will prevent VDD_CPU
# switching to the higher voltage and therfore greatly reduce consumption
# with only a slight decrease in maximum performance)
#
# - limit count of active cpu cores: low impact on idle consumption, high on
# peak/full load consumption
#
# - lower DRAM clockspeed to 408 MHz: 150 mW less idle consumption
#
# - disabling all USB ports (it's only 'all or nothing'): 125 mW less idle
#
# Please be aware that WiFi might add significantly to consumption. Since there
# are too many possible configurations (USB WiFi dongles also considered and
# possibilities to tweak power management settings with individual WiFi chips)
# h3consumption does not adjust WiFi settings -- only the -p switch lists
# configured WiFi devices.
#
# In case you don't need WiFi on the H3 boards with onboard WiFi adjust
# /etc/modules and comment the WiFi module out (8189es, 8189fs or bcmdhd).
# Please keep also in mind that you can control networking consumption also
# on a 'on demand' basis. In case you use a H3 board as data logger and need
# WiFi only for a short time every 24 hours, disabling WiFi and only enabling
# it for data transfers will save you between 300 and 1000 mW with 8189FTV as
# used on Orange Pi Lite, PC Plus or Plus 2E for example:
#
# ifconfig wlan0 down && rmmod -f 8189fs / modprobe 8189fs && sleep 0.5 && ifconfig wlan0 up
#
# Same with the Gigabit Ethernet equipped H3 boards: switching there to Fast
# Ethernet when no high speed transfers are needed saves a whopping 370 mW
# (and the same will happen on the switch's side if a more modern Gbit switch
# is in use):
#
# ethtool -s eth0 speed 100 duplex full / ethtool -s eth0 speed 1000 duplex full
#
# More information (and discussion in case questions arise!) in Armbian forum:
# http://forum.armbian.com/index.php/topic/1614-running-h3-boards-with-minimal-consumption/
# http://forum.armbian.com/index.php/topic/1748-sbc-consumptionperformance-comparisons/
# http://forum.armbian.com/index.php/topic/1823-opi-pc-wireless-not-powering-off/
#
#############################################################################
#
# CHANGES:
#
# v0.1: Initial release
#
#############################################################################
#
# TODO:
#
# - Write documentation as nicely as it's done for h3disp
# - Allow higher DRAM clock in fex file than set from /etc/rc.local
# - Add revert mode, relinking original fex/bin and restore all original
# settings
#
#############################################################################
Main() {
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ensure script is running as root
if [ "$(id -u)" != "0" ]; then
echo "This script must be executed as root. Exiting" >&2
exit 1
fi
# check installation
CheckInstallation
if [ $# -eq 0 ]; then
DisplayUsage ; exit 0
else
FexSettings="$(mktemp /tmp/${0##*/}.XXXXXX)"
RCLocalContents="$(mktemp /tmp/${0##*/}.XXXXXX)"
ReadSettings
ParseOptions "$@"
ChangeSettings
FinalizeSettings
fi
echo -e "Settings changed. Please reboot for changes to take effect\nand verify settings after the reboot using \"${0##*/} -p\""
# Let's see whether we have to collect debug output
case ${Debug} in
TRUE)
which curl >/dev/null 2>&1 || apt-get -f -qq -y install curl
echo -e "\nDebug output has been collected at the following URL: \c"
(cat "${DebugOutput}"; echo -e "\n\n\nfex contents:\n" ; cat "${MyTmpFile}") \
| curl -F 'sprunge=<-' http://sprunge.us
;;
esac
} # Main
CheckInstallation() {
# check if tool can rely on Orange Pi environment
if [ ! -f /etc/orangepi.txt ]; then
echo -e "Error. This tool requires an Orange Pi installation. Exiting." >&2
exit 1
fi
# check platform and kernel
case $(uname -r) in
3.4.*)
HARDWARE=$(awk '/Hardware/ {print $3}' </proc/cpuinfo)
if [ "X${HARDWARE}" != "Xsun8i" ]; then
echo "This tool works only on H3 devices. Exiting." >&2
exit 1
fi
;;
*)
echo "This tool requires legacy kernel on H3 devices. Exiting." >&2
exit 1
;;
esac
# ensure ethtool is installed
which ethtool >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo -e "\nPlease be patient, external requirements are to be installed.\n"
apt-get -f -qq -y install ethtool >/dev/null 2>&1
fi
} # CheckInstallation
ParseOptions() {
while getopts 'hHvVpPe:E:m:M:c:C:d:D:u:U:g:G:w:W:' c ; do
case ${c} in
H)
export FullUsage=TRUE
DisplayUsage
exit 0
;;
h)
DisplayUsage
exit 0
;;
v|V)
# Increase verbosity. Will try to upload debug output from script
# to ease reporting of bugs or strange behaviour. Use only when
# asked for.
export Debug=TRUE
DebugOutput="$(mktemp /tmp/${0##*/}.XXXXXX)"
trap "rm \"${DebugOutput}\" ; exit 0" 0 1 2 3 15
set -x
exec 2>"${DebugOutput}"
;;
e|E)
# Ethernet: either none, fast or gbit
Ethernet=$(echo -n ${OPTARG} | tr '[:upper:]' '[:lower:]')
;;
g|G)
# GPU/HDMI: either on or off
GPUHDMI=$(echo -n ${OPTARG} | tr '[:upper:]' '[:lower:]')
;;
m|M)
# maximum allowed cpu clockspeed
MaxClockspeed=$(echo -n ${OPTARG} | tr -d -c '[:digit:]')
;;
c|C)
# count of cpu cores: 1 - 4
CPUCores=$(echo -n ${OPTARG} | tr -d -c '[:digit:]')
;;
d)
# dram clockspeed: 408 - 624 mhz
DRAMLowerLimit=408
DramClockspeed=$(echo -n ${OPTARG} | tr -d -c '[:digit:]')
;;
D)
# dram clockspeed: 132 - 624 mhz
DRAMLowerLimit=132
DramClockspeed=$(echo -n ${OPTARG} | tr -d -c '[:digit:]')
;;
u|U)
# All USB ports on or off
USBUsed=$(echo -n ${OPTARG} | tr '[:upper:]' '[:lower:]')
;;
p|P)
# print active settings
PrintActiveSettings
exit 0
;;
w|W)
# Wi-Fi powermanagement
WiFi=$(echo -n ${OPTARG} | tr '[:upper:]' '[:lower:]')
;;
esac
done
} # ParseOptions
ChangeSettings() {
# Ethernet
case ${Ethernet} in
"")
: ;;
fast)
echo 'ethtool -s eth0 speed 100 duplex full' >>"${RCLocalContents}"
;;
on)
BOARD=$(awk -F"=" '/^BOARD=/ {print $2}' </etc/orangepi-release)
if [ "X${BOARD}" = "X" ]; then
echo "Orange Pi installation too old, please apt-get upgrade before. Exiting." >&2
exit 1
else
OrigSettings=$(bin2fex /boot/bin/${BOARD}.bin 2>/dev/null | awk -F" " '/^gmac_used/ {print $3}')
sed -i -e "s/^gmac_used\ =\ 0/gmac_used = ${OrigSettings}/g" "${FexSettings}"
fi
;;
off)
sed -i -e 's/^gmac_used\ =\ \(.*\)/gmac_used = 0/g' "${FexSettings}"
;;
*)
echo "Parameter error: -e requires either on, fast or off. Exiting" >&2
exit 1
;;
esac
# Wi-Fi powermanagement
case ${WiFi} in
"")
: ;;
on)
rm -f /etc/NetworkManager/dispatcher.d/99enable-power-management \
/etc/NetworkManager/dispatcher.d/99disable-power-management \
/etc/NetworkManager/conf.d/zz-override-wifi-powersave-off.conf
;;
off)
rm -f /etc/NetworkManager/dispatcher.d/99enable-power-management \
/etc/NetworkManager/dispatcher.d/99disable-power-management \
/etc/NetworkManager/conf.d/zz-override-wifi-powersave-off.conf
echo "Note: This action applies only to NetworkManager based connections"
case "$(lsb_release -sc)" in
jessie)
mkdir -p /etc/NetworkManager/dispatcher.d/
cat <<-'EOF' > /etc/NetworkManager/dispatcher.d/99disable-power-management
#!/bin/sh
case "$2" in
up) /sbin/iwconfig $1 power off || true ;;
down) /sbin/iwconfig $1 power on || true ;;
esac
EOF
chmod 755 /etc/NetworkManager/dispatcher.d/99disable-power-management
;;
xenial)
mkdir -p /etc/NetworkManager/conf.d/
cat <<-EOF > /etc/NetworkManager/conf.d/zz-override-wifi-powersave-off.conf
[connection]
wifi.powersave = 2
EOF
;;
*)
echo "This action is supported only in Jessie and Xenial based releases. Exiting" >&2
exit 1
;;
esac
;;
*)
echo "Parameter error: -w requires either on or off. Exiting" >&2
exit 1
;;
esac
# Maximum cpu clock in mhz
case ${MaxClockspeed} in
"")
: ;;
*)
HardwareUpperLimit=$(awk -F" " '/^max_freq = / {print $3 / 1000000}' <"${FexSettings}")
HardwareLowerLimit=$(awk -F" " '/^min_freq = / {print $3 / 1000000}' <"${FexSettings}")
if [ ${MaxClockspeed} -lt ${HardwareLowerLimit} ]; then
# adjust to lowest allowed clockspeed
sed -i "s/MAX_SPEED=\(.*\)/MAX_SPEED=${HardwareLowerLimit}000/" /etc/default/cpufrequtils
elif [ ${MaxClockspeed} -gt ${HardwareUpperLimit} ]; then
# adjust to highest allowed clockspeed
sed -i "s/MAX_SPEED=\(.*\)/MAX_SPEED=${HardwareUpperLimit}000/" /etc/default/cpufrequtils
else
# check cpufreq since not every value is possible
for i in $(awk -F" " '{print $1}' </sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state | sed 's/000$//') ; do
if [ $i -ge ${MaxClockspeed} ]; then
sed -i "s/MAX_SPEED=\(.*\)/MAX_SPEED=${i}000/" /etc/default/cpufrequtils
break
fi
done
fi
;;
esac
# dram clockspeed in mhz
case ${DramClockspeed} in
"")
: ;;
*)
BOARD=$(awk -F"=" '/^BOARD=/ {print $2}' </etc/orangepi-release)
case ${BOARD} in
nanopineo|nanopiair)
HardwareUpperLimit=432
;;
*)
HardwareUpperLimit=624
;;
esac
if [ ${DramClockspeed} -lt ${DRAMLowerLimit} ]; then
# adjust to lowest allowed clockspeed
DramClockspeed=${DRAMLowerLimit}
elif [ ${DramClockspeed} -gt ${HardwareUpperLimit} ]; then
# adjust to highest allowed clockspeed
DramClockspeed=${HardwareUpperLimit}
else
# round dramfreq since not every value is possible: between 132 and 384 mhz
# 12 mhz steps are possible, above 24 mhz steps
if [ ${DramClockspeed} -le 384 ]; then
RoundedValue=$(( ${DramClockspeed} / 12 ))
DramClockspeed=$(( ${RoundedValue} * 12 ))
else
RoundedValue=$(( ${DramClockspeed} / 24 ))
DramClockspeed=$(( ${RoundedValue} * 24 ))
fi
fi
echo "echo ${DramClockspeed}000 >/sys/devices/platform/sunxi-ddrfreq/devfreq/sunxi-ddrfreq/userspace/set_freq" \
>>"${RCLocalContents}"
sed -i "s/dram_clk\ =\ \(.*\)/dram_clk = ${DramClockspeed}/" "${FexSettings}"
;;
esac
# Active CPU cores
case ${CPUCores} in
""|4)
# enable corekeeper
sed -i -e 's/^corekeeper_enabled\ =\ 0/corekeeper_enabled = 1/g' "${FexSettings}"
echo "# All CPU cores active" >>"${RCLocalContents}"
;;
3)
# disable corekeeper and 1 core in /etc/rc.local
sed -i -e 's/^corekeeper_enabled\ =\ 1/corekeeper_enabled = 0/g' "${FexSettings}"
echo "echo 0 >/sys/devices/system/cpu/cpu\3/online" >>"${RCLocalContents}"
;;
2)
# disable corekeeper and 2 cores in /etc/rc.local
sed -i -e 's/^corekeeper_enabled\ =\ 1/corekeeper_enabled = 0/g' "${FexSettings}"
echo "for i in 3 2; do echo 0 >/sys/devices/system/cpu/cpu\${i}/online; done" >>"${RCLocalContents}"
;;
1)
# disable corekeeper and 3 cores in /etc/rc.local
sed -i -e 's/^corekeeper_enabled\ =\ 1/corekeeper_enabled = 0/g' "${FexSettings}"
echo "for i in 3 2 1; do echo 0 >/sys/devices/system/cpu/cpu\${i}/online; done" >>"${RCLocalContents}"
;;
*)
echo "Parameter error: -c requires 1, 2, 3 or 4. Exiting" >&2
exit 1
;;
esac
# GPU/HDMI
case ${GPUHDMI} in
"")
: ;;
on)
sed -i -e 's/^hdmi_used\ =\ 0/hdmi_used = 1/' \
-e 's/^mali_used\ =\ 0/mali_used = 1/' \
-e 's/^disp_init_enable\ =\ 0/disp_init_enable = 1/' "${FexSettings}"
;;
off)
sed -i -e 's/^hdmi_used\ =\ 1/hdmi_used = 0/' \
-e 's/^mali_used\ =\ 1/mali_used = 0/' \
-e 's/^disp_init_enable\ =\ 1/disp_init_enable = 0/' "${FexSettings}"
;;
*)
echo "Parameter error: -g requires either on or off. Exiting" >&2
exit 1
;;
esac
# USB
case ${USBUsed} in
"")
: ;;
on)
sed -i -e 's/^usb_used\ =\ 0/usb_used = 1/g' "${FexSettings}"
;;
off)
sed -i -e 's/^usb_used\ =\ 1/usb_used = 0/g' "${FexSettings}"
;;
*)
echo "Parameter error: -u requires either on or off. Exiting" >&2
exit 1
;;
esac
} # ChangeSettings
PrintActiveSettings() {
# function that prints the active consumption relevant settings
# cpu settings
echo -e "Active settings:\n"
HardwareLimit=$(awk -F" " '/^max_freq = / {print $3 / 1000000}' <"${FexSettings}")
SoftwareLimit=$(awk -F"=" '/^MAX_SPEED/ {print $2 / 1000}' </etc/default/cpufrequtils)
CountOfActiveCores=$(grep -c '^processor' /proc/cpuinfo)
echo -e "cpu ${SoftwareLimit} mhz allowed, ${HardwareLimit} mhz possible, ${CountOfActiveCores} cores active\n"
# dram settings
echo -e "dram $(sed 's/000$//' </sys/devices/platform/sunxi-ddrfreq/devfreq/sunxi-ddrfreq/cur_freq) mhz\n"
# display active or headless mode
echo -e "hdmi/gpu $(awk -F" " '/^hdmi_used/ {print $3}' <"${FexSettings}" | head -n 1 | sed -e 's/1/active/' -e 's/0/off/')\n"
# USB ports active or disabled
echo -e "usb ports $(awk -F" " '/^usb_used/ {print $3}' <"${FexSettings}" | head -n 1 | sed -e 's/1/active/' -e 's/0/off/')\n"
# network
ethtool eth0 >/dev/null 2>&1 && echo -e "eth0 $(ethtool eth0 | egrep "Speed|Link d|Duplex" | tr "\n" " " | awk '{print $2"/"$4", Link: "$7}')\n"
ListOfWiFis=$(iwconfig 2>&1 | egrep -v "lo|tunl0|eth0" | grep -v "^ " | awk -F" " '{print $1}')
for i in ${ListOfWiFis} ; do
iwconfig $i
done
} # PrintActiveSettings
DisplayUsage() {
# check if stdout is a terminal...
if test -t 1; then
# see if it supports colors...
ncolors=$(tput colors)
if test -n "$ncolors" && test $ncolors -ge 8; then
BOLD="$(tput bold)"
NC='\033[0m' # No Color
LGREEN='\033[1;32m'
fi
fi
echo -e "Usage: ${BOLD}${0##*/} [-h/-H] [-p] [-g on|off] [-m max_cpufreq] [-c 1|2|3|4]\n [-d dram_freq] [-D dram_freq] [-u on|off] [-e on|off|fast] ${NC}\n"
echo -e "############################################################################"
if [ ${FullUsage} ]; then
echo -e "\nDetailed Description:"
grep "^#" "$0" | grep -v "^#\!/bin/bash" | sed 's/^#//'
fi
echo -e "\n This tool allows to adjust a few consumption relevant settings of your\n H3 device. Use the following switches\n"
echo -e " ${BOLD}-h|-H${NC} displays help or verbose help text"
echo -e " ${BOLD}-p${NC} print currently active settings"
echo -e " ${BOLD}-g on|off${NC} disables GPU/HDMI for headless use"
echo -e " ${BOLD}-m max_cpufreq${NC} adjusts maximum allowed cpu clockspeed (mhz)"
echo -e " ${BOLD}-c 1|2|3|4${NC} activate only this count of CPU cores"
echo -e " ${BOLD}-d dram_freq${NC} adjusts dram clockspeed (408 - 624 mhz)"
echo -e " ${BOLD}-D dram_freq${NC} like -d but as low as 132 mhz possible (experimental!)"
echo -e " ${BOLD}-u on|off${NC} enables/disabled all USB ports"
echo -e " ${BOLD}-e on|off|fast${NC} enables/disables Ethernet, the fast switch\n forces 100 mbits/sec negotiation on gigabit devices"
echo -e " ${BOLD}-w on|off${NC} enables/disables Wi-Fi powermanagement when interface\n supports this and is controlled by network-manager\n"
echo -e "############################################################################\n"
} # DisplayUsage
ReadSettings() {
# This function parses script.bin and install needed tools if necessary
# check whether we've the necessary tools available
Fex2Bin="$(which fex2bin)"
if [ "X${Fex2Bin}" = "X" ]; then
apt-get -f -qq -y install sunxi-tools >/dev/null 2>&1 || InstallSunxiTools >/dev/null 2>&1
fi
which fex2bin >/dev/null 2>&1 || (echo -e "Aborted\nfex2bin/bin2fex not found and unable to install. Exiting" >&2 ; exit 1)
# convert script.bin to temporary fex file
bin2fex /boot/script.bin "${FexSettings}" >/dev/null 2>&1
} # ReadSettings
FinalizeSettings() {
# convert modified fex file back to script.bin, modify /etc/rc.local
# create copy and backup to be able to recover from failed conversion
cd /boot
if [ -L script.bin ]; then
Original="$(readlink -f script.bin)" && (rm script.bin ; cp -p "${Original}" script.bin)
fi
cp -p script.bin script.bin.bak
fex2bin "${FexSettings}" /boot/script.bin 2>/dev/null
if [ $? -ne 0 ]; then
mv /boot/script.bin.bak /boot/script.bin
echo -e "Aborted\nWriting script.bin went wrong. Nothing changed." >&2
logger "Writing script.bin went wrong. Nothing changed"
exit 1
fi
if [ -s "${RCLocalContents}" ];then
# Adjust /etc/rc.local contents if necessary, first create clean file without h3consumption
# additions
egrep -v "exit\s*0|h3consumption|sun8i-corekeeper" /etc/rc.local | sed '/^\s*$/d' >"${FexSettings}"
echo -e "\n### do NOT edit the following lines, always use h3consumption instead ###" >>"${FexSettings}"
cat "${RCLocalContents}" | while read ; do
echo -e "${REPLY} # h3consumption" >>"${FexSettings}"
done
echo -e "\nexit 0" >>"${FexSettings}"
cat "${FexSettings}" >/etc/rc.local
rm "${RCLocalContents}"
fi
rm "${FexSettings}"
} # FinalizeSettings
InstallSunxiTools() {
sleep 1
apt-get -f -qq -y install libusb-1.0-0-dev || (echo -e "Aborted\nNot possible to install a sunxi-tools requirement" ; exit 1)
cd /tmp
git clone https://github.com/linux-sunxi/sunxi-tools
cd sunxi-tools
make
make install
} # InstallSunxiTools
Main "$@"

491
external/packages/bsp/h3disp vendored Executable file
View File

@@ -0,0 +1,491 @@
#!/bin/bash
#
# h3disp
#
# Patches fex/script.bin settings to modify display settings. Currently
# rather limited and only supporting HDMI and the available presets.
#
#############################################################################
#
# Background informations:
#
# Only a certain amount of predefined video modes is available on H3 devices
# as can be seen here: http://linux-sunxi.org/Fex_Guide#disp_init_configuration
#
# Purpose of this script is to display the available reasonable settings and
# let the user choose from them to adjust fex file accordingly afterwards.
# In the meantime it's also possible to specify available resolutions on the
# command line. To display possible values use the -h switch.
#
# If HDMI-to-DVI adapters are used another fix has to be applied to the fex
# file: http://linux-sunxi.org/Orange_Pi_One#HDMI_to_DVI_converters -- so ask
# user whether he plans to use such an adapter and adjust fex file accordingly
#
#############################################################################
#
# CHANGES:
#
# v0.6: Added frame buffer config (fb[0-1]_format, fb[0-1]_width, fb[0-1]_height)
#
# v0.5: Added bare modes display (-i)
#
# v0.4: Added new modes in a combination with kernel patch, but they refuse to work.
# Additional work is needed for all modes larger than 10
#
# v0.3: Added the ability to set the colour-range HDMI-output and spruced the
# output of h3disp in general with a splash of colour. Also, don't spit
# out so much text by default.
#
# v0.2: Added non-interactive mode. You can provide one or two arguments on
# the command line, eg. 'h3disp -m 1080p60 -d' (1920x1080@60Hz DVI) or
# 'h3disp -m 720i' (1280x720@30Hz HDMI). Complete list of modes via
# 'h3disp -h'
#
# v0.1: Initial release to adjust display settings in script.bin on commonly
# used Debian based OS images for H3 devices running Linux.
#
#############################################################################
#
# TODO:
#
# - implement real user interaction: dialog that asks which of the available
# HDMI modes to choose and whether a HDMI-to-DVI converter is used or not
#
# - maybe implement live resolution switching as outlined by Jernej:
# http://forum.armbian.com/index.php/topic/617-wip-orange-pi-one-support-for-the-upcoming-orange-pi-one/?p=5305
# (we would also need a working set of fbset modes in /etc/fb.modes
# of course)
#
# - maybe add the chosen mode to /boot/boot.cmd and create /boot/boot.scr
# afterwards?
#
#############################################################################
Main() {
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ensure script is running as root
if [ "$(id -u)" != "0" ]; then
echo "This script must be executed as root. Exiting" >&2
exit 1
fi
# check for supported boards
/bin/bash -n /etc/orangepi-release && . /etc/orangepi-release
if [ "X${LINUXFAMILY}" = "Xsun8i" -a "X${BRANCH}" = "Xdefault" -a "X${BOARD}" != "Xorangepizero" ]; then
# Supported board/kernel combination so proceed
:
else
echo "Unsupported board/kernel combination: ${BOARD_NAME} running $(uname -a | cut -f3 -d' '). Exiting" >&2
exit 1
fi
# interactive mode if no arguments are provided -- currently not implemented
# otherwise we try to parse the command line arguments and use these
if [ $# -eq 0 ]; then
DisplayUsage ; exit 0
# Provide a list with possible HDMI display settings and store the chosen
# one in the HDMIMode variable
:
# ask the user whether he uses a HDMI-to-DVI converter and if true then
# set DVIUsed=TRUE
:
else
ParseOptions "$@"
if [ -v ColourRange ]; then
re='^[0-9]+$'
if ! [[ ${ColourRange} =~ ${re} ]] ; then
echo "$0: Invalid colour-range specified, only values 0-2 are supported for now!"
exit 1
fi
if [[ ${ColourRange} -lt 0 || ${ColourRange} -gt 2 ]] ; then
echo "$0: Invalid colour-range specified, only values 0-2 are supported for now!"
exit 1
fi
fi
if [ -v FrameBuffer ]; then
re='^(0|4|5|6|7|8|9|10|12):[0-9]{1,4}:[0-9]{1,4}$'
if ! [[ ${FrameBuffer} =~ ${re} ]] ; then
echo "$0: Invalid frame buffer config data. use -h option to help."
exit 1
fi
fi
case ${VideoMode} in
0|480i) # res
HDMIMode=0
pll_video=54
;;
1|576i) # res
HDMIMode=1
pll_video=54
;;
2|480p) # res
HDMIMode=2
pll_video=108
;;
3|576p) # res
HDMIMode=3
pll_video=108
;;
4|720p50|1280x720p50) # res
HDMIMode=4
pll_video=297
;;
5|720p60|720p|1280x720p60) # res
HDMIMode=5
pll_video=297
;;
6|1080i50|1920x1080i50) # res
HDMIMode=6
pll_video=297
;;
7|1080i60|1080i|1920x1080i60) # res
HDMIMode=7
pll_video=297
;;
8|1080p24|1920x1080p24) # res
HDMIMode=8
pll_video=297
;;
9|1080p50|1920x1080p50) # res
HDMIMode=9
pll_video=297
;;
10|1080p60|1080p|1920x1080p60) # res
HDMIMode=10
pll_video=297
;;
11|1080p25|1080p|1920x1080p25) # res
HDMIMode=11
pll_video=297
;;
12|1080p30|1080p|1920x1080p30) # res
HDMIMode=12
pll_video=297
;;
13|1080p24_3d|1920x1080p24_3d) # res
HDMIMode=13
pll_video=594
;;
14|720p50_3d|1280x720p50_3d) # res
HDMIMode=14
pll_video=594
;;
15|720p60_3d|1280x720p60_3d) # res
HDMIMode=15
pll_video=594
;;
23|1080p24_3d|1920x1080p24_3d) # res
HDMIMode=23
pll_video=594
;;
24|720p50_3d|1280x720p50_3d) # res
HDMIMode=24
pll_video=594
;;
25|720p60_3d|1280x720p60_3d) # res
HDMIMode=25
pll_video=594
;;
26|1080p25|1080p|1920x1080p25) # res
HDMIMode=26
pll_video=297
;;
27|1080p30|1080p|1920x1080p30) # res
HDMIMode=27
pll_video=297
;;
28|4kp30|3840x2160P30) # res
HDMIMode=28
pll_video=297
;;
29|4kp25|3840x2160P25) # res
HDMIMode=29
pll_video=297
;;
31|800x480) # res
HDMIMode=31
pll_video=594
;;
32|1024x768) # res
HDMIMode=32
pll_video=260
;;
33|1280x1024) # res
HDMIMode=33
pll_video=432
;;
34|1360x768) # res
HDMIMode=34
pll_video=342
;;
35|1440x900) # res
HDMIMode=35
pll_video=432
;;
36|1680x1050) # res
HDMIMode=36
pll_video=294
;;
37|2048x1536) # res
HDMIMode=37
pll_video=688
;;
*)
if [ ${VideoMode} ]; then
echo -e "$0: missing video mode. Try one of the following:\n"
else
echo -e "$0: illegal video mode \"-m ${VideoMode}\". Try one of the following:\n"
fi
ShowVideoModes
exit 0
;;
esac
fi
echo -e "Now trying to patch script.bin with your settings. \c"
PatchScriptBin "${HDMIMode}" "${DVIUsed:-FALSE}" "${pll_video}"
echo "Successfully finished. Please reboot for changes to take effect"
# Let's see whether we have to collect debug output
case ${Debug} in
TRUE)
which curl >/dev/null 2>&1 || apt-get -f -qq -y install curl
echo -e "\nDebug output has been collected at the following URL: \c"
(cat "${DebugOutput}"; echo -e "\n\n\nfex contents:\n" ; cat "${MyTmpFile}") \
| curl -F 'sprunge=<-' http://sprunge.us
;;
esac
} # Main
ParseOptions() {
while getopts 'hHvVdDm:M:c:C:i:f:F' c ; do
case ${c} in
H)
export FullUsage=TRUE
DisplayUsage
exit 0
;;
h)
DisplayUsage
exit 0
;;
i)
ShowVideoModes "clean"
exit 0
;;
v|V)
# Increase verbosity. Will try to upload debug output from script
# to ease reporting of bugs or strange behaviour. Use only when
# asked for.
export Debug=TRUE
DebugOutput="$(mktemp /tmp/${0##*/}.XXXXXX)"
trap "rm \"${DebugOutput}\" ; exit 0" 0 1 2 3 15
set -x
exec 2>"${DebugOutput}"
;;
d|D)
# use HDMI-to-DVI converter
export DVIUsed=TRUE
;;
m|M)
# The HDMI mode in question
export VideoMode=${OPTARG}
;;
c|C)
# The colour-range in question
export ColourRange=${OPTARG}
;;
f|F)
# Set frame buffer config
export FrameBuffer=${OPTARG}
;;
esac
done
} # ParseOptions
DisplayUsage() {
# check if stdout is a terminal...
if test -t 1; then
# see if it supports colors...
ncolors=$(tput colors)
if test -n "$ncolors" && test $ncolors -ge 8; then
BOLD="$(tput bold)"
NC='\033[0m' # No Color
LGREEN='\033[1;32m'
fi
fi
echo -e "Usage: ${BOLD}${0##*/} [-h/-H] -m [video mode] [-d] [-c [0-2]] [-f [fb_mode:fb_width:fb_height]]${NC}\n"
echo -e "############################################################################"
if [ ${FullUsage} ]; then
echo -e "\nDetailed Description:"
grep "^#" "$0" | grep -v "^#\!/bin/bash" | sed 's/^#//'
fi
echo -e "\n This is a tool to set the display resolution of your Orange"
echo -e " Pi by patching script.bin.\n\n In case you use an HDMI-to-DVI converter\c"
echo -e " please use the ${LGREEN}-d${NC} switch.\n\n The resolution can be set using the ${LGREEN}-m${NC} switch.\c"
echo -e " The following resolutions\n are currently supported:\n"
ShowVideoModes
echo -e " You can also specify the colour-range for your HDMI-display with the ${LGREEN}-c${NC} switch."
echo -e "\n The following values for ${LGREEN}-c${NC} are currently supported:\n"
echo -e " ${BOLD}0${NC} -- RGB range 16-255 (Default, use \"${LGREEN}-c 0${NC}\")"
echo -e " ${BOLD}1${NC} -- RGB range 0-255 (Full range, use \"${LGREEN}-c 1${NC}\")"
echo -e " ${BOLD}2${NC} -- RGB range 16-235 (Limited video, \"${LGREEN}-c 2${NC}\")\n"
echo -e "To change frame buffer config use ${LGREEN}-f${NC} option and data in format ${BOLD}fb_mode:fb_width:fb_height${NC} where:"
echo -e " ${BOLD}fb_mode${NC} :"
echo -e " ${LGREEN}0${NC} -- DEFAULT, ${LGREEN}4${NC} -- RGB655, ${LGREEN}5${NC} -- RGB565, ${LGREEN}6${NC} -- RGB556, ${LGREEN}7${NC} -- ARGB1555"
echo -e " ${LGREEN}8${NC} -- RGBA5551, ${LGREEN}9${NC} -- RGB888, ${LGREEN}10${NC} -- ARGB8888, ${LGREEN}12${NC} -- ARGB4444"
echo -e " ${BOLD}fb_width${NC}:"
echo -e " width resolution in pixel -- range 0-9999"
echo -e " ${BOLD}fb_height${NC}:"
echo -e " height resolution in pixel -- range 0-9999"
echo -e "############################################################################\n"
} # DisplayUsage
ShowVideoModes() {
local clean=$1
# check if stdout is a terminal...
if test -t 1; then
# see if it supports colors...
ncolors=$(tput colors)
if test -n "$ncolors" && test $ncolors -ge 8; then
BOLD="$(tput bold)"
NC='\033[0m' # No Color
LGREEN='\033[1;32m'
fi
fi
OIFS=${IFS}
IFS="|"
awk -F" " '/ # res/ {print $1}' <"${0}" | tr -d ')' | grep -v 'awk' | while read ; do
set ${REPLY}
if [ ! $clean ]; then
echo -e " ${BOLD}${2}${NC}\tuse \"${LGREEN}-m ${2}${NC}\" or \"${LGREEN}-m ${1}${NC}\""
else
echo -e "${2}"
fi
done
IFS=${OIFS}
if [ ! $clean ]; then
echo -e "\n Two examples:\n\n '${BOLD}${0##*/}${NC} ${LGREEN}-m 1080p60 -d${NC}' (1920x1080@60Hz DVI)"
echo -e " '${BOLD}${0##*/}${NC} ${LGREEN}-m 720i${NC}' (1280x720@30Hz HDMI)\n"
fi
} # ShowVideoModes
## Usage: FexChange <fexfile> <section> <key> <value>
## Either changes the value of a given key or adds the key=value to the section
FexChange() {
# Search in file ($1) in section ($2) for key ($3)
found=$(sed -n -e "/^\[$2\]/,/^\[/{/^$3\s*=/p}" "$1")
if [ -n "$found" ]; then
# Replace in file ($1) in section ($2) key ($3) with value ($4)
sed -i -e "/^\[$2\]/,/^\[/{s/^\($3\s*=\s*\).*/\1$4/}" "$1"
else
# Append in file ($1) in section ($2) key ($3) with value ($4)
sed -i -e "/^\[$2\]/,/^\[/{/^\[/i$3 = $4\n" -e "}" "$1"
fi
}
PatchScriptBin() {
# This function will be called with 3 arguments:
# $1 HDMI mode to set
# $2 wether HDMI-to-DVI converter should be used or not (has to be TRUE)
# $3 pll_video value
# check whether we've the necessary tools available
Fex2Bin="$(which fex2bin)"
if [ "X${Fex2Bin}" = "X" ]; then
apt-get -f -qq -y install sunxi-tools >/dev/null 2>&1 || InstallSunxiTools >/dev/null 2>&1
fi
which fex2bin >/dev/null 2>&1 || (echo -e "Aborted\nfex2bin/bin2fex not found and unable to install. Exiting" >&2 ; exit 1)
# try to find location of script.bin
Path2ScriptBin=/boot
if [ ! -f "${Path2ScriptBin}/script.bin" ]; then
Path2ScriptBin="$(df | awk -F" " '/^\/dev\/mmcblk0p1/ {print $6}')"
if [ ! -f "${Path2ScriptBin}/script.bin" ]; then
echo -e "Aborted\nCan not find script.bin. Ensure boot partition is mounted" >&2
logger "Can not find script.bin. Ensure boot partition is mounted"
exit 1
fi
fi
# check for symlink
ScriptBin="$(readlink -f "${Path2ScriptBin}/script.bin")"
# create temp file
MyTmpFile="$(mktemp /tmp/${0##*/}.XXXXXX)"
# convert script.bin to temporary fex file
bin2fex <"${ScriptBin}" 2>/dev/null >"${MyTmpFile}"
if [ $? -ne 0 ]; then
echo -e "Aborted\nCould not convert script.bin to fex. Exiting" >&2
logger "Could not convert script.bin to fex"
exit 1
fi
# create backup to be able to recover from failed conversion
cp -p "${ScriptBin}" "${Path2ScriptBin}/script.bin.bak"
# add or replace ini values
FexChange "${MyTmpFile}" "disp_init" "screen0_output_type" "3"
FexChange "${MyTmpFile}" "disp_init" "screen0_output_mode" "$1"
FexChange "${MyTmpFile}" "disp_init" "screen1_output_type" "3"
FexChange "${MyTmpFile}" "disp_init" "screen1_output_mode" "$1"
FexChange "${MyTmpFile}" "clock" "pll_video" "$3"
if [ -v ColourRange ]; then
FexChange "${MyTmpFile}" "disp_init" "screen0_out_color_range" "${ColourRange}"
fi
if [ -v FrameBuffer ]; then
FrameBuffer_config=($(echo "${FrameBuffer}" | tr ':' '\n'))
FexChange "${MyTmpFile}" "disp_init" "fb0_format" "${FrameBuffer_config[0]}"
FexChange "${MyTmpFile}" "disp_init" "fb0_width" "${FrameBuffer_config[1]}"
FexChange "${MyTmpFile}" "disp_init" "fb0_height" "${FrameBuffer_config[2]}"
FexChange "${MyTmpFile}" "disp_init" "fb1_format" "${FrameBuffer_config[0]}"
FexChange "${MyTmpFile}" "disp_init" "fb1_width" "${FrameBuffer_config[1]}"
FexChange "${MyTmpFile}" "disp_init" "fb1_height" "${FrameBuffer_config[2]}"
fi
if [ "X$2" = "XTRUE" ]; then
# add entries necessary for HDMI-to-DVI adapters
FexChange "${MyTmpFile}" "hdmi_para" "hdcp_enable" "0"
FexChange "${MyTmpFile}" "hdmi_para" "hdmi_cts_compatibility" "1"
else
FexChange "${MyTmpFile}" "hdmi_para" "hdcp_enable" "1"
FexChange "${MyTmpFile}" "hdmi_para" "hdmi_cts_compatibility" "0"
fi
# convert temporary fex file back to script.bin. We delete symlinks to
# prevent future board support package updates overwriting h3disp changes
rm "${Path2ScriptBin}/script.bin"
fex2bin "${MyTmpFile}" "${Path2ScriptBin}/script.bin" 2>/dev/null
if [ $? -ne 0 ]; then
mv "${Path2ScriptBin}/script.bin.bak" "${ScriptBin}"
if [ "${ScriptBin}" != "${Path2ScriptBin}/script.bin" ]; then
cd "${Path2ScriptBin}"
ln -sf "${ScriptBin}" script.bin
fi
echo -e "Aborted\nWriting script.bin went wrong. Nothing changed." >&2
echo -e "You may look at ${MyTmpFile} to see if there is an error there." >&2
logger "Writing script.bin went wrong. Nothing changed"
exit 1
else rm "${MyTmpFile}"
fi
} # PatchScriptBin
InstallSunxiTools() {
sleep 1
apt-get -f -qq -y install libusb-1.0-0-dev || (echo -e "Aborted\nNot possible to install a sunxi-tools requirement" ; exit 1)
cd /tmp
git clone https://github.com/linux-sunxi/sunxi-tools
cd sunxi-tools
make
make install
} # InstallSunxiTools
Main "$@"

View File

@@ -0,0 +1,3 @@
# HW acceleration is not supported on this platform yet
vo=x11
sws-scaler=fast-bilinear

144
external/packages/bsp/mpv/mpv_sunxi.conf vendored Normal file
View File

@@ -0,0 +1,144 @@
#
# MPV configuration file for Orange Pi
#
# Warning:
#
# The commented example options usually do _not_ set the default values. Call
# mpv with --list-options to see the default values for most options. There is
# no builtin or example mpv.conf with all the defaults.
#
#
# Configuration files are read system-wide from /etc/mpv/mpv.conf
# and per-user from ~/.config/mpv/mpv.conf, where per-user settings override
# system-wide settings, all of which are overridden by the command line.
#
# Configuration file settings and the command line options use the same
# underlying mechanisms. Most options can be put into the configuration file
# by dropping the preceding '--'. See the man page for a complete list of
# options.
#
# Lines starting with '#' are comments and are ignored.
#
# See the CONFIGURATION FILES section in the man page
# for a detailed description of the syntax.
#
# Profiles should be placed at the bottom of the configuration file to ensure
# that settings wanted as defaults are not restricted to specific profiles.
##################
# video settings #
##################
# Start in fullscreen mode by default.
#fs=yes
# force starting with centered window
#geometry=50%:50%
# don't allow a new window to have a size larger than 90% of the screen size
#autofit-larger=90%x90%
# Do not close the window on exit.
#keep-open=yes
# Do not wait with showing the video window until it has loaded. (This will
# resize the window once video is loaded. Also always shows a window with
# audio.)
#force-window=immediate
# Disable the On Screen Controller (OSC).
#osc=no
# Keep the player window on top of all other windows.
#ontop=yes
# Specify default video driver (see --vo=help for a list).
# This one selects high quality video scaling etc. - can cause problems with
# some drivers and GPUs.
vo=vdpau
# Force video to lock on the display's refresh rate, and change video and audio
# speed to some degree to ensure synchronous playback - can cause problems
# with some drivers and desktop environments.
#video-sync=display-resample
# Enable hardware decoding if available. Often, this does not work with all
# video outputs, but should work well with default settings on most systems.
# If performance or energy usage is an issue, forcing the vdpau or vaapi VOs
# may or may not help.
hwdec=vdpau
hwdec-codecs=all
##################
# audio settings #
##################
# Specify default audio driver (see --ao=help for a list).
#ao=alsa
# Disable softvol usage, and always use the system mixer if available.
#softvol=no
# Do not filter audio to keep pitch when changing playback speed.
#audio-pitch-correction=no
# Output 5.1 audio natively, and upmix/downmix audio with a different format.
#audio-channels=5.1
# Disable any automatic remix, _if_ the audio output accepts the audio format.
# of the currently played file. See caveats mentioned in the manpage.
# (This is the default.)
#audio-channels=auto
##################
# other settings #
##################
# Pretend to be a web browser. Might fix playback with some streaming sites,
# but also will break with shoutcast streams.
#user-agent="Mozilla/5.0"
# cache settings
#
# Use 150MB input cache by default. The cache is enabled for network streams only.
#cache-default=153600
#
# Use 150MB input cache for everything, even local files.
#cache=153600
#
# Disable the behavior that the player will pause if the cache goes below a
# certain fill size.
#cache-pause=no
#
# Read ahead about 5 seconds of audio and video packets.
#demuxer-readahead-secs=5.0
#
# Raise readahead from demuxer-readahead-secs to this value if a cache is active.
#cache-secs=50.0
# Display English subtitles if available.
#slang=en
# Play Finnish audio if available, fall back to English otherwise.
#alang=fi,en
# Change subtitle encoding. For Arabic subtitles use 'cp1256'.
# If the file seems to be valid UTF-8, prefer UTF-8.
#sub-codepage=utf8:cp1256
# You can also include other configuration files.
#include=/path/to/the/file/you/want/to/include
############
# Profiles #
############
# The options declared as part of profiles override global default settings,
# but only take effect when the profile is active.
# The following profile can be enabled on the command line with: --profile=invert
#[invert]
# The profile forces this video filter:
#vf-add=flip

View File

@@ -0,0 +1,44 @@
#-----------------------------------------------------------------
# Orange Pi first run configuration
# Set optional end user configuration
# - Rename this file from /boot/orangepi_first_run.txt.template to /boot/orangepi_first_run.txt
# - Settings below will be applied only on 1st run of Orange Pi
#-----------------------------------------------------------------
#-----------------------------------------------------------------
# General:
# 1 = delete this file, after first run setup is completed.
FR_general_delete_this_file_after_completion=1
#-----------------------------------------------------------------
#Networking:
# Change default network settings
# Set to 1 to apply any network related settings below
FR_net_change_defaults=0
# Enable WiFi or Ethernet.
# NB: If both are enabled, WiFi will take priority and Ethernet will be disabled.
FR_net_ethernet_enabled=1
FR_net_wifi_enabled=0
#Enter your WiFi creds
# SECURITY WARN: Your wifi keys will be stored in plaintext, no encryption.
FR_net_wifi_ssid='MySSID'
FR_net_wifi_key='MyWiFiKEY'
# Country code to enable power ratings and channels for your country. eg: GB US DE | https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
FR_net_wifi_countrycode='GB'
#If you want to use a static ip, set it here
FR_net_use_static=0
FR_net_static_ip='192.168.0.100'
FR_net_static_mask='255.255.255.0'
FR_net_static_gateway='192.168.0.1'
FR_net_static_dns='8.8.8.8 8.8.4.4' #2 entries max, seperated by a space.
#-----------------------------------------------------------------

View File

@@ -0,0 +1,475 @@
#!/bin/bash
#
# orangepimonitor-daemon
#
# This script relies on information gathered in armhwinfo. It
# calls armhwinfo in query mode and relies then on the exported
# variables: HARDWARE ARCH KERNELID MACHINE ID VERSION
#
# The purpose is to create an environment for rpimonitord so that
# relevant hardware informations can be monitored easily. This
# script starts uses configuration files in /etc/orangepimonitor/,
# collects data sources below /etc/orangepimonitor/datasources/ and
# adjusts templates for RPi-Monitor on the fly. Only if the file
# /etc/orangepimonitor/start-monitoring exists this script relinks
# /etc/rpimonitor/data.conf and starts rpimonitord if not already
# running.
#
# In case the script detects that not all necessary data sources
# are available through sysfs it will act as a daemon to collect
# data on its own and to write it to the approriate file. As an
# example the SoC's temperature: Running on an AXP209 based board
# the script will check /sys/class/thermal/thermal_zone0/temp and
# if existing link it to /etc/orangepimonitor/datasources/soctemp.
# In case it does not exist the script will create a normal file
# at this location and writes the thermal value to it using the
# sunxi_axp209_temp binary in an endless loop.
#
# At least the following files/symlinks will be provided below
# /etc/orangepimonitor/datasources/ depending on SoC/PMIC in question:
#
# soctemp (SoC's internal temp in degree Celsius * 1000)
# pmictemp (PMIC's internal temp in degree Celsius * 1000)
# ac_voltage (DC-IN voltage in V * 1000000)
# usb_voltage (USB OTG voltage in V * 1000000)
# battery_voltage (battery voltage in V * 1000000)
# ac_current (DC-IN current in A * 1000000)
# usb_current (USB OTG current in A * 1000000)
# battery_current (battery current in A * 1000000)
#
# When extended debugging has been chosen (using _orangepi-monitoring_
# this can be configured. Then /etc/orangepimonitor/start-monitoring
# contains DEBUG) this script will also provide a few more files:
#
# cpustat (cpu_stat,system_stat,user_stat,nice_stat,iowait_stat,irq_stat
# collected through /proc/cpustat in daemon mode)
# cpu_count (number of active CPU cores)
# vcorevoltage (Vcore in V * 1000 based on sysfs or script.bin/.dtb)
#
# Disk monitoring: For configured disks the following parameters can be
# monitored: temperature, S.M.A.R.T. health, load cycle count and CRC
# errors indicating connection/cable problems. The config file used is
# /etc/orangepimonitoring/disks.conf
#
# Filesystem monitoring: In /etc/orangepimonitoring/filesystems.conf
# mountpoints and trigger values can be defined that will be used to
# create the template stuff for these fs at startup of this script.
#
# The behaviour of this script can be configured through another tool
# called orangepi-monitoring. The latter will also check for connected
# disks, get their name and GUID and let the user choose whether the
# disk should be monitored or not. The information has to be stored in
# /etc/orangepimonitor/disks.conf relying on the GUIDs of the disks.
# define some variables:
CheckInterval=7.5 # time in seconds between two checks
DiskCheckInterval=60 # time in seconds between disk checks
Main() {
PreRequisits
case ${BOARD_NAME} in
Cubieboard|Cubietruck|Orange|"Lamobo R1"|"Lime 2"|Lime|"Banana Pi"|Micro|"Banana Pi"|"Banana Pi Pro")
DealWithAXP209
;;
"Banana M2")
DealWithNewBoard
# DealWithAXP221
;;
"Cubietruck Plus"|"Banana Pi M3"|"pcDuino8 Uno")
DealWithNewBoard
# DealWithAXP818
;;
Guitar|"Roseapple Pi")
DealWithNewBoard
# DealWithS500
;;
"Odroid XU4"|"Odroid XU3")
DealWithNewBoard
# DealWithExynos4
;;
"Odroid C1")
DealWithNewBoard
# DealWithS805
;;
Clearfog|"Turris Omnia")
DealWithNewBoard
# DealWithArmada38x
;;
"Cubox i4"|"HB i2eX"|"Cubox i2eX"|"HB i1"|"HB i2"|"Wandboard")
DealWithNewBoard
# DealWithiMX6
;;
"Orange Pi PC"|"Orange Pi Plus"|"Orange Pi 2"|"Orange Pi One"|"Orange Pi Lite")
DealWithNewBoard
# DealWithH3
;;
Geekbox)
DealWithNewBoard
# DealWithRK3368
;;
*)
# No templates exist now. Combine sane defaults with some guessing
DealWithNewBoard
;;
esac
# Create the Orange Pi templates
CreateTemplates
exit 0
# Decide depending on existence of /etc/orangepimonitor/start-monitoring
ShouldMonitoringBeStarted
# Provide missing data in daemon mode
LoopEndlessly
} # Main
LoopEndlessly() {
while true ; do
# get VCore
read CPUFreq </sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
GetVCore ${CPUFreq} >/tmp/VCore
# check disk temperature(s). We execute this only every ${DiskCheckInterval} since
# it's a bit costly (S.M.A.R.T. queries).
TimeNow=$(( $(date "+%s") / ${DiskCheckInterval} ))
if [[ ${TimeNow} -gt ${LastDiskCheck} ]]; then
# time for a disk check. If ${CheckAllDisks} is FALSE and /dev/sda exists we
# only query this device otherwise all available (might be none)
CheckDisks
# update check timestamp
LastDiskCheck=${TimeNow}
fi
# External temperature from weather stations
# TimeNow=$(( $(date "+%s") / ${TempCheckInterval} ))
# if [[ ${TimeNow} -gt ${LastTempCheck} ]]; then
# read in external temp values from 2 different web sources
# ExternalTemp=$(GetExternalTemp)
# LastExternalTemp=$(SanitizeValue ${ExternalTemp} ${LastExternalTemp} | tee /tmp/externaltemp)
# LastTempCheck=${TimeNow}
# fi
# cpustat
TimeNow=$(( $(date "+%s") / ${CpuStatCheckInterval} ))
if [[ ${TimeNow} -gt ${LastCpuStatCheck} ]]; then
ProcessStats
LastCpuStatCheck=${TimeNow}
fi
sleep ${CheckInterval}
done
} # LoopEndlessly
CheckDisks() {
# To be done based on new /etc/orangepimonitoring/disks.conf config file
:
} # CheckDisks
DealWithAXP209() {
# check existence of sysfs nodes
if [ -f /sys/devices/virtual/thermal/thermal_zone0/temp ]; then
ln -fs /sys/devices/virtual/thermal/thermal_zone0/temp /etc/orangepimonitor/datasources/soctemp
else
if [ -L /etc/orangepimonitor/datasources/soctemp ]; then
rm -f /etc/orangepimonitor/datasources/soctemp
fi
echo -n 25000 >/etc/orangepimonitor/datasources/soctemp
export GetSoCTemp="${ARCH}-${BOARD_NAME}"
fi
if [ -d /sys/devices/platform/soc@01c00000/1c2ac00.i2c/i2c-0/0-0034 ]; then
# mainline kernel and 'axp209 mainline sysfs interface' patch applied
ln -fs /sys/power/axp_pmu/ac/voltage /etc/orangepimonitor/datasources/ac_voltage
ln -fs /sys/power/axp_pmu/ac/amperage /etc/orangepimonitor/datasources/ac_current
ln -fs /sys/power/axp_pmu/vbus/voltage /etc/orangepimonitor/datasources/usb_voltage
ln -fs /sys/power/axp_pmu/vbus/amperage /etc/orangepimonitor/datasources/usb_current
ln -fs /sys/power/axp_pmu/battery/voltage /etc/orangepimonitor/datasources/battery_voltage
ln -fs /sys/power/axp_pmu/battery/amperage /etc/orangepimonitor/datasources/battery_current
ln -fs /sys/power/axp_pmu/pmu/temp /etc/orangepimonitor/datasources/pmictemp
ln -fs /sys/power/axp_pmu/battery/capacity /etc/orangepimonitor/datasources/battery_percent
ln -fs /sys/power/axp_pmu/battery/charging /etc/orangepimonitor/datasources/battery_charging
ln -fs /sys/power/axp_pmu/charger/amperage /etc/orangepimonitor/datasources/charger_current
ln -fs /sys/power/axp_pmu/battery/connected /etc/orangepimonitor/datasources/battery_connected
ln -fs /sys/power/axp_pmu/battery/charge /etc/orangepimonitor/datasources/battery_charge
fi
if [ -d /sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply ]; then
# sunxi 3.4 kernel
SysFSPrefix=/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-supplyer.28/power_supply
ln -fs "${SysFSPrefix}"/ac/voltage_now /etc/orangepimonitor/datasources/ac_voltage
ln -fs "${SysFSPrefix}"/ac/current_now /etc/orangepimonitor/datasources/ac_current
ln -fs "${SysFSPrefix}"/usb/voltage_now /etc/orangepimonitor/datasources/usb_voltage
ln -fs "${SysFSPrefix}"/usb/current_now /etc/orangepimonitor/datasources/usb_current
ln -fs "${SysFSPrefix}"/battery/voltage_now /etc/orangepimonitor/datasources/battery_voltage
ln -fs "${SysFSPrefix}"/battery/current_now /etc/orangepimonitor/datasources/battery_current
ln -fs /sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input /etc/orangepimonitor/datasources/pmictemp
ln -fs /sys/class/power_supply/battery/capacity /etc/orangepimonitor/datasources/battery_percent
ln -fs /sys/class/power_supply/battery/charging /etc/orangepimonitor/datasources/battery_charging
ln -fs /sys/class/power_supply/battery/connected /etc/orangepimonitor/datasources/battery_connected
ln -fs /sys/class/power_supply/battery/charge /etc/orangepimonitor/datasources/battery_charge
fi
# relink template
if [ "X${DebugMode}" = "XDEBUG" ]; then
ln -sf /etc/orangepimonitor/templates/axp209_template_debug.conf /etc/orangepimonitor/templates/cpu_pmic.conf
else
ln -sf /etc/orangepimonitor/templates/axp209_template.conf /etc/orangepimonitor/templates/cpu_pmic.conf
fi
} # DealWithAXP209
DealWithNewBoard() {
# check existence of sysfs nodes
if [ -f /sys/devices/virtual/thermal/thermal_zone0/temp ]; then
ln -fs /sys/devices/virtual/thermal/thermal_zone0/temp /etc/orangepimonitor/datasources/soctemp
elif [ -f /sys/devices/virtual/thermal/thermal_zone1/temp ]; then
ln -fs /sys/devices/virtual/thermal/thermal_zone1/temp /etc/orangepimonitor/datasources/soctemp
fi
# relink template
if [ "X${DebugMode}" = "XDEBUG" ]; then
ln -sf /etc/orangepimonitor/templates/unknown_board_template_debug.conf /etc/orangepimonitor/templates/cpu_pmic.conf
else
ln -sf /etc/orangepimonitor/templates/unknown_board_template.conf /etc/orangepimonitor/templates/cpu_pmic.conf
fi
} # DealWithNewBoard
CreateTemplates() {
# check whether templates we write aren't symlinks to somewhere else
for i in orangepi.conf uptime.conf version.conf ; do
if [ -L /etc/orangepimonitor/templates/${i} ]; then
rm /etc/orangepimonitor/templates/${i}
touch /etc/orangepimonitor/templates/${i}
chmod 711 /etc/orangepimonitor/templates/${i}
fi
done
# check whether our logo is available
if [ ! -f /usr/share/rpimonitor/web/img/orangepi.png ]; then
if [ -L /usr/share/rpimonitor/web/img/orangepi.png ]; then
rm /usr/share/rpimonitor/web/img/orangepi.png
fi
cp -p /etc/orangepimonitor/templates/orangepi.png /usr/share/rpimonitor/web/img/
fi
# create main template
echo "web.page.icon='img/orangepi.png'
web.page.menutitle='RPi-Monitor <sub>('+data.hostname+')</sub>'
web.page.pagetitle='RPi-Monitor ('+data.hostname+')'
web.status.1.name=$BOARD_NAME
web.statistics.1.name=$BOARD_NAME
web.addons.1.name=Addons
web.addons.1.addons=about
include=/etc/orangepimonitor/templates/version.conf
include=/etc/orangepimonitor/templates/uptime.conf
include=/etc/orangepimonitor/templates/cpu_pmic.conf
include=/etc/rpimonitor/template/memory.conf" >/etc/orangepimonitor/orangepi.conf
# remove firmware line in version info:
grep -v "Firmware" /etc/rpimonitor/template/version.conf | sed 's|line.5|line.4|' >/etc/orangepimonitor/templates/version.conf
# uptime template with correct machine name:
sed "s/Raspberry Pi/$ID/" < /etc/rpimonitor/template/uptime.conf >/etc/orangepimonitor/templates/uptime.conf
# check swap settings. In case we're using swap then add template
HowManySwapDevices=$(swapon -s | wc -l)
if [[ ${HowManySwapDevices} -gt 1 ]]; then
echo "include=/etc/rpimonitor/template/swap.conf" >>/etc/orangepimonitor/orangepi.conf
fi
echo "include=/etc/orangepimonitor/template/filesystems.conf
include=/etc/orangepimonitor/template/disks.conf
include=/etc/rpimonitor/template/network.conf" >>/etc/orangepimonitor/orangepi.conf
UpdateFileSystems
UpdateDisks
} #
UpdateFileSystems() {
# Generates /etc/orangepimonitor/template/filesystems.conf dynamically
# based on the contents of /etc/orangepimonitoring/filesystems.conf
# if not existing, create config file with single entry for /
if [ ! -f /etc/orangepimonitoring/filesystems.conf ]; then
echo '/' >/etc/orangepimonitoring/filesystems.conf
chmod 711 /etc/orangepimonitoring/filesystems.conf
fi
# Update template:
} # UpdateFileSystems
UpdateDisks() {
# Generates /etc/orangepimonitor/template/disks.conf dynamically
# based on the contents of /etc/orangepimonitor/disks.conf. The
# current mapping between GUIDs and /dev/sd* nodes will be stored
# in /etc/orangepimonitor/datasources/disk-by-guid
# ensure lookup file is empty:
if [ -L /etc/orangepimonitor/datasources/disk-by-guid ]; then
rm -f /etc/orangepimonitor/datasources/disk-by-guid
fi
echo -n "" >/etc/orangepimonitor/datasources/disk-by-guid
chmod 711 /etc/orangepimonitor/datasources/disk-by-guid
OIFS=${IFS}
IFS=:
cat /etc/orangepimonitor/disks.conf | while read ; do
IFS=:
set ${REPLY}
GUID="$1"
DiskName="$2"
SMARTPrefix="$3"
TempCommand="$4"
CRCAttribute="$5"
LCCAttribute="$6"
IFS=${OIFS}
# try to resolve device node (when not present, then disk's
# not mounted -- we then create the entry without device node)
DeviceNode="$(ResolveGUID ${GUID})"
echo -e "${GUID}\t${DiskName}\t${DeviceNode}" >>/etc/orangepimonitor/datasources/disk-by-guid
# create template stuff for every listed disk
:
done
IFS=${OIFS}
} # UpdateDisks
ResolveGUID() {
# function that will be supplied with a GUID and returns the device node, eg.
# translating 637B7677-18E7-4C7B-8DF3-CFED96EA55C3 to /dev/sdb
# check whether disks are existent
ls /sys/block/sd* >/dev/null 2>&1 || return
for i in /sys/block/sd* ; do
DeviceNode=/dev/${i##*/}
GUID=$(gdisk -l ${DeviceNode} | awk -F" " '/^Disk identifier/ {print $4}')
if [ "X${GUID}" = "X${1}" ]; then
echo -n ${DeviceNode}
break
fi
done
} # GetGUIDforDisk
PreRequisits() {
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
unset LANG
LastDiskCheck=0
# we need the informations gathered from armhwinfo. In case we're not called
# from there, get the variables on our own
if [ "X${BOARD_NAME}" = "X" ]; then
. /etc/init.d/armhwinfo start >/dev/null 2>&1
fi
# check/create /etc/orangepimonitor and /etc/orangepimonitor/datasources
if [ ! -d /etc/orangepimonitor ]; then
mkdir -p -m 755 /etc/orangepimonitor
else
chmod 755 /etc/orangepimonitor
fi
if [ ! -d /etc/orangepimonitor/datasources ]; then
mkdir -p -m 755 /etc/orangepimonitor/datasources
else
chmod 755 /etc/orangepimonitor/datasources
fi
# check whether we should do debug monitoring or normal
read DebugMode </etc/orangepimonitor/start-monitoring
# set default variables
unset LANG
LastDiskCheck=0
LastTempCheck=0
LastUserStat=0
LastNiceStat=0
LastSystemStat=0
LastIdleStat=0
LastIOWaitStat=0
LastIrqStat=0
LastSoftIrqStat=0
LastCpuStatCheck=0
} # PreRequisits
ParseDVFSTable() {
# extract DRAM and dvfs settings from script.bin
bin2fex <"${Path2ScriptBin}/script.bin" 2>/dev/null | \
egrep "^LV._|^LV_|extrem|boot_clock|_freq|^dram_" | \
egrep -v "cpu_freq|dram_freq" | while read ; do
echo "# ${REPLY}"
done >/tmp/dvfs-table
echo -e '\nGetVCore() {' >>/tmp/dvfs-table
# parse /tmp/dvfs-table to get dvfs entries
grep "^# LV._freq" /tmp/dvfs-table | sort -r | while read ; do
set ${REPLY}
CPUFreq=$4
# if [ ${CPUFreq} -eq 0 ]; then
# echo -e "if [ \$1 -ge $(( ${CPUFreq} / 1000 )) ]; then\n\techo -n ${VCore}\nel\c" >>/tmp/dvfs-table
# break
# else
# VCore=$(grep -A1 "^# $2" /tmp/dvfs-table | tail -n1 | awk -F" " '{print $4}')
# echo -e "if [ \$1 -ge $(( ${CPUFreq} / 1000 )) ]; then\n\techo -n ${VCore}\nel\c" >>/tmp/dvfs-table
if [ ${CPUFreq} -ne 0 ]; then
VCore=$(grep -A1 "^# $2" /tmp/dvfs-table | tail -n1 | awk -F" " '{print $4}')
echo -e "if [ \$1 -le $(( ${CPUFreq} / 1000 )) ]; then\n\techo -n ${VCore}\nel\c" >>/tmp/dvfs-table
fi
done
# VCore=$(grep -A1 "^# LV1_freq" /tmp/dvfs-table | tail -n1 | awk -F" " '{print $4}')
echo -e "se\n\techo -n ${VCore}\nfi\n}" >>/tmp/dvfs-table
} # ParseDVFSTable
ProcessStats() {
set $(awk -F" " '/^cpu / {print $2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7"\t"$8}' </proc/stat)
UserStat=$1
NiceStat=$2
SystemStat=$3
IdleStat=$4
IOWaitStat=$5
IrqStat=$6
SoftIrqStat=$7
UserDiff=$(( ${UserStat} - ${LastUserStat} ))
NiceDiff=$(( ${NiceStat} - ${LastNiceStat} ))
SystemDiff=$(( ${SystemStat} - ${LastSystemStat} ))
IdleDiff=$(( ${IdleStat} - ${LastIdleStat} ))
IOWaitDiff=$(( ${IOWaitStat} - ${LastIOWaitStat} ))
IrqDiff=$(( ${IrqStat} - ${LastIrqStat} ))
SoftIrqDiff=$(( ${SoftIrqStat} - ${LastSoftIrqStat} ))
Total=$(( ${UserDiff} + ${NiceDiff} + ${SystemDiff} + ${IdleDiff} + ${IOWaitDiff} + ${IrqDiff} + ${SoftIrqDiff} ))
CPULoad=$(( ( ${Total} - ${IdleDiff} ) * 100 / ${Total} ))
UserLoad=$(( ${UserDiff} *100 / ${Total} ))
SystemLoad=$(( ${SystemDiff} *100 / ${Total} ))
NiceLoad=$(( ${NiceDiff} *100 / ${Total} ))
IOWaitLoad=$(( ${IOWaitDiff} *100 / ${Total} ))
IrqCombinedLoad=$(( ( ${IrqDiff} + ${SoftIrqDiff} ) *100 / ${Total} ))
echo "${CPULoad} ${SystemLoad} ${UserLoad} ${NiceLoad} ${IOWaitLoad} ${IrqCombinedLoad}" >/tmp/cpustat
LastUserStat=${UserStat}
LastNiceStat=${NiceStat}
LastSystemStat=${SystemStat}
LastIdleStat=${IdleStat}
LastIOWaitStat=${IOWaitStat}
LastIrqStat=${IrqStat}
LastSoftIrqStat=${SoftIrqStat}
} # ProcessStats
GetExternalTemp() {
# example function that parses meteo.physik.uni-muenchen.de and mingaweda.de
# temperature values for Munich and compares them. When values are out
# of bounds then only the other value will be returned otherwise the average
ExternalTemp1=$(/usr/bin/links -http.fake-user-agent 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/600.7.12 (KHTML, like Gecko) Version/8.0.7 Safari/600.7.12' -dump "http://www.meteo.physik.uni-muenchen.de/dokuwiki/doku.php?id=wetter:stadt:messung" | awk -F" " '/Lufttemperatur/ {printf ("%0.0f",$4*1000); }')
ExternalTemp2=$(/usr/bin/links -http.fake-user-agent 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/600.7.12 (KHTML, like Gecko) Version/8.0.7 Safari/600.7.12' -dump "http://www.mingaweda.de/wetterdaten/" | awk -F" " '/Ausfu:hrliche/ {printf ("%0.0f",$2*1000); }')
if [ "X${ExternalTemp2}" = "X" ]; then
ExternalTemp2=${ExternalTemp1}
elif [ "X${ExternalTemp1}" = "X" ]; then
ExternalTemp1=${ExternalTemp2}
fi
echo $(( ( ${ExternalTemp1} + ${ExternalTemp2} ) / 2 ))
} # GetExternalTemp
Main

View File

@@ -0,0 +1,153 @@
dynamic.1.name=cpu_frequency
dynamic.1.source=/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
dynamic.1.regexp=(.*)
dynamic.1.postprocess=sprintf("%.3f", $1/1000000)
dynamic.1.rrd=GAUGE
dynamic.2.name=load1,load5,load15
dynamic.2.source=/proc/loadavg
dynamic.2.regexp=^(\S+)\s(\S+)\s(\S+)
dynamic.2.postprocess=
dynamic.2.rrd=GAUGE
dynamic.3.name=scaling_governor
dynamic.3.source=/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
dynamic.3.regexp=(.*)
dynamic.3.postprocess=
dynamic.3.rrd=
dynamic.4.name=cpu_count
dynamic.4.source=grep -c processor /proc/cpuinfo
dynamic.4.regexp=(.*)
dynamic.4.postprocess=
dynamic.4.rrd=GAUGE
#dynamic.5.name=disktemp
#dynamic.5.source=/usr/sbin/smartctl -a /dev/sda | /usr/bin/awk -F" " '/Temperature_Celsius/ {print $10}'
#dynamic.5.regexp=(.*)
#dynamic.5.postprocess=
#dynamic.5.rrd=GAUGE
dynamic.5.name=vcorevoltage
dynamic.5.source=/sys/class/regulator/regulator.2/microvolts
dynamic.5.regexp=(.*)
dynamic.5.postprocess=sprintf("%.2f", $1/1000000)
dynamic.5.rrd=GAUGE
dynamic.6.name=soctemp
dynamic.6.source=/sys/devices/virtual/thermal/thermal_zone0/temp
dynamic.6.regexp=(.*)
dynamic.6.postprocess=
dynamic.6.rrd=GAUGE
dynamic.7.name=coolingstate
dynamic.7.source=/sys/devices/virtual/thermal/cooling_device0/cur_state
dynamic.7.regexp=(.*)
dynamic.7.postprocess=
dynamic.7.rrd=GAUGE
dynamic.8.name=coolinglimit
dynamic.8.source=/sys/devices/soc.0/cpu_budget_cool.16/roomage
dynamic.8.regexp=(.*)
dynamic.8.postprocess=
dynamic.8.rrd=
dynamic.9.name=batterycapacity
dynamic.9.source=/sys/class/power_supply/battery/capacity
dynamic.9.regexp=(.*)
dynamic.9.postprocess=
dynamic.9.rrd=GAUGE
dynamic.10.name=batteryvoltage
dynamic.10.source=/sys/class/power_supply/battery/voltage_now
dynamic.10.regexp=(.*)
dynamic.10.postprocess=sprintf("%.3f", $1/1000000)
dynamic.10.rrd=GAUGE
dynamic.11.name=batterycurrent
dynamic.11.source=/sys/class/power_supply/battery/current_now
dynamic.11.regexp=(.*)
dynamic.11.postprocess=sprintf("%.3f", $1/1000000)
dynamic.11.rrd=GAUGE
dynamic.12.name=pmictemp
dynamic.12.source=/sys/class/axppower/ic_temp
dynamic.12.regexp=(.*)
dynamic.12.postprocess=
dynamic.12.rrd=GAUGE
dynamic.13.name=batterydrain
dynamic.13.source=/sys/class/axppower/power_sply
dynamic.13.regexp=(.*)
dynamic.13.postprocess=sprintf("%.3f", $1/1000000)
dynamic.13.rrd=GAUGE
dynamic.14.name=gpu_frequency
dynamic.14.source=/sys/devices/1c40000.gpu/dvfs/manual
dynamic.14.regexp=^(\S+)
dynamic.14.postprocess=
dynamic.14.rrd=
dynamic.15.name=gputemp
dynamic.15.source=awk '{print $6}' < /sys/devices/1c40000.gpu/dvfs/tempctrl
dynamic.15.regexp=(.*)
dynamic.15.postprocess=
dynamic.15.rrd=
dynamic.16.name=gpuvoltage
dynamic.16.source=/sys/devices/1c40000.gpu/dvfs/voltage
dynamic.16.regexp=^(\S+)
dynamic.16.postprocess=sprintf("%.2f", $1/1000)
dynamic.16.rrd=
web.status.1.content.1.name=CPU/GPU
web.status.1.content.1.icon=cpu.png
web.status.1.content.1.line.1=JustGageBar("Load", "1min", 0, data.load1, 3, 100, 80)+" "+JustGageBar("Load", "5min", 0, data.load5, 3, 100, 80)+" "+JustGageBar("Load", "15min", 0, data.load15, 3, 100, 80)
web.status.1.content.1.line.2="CPU frequency: <b>" + data.cpu_frequency + " GHz</b> &nbsp;(" + data.coolinglimit + ")"
web.status.1.content.1.line.3="Governor: <b>" + data.scaling_governor + "</b> &nbsp;Active CPU cores: <b>" + data.cpu_count + "</b> &nbsp;Vcore: <b>" + data.vcorevoltage + "V</b>"
web.status.1.content.1.line.4="GPU frequency: <b>" + data.gpu_frequency + " MHz</b> &nbsp;GPU voltage: <b>" + data.gpuvoltage + "V</b>"
web.status.1.content.2.name=Temperature
web.status.1.content.2.icon=cpu_temp.png
web.status.1.content.2.line.1=JustGageBar("CPU", "°C",0, data.soctemp , 100,100,80,percentColors,50,70)+" "+JustGageBar("GPU", "°C",0, data.gputemp , 100,100,80,percentColors,50,70)+" "+JustGageBar("PMIC", "°C",0, data.pmictemp , 100,100,80,percentColors,60,80)+" "+JustGageBar("Cooling State", "",0, data.coolingstate , 7,100,80,percentColors,1,2)
web.status.1.content.3.name=Battery
web.status.1.content.3.icon=pmu.png
web.status.1.content.3.line.1=JustGageBar("Battery capacity", "%", 0, data.batterycapacity, 100,100,80,percentColors,100,100)+" "+JustGageBar("Battery voltage", "V", 0, data.batteryvoltage, 5,100,80,percentColors,100,100)+" "+JustGageBar("Battery current", "A", -3, data.batterycurrent, 3,100,80,percentColors,100,100)+" "+JustGageBar("Battery drain", "W", 0, data.batterydrain, 15,100,80,percentColors,6,9)
web.statistics.1.content.1.name=Load / Clockspeeds / Temperature
web.statistics.1.content.1.graph.1=load1
web.statistics.1.content.1.graph.2=load5
web.statistics.1.content.1.graph.3=load15
web.statistics.1.content.1.graph.4=cpu_frequency
web.statistics.1.content.1.graph.5=cpu_count
web.statistics.1.content.1.graph.6=coolingstate
web.statistics.1.content.1.graph.7=soctemp
web.statistics.1.content.1.graph.8=vcorevoltage
web.statistics.1.content.1.graph.9=batterycapacity
web.statistics.1.content.1.graph.10=batteryvoltage
web.statistics.1.content.1.graph.11=batterycurrent
web.statistics.1.content.1.graph.12=pmictemp
web.statistics.1.content.1.graph.13=batterydrain
web.statistics.1.content.1.ds_graph_options.load1.label=Load 1 min
web.statistics.1.content.1.ds_graph_options.load5.label=Load 5 min
web.statistics.1.content.1.ds_graph_options.load15.label=Load 15 min
web.statistics.1.content.1.ds_graph_options.cpu_frequency.label=CPU Clock speed (GHz)
web.statistics.1.content.1.ds_graph_options.cpu_frequency.yaxis=2
web.statistics.1.content.1.ds_graph_options.cpu_count.label=Active CPUs
web.statistics.1.content.1.ds_graph_options.cpu_count.yaxis=2
web.statistics.1.content.1.ds_graph_options.soctemp.label=SoC temp (°C)
web.statistics.1.content.1.ds_graph_options.pmictemp.label=PMIC temp (°C)
web.statistics.1.content.1.ds_graph_options.vcorevoltage.label=Vcore (V)
web.statistics.1.content.1.ds_graph_options.vcorevoltage.yaxis=2
web.statistics.1.content.1.ds_graph_options.coolingstate.label=Cooling State
web.statistics.1.content.1.ds_graph_options.coolingstate.yaxis=2
web.statistics.1.content.1.ds_graph_options.batterycapacity.label=Battery capacity
web.statistics.1.content.1.ds_graph_options.batteryvoltage.label=Battery voltage
web.statistics.1.content.1.ds_graph_options.batteryvoltage.yaxis=2
web.statistics.1.content.1.ds_graph_options.batterycurrent.label=Battery current
web.statistics.1.content.1.ds_graph_options.batterycurrent.yaxis=2
web.statistics.1.content.1.ds_graph_options.batterydrain.label=Battery drain
web.statistics.1.content.1.ds_graph_options.batterydrain.yaxis=2
web.statistics.1.content.1.graph_options.y1axis={ position: "left", min: 35, max: 75 }
web.statistics.1.content.1.graph_options.y2axis={ position: "right" }

View File

@@ -0,0 +1,131 @@
dynamic.1.name=cpu_frequency
dynamic.1.source=/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
dynamic.1.regexp=(.*)
dynamic.1.postprocess=sprintf("%.3f", $1/1000000)
dynamic.1.rrd=GAUGE
dynamic.2.name=load1,load5,load15
dynamic.2.source=/proc/loadavg
dynamic.2.regexp=^(\S+)\s(\S+)\s(\S+)
dynamic.2.postprocess=
dynamic.2.rrd=GAUGE
dynamic.3.name=scaling_governor
dynamic.3.source=/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
dynamic.3.regexp=(.*)
dynamic.3.postprocess=
dynamic.3.rrd=
dynamic.4.name=cpu_count
dynamic.4.source=grep -c processor /proc/cpuinfo
dynamic.4.regexp=(.*)
dynamic.4.postprocess=
dynamic.4.rrd=GAUGE
dynamic.5.name=dram_frequency
dynamic.5.source=/sys/devices/platform/sunxi-ddrfreq/devfreq/sunxi-ddrfreq/cur_freq
dynamic.5.regexp=(.*)
dynamic.5.postprocess=sprintf("%.3f", $1/1000000)
dynamic.5.rrd=GAUGE
dynamic.6.name=soctemp
dynamic.6.source=/etc/orangepimonitor/datasources/soctemp
dynamic.6.regexp=(.*)
dynamic.6.postprocess=
dynamic.6.rrd=GAUGE
dynamic.7.name=externaltemp
dynamic.7.source=/tmp/externaltemp
dynamic.7.regexp=(.*)
dynamic.7.postprocess=sprintf("%.1f", $1/1000)
dynamic.7.rrd=GAUGE
dynamic.8.name=disktemp
dynamic.8.source=/tmp/disktemp
dynamic.8.regexp=(.*)
dynamic.8.postprocess=sprintf("%.1f", $1/1000)
dynamic.8.rrd=GAUGE
dynamic.9.name=vcorevoltage
dynamic.9.source=/tmp/VCore
dynamic.9.regexp=(.*)
dynamic.9.postprocess=sprintf("%.2f", $1/1000)
dynamic.9.rrd=GAUGE
dynamic.10.name=cpu_stat,system_stat,user_stat,nice_stat,iowait_stat,irq_stat
dynamic.10.source=/tmp/cpustat
dynamic.10.regexp=^(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)
dynamic.10.postprocess=
dynamic.10.rrd=GAUGE
dynamic.11.name=coolingstate
dynamic.11.source=/sys/devices/virtual/thermal/cooling_device0/cur_state
dynamic.11.regexp=(.*)
dynamic.11.postprocess=
dynamic.11.rrd=GAUGE
dynamic.12.name=cpuminer
dynamic.12.source=/tmp/khash
dynamic.12.regexp=(.*)
dynamic.12.postprocess=
dynamic.12.rrd=GAUGE
web.status.1.content.1.name=CPU
web.status.1.content.1.icon=cpu.png
web.status.1.content.1.line.1=JustGageBar("Load", "1min", 0, data.load1, 3, 100, 80)+" "+JustGageBar("Load", "5min", 0, data.load5, 3, 100, 80)+" "+JustGageBar("Load", "15min", 0, data.load15, 3, 100, 80)
web.status.1.content.1.line.2="CPU total: <b>" + data.cpu_stat + "%</b> (Sys: " + data.system_stat + "%, User: " + data.user_stat + "%, I/O wait: " + data.iowait_stat + "%, Nice: " + data.nice_stat + "%)"
web.status.1.content.1.line.3="CPU frequency: <b>" + data.cpu_frequency + "GHz</b> &nbsp;DRAM frequency: <b>" + data.dram_frequency + "GHz</b>"
web.status.1.content.1.line.4="Governor: <b>" + data.scaling_governor + "</b> &nbsp;Active CPU cores: <b>" + data.cpu_count + "</b> &nbsp;Vcore: <b>" + data.vcorevoltage + "</b>"
web.status.1.content.3.name=Temperature
web.status.1.content.3.icon=cpu_temp.png
web.status.1.content.3.line.1=JustGageBar("SoC", "°C",0, data.soctemp , 100,100,80,percentColors,50,70)+" "+JustGageBar("Disk", "°C",0, data.disktemp , 100,100,80,percentColors,40,50)+" "+JustGageBar("Cooling State", "",0, data.coolingstate , 5,100,80,percentColors,1,2)
web.statistics.1.content.1.name=Load / Clockspeeds / Temperature
web.statistics.1.content.1.graph.1=load1
web.statistics.1.content.1.graph.2=load5
web.statistics.1.content.1.graph.3=load15
web.statistics.1.content.1.graph.4=cpu_frequency
web.statistics.1.content.1.graph.5=dram_frequency
web.statistics.1.content.1.graph.6=cpu_count
web.statistics.1.content.1.graph.7=soctemp
web.statistics.1.content.1.graph.8=vcorevoltage
web.statistics.1.content.1.graph.9=disktemp
web.statistics.1.content.1.graph.10=cpu_stat
web.statistics.1.content.1.graph.11=coolingstate
web.statistics.1.content.1.graph.12=cpuminer
web.statistics.1.content.1.ds_graph_options.load1.label=Load 1 min
web.statistics.1.content.1.ds_graph_options.load5.label=Load 5 min
web.statistics.1.content.1.ds_graph_options.load15.label=Load 15 min
web.statistics.1.content.1.ds_graph_options.cpu_frequency.label=CPU Clock speed (GHz)
web.statistics.1.content.1.ds_graph_options.cpu_frequency.yaxis=2
web.statistics.1.content.1.ds_graph_options.dram_frequency.label=DRAM Clock speed (GHz)
web.statistics.1.content.1.ds_graph_options.dram_frequency.yaxis=2
web.statistics.1.content.1.ds_graph_options.cpu_count.label=Active CPUs
web.statistics.1.content.1.ds_graph_options.cpu_count.yaxis=2
web.statistics.1.content.1.ds_graph_options.soctemp.label=SoC temp (°C)
web.statistics.1.content.1.ds_graph_options.cpuminer.label=khash/s
web.statistics.1.content.1.ds_graph_options.cpuminer.yaxis=2
web.statistics.1.content.1.ds_graph_options.disktemp.label=Disk temp (°C)
web.statistics.1.content.1.ds_graph_options.vcorevoltage.label=Vcore (V)
web.statistics.1.content.1.ds_graph_options.vcorevoltage.yaxis=2
web.statistics.1.content.1.ds_graph_options.coolingstate.label=Cooling State
web.statistics.1.content.1.ds_graph_options.coolingstate.yaxis=2
web.statistics.1.content.1.ds_graph_options.cpu_stat.label=CPU total (%)
web.statistics.1.content.1.graph_options.y1axis={ position: "left", min: 35, max: 75 }
web.statistics.1.content.1.graph_options.y2axis={ position: "right" }
web.statistics.1.content.2.name=Detailed CPU Stats
web.statistics.1.content.2.graph.1=cpu_stat
web.statistics.1.content.2.graph.2=system_stat
web.statistics.1.content.2.graph.3=user_stat
web.statistics.1.content.2.graph.4=nice_stat
web.statistics.1.content.2.graph.5=iowait_stat
web.statistics.1.content.2.graph.6=irq_stat
web.statistics.1.content.2.ds_graph_options.cpu_stat.label=CPU total (%)
web.statistics.1.content.2.ds_graph_options.system_stat.label=System (%)
web.statistics.1.content.2.ds_graph_options.user_stat.label=User (%)
web.statistics.1.content.2.ds_graph_options.nice_stat.label=Nice (%)
web.statistics.1.content.2.ds_graph_options.iowait_stat.label=I/O wait (%)
web.statistics.1.content.2.ds_graph_options.irq_stat.label=IRQ/softirq (%)
web.statistics.1.content.2.graph_options.y1axis={ position: "left", min: 0, max: 100 }

View File

@@ -0,0 +1,125 @@
dynamic.1.name=cpu_frequency
dynamic.1.source=/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
dynamic.1.regexp=(.*)
dynamic.1.postprocess=sprintf("%.3f", $1/1000000)
dynamic.1.rrd=GAUGE
dynamic.2.name=load1,load5,load15
dynamic.2.source=/proc/loadavg
dynamic.2.regexp=^(\S+)\s(\S+)\s(\S+)
dynamic.2.postprocess=
dynamic.2.rrd=GAUGE
dynamic.3.name=scaling_governor
dynamic.3.source=/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
dynamic.3.regexp=(.*)
dynamic.3.postprocess=
dynamic.3.rrd=
dynamic.4.name=cpu_count
dynamic.4.source=grep -c processor /proc/cpuinfo
dynamic.4.regexp=(.*)
dynamic.4.postprocess=
dynamic.4.rrd=GAUGE
dynamic.6.name=soctemp
dynamic.6.source=/etc/orangepimonitor/datasources/soctemp
dynamic.6.regexp=(.*)
dynamic.6.postprocess=sprintf("%.1f", $1/1000)
dynamic.6.rrd=GAUGE
dynamic.7.name=externaltemp
dynamic.7.source=/tmp/externaltemp
dynamic.7.regexp=(.*)
dynamic.7.postprocess=sprintf("%.1f", $1/1000)
dynamic.7.rrd=GAUGE
dynamic.8.name=disktemp
dynamic.8.source=/tmp/disktemp
dynamic.8.regexp=(.*)
dynamic.8.postprocess=sprintf("%.1f", $1/1000)
dynamic.8.rrd=GAUGE
dynamic.9.name=vcorevoltage
dynamic.9.source=/tmp/VCore
dynamic.9.regexp=(.*)
dynamic.9.postprocess=sprintf("%.2f", $1/1000)
dynamic.9.rrd=GAUGE
dynamic.10.name=cpu_stat,system_stat,user_stat,nice_stat,iowait_stat,irq_stat
dynamic.10.source=/tmp/cpustat
dynamic.10.regexp=^(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)\s(\S+)
dynamic.10.postprocess=
dynamic.10.rrd=GAUGE
dynamic.11.name=coolingstate
dynamic.11.source=/sys/devices/virtual/thermal/cooling_device0/cur_state
dynamic.11.regexp=(.*)
dynamic.11.postprocess=
dynamic.11.rrd=GAUGE
dynamic.12.name=cpuminer
dynamic.12.source=/tmp/khash
dynamic.12.regexp=(.*)
dynamic.12.postprocess=
dynamic.12.rrd=GAUGE
web.status.1.content.1.name=CPU
web.status.1.content.1.icon=cpu.png
web.status.1.content.1.line.1=JustGageBar("Load", "1min", 0, data.load1, 3, 100, 80)+" "+JustGageBar("Load", "5min", 0, data.load5, 3, 100, 80)+" "+JustGageBar("Load", "15min", 0, data.load15, 3, 100, 80)
web.status.1.content.1.line.2="CPU total: <b>" + data.cpu_stat + "%</b> (Sys: " + data.system_stat + "%, User: " + data.user_stat + "%, I/O wait: " + data.iowait_stat + "%, Nice: " + data.nice_stat + "%)"
web.status.1.content.1.line.3="CPU frequency: <b>" + data.cpu_frequency + "GHz</b> &nbsp;DRAM frequency: <b>Not available</b>"
web.status.1.content.1.line.4="Governor: <b>" + data.scaling_governor + "</b> &nbsp;Active CPU cores: <b>" + data.cpu_count + "</b> &nbsp;Vcore: <b>" + data.vcorevoltage + "</b>"
web.status.1.content.3.name=Temperature
web.status.1.content.3.icon=cpu_temp.png
web.status.1.content.3.line.1=JustGageBar("SoC", "°C",0, data.soctemp , 100,100,80,percentColors,50,70)+" "+JustGageBar("Disk", "°C",0, data.disktemp , 100,100,80,percentColors,40,50)+" "+JustGageBar("Cooling State", "",0, data.coolingstate , 5,100,80,percentColors,1,2)
web.statistics.1.content.1.name=Load / Clockspeeds / Temperature
web.statistics.1.content.1.graph.1=load1
web.statistics.1.content.1.graph.2=load5
web.statistics.1.content.1.graph.3=load15
web.statistics.1.content.1.graph.4=cpu_frequency
web.statistics.1.content.1.graph.5=dram_frequency
web.statistics.1.content.1.graph.6=cpu_count
web.statistics.1.content.1.graph.7=soctemp
web.statistics.1.content.1.graph.8=vcorevoltage
web.statistics.1.content.1.graph.9=disktemp
web.statistics.1.content.1.graph.10=cpu_stat
web.statistics.1.content.1.graph.11=coolingstate
web.statistics.1.content.1.graph.12=cpuminer
web.statistics.1.content.1.ds_graph_options.load1.label=Load 1 min
web.statistics.1.content.1.ds_graph_options.load5.label=Load 5 min
web.statistics.1.content.1.ds_graph_options.load15.label=Load 15 min
web.statistics.1.content.1.ds_graph_options.cpu_frequency.label=CPU Clock speed (GHz)
web.statistics.1.content.1.ds_graph_options.cpu_frequency.yaxis=2
web.statistics.1.content.1.ds_graph_options.dram_frequency.label=DRAM Clock speed (GHz)
web.statistics.1.content.1.ds_graph_options.dram_frequency.yaxis=2
web.statistics.1.content.1.ds_graph_options.cpu_count.label=Active CPUs
web.statistics.1.content.1.ds_graph_options.cpu_count.yaxis=2
web.statistics.1.content.1.ds_graph_options.soctemp.label=SoC temp (°C)
web.statistics.1.content.1.ds_graph_options.cpuminer.label=khash/s
web.statistics.1.content.1.ds_graph_options.cpuminer.yaxis=2
web.statistics.1.content.1.ds_graph_options.disktemp.label=Disk temp (°C)
web.statistics.1.content.1.ds_graph_options.vcorevoltage.label=Vcore (V)
web.statistics.1.content.1.ds_graph_options.vcorevoltage.yaxis=2
web.statistics.1.content.1.ds_graph_options.coolingstate.label=Cooling State
web.statistics.1.content.1.ds_graph_options.coolingstate.yaxis=2
web.statistics.1.content.1.ds_graph_options.cpu_stat.label=CPU total (%)
web.statistics.1.content.1.graph_options.y1axis={ position: "left", min: 35, max: 75 }
web.statistics.1.content.1.graph_options.y2axis={ position: "right" }
web.statistics.1.content.2.name=Detailed CPU Stats
web.statistics.1.content.2.graph.1=cpu_stat
web.statistics.1.content.2.graph.2=system_stat
web.statistics.1.content.2.graph.3=user_stat
web.statistics.1.content.2.graph.4=nice_stat
web.statistics.1.content.2.graph.5=iowait_stat
web.statistics.1.content.2.graph.6=irq_stat
web.statistics.1.content.2.ds_graph_options.cpu_stat.label=CPU total (%)
web.statistics.1.content.2.ds_graph_options.system_stat.label=System (%)
web.statistics.1.content.2.ds_graph_options.user_stat.label=User (%)
web.statistics.1.content.2.ds_graph_options.nice_stat.label=Nice (%)
web.statistics.1.content.2.ds_graph_options.iowait_stat.label=I/O wait (%)
web.statistics.1.content.2.ds_graph_options.irq_stat.label=IRQ/softirq (%)
web.statistics.1.content.2.graph_options.y1axis={ position: "left", min: 0, max: 100 }

View File

@@ -0,0 +1,263 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdint.h>
struct mmio {
unsigned long iobase; /* getpagesize() aligned, see mmap(2) */
unsigned long offset; /* additional offset from iobase */
unsigned long range; /* N * uint32_t read/write ops. */
void *iomem;
size_t iosize;
int kmem; /* 0 - /dev/mem, 1 - /dev/kmem */
};
void sysDelay_us(uint16_t us)
{
struct timespec usec;
usec.tv_sec = 0;
usec.tv_nsec = us*1000;
nanosleep(&usec,NULL);
}
void sysDelay_ms(uint16_t ms)
{
struct timespec msec;
msec.tv_sec = 0;
msec.tv_nsec = ms*1000000;
nanosleep(&msec,NULL);
}
static inline uint32_t readl(void *ptr)
{
uint32_t *data = ptr;
return *data;
}
static inline void writel(uint32_t value, void *ptr)
{
uint32_t *data = ptr;
*data = value;
}
uint32_t mmio_readl(const struct mmio *io, unsigned int offset)
{
void *addr;
addr = io->iomem + io->offset + offset;
return readl(addr);
}
void mmio_writel(const struct mmio *io, unsigned int offset, uint32_t value)
{
void *addr;
addr = io->iomem + io->offset + offset;
writel(value, addr);
}
static void mmio_normalize(struct mmio *mo)
{
int npages = 0;
mo->iobase += mo->offset;
mo->offset = mo->iobase & (getpagesize() - 1);
mo->iobase = mo->iobase & ~(getpagesize() - 1);
npages += (mo->range * sizeof(uint32_t)) / getpagesize();
npages += 1;
mo->iosize = npages * getpagesize();
}
static void mmio_init(struct mmio *mo)
{
char *device;
int iofd;
if (!mo->kmem)
device = "/dev/mem";
else
device = "/dev/kmem";
iofd = open(device, O_RDWR);
if (iofd < 0)
{
//ie_errno("open() failed");
printf("open failed\n");
exit(-1);
// TODO:
}
mo->iomem = mmap(NULL, mo->iosize,
PROT_READ|PROT_WRITE,
MAP_SHARED,
iofd, mo->iobase);
if (mo->iomem == MAP_FAILED)
{
printf("can't map\n");
exit(-1);
//die_errno("can't map @ %0lX", mo->iobase);
}
close(iofd);
}
int mmio_map(struct mmio *io, unsigned long base, size_t length)
{
memset(io, 0, sizeof(*io));
io->iobase = base;
io->offset = 0;
io->range = length;
mmio_normalize(io);
mmio_init(io);
return 0;
}
void mmio_unmap(struct mmio *io)
{
if (munmap(io->iomem, io->iosize))
{
exit(-1);
//die_errno("can't unmap @ %lX", io->iobase);
}
memset(io, 0, sizeof(*io));
}
unsigned long mmio_read(unsigned long iobase)
{
struct mmio io;
uint32_t rdata;
mmio_map(&io, iobase, 0);
rdata = mmio_readl(&io, 0);
mmio_unmap(&io);
return rdata;
}
unsigned long mmio_write(unsigned long iobase, unsigned long data2)
{
struct mmio io;
uint32_t data;
mmio_map(&io, iobase, 0);
mmio_writel(&io, 0, data2);
data = mmio_readl(&io, 0);
mmio_unmap(&io);
if (data != data2)
return -1;
else
return 0;
}
unsigned long mmio_write2(unsigned long iobase, unsigned long data2)
{
struct mmio io;
uint32_t data;
mmio_map(&io, iobase, 0);
mmio_writel(&io, 0, data2);
data = mmio_readl(&io, 0);
mmio_unmap(&io);
if (data != data2)
return -1;
else
return 0;
}
void * mmiof_init(unsigned long iobase)
{
struct mmio io1;
unsigned long offset;
// unsigned long iobase;
unsigned long range;
size_t iosize;
void *iomem;
// mmio_map(&io1, 0x18040000, 0);
//memset(io1, 0, sizeof(*io1));
// iobase = 0x18040000;
//offset = 0;
range = 0;
// mmio_normalize(&io1);
int npages = 0;
//iobase += offset;
offset = iobase & (getpagesize() - 1);
iobase = iobase & ~(getpagesize() - 1);
npages += (range * sizeof(uint32_t)) / getpagesize();
npages += 1;
iosize = npages * getpagesize();
//mmio_init(&io1);
char *device;
int iofd;
device = "/dev/mem";
//device = "/dev/kmem";
iofd = open(device, O_RDWR);
if (iofd < 0)
{
//ie_errno("open() failed");
printf("open failed\n");
exit(-1);
// TODO:
}
iomem = mmap(NULL, iosize, PROT_READ|PROT_WRITE, MAP_SHARED, iofd, iobase);
if (iomem == MAP_FAILED)
{
printf("can't map\n");
exit(-1);
//die_errno("can't map @ %0lX", mo->iobase);
}
close(iofd);
return iomem;
}
unsigned long mmiof_read(void * iomem, unsigned long offset)
{
void *addr;
addr = iomem + offset;
unsigned long read_data = readl(addr);
return read_data;
}
void mmiof_write(void * iomem, unsigned long offset, unsigned long value)
{
void *addr;
addr = iomem + offset;
uint32_t *data = addr;
*data = value;
}
void mmiof_close(void * iomem)
{
if (munmap(iomem, 4096))
{
exit(-1);
//die_errno("can't unmap @ %lX", io->iobase);
}
}

View File

@@ -0,0 +1,38 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include "mod_mmio.h"
//#define _debug ;
const int SoCTempAdjustment = 1447 ;
int main(int argc, char *argv[])
{
mmio_write(0x01c25000, 0x0027003f) ;
mmio_write(0x01c25010, 0x00040000) ;
mmio_write(0x01c25018, 0x00010fff) ;
mmio_write(0x01c25004, 0x00000010) ;
#ifdef _debug
printf("w 0x01c25000: %08lx\n", mmio_read(0x01c25000)) ;
printf("w 0x01c25010: %08lx\n", mmio_read(0x01c25010)) ;
printf("w 0x01c25018: %08lx\n", mmio_read(0x01c25018)) ;
printf("w 0x01c25004: %08lx\n", mmio_read(0x01c25004)) ;
printf("r 0x01c25020: %08lx\n", mmio_read(0x01c25020)) ;
#endif
printf("%0.1f\n",(float)(mmio_read(0x01c25020)-SoCTempAdjustment)/10.0);
return 0;
}

View File

@@ -0,0 +1,15 @@
[Unit]
Description=Bluetooth AP6212
After=bluetooth.target
[Service]
Type=forking
ExecStartPre=/usr/sbin/rfkill unblock all
ExecStart=/usr/bin/brcm_patchram_plus -d --enable_hci --no2bytes --use_baudrate_for_downloade --tosleep 200000 --baudrate 1500000 --patchram /lib/firmware/ap6212/bcm43438a1.hcd /dev/ttyS1
TimeoutSec=0
RemainAfterExit=yes
SysVStartPriority=99
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,14 @@
[Unit]
Description=Bluetooth AW859A
After=bluetooth.target
[Service]
Type=forking
ExecStartPre=/usr/sbin/rfkill unblock all
ExecStart=/usr/bin/hciattach_opi -n -s 1500000 /dev/ttyBT0 sprd
TimeoutSec=0
RemainAfterExit=yes
SysVStartPriority=99
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,13 @@
[Unit]
Description=Init Hdmi Audio
After=bluetooth.target
[Service]
Type=forking
ExecStart=/usr/bin/inithdmiaudio /usr/share/sounds/alsa/Rear_Left.wav -D 2
TimeoutSec=0
RemainAfterExit=yes
SysVStartPriority=99
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,15 @@
[Unit]
Description=Bluetooth RTL8723BS
After=bluetooth.target
[Service]
Type=forking
ExecStartPre=/usr/sbin/rfkill unblock all
ExecStart=/usr/bin/rtk_hciattach -n -s 115200 /dev/ttyS1 rtk_h5
TimeoutSec=0
RemainAfterExit=yes
SysVStartPriority=99
[Install]
WantedBy=multi-user.target