Sie sind hier : Homepage →  > Linux (12) Technik des NAS-540→  > Einblick in ein NAS-542 OS→  1. Start-Sript "rcS"

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 jetzt eine Info-Datei, kein Script mehr.

Das Script "scR" ist nur die Vorlage gewesen für diese Ausführungen hier. Diese Datei hier können Sie also nicht mehr als "Script" in der shell laufen lassen, da viele Kommentare nicht auskommentiert sind. Es geht um das Verstehen der Ablauf-Reihenfolge. Dieses Script wird ganz am Ende von dem /init script aufgerufen.
.

rcS - 1.Start-Script in /etc/init.d/

.

  • # Dieses erste Start-Script steht in /etc/init.d/
  • # Alle Textausgaben (Texte, Bestätigungen und Warnungen und Fehler) des Scrpts mit "echo" werden auf die serielle Schnittstelle ausgegeben, die auf dem Prozessorboard zu finden ist, sofern sie nicht in Dateien umgelenkt werden.

.
#!/bin/sh
.

  • # NOTE:
  • # The main job of this script is ...
  • # 1. Prepare the root file system. (das wird im RAM in der RAM-Disk erstellt)
  • # 2. Mount system disk image from HDD (Hard-Disk-Drive). (wenn das System bereits installiert war)
  • # 3. Handle the condition that there is not valid system disk image. (wenn das System noch nie installiert war)

.

  • # In dem folgenden Aufruf der Datei "profile"werden jetzt erstmalig in diesem Boot-Prozess die typischen Linux Variablen gesetzt

.

. /etc/profile

.

  • # Und dann wird nochmal abgefragt : "Which kernel and system image partitions ?" Warum ?? Das ist nicht ganz ersichtlich, vermutlich weil ja von einem USB Stick gestartet werden könnte oder doch nicht ??


CURR_BOOTFROM_UPDATED="0"
NEXT_BOOTFROM=`${INFO_PRINTENV} next_bootfrom | awk -F"=" '{print $2}'`
CURR_BOOTFROM=`${INFO_PRINTENV} curr_bootfrom | awk -F"=" '{print $2}'`

if [ "${NEXT_BOOTFROM}" != "${CURR_BOOTFROM}" ]; then
    CURR_BOOTFROM="${NEXT_BOOTFROM}"
    CURR_BOOTFROM_UPDATED="1"
fi

  • # Hier wird die Partition bzw. das Image des höchsten Kernels bestimmt.


if [ "${CURR_BOOTFROM}" = "1" ]; then
    IMG_MTD=5
else
    IMG_MTD=7
fi

NEW_ROOT=""
SYSINIT_PASSWD="\$1\$\$4eHwTd8s1.UjO3wA36fmX1"

SYSINIT_PATH="/mnt/sysinit"

MODEL_ID=`${MRD_MODEL} -p`
RAM_BOOT_ABLE="YES"

  • # Set arp_ignore to 1 to reply only if the target IP address is local address


echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

  • # der CONF_PATH wurde in profile gesetzt


