build/scripts/armhwinfo

365 lines
16 KiB
Text
Raw Normal View History

#!/bin/bash
2014-10-08 07:39:24 +02:00
### BEGIN INIT INFO
# Provides: armhwinfo
2017-05-14 22:10:51 +02:00
# Required-Start:
2014-10-12 09:20:35 +02:00
# Required-Stop: glibc
2014-10-12 07:27:38 +02:00
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Armbian gathering hardware information
2014-10-08 07:39:24 +02:00
### END INIT INFO
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Starting with 5.15 read in $BOARD (odroidc2), $BOARD_NAME ("Odroid C2") and $VERSION (5.15)
. /etc/armbian-release
collect_information() {
ifconfig | grep -q eth0 || (ifconfig eth0 up ; sleep 2)
TMPFILE=$(mktemp /tmp/${0##*/}.XXXXXX)
trap "rm \"${TMPFILE}\" ; exit 0" 0 1 2 3 15
dmesg >"${TMPFILE}"
ARCH=$(lscpu | awk '/Architecture/ {print $2}')
2017-04-25 11:50:48 +02:00
HARDWARE=$(awk '/Hardware/ {print $3}' </proc/cpuinfo | head -n1)
[ "X${HARDWARE}" = "XAllwinner" ] && HARDWARE=$(awk '/Hardware/ {print $4}' </proc/cpuinfo | head -n1)
2017-04-25 15:47:20 +02:00
[ "X${HARDWARE}" = "XSAMSUNG" ] && HARDWARE=$(awk '/Hardware/ {print $4}' </proc/cpuinfo | head -n1)
KERNELID=$(uname -r)
} # collect_information
set_io_scheduler() {
for i in $( lsblk -idn -o NAME ); do
read ROTATE </sys/block/$i/queue/rotational
2017-04-25 15:47:20 +02:00
case ${ROTATE} in
1) # mechanical drives
echo cfq >/sys/block/$i/queue/scheduler
echo -e "[\e[0;32m ok \x1B[0m] Setting cfg I/O scheduler for $i"
;;
0) # flash based
echo noop >/sys/block/$i/queue/scheduler
echo -e "[\e[0;32m ok \x1B[0m] Setting noop I/O scheduler for $i"
;;
esac
done
} # set_io_scheduler
prepare_temp_monitoring() {
# still an ugly hack but better do it just once at startup instead of every login
[ -d /etc/armbianmonitor/datasources ] || mkdir -p -m775 /etc/armbianmonitor/datasources
2017-04-20 09:38:24 +02:00
# PMIC check
if [[ -f /sys/power/axp_pmu/pmu/temp ]]; then
ln -fs /sys/power/axp_pmu/pmu/temp /etc/armbianmonitor/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/armbianmonitor/datasources/pmictemp
2017-04-20 09:38:24 +02:00
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/armbianmonitor/datasources/pmictemp
elif [[ -f /sys/class/axppower/ic_temp ]]; then
ln -fs /sys/class/axppower/ic_temp /etc/armbianmonitor/datasources/pmictemp
fi
2017-04-20 09:38:24 +02:00
# 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/armbianmonitor/datasources/soctemp
2017-04-20 09:38:24 +02:00
else
case ${LINUXFAMILY} in
s500|rockchip)
# S500 legacy -- thermal_zone0 is battery
# RK3288 legacy -- thermal_zone2 is gpu_thermal
# TODO: deal correctly with RK3288 mainline (probably based on $KERNELID)
ln -fs /sys/devices/virtual/thermal/thermal_zone1/temp /etc/armbianmonitor/datasources/soctemp
;;
*)
# mainline kernel, Armada 38x, sun50i/sun8i legacy
ln -fs /sys/devices/virtual/thermal/thermal_zone0/temp /etc/armbianmonitor/datasources/soctemp
;;
esac
fi
} # prepare_temp_monitoring
prepare_board() {
# prevent logrotate from compressing rotated logs when /var/log lives on compressed fs
CheckDevice=$(for i in /var/log /var / ; do findmnt -n -o SOURCE $i && break ; done)
[ -n "${CheckDevice}" ] && grep "^${CheckDevice}" /etc/mtab | grep -q compress && \
for ConfigFile in /etc/logrotate.d/* ; do
sed -i -e "s/^\s\+compress/\t# compress/" \
-e "s/^\s\+delaycompress/\t# delaycompress/" "${ConfigFile}"
done
# IRQ distribution based on $HARDWARE and/or $BOARD, probably some sort of user feedback (leds)
case ${HARDWARE} in
Freescale) # i.MX6 boards, send Ethernet to cpu3, MMC to cpu1/cpu2 (when available)
echo 2 >/proc/irq/$(awk -F":" "/mmc0/ {print \$1}" </proc/interrupts | sed 's/\ //g' | head -1)/smp_affinity 2>/dev/null
echo 4 >/proc/irq/$(awk -F":" "/mmc1/ {print \$1}" </proc/interrupts | sed 's/\ //g' | head -1)/smp_affinity 2>/dev/null
echo 8 >/proc/irq/$(awk -F":" "/ethernet/ {print \$1}" </proc/interrupts | sed 's/\ //g' | head -1)/smp_affinity 2>/dev/null
echo 7 >/sys/class/net/eth0/queues/rx-0/rps_cpus
;;
gs705a) # Roseapple Pi/LeMaker Guitar: send USB IRQs to cpu1/cpu2, DMA0 to cpu2 and Ethernet + SD card to cpu3
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 2>/dev/null
echo 4 >/proc/irq/$(awk -F":" "/usb3/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity 2>/dev/null
echo 4 >/proc/irq/$(awk -F":" "/owl_dma0/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 8 >/proc/irq/$(awk -F":" "/ethernet_mac/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 8 >/proc/irq/$(awk -F":" "/sdcard/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
;;
Marvell) # Clearfog: Send network IRQs to cpu1 on both kernels
2017-04-25 15:47:20 +02:00
for i in $(awk -F':' '/mwlwifi|mvneta|eth0/{print $1}' /proc/interrupts | sed 's/\ //g'); do
echo 2 >/proc/irq/$i/smp_affinity
done
;;
2017-04-21 18:24:03 +02:00
ODROIDC) # ODROID-C0/C1/C1+
echo 1 >/proc/irq/$(awk -F":" "/usb1/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity_list
2017-04-25 15:47:20 +02:00
for i in $(awk -F':' '/Mali_/{print $1}' </proc/interrupts | sed 's/\ //g'); do echo 1 >/proc/irq/${i}/smp_affinity_list; done
2017-04-21 18:24:03 +02:00
echo 2 >/proc/irq/$(awk -F":" "/usb2/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity_list
echo 3 >/proc/irq/$(awk -F":" "/eth0/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity_list
echo 7 >/sys/class/net/eth0/queues/rx-0/rps_cpus
2017-04-21 18:24:03 +02:00
;;
ODROID-C2) # send eth0 to cpu3, mmc/usb2 to cpu2 and usb1 to cpu1
2016-06-12 19:15:44 +03:00
# Basics: http://forum.odroid.com/viewtopic.php?f=115&t=8121#p65777
2017-04-25 15:47:20 +02:00
for i in $(awk -F':' '/sd_emmc|usb2/{print $1}' </proc/interrupts | sed 's/\ //g'); do
echo 1 >/proc/irq/$i/smp_affinity_list
2016-06-12 19:15:44 +03:00
done
echo 2 >/proc/irq/$(awk -F":" "/usb1/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity_list
echo 3 >/proc/irq/$(awk -F":" "/eth0/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity_list
echo 7 >/sys/class/net/eth0/queues/rx-0/rps_cpus
;;
2017-04-11 19:18:11 +02:00
ODROID-XU3|EXYNOS) # ODROID XU3/XU4
echo 2 >/proc/irq/$(awk -F":" "/usb2/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 4 >/proc/irq/$(awk -F":" "/usb3/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 8 >/proc/irq/$(awk -F":" "/usb5/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 16 >/proc/irq/$(awk -F":" "/dw-mci/ {print \$1}" </proc/interrupts | sed 's/\ //g' | tail -1)/smp_affinity
echo 32 >/proc/irq/$(awk -F":" "/dw-mci/ {print \$1}" </proc/interrupts | sed 's/\ //g' | head -1)/smp_affinity
2017-04-25 15:47:20 +02:00
for i in $(awk -F':' '/11800000.mali/{print $1}' </proc/interrupts | sed 's/\ //g'); do
echo 64 >/proc/irq/$i/smp_affinity
done
2017-04-11 19:18:11 +02:00
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
;;
sun4i|sun5i) # only one core, nothing to improve
:
;;
sun6i) # Banana Pi M2: process eth0 on cpu3, SDIO on cpu2, USB on cpu1
2017-04-25 15:47:20 +02:00
for i in $(awk -F':' '/hcd:usb/{print $1}' /proc/interrupts | sed 's/\ //g'); do
echo 2 >/proc/irq/$i/smp_affinity
done
2017-04-25 15:47:20 +02:00
for i in $(awk -F':' '/sunxi-mmc/{print $1}' /proc/interrupts | sed 's/\ //g'); do
echo 4 >/proc/irq/$i/smp_affinity
done
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
;;
sun7i) # try to redistribute eth0 irq to dedicated core
echo 2 >/proc/irq/$(awk -F":" '/eth0/ {print $1}' </proc/interrupts | sed 's/\ //g')/smp_affinity 2>/dev/null
;;
sun8i) # H3 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="1c30000.ethernet"; WiFi="wlan0"; USB1="usb1"; USB2="usb2"; USB3="usb3"
;;
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
;;
2017-04-21 18:24:03 +02:00
"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
2017-04-25 15:47:20 +02:00
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")
# Wifi module reload workaround / fix
[[ -n $(lsmod | grep 8189es) ]] && rmmod 8189es && modprobe 8189es
# Send SDIO to cpu1, USB to cpu2, Ethernet to cpu3
2017-04-25 15:47:20 +02:00
for i in $(awk -F':' '/sunxi-mmc/{print $1}' </proc/interrupts | sed 's/\ //g'); do
echo 2 >/proc/irq/$i/smp_affinity
done
2017-04-25 15:47:20 +02:00
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*|*Pine*) # A64/H64/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
2017-04-14 14:16:22 +02:00
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
;;
2017-04-23 18:48:18 +02:00
*)
case ${BOARD} in
espressobin) # try to redistribute eth0 irq to dedicated core
echo 2 >/proc/irq/$(awk -F":" '/eth0/ {print $1}' </proc/interrupts | sed 's/\ //g')/smp_affinity 2>/dev/null
;;
2017-04-24 08:39:35 +02:00
tinkerboard|miqi) # usb1 on cpu1, usb3 (EHCI) on cpu2, eth0 and GPU on cpu3
echo 2 >/proc/irq/$(awk -F":" "/usb1/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 4 >/proc/irq/$(awk -F":" "/usb3/ {print \$1}" </proc/interrupts | sed 's/\ //g')/smp_affinity
echo 8 >/proc/irq/$(awk -F":" "/eth0/ {print \$1}" </proc/interrupts | sed 's/\ //g' | head -n1)/smp_affinity
echo 7 >/sys/class/net/eth0/queues/rx-0/rps_cpus
for i in $(awk -F':' '/gpu/{print $1}' /proc/interrupts | sed 's/\ //g'); do
echo 8 >/proc/irq/$i/smp_affinity
done
;;
2017-04-23 18:48:18 +02:00
esac
;;
esac
} # prepare_board
log_hardware_info() {
2016-03-03 00:58:49 +01:00
Log=/var/log/armhwinfo.log
[ -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##*/}"
if [ -f ${Log} ]; then
echo -e "\n\n\n$(date) $HARDWARE $ARCH $KERNELID $MACHINE $BOARD_NAME $VERSION" >>${Log}
else
echo "$(date) $HARDWARE $ARCH $KERNELID $MACHINE $BOARD_NAME $VERSION" >>${Log}
chmod 755 ${Log}
fi
echo -e "\n### dmesg:\n" >>${Log}
cat "${TMPFILE}" >>${Log}
echo -e "\n### armbian-release:\n" >>${Log}
cat /etc/armbian-release >>${Log}
echo -e "\n### boot environment:\n" >>${Log}
cat /boot/armbianEnv.txt >>${Log} 2>/dev/null || grep -v "^#" /boot/boot.ini | sed '/^\s*$/d' >>${Log}
echo -e "\n### lsusb:" >>${Log}
[ -f /boot/.force-verbose ] && USBVERBOSE="-v" || echo "" >>${Log}
lsusb ${USBVERBOSE} 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}
2017-05-14 22:10:51 +02:00
cat /proc/meminfo >>${Log}
echo -e "\n### ifconfig:\n" >>${Log}
ifconfig >>${Log}
echo -e "### partitions:\n" >>${Log}
cat /proc/partitions >>${Log}
2016-09-21 19:01:27 +02:00
echo -e "\n### df:\n" >>${Log}
df -h >>${Log}
2016-06-07 16:31:41 +02:00
[[ -e /boot/script.bin ]] && echo -e "\n### /boot/script.bin --> $(readlink /boot/script.bin)" >>${Log}
get_flash_information >>${Log} &
2016-06-07 16:31:41 +02:00
(sleep 20 && echo -e "\n### interrupts:\n$(cat /proc/interrupts)" >>${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
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
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/armhwinfo.log ]; then
RebootCount=$(grep -c '^### df:' /var/log/armhwinfo.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/armhwinfo.log)"
if [ "X${IozoneResults}" != "X" ]; then
set ${IozoneResults}
Readspeed=$1
Writespeed=$2
if [ ${Readspeed} -lt 800 -o ${Writespeed} -lt 400 ]; then
show_motd_warning "Your SD card seems to be very slow. Please check performance using armbianmonitor -c"
fi
fi
fi
fi
} # check_sd_card_speed
case $1 in
*start*)
# set optimal disk scheduler settings
set_io_scheduler &
2017-05-14 22:10:51 +02:00
# check sd card speed once on 3rd boot too warn for too slow media
check_sd_card_speed &
# get hardware information and rely on contents of /etc/armbian-release
collect_information
2017-05-14 22:10:51 +02:00
# hardware preparation
prepare_board &
prepare_temp_monitoring &
2017-05-14 22:10:51 +02:00
# display message, log hardware id to file, write log
2016-06-07 16:31:41 +02:00
echo -e "[\e[0;32m ok \x1B[0m] Starting ARM hardware info: $ID (${VERSION})"
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
;;
query)
# armbianmonitor mode -- only interested in hardware info
2016-06-07 16:31:41 +02:00
collect_information >/dev/null
prepare_board >/dev/null
export HARDWARE ARCH KERNELID MACHINE BOARD_NAME VERSION
;;
*stop*)
case ${LINUXFAMILY} 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
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/armhwinfo.log
sync
;;
esac