#!/bin/bash ### BEGIN INIT INFO # Provides: armhwinfo # Required-Start: # Required-Stop: glibc # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Armbian gathering hardware information ### 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}') HARDWARE=$(awk '/Hardware/ {print $3}' /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 # 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 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 # 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 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}" /dev/null echo 4 >/proc/irq/$(awk -F":" "/mmc1/ {print \$1}" /dev/null echo 8 >/proc/irq/$(awk -F":" "/ethernet/ {print \$1}" /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/irq/$(awk -F":" "/usb2/ {print \$1}" /dev/null echo 4 >/proc/irq/$(awk -F":" "/usb3/ {print \$1}" /dev/null echo 4 >/proc/irq/$(awk -F":" "/owl_dma0/ {print \$1}" /proc/irq/$(awk -F":" "/ethernet_mac/ {print \$1}" /proc/irq/$(awk -F":" "/sdcard/ {print \$1}" /proc/irq/$i/smp_affinity done ;; ODROIDC) # ODROID-C0/C1/C1+ echo 1 >/proc/irq/$(awk -F":" "/usb1/ {print \$1}" /proc/irq/${i}/smp_affinity_list; done echo 2 >/proc/irq/$(awk -F":" "/usb2/ {print \$1}" /proc/irq/$(awk -F":" "/eth0/ {print \$1}" /sys/class/net/eth0/queues/rx-0/rps_cpus ;; ODROID-C2) # send eth0 to cpu3, mmc/usb2 to cpu2 and usb1 to cpu1 # Basics: http://forum.odroid.com/viewtopic.php?f=115&t=8121#p65777 for i in $(awk -F':' '/sd_emmc|usb2/{print $1}' /proc/irq/$i/smp_affinity_list done echo 2 >/proc/irq/$(awk -F":" "/usb1/ {print \$1}" /proc/irq/$(awk -F":" "/eth0/ {print \$1}" /sys/class/net/eth0/queues/rx-0/rps_cpus ;; ODROID-XU3|EXYNOS) # ODROID XU3/XU4 echo 2 >/proc/irq/$(awk -F":" "/usb2/ {print \$1}" /proc/irq/$(awk -F":" "/usb3/ {print \$1}" /proc/irq/$(awk -F":" "/usb5/ {print \$1}" /proc/irq/$(awk -F":" "/dw-mci/ {print \$1}" /proc/irq/$(awk -F":" "/dw-mci/ {print \$1}" /proc/irq/$i/smp_affinity done 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 for i in $(awk -F':' '/hcd:usb/{print $1}' /proc/interrupts | sed 's/\ //g'); do echo 2 >/proc/irq/$i/smp_affinity done 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}' /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}' /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/irq/$(awk -F":" "/${USB2}/ {print \$1}" /proc/irq/$(awk -F":" "/${GbE}/ {print \$1}" /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/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 for i in $(awk -F':' '/sunxi-mmc/{print $1}' /proc/irq/$i/smp_affinity done for i in $(awk -F':' '/hcd:usb/{print $1}' /proc/irq/$i/smp_affinity done echo 8 >/proc/irq/$(awk -F":" "/${GbE}/ {print \$1}" /proc/irq/$(awk -F":" "/usb1/ {print \$1}" /proc/irq/$(awk -F":" "/usb2/ {print \$1}" /proc/irq/$(awk -F":" "/sunxi-mmc/ {print \$1}" /proc/irq/$(awk -F":" "/eth/ {print \$1}" /sys/class/net/eth0/queues/rx-0/rps_cpus ;; *) case ${BOARD} in espressobin) # try to redistribute eth0 irq to dedicated core echo 2 >/proc/irq/$(awk -F":" '/eth0/ {print $1}' /dev/null ;; tinkerboard|miqi) # usb1 on cpu1, usb3 (EHCI) on cpu2, eth0 and GPU on cpu3 echo 2 >/proc/irq/$(awk -F":" "/usb1/ {print \$1}" /proc/irq/$(awk -F":" "/usb3/ {print \$1}" /proc/irq/$(awk -F":" "/eth0/ {print \$1}" /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 ;; esac ;; esac } # prepare_board log_hardware_info() { 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} cat /proc/meminfo >>${Log} echo -e "\n### ifconfig:\n" >>${Log} ifconfig >>${Log} echo -e "### partitions:\n" >>${Log} cat /proc/partitions >>${Log} echo -e "\n### df:\n" >>${Log} df -h >>${Log} [[ -e /boot/script.bin ]] && echo -e "\n### /boot/script.bin --> $(readlink /boot/script.bin)" >>${Log} get_flash_information >>${Log} & (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 </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 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' ' >/var/log/armhwinfo.log sync ;; esac