prepare_config_partition()
{
    if [ "${CONF_PATH}" != "" ]; then
        echo "--- remove all files in ${CONF_PATH}"
        rm -rf ${CONF_PATH}/*
    fi

  • # hier die diversen Konsolen-Ausgaben dieser Lösch-Funktion


    echo "--- umount ${CONF_PATH}"
    umount ${CONF_PATH}

    echo "--- remove \"ubi_config\" volume"
    ubirmvol /dev/ubi${CONFIG_MTD_NUM} -N ubi_config

    echo "--- detach ubi${CONFIG_MTD_NUM} from dev/mtd${CONFIG_MTD_NUM}"
    ubidetach -m ${CONFIG_MTD_NUM}

    sleep 1

    if [ $? == 0 ]; then
        echo "--- flash_erase ${CONFIG_MTD} 0 0"
        flash_erase ${CONFIG_MTD} 0 0  

  • # attach config mtd partition

 
       echo "--- mount ${CONF_PATH} back"
       ubiattach -m ${CONFIG_MTD_NUM} -d ${CONFIG_MTD_NUM} 

       #ubimkvol /dev/ubi${CONFIG_MTD_NUM} -N ubi_config -s 8MiB  - was sollte das hier ??

       ubimkvol /dev/ubi${CONFIG_MTD_NUM} -N ubi_config -m
       ${MOUNT} -t ${NAND_FS_TYPE} ubi${CONFIG_MTD_NUM}:ubi_config ${CONF_PATH}
       
    else
        ${ECHO} -e "\033[032mumount fail, skip flash_erase ${CONFIG_MTD} 0 0 ...\033[0m"
    fi
}
.

Nochmal die USB Sticks an den 3 Ports abfragen

.

  • # Die Existens eines USB Sticks an einem der 3 Ports (nochmal) abfragen

.
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

            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
}

no_image_handler()
{
.

  •     # Allow a user 'sysinit' to login FTP server

.
    ${SED} -i -e "s/^sysinit:\!\!:/sysinit:${SYSINIT_PASSWD}:/g" /etc/shadow
    ${MKDIR} -m 777 -p ${SYSINIT_PATH}

    echo "Starting Pure-FTPd ..."
    /bin/pure-ftpd.official `/bin/cat /etc/pure-ftpd.arg`
.

  • #    Count 10 seconds to wait for all device being detected.

.
    sleep 1
    echo "1 second..."
    sleep 1
    echo "2 second..."
    sleep 1
    echo "3 second..."
    sleep 1
    echo "4 second..."
    sleep 1
    echo "5 second..."
    sleep 1
    echo "6 second..."
    sleep 1
    echo "7 second..."
    sleep 1
    echo "8 second..."
    sleep 1
    echo "9 second..."
    sleep 1
    echo "10 second..."

  •     # Scan USB disk for HW test.

 
   check_and_run_usbkey
}
.

  • # Die Variable $1 is extracted image filename (sysdisk.img)

.
checksum_img()
{
    SYS_CHECKSUM_NOW=`${MD5SUM} $1 | ${AWK} '{print $1}'`
    SYS_CHECKSUM_INFO=`${INFO_PRINTENV} img_checksum_${CURR_BOOTFROM} 2>/dev/null | ${AWK} -F"=" '{print $2}'`

    echo "Checksum of sysdisk.img : ${SYS_CHECKSUM_NOW}"
    echo "Checksum from INFO  : ${SYS_CHECKSUM_INFO}"

    if [ "x"${SYS_CHECKSUM_INFO} == "x" ]; then
        echo "Checksum from INFO does not exist! Assume the sysdisk image is OK!"
        return 0
    fi

    if [ "x"${SYS_CHECKSUM_NOW} == "x"${SYS_CHECKSUM_INFO} ] || [ -e ${DISK_PATH}/mount.sda1.rw.flag ]; then
        return 0
    else
        return 1
    fi
}
.

Immer per Checksum abprüfen, ob der Kernel intakt ist :


  • # if one sys-root image or kernel is currpt => bootform another sys-root
  • # if dual sys-root or kernel are currpt => the buzzer beeps forever


flash_fail_handler()

{
    echo "the sys-root image /dev/mtdblock${IMG_MTD} is currupt !!"
    CURR_BOOTFROM=`${INFO_PRINTENV} curr_bootfrom | ${AWK} -F"=" '{print $2}'`
    CHANGE_BOOT_PART=`${INFO_PRINTENV} change_boot_part | ${AWK} -F"=" '{print $2}'`

    if [ "x"${CHANGE_BOOT_PART} == "x" ] || [ "${CHANGE_BOOT_PART}" == "0" ]; then

        ${INFO_SETENV} change_boot_part 1

        if [ "${CURR_BOOTFROM}" == "1" ]; then
            ${INFO_SETENV} next_bootfrom 2
        else
            ${INFO_SETENV} next_bootfrom 1
        fi

        echo "change boot image and reboot !!"
        ${REBOOT}

    elif [ "${CHANGE_BOOT_PART}" == "1" ]; then
        echo "Dual images are currupt !!!"
        no_image_handler
        ${BUZZERC} -t 31
    else
        echo "the printinfo value change_boot_part is fail !!!"
    fi

    exit 0
}
.

  • # rescan the host if the HDD (Hard-Disk-Drive) pin is on - but the scsi device can not found

.
rescan_lost_scsi_device()
{
    hostNum=`ls /sys/class/scsi_host | wc -l`
    hostIdLst=`ls /sys/class/scsi_host | cut -c 5`

    for hostId in ${hostIdLst}
    do
        hddId=$((${hostNum}-${hostId}))
        #rescan scsi if hdd_detect pin detect the hdd but NAS can not found scsi device
        if [ "`cat /proc/hdd${hddId}_detect`" == "1" ] && [ "`ls /sys/class/scsi_device | grep \"${hostId}:0:0:0\"`" == "" ]; then
            ${ECHO} -e "\033[031m*** rescan host${hostId} ***\033[0m" > /dev/console
            ${ECHO} -e "\033[031m*** rescan host${hostId} ***\033[0m" > /tmp/sto_log
            chmod 777 /tmp/sto_log
            ${ECHO} "- - -" > /sys/class/scsi_host/host${hostId}/scan
            sleep 3
        fi
    done
}

rescan_lost_scsi_device

${ECHO} -e "\033[031m*** Stage 2: Prepare the root file system ***\033[0m"

if [ "${CURR_BOOTFROM_UPDATED}" = "1" ]; then
    ${INFO_SETENV} curr_bootfrom ${CURR_BOOTFROM}
fi

  • # run telnetd - for development only
  • # das kann hier für die Entwickler eingeschaltet werden
  • # /sbin/telnetd

 .

  • # Create device node for gpio control


mknod -m 644 /dev/gpio c `cat /proc/devices  | grep gpio | awk '{print $1}'` 0

# set LED to blink green
# set LED SYS GREEN BLINK

#Initialize Fan control

${ECHO} "Initialize fan control"
mmiotool -w 0x90470058 0x05000000
mmiotool -w 0x90458000 0x80000001
mmiotool -w 0x90458028 0x80001388
.

Hier wird der 256 MB NAND-flash Chip initialisiert

.

  • # Mount the NAND-chip for System-Disk-image. - Der NAND-Chip oder der NAND-Speicher ist wie eine Festplatte als Block-Device strukturiert und braucht darum einen entsprechenden Treiber. Jetzt erst kann der (barebox) bootloader die einzelnen Partitionen ansprechen. Das zu startende System-Image "wohnt" in einer der Partitionen in dem NAND-Flash Speicher.


${ECHO} -e "\033[033mMount system partition...\033[0m"
${MKDIR} -p ${NAND_PATH}
ls -l /dev/ubi*

if [ ! -e /dev/ubi_ctrl ]; then
    ${ECHO} -e "\033[033mCreating /dev/ubi_ctrl ...\033[0m"
    M="`cat /sys/class/misc/ubi_ctrl/dev | awk -F':' '{print $1}'`"
    m="`cat /sys/class/misc/ubi_ctrl/dev | awk -F':' '{print $2}'`"
    mknod /dev/ubi_ctrl c $M $m
    if [ "$?" != "0" ]; then
        ${ECHO} "failed."
        no_image_handler
    fi
fi
.

  • # check key here - the earliest location to let pt/pk key work without errors

.
check_and_run_usbkey

ubiattach -m ${IMG_MTD} -d ${IMG_MTD}
mount -t ${NAND_FS_TYPE} -o ro ubi${IMG_MTD}:ubi_rootfs${CURR_BOOTFROM} ${NAND_PATH}

  • # I don't know why yaffs2 mount NAND with privilege 666.
  • # /bin/chmod 755 ${NAND_PATH}


if [ ! -e "${NAND_PATH}/sysdisk.img.gz" ]; then
    echo "NAND Flash Corrupt... "
    flash_fail_handler
    no_image_handler
#    flash_fail_handler
    exit
fi
.

  • ##### HTP - was genau wird hier abgeprüft ????
  • # execute "HTP forever" - "forever" ist eine Programmfunktion, damit ein Script nicht endlos läuft und evtl. außer Kontrolle gerät.

.
HTP_PIN=`cat /proc/htp_pin`
if [ ${HTP_PIN} == 1 ] && [ -f ${HTP_PATH}/htp.lst.internal ] ; then
        ${ECHO} -e "\033[031mHTP jumper detected. Start HTP internal test!\033[0m"
    if [ -e ${HTP_PATH}/htp_main.sh ]; then
        ${HTP_PATH}/htp_main.sh
    else
            ${HTP_PATH}/htp_main -l -f ${HTP_PATH}/htp.lst.internal
    fi
    exit 1
fi
.
/bin/storage_asm_mntfw_swap.sh ${DISK_PATH}
Flag_HD_Exists=$?

echo ${Flag_HD_Exists}
if [ "$Flag_HD_Exists" == "0" ]; then
    # check sysdisk.img md5sum

  • # an dierser Stelle hat das Script heraugefunden, es gibt (mindestens) eine HDD Disk-0.


    echo "Boot from disk"
.

Von der Festsplatte starten (wird jedenfalls versucht)


    if [ -f ${DISK_PATH}/sysdisk.img ]; then
        checksum_img ${DISK_PATH}/sysdisk.img
        if [ $? -eq 0 ]; then

            echo "Checksum pass!"
.
        else
            echo "Checksum does NOT match, system may be doing firmware upgrade. Extract new firmware from NAND flash ..."
            gzip -cd ${NAND_PATH}/sysdisk.img.gz > ${DISK_PATH}/sysdisk.img
            if [ $? -ne 0 ]; then
                flash_fail_handler
            else
                /bin/sync
                checksum_img ${DISK_PATH}/sysdisk.img
                if [ $? -eq 0 ]; then
                    echo "Checksum pass!"
                    BOOTDEV="DISK"
                else
                    echo -e "\033[031mChecksum of sysdisk.img does NOT match!\033[0m"
                    no_image_handler
                    exit 0
                fi
            fi
        fi
    else

  • # "System disk image does NOT exist on HDD (Hard-Disk-Drive)! Extract new firmware from NAND flash ..."


        echo "System disk image does NOT exist on HDD (Hard-Disk-Drive)! Extract new firmware from NAND flash ..."

  • # Das Entpackprogramm gzip muß also in dem "u-boot" loader enthalten sein, sont kann das Systemdisk-Image nicht entpackt werden.


        gzip -cd ${NAND_PATH}/sysdisk.img.gz > ${DISK_PATH}/sysdisk.img
        if [ $? -ne 0 ]; then
            flash_fail_handler
        else            
            /bin/sync

            checksum_img ${DISK_PATH}/sysdisk.img
            if [ $? -eq 0 ]; then
                echo "Checksum pass!"
                BOOTDEV="DISK"
            else
                echo -e "\033[031mChecksum of sysdisk.img does NOT match!\033[0m"
                no_image_handler
                exit 0
            fi
        fi
    fi

else

  • # "WARNING: No valid partition on HDD or no HDD (Hard-Disk-Drive) plugged!"
  • # Ob das System aus dem RAM startbar (bootable) ist , ist bereits vorher abgefragt worden. oder meint der Entwickler, ob das System aus dem Nand-flash gestartet werden kann ? Das ist nicht schlüssig.


    echo "WARNING: No valid partition on HDD or no HDD (Hard-Disk-Drive) plugged!"
    if [ "$RAM_BOOT_ABLE" == "YES" ]; then
        BOOTDEV="RAM"
    else
        no_image_handler
        exit 0
    fi
fi
.

Gibt es (oder gab es) eine (erste) Festplatte ?

.

  • # An dieser Stelle hat das Start-1-Script erkannt, ob überhaupt eine Fest-Platte (Hard-Disk-Drive) oder ein formatierter USB Stick vorhanden ist und von welchem Device (USB oder Platte oder aus dem RAM) gestartet werden kann.

.
export BOOTDEV

if [ "${BOOTDEV}" == "RAM" ]; then
    echo "WARNING: No valid partition on HDD or no HDD plugged"

    echo "Boot from RAM disk"

    ${MKDIR} -p ${DISK_PATH}
    ${MOUNT} -t ramfs none ${DISK_PATH}

    gzip -cd ${NAND_PATH}/sysdisk.img.gz >  ${DISK_PATH}/sysdisk.img


    if [ $? -ne 0 ]; then
        flash_fail_handler
    fi
fi

  • # the sysdisk is correct now


IS_CHANGE_BOOT_PART_EXIST=`${INFO_PRINTENV} | grep change_boot_part`
if [ "${IS_CHANGE_BOOT_PART_EXIST}" != "" ]; then
    CHANGE_BOOT_PART=`${INFO_PRINTENV} change_boot_part | awk -F"=" '{print $2}'`
    if [ "${CHANGE_BOOT_PART}" == "1" ]; then
        ${INFO_SETENV} change_boot_part 0
    fi
fi
.

  • # Must mount read-only

.
${MOUNT} -o remount,ro ${DISK_PATH}

if [ -e ${DISK_PATH}/mount.sda1.rw.flag ]; then
     ${MOUNT} -o remount,rw ${DISK_PATH}
fi

  • # Mount System Disk image for copying files from it.


if [ -f ${DISK_PATH}/sysdisk.img ]; then
    echo -e "\033[033mMount system disk image ...\033[0m"
    ${MKDIR} -p ${IMG_PATH}
    ${MOUNT} -t ext2 -o loop,ro ${DISK_PATH}/sysdisk.img ${IMG_PATH}

    if [ $? -ne 0 ]; then
        no_image_handler
        exit 1
    fi

else
    echo -e "\033[032mImage file (${DISK_PATH}/sysdisk.img) doesn't exist!\033[0m"
    no_image_handler
    exit 1
fi
.

Das ist eine der wichtigsten Stufen des Startsystems - die RAM-Disk wird erstellt und das sysdisk Image wird aus der Nand-Flash Partitiion dort hinein entpackt/expandiert.

.

Die ersten Verzeichnisse werden in der neu angelegten RAM-Disk montiert.


  • # Mount some read-only directories - dieser Vorgang wird bei jedem Neustart aufs Neue ausgeführt !!


${MOUNT} --bind ${IMG_PATH}/usr /usr
${MOUNT} --bind ${IMG_PATH}/lib/security /lib/security
${MOUNT} --bind ${IMG_PATH}/lib/modules /lib/modules
${MOUNT} --bind ${IMG_PATH}/lib/locale /lib/locale

cp -a ${IMG_PATH}/bin/* /bin/
cp -a ${IMG_PATH}/sbin/* /sbin/


  • # Backup default /etc/zyxel


${MKDIR} -p /tmp/zyxel
cp -a ${CONF_PATH}/* /tmp/zyxel

  • # Mount /etc/zyxel from NAND flash (will re-create it if needed)


ubiattach -m ${CONFIG_MTD_NUM} -d ${CONFIG_MTD_NUM}
${MOUNT} -t ${NAND_FS_TYPE} ubi${CONFIG_MTD_NUM}:ubi_config ${CONF_PATH}
#${MOUNT} -t ${NAND_FS_TYPE} ${CONFIG_MTD_BLOCK} ${CONF_PATH}

if [ "$?" != "0" ]; then
    ${ECHO} "mount ${CONF_PATH} failed"
    prepare_config_partition
    /bin/cp -af /tmp/zyxel /etc/
elif [ ! -e ${CONF_PATH}/conf ]; then
    ${ECHO} "${CONF_PATH}/conf does not exist.. recoverying ${CONF_PATH} ..."
    prepare_config_partition
    /bin/cp -af /tmp/zyxel /etc/
else
    ${ECHO} "mount ${CONF_PATH} successfully and ${CONF_PATH}/conf exist, nothing special."
fi

rm -rf /tmp/zyxel
.

  • ##### Check configuration restoration

.
if [ -f ${CONF_PATH}/zyconf.tgz ]; then
    ${ECHO} "Restoring configuration file ..."
    /bin/tar -zxf ${CONF_PATH}/zyconf.tgz -C ${CONF_PATH}

    if [ $? != 0 ]; then
        /bin/echo "*** Fail to restore configuration ***"
    fi

    /bin/rm -rf ${CONF_PATH}/zyconf.tgz
fi

/bin/chmod 777 ${CONF_PATH}

  • ##### Enhance reading performance
  • #echo "1024" > /sys/block/sda/queue/read_ahead_kb

  • # und hier am Ende wir das zweite Start-Sript "rcS2" aufgerufen

.
${IMG_PATH}/etc/init.d/rcS2

  • # Ende des Start-Scripts 1 - von "rcS"

.....

.

Startseite -- © 2001/2022 - Copyright by Dipl.-Ing. Gert Redlich / Germany - D-65191 Wiesbaden - Telefon-Nummer - Impressum