Diese Seiten sind unsere internen Protokolle aus dem Labor.
Aufgrund der fortlaufenden Protokollierung der Ergänzungen sowie der Verbesserungen ist die Reihenfolge / Chronologie der Seiten aus dem Ruder gelaufen - leicht durcheinander geraten.
.
Das hier ist quasi das Script für das "basic environment"
Nachtrag : Es ist aber bei weitem nicht das erste ausführbare Script in der Boot-Reihenfolge. Zuvor kommen diese beiden hier.
Damit ein Scipt wie dieses hier überhaupt ausgeführt werden kann, muß ein Bootloader mit einem Mini-Betriebssystem in irgend ein RAM geladen worden sein, der die sogenannten Kommandozeilenbefehle sowie solch einer Script-Datei ausführen (interpretieren) kann.
Dieses init-Script ist im aktuellen root Verzeichnis des virtuellen RAM-Disk- Dateisystems "ganz unten" abgelegt und hat etwa 6,8 Kilobyte Länge. Die (für uns) wichtigste Information außer der Definition von Variablen, die dann in den nächsten Scripten einfach als "vorhanden" vorausgesetzt werden, ist, daß am Ende dieses "init-Scripts" das nächste und eigenliche Start-Script-1 "rcS" aufgerufen wird, welches dann am Ende wiederum das 2. Start-Script "rcR2" aufruft.
Das bedeutet, an dieser Stelle hier ist das "barebox"- Bootloader-Programm bereits ins RAM geladen und die typische (aber minimale) Kommandozeile, die zum Abarbeiten von script-Dateien gebraucht wird, funktioniert.
.
..... noch früheren kleinen "init" Scripts, ist einer der in Firmware enthaltene Zyxel/Debian Kernel zu dieser Zeit schon ins RAM geladen (?).
.
init-Script - (= init-2) prepare basic environment
.
#!/bin/sh
.
- # NOTE:
- # /init only prepare "basic environment"
- # User can't press Ctrl+C to break /init; this is different from /etc/init.d/rcS.
.
- # Hier werden also die allerersten Variablen erstellt und gesetzt, bevor im nachfolgenden Script-1 "rcS" ein aus der Firmware geholtes weiteres zusätzliches Definitions-Script "profile" mit weiteren Variablen aufgerufen wird.
.
Diese Variablen sind gesetzt:
ECHO = | "/bin/echo" |
RM = | "/bin/rm" |
IFCONFIG = | "/sbin/ifconfig" |
IP = | "/bin/ip" |
MOUNT = | "/bin/mount" |
MKDIR = | "/bin/mkdir" |
RMDIR = | "/bin/rmdir" |
CAT = | "/bin/cat" |
MDEV = | "/sbin/mdev" |
SETTING_PATH = | "/etc/settings" |
if [ -f ${SETTING_PATH}/firmware_info_path ]; then
BASE_PATH="`cat ${SETTING_PATH}/firmware_info_path`"
else
BASE_PATH="/firmware"
fi
BASE_PATH = | "/firmware" |
.
Das alles sind ja erstmal nur virtuelle Pfade im Speicher, denn die RAM-Disk ist ja noch gar nicht erstellt oder installiert.
.
Diese Variablen werden "zusammengebaut" :
NAND_PATH = | "${BASE_PATH}/mnt/nand" |
DISK_PATH = | "${BASE_PATH}/mnt/sysdisk" |
INFO_PATH = | "${BASE_PATH}/mnt/info" |
MRD_MAC = | "${BASE_PATH}/sbin/mrd_mac" |
INFO_PRINTENV = | "${BASE_PATH}/sbin/info_printenv" |
INFO_SETENV = | "${BASE_PATH}/sbin/info_setenv" |
IMG_PATH = | "/ram_bin" |
USB_PATH = | "/mnt/partnerkey" |
.
- # Die obigen Variablen sind jetzt bereits für die nachfolgenden Scripte und Aktionen angelegt und mit Werten gefüllt bzw. definiert.
.
Im Klartext :
NAND_PATH = | /firmware/mnt/nand |
DISK_PATH = | /firmware/mnt/sysdisk |
INFO_PATH = | /firmware/mnt/info |
MRD_MAC = | /firmware/sbin/mrd_mac |
INFO_PRINTENV = | /firmware/sbin/info_printenv |
INFO_SETENV = | /firmware/sbin/info_setenv |
.
Weitere Start-Variablen werden gesetzt :
Which kernel and which system image partitions ?
.
CURR_BOOTFROM = | `${INFO_PRINTENV} curr_bootfrom awk -F"=" '{print $2}'` |
NEXT_BOOTFROM = | `${INFO_PRINTENV} next_bootfrom awk -F"=" '{print $2}'` |
.
if [ "${NEXT_BOOTFROM}" != "${CURR_BOOTFROM}" ]; then
CURR_BOOTFROM="${NEXT_BOOTFROM}"
fi
.
Im Klartext:
CURR_BOOTFROM = | /firmware/sbin/info_printenv curr_bootfrom awk -F"=" '{print $2}'` |
NEXT_BOOTFROM = | /firmware/sbin/info_printenv next_bootfrom awk -F"=" '{print $2}'` |
Weiterhin die Abfrage : Ist "NEXT_BOOTFROM" größer als "CURR_BOOTFROM", dann setze "CURR_BOOTFROM" = "NEXT_BOOTFROM" - also starte immer den Kernel der jeweils höchsten verfügbaren Firmware (nach einem Update).
.
Welche USB Geräte sind aktuell eingesteckt ?
- # Ab hier geht es nur um (eventuell) eingesteckte USB Geräte an den drei USB-3 Ports
check_and_run_usbkey()
{
USB_CHECK_FILE="${USB_PATH}/nas5xx_check_file"
any_usb=`ls /sys/block/ | grep sd`
${ECHO} "${any_usb}"
if [ -n "${any_usb}" ]; then
${MKDIR} ${USB_PATH}
for usb in ${any_usb}
do
${ECHO} "checking ${usb}"
#Get the number of question marks
qmark_num=`fdisk -l /dev/${usb} | grep "^"/dev/${usb} | grep -c "?"`
partition_num=`fdisk -l /dev/${usb} | grep "^"/dev/${usb}`
if [ "${qmark_num}" == "4" ] || [ "${partition_num}" == "" ]; then
mnt_point=/dev/${usb}
${ECHO} "Trying to mount ${mnt_point}"
${MOUNT} -o iocharset=utf8,shortname=mixed ${mnt_point} ${USB_PATH}
else
mnt_point=`fdisk -l /dev/${usb} | grep "^"/dev/${usb} | awk '{print $1}' | sed -n '1p'`
${ECHO} "Trying to mount ${mnt_point}"
${MOUNT} -o iocharset=utf8,shortname=mixed ${mnt_point} ${USB_PATH}
fi
- # Konnte ein USB Device gemounted werden !
mount_SUC=`${CAT} /proc/mounts | grep ${USB_PATH}`
if [ "${mount_SUC}" != "" ]; then
/sbin/check_key ${USB_CHECK_FILE}
if [ $? == 0 ]; then
${USB_PATH}/usb_key_func.sh
test $? -eq 0 && exit 0
fi
${UMOUNT} ${USB_PATH}
else
${ECHO} "Fail to mount ${mnt_point}"
fi
done
${RMDIR} ${USB_PATH}
fi
}
${ECHO} -e "\033[031m*** Stage 1: Setup system and device drivers ***\033[0m"
- # set LED to blink green
setLED SYS GREEN BLINK
- # Mount procfs and sysfs for ifconfig and hwclock
${MOUNT} -t proc /proc /proc
${MOUNT} -t sysfs /sys /sys
${MOUNT} -t usbfs none /proc/bus/usb
${MOUNT} -t devpts devpts /dev/pts
- # Create device node for gpio control
mknod -m 644 /dev/gpio c `cat /proc/devices | grep gpio | awk '{print $1}'` 0
.
Die Pfade werden montiert und gesetzt
.
- # Write some info to ${INFO_PATH}
.
- FWVERSION=`${BASE_PATH}/sbin/info_printenv fwversion_${CURR_BOOTFROM} 2>/dev/null | awk -F"=" '{print $2}'`
- REVISION=`${BASE_PATH}/sbin/info_printenv revision_${CURR_BOOTFROM} 2>/dev/null | awk -F"=" '{print $2}'`
- MODELID=`${BASE_PATH}/sbin/info_printenv modelid_${CURR_BOOTFROM} 2>/dev/null | awk -F"=" '{print $2}'`
- CORE_CHECKSUM=`${BASE_PATH}/sbin/info_printenv core_checksum_${CURR_BOOTFROM} 2>/dev/null | awk -F"=" '{print $2}'`
- ZLD_CHECKSUM=`${BASE_PATH}/sbin/info_printenv zld_checksum_${CURR_BOOTFROM} 2>/dev/null | awk -F"=" '{print $2}'`
- ROMFILE_CHECKSUM=`${BASE_PATH}/sbin/info_printenv romfile_checksum_${CURR_BOOTFROM} 2>/dev/null | awk -F"=" '{print $2}'`
- IMG_CHECKSUM=`${BASE_PATH}/sbin/info_printenv img_checksum_${CURR_BOOTFROM} 2>/dev/null | awk -F"=" '{print $2}'`
.
Im Klartext :
FWVERSION= | /firmware/sbin/info_printenv fwversion_${CURR_BOOTFROM} 2 > /dev/null awk -F"=" '{print $2}'` |
REVISION= | /firmware/sbin/info_printenv revision_${CURR_BOOTFROM} 2 > /dev/null awk -F"=" '{print $2}'` |
MODELID= | /firmware/sbin/info_printenv modelid_${CURR_BOOTFROM} 2 > /dev/null awk -F"=" '{print $2}'` |
CORE_CHECKSUM= | /firmware/sbin/info_printenv core_checksum_${CURR_BOOTFROM} 2 > /dev/null awk -F"=" '{print $2}'` |
ZLD_CHECKSUM= | /firmware/sbin/info_printenv zld_checksum_${CURR_BOOTFROM} 2 > /dev/null awk -F"=" '{print $2}'` |
ROMFILE_CHECKSUM= | /firmware/sbin/info_printenv romfile_checksum_${CURR_BOOTFROM} 2 > /dev/null awk -F"=" '{print $2}'` |
IMG_CHECKSUM= | /firmware/sbin/info_printenv img_checksum_${CURR_BOOTFROM} 2 > /dev/null awk -F"=" '{print $2}'` |
Diese Variablen sind in virtuellen Namen abgelegt ???
.
if [ ! -d ${INFO_PATH} ]; then
${MKDIR} -p ${INFO_PATH}
fi
.
- # Die oben zusammengebauten Variablen werden hier in einzelne Dateien nach "${INFO_PATH}/" geschrieben oder ausgegeben:
echo ${FWVERSION} > ${INFO_PATH}/fwversion
echo ${REVISION} > ${INFO_PATH}/revision
echo ${MODELID} > ${INFO_PATH}/modelid
echo ${CORE_CHECKSUM} > ${INFO_PATH}/core_checksum
echo ${ZLD_CHECKSUM} > ${INFO_PATH}/zld_checksum
echo ${ROMFILE_CHECKSUM} > ${INFO_PATH}/romfile_checksum
echo ${IMG_CHECKSUM} > ${INFO_PATH}/img_checksum
.
Im Klartext :
echo ${FWVERSION} > | /firmware/mnt/info/fwversion |
echo ${REVISION} > | /firmware/mnt/info/revision |
echo ${MODELID} > | /firmware/mnt/info/modelid |
echo ${CORE_CHECKSUM} > | /firmware/mnt/info/core_checksum |
echo ${ZLD_CHECKSUM} > | /firmware/mnt/info/zld_checksum |
echo ${ROMFILE_CHECKSUM} > | /firmware/mnt/info/romfile_checksum |
echo ${IMG_CHECKSUM} > | /firmware/mnt/info/img_checksum |
.
- # check if rootfs key (auf einem USB-Stick) inserted
MODELID_1="`${INFO_PRINTENV} modelid_1`"
MODELID_2="`${INFO_PRINTENV} modelid_2`"
if [ "${MODELID_1}" = "" ] && [ "${MODELID_2}" = "" ]; then
check_and_run_usbkey
fi
.
- # Driver to initialize MindSpeed hardware devices (network interface included)
- # Dieser Prozessor wird von MindSpeed gefertigt und enthält diverse Peripherie einschließlich LAN und/oder WLAN. Das Netzwerk- Interface wird frühzeitig benötigt, um evtl. von einem TFTP Server zu starten
.
/etc/hotplug2.rules --set-worker /lib/worker_fork.so --max-children 1 &
echo "${MDEV}" > /proc/sys/kernel/hotplug
${MDEV} -s
- #sleep 1
- #Insert pfe module with lro on and tx_qos off.
insmod pfe lro_mode=1 tx_qos=0
- #sleep 2
.
Der Aufpasser - der "watchdog-timer"
.
- # set watchdog timer
- # - if wdt is not reset until 15 seconds -> reset CPU
- # - in normal status, wdt will be reset every 8 seconds
WDT_DEV="/dev/comcerto_wdt"
RETRY_TIMES=0
MAX_RETRY_TIMES=10
ls -l ${WDT_DEV}
while [ ! -c "${WDT_DEV}" ] && [ ${RETRY_TIMES} -lt ${MAX_RETRY_TIMES} ]
do
RETRY_TIMES=$((RETRY_TIMES+1))
echo "no ${WDT_DEV} exist, sleep 1 second and retry it (${RETRY_TIMES})."
sleep 1
done
if [ -c ${WDT_DEV} ]; then
echo -e "\033[032mStarting watchdog ...\033[0m"
/bin/nice -n -20 /sbin/watchdog -t 8 -T 15 ${WDT_DEV}
else
echo -e "\033[032mNo ${WDT_DEV} exist and watchdog will not be started.\033[0m"
fi
- # stop MCU watchdog timer (will reset CPU every 60 seconds if MCU watchdog timer is not reset)
# 1: stop(reset) MCU watchdog
# 0: resume MCU watchdog timer
ls -l /proc/mcu_wdt
echo 1 > /proc/mcu_wdt
- #Set the port range from 32769 to 42768
${ECHO} "32769 42768" > /proc/sys/net/ipv4/ip_local_port_range
${ECHO} 8192 > /proc/sys/vm/min_free_kbytes
${ECHO} 100 > /proc/sys/vm/vfs_cache_pressure
${ECHO} 5 > /proc/sys/vm/dirty_background_ratio
${ECHO} 10 > /proc/sys/vm/dirty_ratio
${ECHO} "1 1" > /proc/sys/vm/lowmem_reserve_ratio
- #Set the TCP memory parameter to tune up performance
${ECHO} "512 87380 2048000" > /proc/sys/net/ipv4/tcp_rmem
${ECHO} "512 65536 2048000" > /proc/sys/net/ipv4/tcp_wmem
- #Set the net core buffer to tune up performanc
${ECHO} 524288 > /proc/sys/net/core/rmem_max
${ECHO} 524288 > /proc/sys/net/core/wmem_max
- ##### Setup Network settings for temporary use
${IFCONFIG} eth0 down
${IFCONFIG} eth0 hw ether `${MRD_MAC} eth0`
${IP} link set dev eth0 name egiga0
${IFCONFIG} eth1 down
${IFCONFIG} eth1 hw ether `${MRD_MAC} eth1`
${IP} link set dev eth1 name egiga1
${IFCONFIG} egiga0 up
${IFCONFIG} egiga1 up
${IFCONFIG} lo add 127.0.0.1 netmask 255.0.0.0
${IFCONFIG} lo up
- # Enable Generic Segmentation Offload
/sbin/ethtool -K egiga0 gso on
/sbin/ethtool -K egiga1 gso on
- # Set RTC time to system time
/sbin/rtcAccess init
/sbin/rtcAccess rtctosys
- # Bill's patch for performanc stability
echo 2 > /proc/sys/vm/overcommit_memory
echo 80 > /proc/sys/vm/overcommit_ratio
- # linuxrc runs /etc/init.d/rcS according to /etc/inittab.
- # Die Datei "linuxrc" liegt auch ganz unten im root Verzeichnis / und ist bei mir "nur" ein Link auf "/bin/busybox" - da stimmt doch etwas nicht .......
.
Bis hierhin ist immer noch kein Zyxel Debian Kernel geladen
Oder ich habe die Zeile übersehen, bei der das Mini-Linux des Bootloaders entfernt und der eigentliche - von 2 alternativen ausgewählte - Zyxel Debian Kernel aus der Firmware geladen wird.
.
/linuxrc
.
- #/sbin/init --- dieser Link, wenn er aktiv wäre, verweist auch auf "/bin/buysbox" ????? die Datei busybox ist aber 480 Kilobyte groß, das ist nicht plausibel.
- ########################################################################
- # NOTE: Do NOT append any code after this line.
.
.