硬件架构

2026-02-01T12:41:03.png

幸狐官网学习网址

https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-quick-start/

启动流程

/etc/init.d/rcS

#!/bin/sh


# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do

     # Ignore dangling symlinks (if any).
     [ ! -f "$i" ] && continue

     case "$i" in
        *.sh)
            # Source shell script for speed.
            (
                trap - INT QUIT TSTP
                set start
                . $i
            )
            ;;
        *)
            # No sh extension, so fork subprocess.
            $i start
            ;;
    esac
done

S01seedrng

初始化随机数种子

#! /bin/sh
#
# Preserve the random seed between reboots. See urandom(4).
#
# This script can be called multiple times during operation (e.g. with
# "reload" argument) to refresh the seed.

# The following arguments can be added to SEEDRNG_ARGS in
# /etc/default/seedrng:
#   --seed-dir=/path/to/seed/directory
#     Path to the directory where the seed and the lock files are stored.
#     for optimal operation, this should be a persistent, writeable
#     location. Default is /var/lib/seedrng
#
#  --skip-credit
#     Set this to true only if you do not want seed files to actually
#     credit the RNG, for example if you plan to replicate this file
#     system image and do not have the wherewithal to first delete the
#     contents of /var/lib/seedrng.
#
# Example:
# SEEDRNG_ARGS="--seed-dir=/data/seedrng --skip-credit"
#

DAEMON="seedrng"
SEEDRNG_ARGS=""

# shellcheck source=/dev/null
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"

case "$1" in
        start|stop|restart|reload)
                # Never fail, as this isn't worth making a fuss
                # over if it doesn't go as planned.
                # shellcheck disable=SC2086 # we need the word splitting
                seedrng $SEEDRNG_ARGS || true;;
        *)
                echo "Usage: $0 {start|stop|restart|reload}"
                exit 1
esac

S01syslogd

开启syslog的守护进程

#!/bin/sh

DAEMON="syslogd"
PIDFILE="/var/run/$DAEMON.pid"

SYSLOGD_ARGS=""

# shellcheck source=/dev/null
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"

# BusyBox' syslogd does not create a pidfile, so pass "-n" in the command line
# and use "-m" to instruct start-stop-daemon to create one.
start() {
        printf 'Starting %s: ' "$DAEMON"
        # shellcheck disable=SC2086 # we need the word splitting
        start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/sbin/$DAEMON" \
                -- -n $SYSLOGD_ARGS
        status=$?
        if [ "$status" -eq 0 ]; then
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

stop() {
        printf 'Stopping %s: ' "$DAEMON"
        start-stop-daemon -K -q -p "$PIDFILE"
        status=$?
        if [ "$status" -eq 0 ]; then
                rm -f "$PIDFILE"
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

restart() {
        stop
        sleep 1
        start
}

case "$1" in
        start|stop|restart)
                "$1";;
        reload)
                # Restart, since there is no true "reload" feature.
                restart;;
        *)
                echo "Usage: $0 {start|stop|restart|reload}"
                exit 1
esac

S02klogd

开启klogd的守护进程

#!/bin/sh

DAEMON="klogd"
PIDFILE="/var/run/$DAEMON.pid"

KLOGD_ARGS=""

# shellcheck source=/dev/null
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"

# BusyBox' klogd does not create a pidfile, so pass "-n" in the command line
# and use "-m" to instruct start-stop-daemon to create one.
start() {
        printf 'Starting %s: ' "$DAEMON"
        # shellcheck disable=SC2086 # we need the word splitting
        start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/sbin/$DAEMON" \
                -- -n $KLOGD_ARGS
        status=$?
        if [ "$status" -eq 0 ]; then
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

stop() {
        printf 'Stopping %s: ' "$DAEMON"
        start-stop-daemon -K -q -p "$PIDFILE"
        status=$?
        if [ "$status" -eq 0 ]; then
                rm -f "$PIDFILE"
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

restart() {
        stop
        sleep 1
        start
}

case "$1" in
        start|stop|restart)
                "$1";;
        reload)
                # Restart, since there is no true "reload" feature.
                restart;;
        *)
                echo "Usage: $0 {start|stop|restart|reload}"
                exit 1
esac

S02sysctl TODO

sysctl相关操作

#!/bin/sh
#
# This script is used by busybox and procps-ng.
#
# With procps-ng, the "--system" option of sysctl also enables "--ignore", so
# errors are not reported via syslog. Use the run_logger function to mimic the
# --system behavior, still reporting errors via syslog. Users not interested
# on error reports can add "-e" to SYSCTL_ARGS.
#
# busybox does not have a "--system" option neither reports errors via syslog,
# so the scripting provides a consistent behavior between the implementations.
# Testing the busybox sysctl exit code is fruitless, as at the moment, since
# its exit status is zero even if errors happen. Hopefully this will be fixed
# in a future busybox version.

PROGRAM="sysctl"

SYSCTL_ARGS=""

# shellcheck source=/dev/null
[ -r "/etc/default/$PROGRAM" ] && . "/etc/default/$PROGRAM"

# Files are read from directories in the SYSCTL_SOURCES list, in the given
# order. A file may be used more than once, since there can be multiple
# symlinks to it. No attempt is made to prevent this.
SYSCTL_SOURCES="/etc/sysctl.d/ /usr/local/lib/sysctl.d/ /usr/lib/sysctl.d/ /lib/sysctl.d/ /etc/sysctl.conf"

# If the logger utility is available all messages are sent to syslog, except
# for the final status. The file redirections do the following:
#
# - stdout is redirected to syslog with facility.level "kern.info"
# - stderr is redirected to syslog with facility.level "kern.err"
# - file dscriptor 4 is used to pass the result to the "start" function.
#
run_logger() {
        # shellcheck disable=SC2086 # we need the word splitting
        find $SYSCTL_SOURCES -maxdepth 1 -name '*.conf' -print0 2> /dev/null | \
        xargs -0 -r -n 1 readlink -f | {
                prog_status="OK"
                while :; do
                        read -r file || {
                                echo "$prog_status" >&4
                                break
                        }
                        echo "* Applying $file ..."
                        /sbin/sysctl -p "$file" $SYSCTL_ARGS || prog_status="FAIL"
                done 2>&1 >&3 | /usr/bin/logger -t sysctl -p kern.err
        } 3>&1 | /usr/bin/logger -t sysctl -p kern.info
}

# If logger is not available all messages are sent to stdout/stderr.
run_std() {
        # shellcheck disable=SC2086 # we need the word splitting
        find $SYSCTL_SOURCES -maxdepth 1 -name '*.conf' -print0 2> /dev/null | \
        xargs -0 -r -n 1 readlink -f | {
                prog_status="OK"
                while :; do
                        read -r file || {
                                echo "$prog_status" >&4
                                break
                        }
                        echo "* Applying $file ..."
                        /sbin/sysctl -p "$file" $SYSCTL_ARGS || prog_status="FAIL"
                done
        }
}

if [ -x /usr/bin/logger ]; then
        run_program="run_logger"
else
        run_program="run_std"
fi

start() {
        printf '%s %s: ' "$1" "$PROGRAM"
        status=$("$run_program" 4>&1)
        echo "$status"
        if [ "$status" = "OK" ]; then
                return 0
        fi
        return 1
}

case "$1" in
        start)
                start "Running";;
        restart|reload)
                start "Rerunning";;
        stop)
                :;;
        *)
                echo "Usage: $0 {start|stop|restart|reload}"
                exit 1
esac

S10udev

udev相关的操作

#!/bin/sh
#
# udev  This is a minimal non-LSB version of a UDEV startup script.  It
#       was derived by stripping down the udev-058 LSB version for use
#       with buildroot on embedded hardware using Linux 2.6.34+ kernels.
#
#       You may need to customize this for your system's resource limits
#       (including startup time!) and administration.  For example, if
#       your early userspace has a custom initramfs or initrd you might
#       need /dev much earlier; or without hotpluggable busses (like USB,
#       PCMCIA, MMC/SD, and so on) your /dev might be static after boot.
#
#       This script assumes your system boots right into the eventual root
#       filesystem, and that init runs this udev script before any programs
#       needing more device nodes than the bare-bones set -- /dev/console,
#       /dev/zero, /dev/null -- that's needed to boot and run this script.
#

# Check for config file and read it
UDEV_CONFIG=/etc/udev/udev.conf
test -r $UDEV_CONFIG || exit 6
. $UDEV_CONFIG

case "$1" in
    start)
        printf "Populating %s using udev: " "${udev_root:-/dev}"
        [ -e /proc/sys/kernel/hotplug ] && printf '\000\000\000\000' > /proc/sys/kernel/hotplug
        /sbin/udevd -d || { echo "FAIL"; exit 1; }
        udevadm trigger --type=subsystems --action=add
        udevadm trigger --type=devices --action=add
        udevadm settle --timeout=30 || echo "udevadm settle failed"
        echo "done"
        ;;
    stop)
        # Stop execution of events
        udevadm control --stop-exec-queue
        killall udevd
        ;;
    *)
        echo "Usage: $0 {start|stop}"
        exit 1
        ;;
esac


exit 0

S20linkmount

分区建立和挂载的操作

#!/bin/sh
bootmedium=emmc
linkdev(){
if [ ! -d "/dev/block/by-name" ];then
mkdir -p /dev/block/by-name
cd /dev/block/by-name
ln -sf /dev/mmcblk0p1 env
ln -sf /dev/mmcblk0p2 idblock
ln -sf /dev/mmcblk0p3 uboot
ln -sf /dev/mmcblk0p4 boot
ln -sf /dev/mmcblk0p5 oem
ln -sf /dev/mmcblk0p6 userdata
ln -sf /dev/mmcblk0p7 rootfs
fi }
mount_part(){
if [ -z "$1" -o -z "$2" -o -z "$3" ];then
        echo "Invalid paramter, exit !!!"
        exit 1
fi
root_dev=$(mountpoint -n /)
root_dev=${root_dev%% *}
partname=$1
part_dev=/dev/block/by-name/$1
mountpt=$2
part_fstype=$3
part_realdev=$(realpath $part_dev)

if [ ! -d $mountpt ]; then
        if [ "$mountpt" = "IGNORE" -a "emmc" = "$bootmedium" ];then
                if [ "$root_dev" = "$part_realdev" ];then
                        resize2fs $part_dev
                fi
                return 0;
        elif [ "$mountpt" = "IGNORE" -a "sd_card" = "$bootmedium" ];then
                if [ "$root_dev" = "$part_realdev" ];then
                        resize2fs $part_dev
                fi
                return 0;
        else
                echo "${0} info: mount point path [$mountpt] not found, skip..."
                return 1;
        fi
fi

if test -h $part_dev; then
case $bootmedium in
        emmc|sd_card)
                if [ "$root_dev" = "$part_realdev" ];then
                        resize2fs $part_dev
                else
                        e2fsck -y $part_dev
                        mount -t $part_fstype $part_dev $mountpt
                        if [ $? -eq 0 ]; then
                                resize2fs $part_dev
                                tune2fs $part_dev -L $partname
                        else
                                echo "mount $partname error, try to format..."
                                mke2fs -F -L $partname $part_dev  &&                                    tune2fs -c 0 -i 0 $part_dev &&                                  mount -t $part_fstype $part_dev $mountpt
                        fi
                fi
                ;;
        spi_nand|slc_nand)
                if [ $partname = "rootfs" ];then
                        echo "rootfs mount on $root_dev"
                elif [ "$part_fstype" = "ubifs" ]; then
                        part_no=$(echo $part_realdev | grep -oE "[0-9]*$")
                        ubi_dev=/dev/ubi${part_no}
                        ubi_vol=${ubi_dev}_0
                        mount | grep $ubi_vol
                        if [ $? -eq 0 ];then
                                echo "***********$partname has been mounted***********"
                        else
                                if [ ! -e $ubi_vol ];then
                                        echo "***********$ubi_vol not exist***********"
                                        if [ ! -e $ubi_dev ];then
                                                echo "***********$ubi_dev not exist***********"
                                                ubiattach /dev/ubi_ctrl -m $part_no -d $part_no
                                                if [ $? -ne 0 ];then
                                                        echo "ubiattach $part_realdev error, try to format..."
                                                        ubiformat -y $part_realdev
                                                        ubiattach /dev/ubi_ctrl -m $part_no -d $part_no
                                                fi
                                        fi
                                        ubi_info_dir=/sys/class/ubi/ubi${part_no}
                                        avail_eraseblocks=$(cat $ubi_info_dir/avail_eraseblocks)
                                        eraseblock_size=$(cat $ubi_info_dir/eraseblock_size)
                                        echo "try to make volume: $ubi_vol ..."
                                        ubimkvol $ubi_dev -N $partname -s $((avail_eraseblocks*eraseblock_size))
                                fi
                                mount -t $part_fstype $ubi_vol $mountpt
                        fi
                elif [ "$part_fstype" = "squashfs" ]; then
                        part_no=$(echo $part_realdev | grep -oE "[0-9]*$")
                        ubi_dev=/dev/ubi${part_no}
                        ubi_vol=${ubi_dev}_0
                        ubi_block=/dev/ubiblock${part_no}_0
                        mount | grep $ubi_block
                        if [ $? -eq 0 ];then
                                echo "***********$partname has been mounted***********"
                        else
                                if [ ! -e $ubi_block ];then
                                        echo "***********$ubi_block not exist***********"
                                        ubiattach /dev/ubi_ctrl -m $part_no -d $part_no
                                        if [ $? -ne 0 ];then
                                                echo "ubiattach $part_realdev error, return !!!"
                                                echo "Please check the device: $part_realdev"
                                                return 1
                                        fi
                                        ubiblock -c $ubi_vol
                                fi
                                mount -t $part_fstype $ubi_block $mountpt
                        fi
                elif [ "$part_fstype" = "erofs" ]; then
                        part_no=$(echo $part_realdev | grep -oE "[0-9]*$")
                        ubi_dev=/dev/ubi${part_no}
                        ubi_vol=${ubi_dev}_0
                        ubi_block=/dev/ubiblock${part_no}_0
                        mount | grep $ubi_block
                        if [ $? -eq 0 ];then
                                echo "***********$partname has been mounted***********"
                        else
                                if [ ! -e $ubi_block ];then
                                        echo "***********$ubi_block not exist***********"
                                        ubiattach /dev/ubi_ctrl -m $part_no -d $part_no
                                        if [ $? -ne 0 ];then
                                                echo "ubiattach $part_realdev error, return !!!"
                                                echo "Please check the device: $part_realdev"
                                                return 1
                                        fi
                                        ubiblock -c $ubi_vol
                                fi
                                mount -t $part_fstype $ubi_block $mountpt
                        fi
                else
                        echo "Error: wrong filesystem type: $part_fstype, return !!!"
                        return 1
                fi
                ;;
        spi_nor)
                if [ "$root_dev" = "$part_realdev" ];then
                        echo "***********$part_dev has been mounted, skipping***********"
                else
                        echo "mount -t $part_fstype $part_dev $mountpt"
                        mount -t $part_fstype $part_dev $mountpt
                        if [ $? -eq 0 ]; then
                                echo "***********succeed in mounting***********"
                        elif [ "$part_fstype" = "jffs2" ]; then
                                echo "mount $partname error, try to format..."
                                echo "flash_erase -j ${part_realdev/block/} 0 0 && mount -t $part_fstype $part_dev $mountpt"
                                flash_erase -j ${part_realdev/block/} 0 0 && mount -t $part_fstype $part_dev $mountpt
                        else
                                echo "mount $partname error, skipping! Please check the filesystem."
                        fi
                fi
                ;;
        *)
                echo "Invalid Parameter: Check bootmedium !!!"
                exit 1
                ;;
esac
fi
}
case $1 in start) linkdev;
mount_part rootfs IGNORE ext4 ;
mount_part userdata /userdata ext4 ;
mount_part oem /oem ext4 ;
;; linkdev) linkdev ;
;; stop) printf stop $0 finished\n ;; *) echo Usage: $0 {start|stop} exit 1 ;; esac

S20urandom

随机数初始化相关

#! /bin/sh
#
# urandom       This script saves the random seed between reboots.
#               It is called from the boot, halt and reboot scripts.
#
# Version:      @(#)urandom  1.33  22-Jun-1998  miquels@cistron.nl
#

[ -c /dev/urandom ] || exit 0
#. /etc/default/rcS

case "$1" in
        start|"")
                # check for read only file system
                if ! touch /etc/random-seed 2>/dev/null
                then
                        echo "read-only file system detected...done"
                        exit
                fi
                if [ "$VERBOSE" != no ]
                then
                        printf "Initializing random number generator... "
                fi
                # Load and then save 512 bytes,
                # which is the size of the entropy pool
                cat /etc/random-seed >/dev/urandom
                rm -f /etc/random-seed
                umask 077
                dd if=/dev/urandom of=/etc/random-seed count=1 \
                        >/dev/null 2>&1 || echo "urandom start: failed."
                umask 022
                [ "$VERBOSE" != no ] && echo "done."
                ;;
        stop)
                if ! touch /etc/random-seed 2>/dev/null
                then
                        exit
                fi
                # Carry a random seed from shut-down to start-up;
                # see documentation in linux/drivers/char/random.c
                [ "$VERBOSE" != no ] && printf "Saving random seed... "
                umask 077
                dd if=/dev/urandom of=/etc/random-seed count=1 \
                        >/dev/null 2>&1 || echo "urandom stop: failed."
                [ "$VERBOSE" != no ] && echo "done."
                ;;
        *)
                echo "Usage: urandom {start|stop}" >&2
                exit 1
                ;;
esac

S21appinit

#!/bin/sh
#初始化环境变量
[ -f /etc/profile.d/RkEnv.sh ] && source /etc/profile.d/RkEnv.sh
case $1 in
        start)
                sh /oem/usr/bin/RkLunch.sh #运行脚本
                ;;
        stop)
                sh /oem/usr/bin/RkLunch-stop.sh
                ;;
        *)
                exit 1
                ;;
esac

RkLunch.sh

#!/bin/sh

rcS() {
        #运行用户的启动脚本
        for i in /oem/usr/etc/init.d/S??*; do

                # Ignore dangling symlinks (if any).
                [ ! -f "$i" ] && continue #检查文件是否存在且是普通文件

                case "$i" in#根据文件名后缀选择不同的执行方式
                *.sh)
                        # Source shell script for speed.
                        (
                                trap - INT QUIT TSTP #清楚信号处理
                                set start #设置位置参数 $1 = "start"
                                . $i #执行shell脚本
                        )
                        ;;
                *)
                        # No sh extension, so fork subprocess.
                        $i start #非sh拓展的直接执行
                        ;;
                esac
        done
}

#检查参数2是否是符号链接,如果不是则强制创建参数1的软链接
check_linker() {
        [ ! -L "$2" ] && ln -sf $1 $2
}

network_init() {
       #提取HWaddr 地址
        ethaddr1=$(ifconfig -a | grep "eth.*HWaddr" | awk '{print $5}')
        
        #如果文件存在则比对mac地址是否一样,不一样则重新设置
        if [ -f /data/ethaddr.txt ]; then
                ethaddr2=$(cat /data/ethaddr.txt)
                if [ $ethaddr1 == $ethaddr2 ]; then
                        echo "eth HWaddr cfg ok"
                else
                        ifconfig eth0 down
                        ifconfig eth0 hw ether $ethaddr2
                fi
        #文件不存在则将获取到的mac地址写入到文件中        
        else
                echo $ethaddr1 >/data/ethaddr.txt
        fi
        #启动网络并随机分配IP地址
        ifconfig eth0 up && udhcpc -i eth0 >/dev/null 2>&1
}

post_chk() {
        #TODO: ensure /userdata mount done
        #等待30秒 判断userdata是否挂起
        cnt=0
        while [ $cnt -lt 30 ]; do
                cnt=$((cnt + 1))
                if mount | grep -w userdata; then
                        break
                fi
                sleep .1
        done

        # if ko exist, install ko first
        default_ko_dir=/ko
        #加载驱动
        if [ -f "/oem/usr/ko/insmod_ko.sh" ]; then
                default_ko_dir=/oem/usr/ko
        fi
        if [ -f "$default_ko_dir/insmod_ko.sh" ]; then
                cd $default_ko_dir && sh insmod_ko.sh && cd -
        fi
        
        #初始化网络
        network_init &
        
        #创建软链接
        check_linker /userdata /oem/usr/www/userdata
        check_linker /media/usb0 /oem/usr/www/usb0
        check_linker /mnt/sdcard /oem/usr/www/sdcard
        # if /data/rkipc not exist, cp /usr/share
        rkipc_ini=/userdata/rkipc.ini
        default_rkipc_ini=/tmp/rkipc-factory-config.ini
        
        #如果不存在rkipc.ini文件
        if [ ! -f "/oem/usr/share/rkipc.ini" ]; then
        #lsmod显示加载的所有内核,判断加载的摄像头然后拷贝初始化文件
                lsmod | grep mis5001
                if [ $? -eq 0 ]; then
                        ln -s -f /oem/usr/share/rkipc-mis5001-500w.ini $default_rkipc_ini
                fi
                lsmod | grep sc530ai
                if [ $? -eq 0 ]; then
                        ln -s -f /oem/usr/share/rkipc-500w.ini $default_rkipc_ini
                fi
                lsmod | grep sc4336
                if [ $? -eq 0 ]; then
                        ln -s -f /oem/usr/share/rkipc-400w.ini $default_rkipc_ini
                fi
                lsmod | grep sc3336
                if [ $? -eq 0 ]; then
                        ln -s -f /oem/usr/share/rkipc-300w.ini $default_rkipc_ini
                fi
                lsmod | grep imx415
                if [ $? -eq 0 ]; then
                        ln -s -f /oem/usr/share/rkipc-800w.ini $default_rkipc_ini
                fi
        fi

        # check md5sum
        # tmp_md5=/tmp/.rkipc-ini.md5sum
        # data_md5=/userdata/.rkipc-default.md5sum
        # md5sum $default_rkipc_ini > $tmp_md5
        # chk_rkipc=`cat $tmp_md5|awk '{print $1}'`
        # rm $tmp_md5
        # if [ ! -f $data_md5 ];then
        #       md5sum $default_rkipc_ini > $data_md5
        # fi
        # grep -w $chk_rkipc $data_md5
        # if [ $? -ne 0 ] ;then
        #       rm -f $rkipc_ini
        #       echo "$chk_rkipc" > $data_md5
        # fi
        
        #如果不存在初始化文件就退出
        if [ ! -f "$default_rkipc_ini" ]; then
                echo "Error: not found rkipc.ini !!!"
                exit -1
        fi
        #如果rkipc.ini不存在则拷贝
        #if [ ! -f "$rkipc_ini" ]; then
                cp $default_rkipc_ini $rkipc_ini -f
        #fi
        
        #如果image.bmp不存在则拷贝
        if [ ! -f "/userdata/image.bmp" ]; then
                cp -fa /oem/usr/share/image.bmp /userdata/
        fi
        
        #如果音频测试文件存在则调用rk_mpi_ao_test进行文件输出 喇叭测试
        if [ -f "/oem/usr/share/speaker_test.wav" ]; then
                rk_mpi_ao_test -i /oem/usr/share/speaker_test.wav --sound_card_name=hw:0,0 --device_ch=2 --device_rate=8000 --input_rate=8000 --input_ch=2 --set_volume 50
        fi
        
        # 运行rkipc进程,制定aig配置文件
        if [ -d "/oem/usr/share/iqfiles" ]; then
                rkipc -a /oem/usr/share/iqfiles &
        else
                rkipc &
        fi
}

rcS

#配置产生core
ulimit -c unlimited
echo "/data/core-%p-%e" >/proc/sys/kernel/core_pattern
# echo 0 > /sys/devices/platform/rkcif-mipi-lvds/is_use_dummybuf

echo 1 >/proc/sys/vm/overcommit_memory

post_chk &

S25backlight

就是加载一个调节背光的驱动

#!/bin/sh

start(){
        if [ -f "/oem/usr/ko/pwm_bl.ko" ]; then
                sleep 1
                insmod /oem/usr/ko/pwm_bl.ko
        fi
}

case $1 in
start)
        start &
        ;;
*)
        exit 1
        ;;
esac

S30dbus

dbus相关

#!/bin/sh
# 创建需要的文件夹
[ -d /run/dbus ] || mkdir -p /run/dbus
[ -d /var/lock/subsys ] || mkdir -p /var/lock/subsys
[ -d /tmp/dbus ] || mkdir -p /tmp/dbus

#返回值
RETVAL=0

start() {
    printf "Starting system message bus: "

    dbus-uuidgen --ensure # 确保生成唯一的D-Bus UUID
    dbus-daemon --system # 启动系统级D-Bus守护进程
    RETVAL=$? # 获取返回值
    echo "done"
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/dbus-daemon # 创建锁文件
}

stop() {
    printf "Stopping system message bus: "

    ## we don't want to kill all the per-user $processname, we want
    ## to use the pid file *only*; because we use the fake nonexistent
    ## program name "$servicename" that should be safe-ish
    killall dbus-daemon # 终止所有dbus-daemon进程
    RETVAL=$?
    echo "done"
    if [ $RETVAL -eq 0 ]; then
        rm -f /var/lock/subsys/dbus-daemon # 删除锁文件
        rm -f /run/messagebus.pid # 删除PID文件
    fi
}

# See how we were called.
# 根据传入的命令执行
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    condrestart)
        if [ -f /var/lock/subsys/$servicename ]; then
            stop
            start
        fi
        ;;
    reload)
        echo "Message bus can't reload its configuration, you have to restart it"
        RETVAL=$?
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|condrestart|reload}"
        ;;
esac
exit $RETVAL

S40bluetoothd

开启蓝牙进程并将pid写入到/var/run/bluetoothd.pid

#!/bin/sh

DAEMON="bluetoothd"
PIDFILE="/var/run/$DAEMON.pid"

BLUETOOTHD_ARGS="-n"

# shellcheck source=/dev/null
#检查PID文件是否存在
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"

#开启蓝牙
start() {
        printf 'Starting %s: ' "$DAEMON"
        # shellcheck disable=SC2086 # we need the word splitting
        start-stop-daemon -S -q -m -b -p "$PIDFILE" -x "/usr/libexec/bluetooth/$DAEMON" \
                -- $BLUETOOTHD_ARGS
        status=$?
        if [ "$status" -eq 0 ]; then
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

stop() {
        printf 'Stopping %s: ' "$DAEMON"
        start-stop-daemon -K -q -p "$PIDFILE"
        status=$?
        if [ "$status" -eq 0 ]; then
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

restart() {
        stop
        sleep 1
        start
}

reload() {
        printf 'Reloading %s: ' "$DAEMON"
        start-stop-daemon -K -s HUP -q -p "$PIDFILE"
        status=$?
        if [ "$status" -eq 0 ]; then
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

case "$1" in
        start|stop|restart|reload)
                "$1";;
        *)
                echo "Usage: $0 {start|stop|restart|reload}"
                exit 1
esac

S40network

开启网络相关的配置

#!/bin/sh
#
# Start the network....
#

# Debian ifupdown needs the /run/network lock directory
mkdir -p /run/network

case "$1" in
  start)
        printf "Starting network: "
        /sbin/ifup -a
        [ $? = 0 ] && echo "OK" || echo "FAIL"
        ;;
  stop)
        printf "Stopping network: "
        /sbin/ifdown -a
        [ $? = 0 ] && echo "OK" || echo "FAIL"
        ;;
  restart|reload)
        "$0" stop
        "$0" start
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit $?

S49ntp

开启ntp进程并将pid写入到/var/run/ntpd.pid

#!/bin/sh
#
# Starts Network Time Protocol daemon
#

DAEMON="ntpd"
PIDFILE="/var/run/$DAEMON.pid"

NTPD_ARGS=" -g"

# shellcheck source=/dev/null
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"

start() {
        printf 'Starting %s: ' "$DAEMON"
        # shellcheck disable=SC2086 # we need the word splitting
        start-stop-daemon -S -q -p "$PIDFILE" -x "/usr/sbin/$DAEMON" \
                -- $NTPD_ARGS -p "$PIDFILE"
        status=$?
        if [ "$status" -eq 0 ]; then
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

stop() {
        printf 'Stopping %s: ' "$DAEMON"
        start-stop-daemon -K -q -p "$PIDFILE"
        status=$?
        if [ "$status" -eq 0 ]; then
                rm -f "$PIDFILE"
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

restart() {
        stop
        sleep 1
        start
}

case "$1" in
        start|stop|restart)
                "$1";;
        reload)
                # Restart, since there is no true "reload" feature.
                restart;;
        *)
                echo "Usage: $0 {start|stop|restart|reload}"
                exit 1
esac

S50sshd

开启sshd进程

#启动sshd
#!/bin/sh
#
# sshd        Starts sshd.
#

# Make sure the ssh-keygen progam exists
# 确保ssh-keygen存在
[ -f /usr/bin/ssh-keygen ] || exit 0

umask 077

start() {
        chown root:root /var/empty/
        # Create any missing keys
        /usr/bin/ssh-keygen -A

        printf "Starting sshd: "
        /usr/sbin/sshd
        touch /var/lock/sshd
        echo "OK"
}
stop() {
        printf "Stopping sshd: "
        killall sshd
        rm -f /var/lock/sshd
        echo "OK"
}
restart() {
        stop
        start
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart|reload)
        restart
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit $?

S50telnet

开启telnet进程并将pid写入到/var/run/telnetd.pid

#!/bin/sh
#
# Start telnet....
#

TELNETD_ARGS=-F
[ -r /etc/default/telnet ] && . /etc/default/telnet

start() {
      printf "Starting telnetd: "
      start-stop-daemon -S -q -m -b -p /var/run/telnetd.pid \
                        -x /usr/sbin/telnetd -- $TELNETD_ARGS
      [ $? = 0 ] && echo "OK" || echo "FAIL"
}

stop() {
        printf "Stopping telnetd: "
        start-stop-daemon -K -q -p /var/run/telnetd.pid \
                          -x /usr/sbin/telnetd
        [ $? = 0 ] && echo "OK" || echo "FAIL"
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart|reload)
        stop
        start
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit $?

S50usbdevice TODO

USB相关,还未细看

#!/bin/sh
#
# setup configfs for adbd, usb mass storage and MTP....
# For kernel v4.4 usb configfs
#
# Load default env variables from profiles
. /etc/profile

UMS_EN=off
ADB_EN=on
MTP_EN=off
NTB_EN=off
ACM_EN=off
UAC1_EN=off
UAC2_EN=off
UVC_EN=off
RNDIS_EN=on
HID_EN=off

USB_ATTRIBUTE=0x409
USB_GROUP=rockchip
USB_SKELETON=b.1

CONFIGFS_DIR=/sys/kernel/config
USB_CONFIGFS_DIR=${CONFIGFS_DIR}/usb_gadget/${USB_GROUP}
USB_STRINGS_DIR=${USB_CONFIGFS_DIR}/strings/${USB_ATTRIBUTE}
USB_FUNCTIONS_DIR=${USB_CONFIGFS_DIR}/functions
USB_CONFIGS_DIR=${USB_CONFIGFS_DIR}/configs/${USB_SKELETON}

# For VBUS_ALWAYS_ON usb otg is not support ums
# Since the block to ums is always occupated by USB due to no disconneted state
UMS_BLOCK=/userdata/ums_shared.img
UMS_BLOCK_SIZE=0        #unit M
UMS_BLOCK_TYPE=fat
UMS_BLOCK_AUTO_MOUNT=off
UMS_RO=0

UVC_DIR=${USB_FUNCTIONS_DIR}/uvc.gs6/
UVC_STREAMING_DIR=${UVC_DIR}/streaming/
UVC_CONTROL_DIR=${UVC_DIR}/control/
UVC_U_DIR=${UVC_STREAMING_DIR}/uncompressed/u/
UVC_M_DIR=${UVC_STREAMING_DIR}/mjpeg/m/
UVC_F_DIR=${UVC_STREAMING_DIR}/framebased/f/

test_write()
{
        test -e $2 && echo $1 > $2
}

function_init()
{
        mkdir ${USB_FUNCTIONS_DIR}/uac1.gs0
        test_write 1 ${USB_FUNCTIONS_DIR}/uac1.gs0/c_feature_unit
        test_write 1 ${USB_FUNCTIONS_DIR}/uac1.gs0/p_feature_unit
        mkdir ${USB_FUNCTIONS_DIR}/uac2.gs0
        test_write 1 ${USB_FUNCTIONS_DIR}/uac2.gs0/c_feature_unit
        test_write 1 ${USB_FUNCTIONS_DIR}/uac2.gs0/p_feature_unit
        mkdir ${USB_FUNCTIONS_DIR}/ffs.adb
        mkdir ${USB_FUNCTIONS_DIR}/ffs.ntb
        mkdir ${USB_FUNCTIONS_DIR}/mtp.gs0
        mkdir ${USB_FUNCTIONS_DIR}/rndis.gs0
        #write /config/usb_gadget/g1/functions/rndis.gs0/wceis 1
        mkdir ${USB_FUNCTIONS_DIR}/acm.gs6
        mkdir ${USB_FUNCTIONS_DIR}/mass_storage.0
        mkdir ${USB_FUNCTIONS_DIR}/uvc.gs6
        mkdir ${USB_FUNCTIONS_DIR}/hid.usb0
}

configfs_init()
{
        echo "Debug: configfs_init"
        mkdir /dev/usb-ffs

        mount -t configfs none ${CONFIGFS_DIR}
        mkdir ${USB_CONFIGFS_DIR} -m 0770
        echo 0x2207 > ${USB_CONFIGFS_DIR}/idVendor
        echo 0x0310 > ${USB_CONFIGFS_DIR}/bcdDevice
        echo 0x0200 > ${USB_CONFIGFS_DIR}/bcdUSB
        mkdir ${USB_STRINGS_DIR}   -m 0770
        SERIAL=`cat /proc/cpuinfo | grep Serial | awk '{print $3}'`
        if [ -z $SERIAL ];then
                SERIAL=0123456789ABCDEF
        fi
        echo $SERIAL > ${USB_STRINGS_DIR}/serialnumber
        echo "rockchip"  > ${USB_STRINGS_DIR}/manufacturer
        echo "rk3xxx"  > ${USB_STRINGS_DIR}/product

        function_init

        mkdir ${USB_CONFIGS_DIR}  -m 0770
        mkdir ${USB_CONFIGS_DIR}/strings/${USB_ATTRIBUTE}  -m 0770

        echo 0x1 > ${USB_CONFIGFS_DIR}/os_desc/b_vendor_code
        echo "MSFT100" > ${USB_CONFIGFS_DIR}/os_desc/qw_sign
        echo 500 > ${USB_CONFIGS_DIR}/MaxPower
        ln -s ${USB_CONFIGS_DIR} ${USB_CONFIGFS_DIR}/os_desc/b.1
}

make_config_string()
{
        tmp=$CONFIG_STRING
        if [ -n "$CONFIG_STRING" ]; then
                CONFIG_STRING=${tmp}_${1}
        else
                CONFIG_STRING=$1
        fi
}

parse_parameter()
{
        # find name and var
        NAME=`echo $1 | awk -F "=" '{print $1}'`
        VAR=`echo $1 | awk -F "=" '{print $2}'`

        case "$NAME" in
                ums_block)
                        UMS_BLOCK=${VAR}
                        ;;
                ums_block_size)
                        if [ ! "$VAR" -gt 0 ] 2>/dev/null ;then
                                echo "$VAR is not a number"
                                exit 1
                        fi
                        UMS_BLOCK_SIZE=${VAR}
                        ;;
                ums_block_type)
                        UMS_BLOCK_TYPE=${VAR}
                        ;;
                ums_block_auto_mount)
                        UMS_BLOCK_AUTO_MOUNT=${VAR}
                        ;;
                ums_ro)
                        if [ "$VAR" != "off" ]; then
                                echo "Set UMS read-only"
                                UMS_RO=1
                        fi
                                UMS_RO=0
                        ;;
        esac
}

parameter_init()
{
        while read line
        do
                case "$line" in
                        usb_mtp_en)
                                MTP_EN=on
                                make_config_string mtp
                                ;;
                        usb_adb_en)
                                ADB_EN=on
                                make_config_string adb
                                ;;
                        usb_ums_en)
                                UMS_EN=on
                                make_config_string ums
                                ;;
                        usb_ntb_en)
                                NTB_EN=on
                                make_config_string ntb
                                ;;
                        usb_acm_en)
                                ACM_EN=on
                                make_config_string acm
                                ;;
                        usb_uac1_en)
                                UAC1_EN=on
                                make_config_string uac1
                                ;;
                        usb_uac2_en)
                                UAC2_EN=on
                                make_config_string uac2
                                ;;
                        usb_uvc_en)
                                UVC_EN=on
                                make_config_string uvc
                                ;;
                        usb_rndis_en)
                                RNDIS_EN=on
                                make_config_string rndis
                                ;;
                        usb_hid_en)
                                HID_EN=on
                                make_config_string hid
                                ;;
                        *)
                                parse_parameter ${line}
                                ;;
                esac
        done < $USB_CONFIG_FILE

        case "$CONFIG_STRING" in
                ums)
                        PID=0x0000
                        ;;
                mtp)
                        PID=0x0001
                        ;;
                adb)
                        PID=0x0006
                        ;;
                mtp_adb | adb_mtp)
                        PID=0x0011
                        ;;
                ums_adb | adb_ums)
                        PID=0x0018
                        ;;
                acm)
                        PID=0x1005
                        ;;
                *)
                        PID=0x0019
        esac
}

use_os_desc()
{
        if [ $MTP_EN = on ];then
                echo "MTP" > ${USB_FUNCTIONS_DIR}/mtp.gs0/os_desc/interface.MTP/compatible_id
                echo 1 > ${USB_CONFIGFS_DIR}/os_desc/use
        fi
}

pre_run_binary()
{
        if [ $ADB_EN = on ];then
                mkdir /dev/usb-ffs/adb -m 0770
                mount -o uid=2000,gid=2000 -t functionfs adb /dev/usb-ffs/adb
                start-stop-daemon --start --quiet --background --exec /usr/bin/adbd
        fi

        if [ $NTB_EN = on ];then
                mkdir /dev/usb-ffs/ntb -m 0770
                mount -o uid=2000,gid=2000 -t functionfs ntb /dev/usb-ffs/ntb
                # Not start app here
        fi

        # Add uvc app here with start-stop-daemon
}

configure_uvc_resolution_yuyv()
{
        W=$1
        H=$2
        DIR=${UVC_U_DIR}/${H}p/
        mkdir ${DIR}
        echo $W > ${DIR}/wWidth
        echo $H > ${DIR}/wHeight
        echo 333333 > ${DIR}/dwDefaultFrameInterval
        echo $((W*H*20)) > ${DIR}/dwMinBitRate
        echo $((W*H*20)) > ${DIR}/dwMaxBitRate
        echo $((W*H*2)) > ${DIR}/dwMaxVideoFrameBufferSize
        echo -e "333333\n666666\n1000000\n2000000" > ${DIR}/dwFrameInterval
}

configure_uvc_resolution_mjpeg()
{
        W=$1
        H=$2
        DIR=${UVC_M_DIR}/${H}p/
        mkdir ${DIR}
        echo $W > ${DIR}/wWidth
        echo $H > ${DIR}/wHeight
        echo 333333 > ${DIR}/dwDefaultFrameInterval
        echo $((W*H*20)) > ${DIR}/dwMinBitRate
        echo $((W*H*20)) > ${DIR}/dwMaxBitRate
        echo $((W*H*2)) > ${DIR}/dwMaxVideoFrameBufferSize
        echo -e "333333\n666666\n1000000\n2000000" > ${DIR}/dwFrameInterval
}

configure_uvc_resolution_h264()
{
        W=$1
        H=$2
        DIR=${UVC_F_DIR}/${H}p/
        mkdir ${DIR}
        echo $W > ${DIR}/wWidth
        echo $H > ${DIR}/wHeight
        echo 333333 > ${DIR}/dwDefaultFrameInterval
        echo $((W*H*10)) > ${DIR}/dwMinBitRate
        echo $((W*H*10)) > ${DIR}/dwMaxBitRate
        #echo $((W*H*2)) > ${DIR}/dwMaxVideoFrameBufferSize
        echo -e "333333\n666666\n1000000\n2000000" > ${DIR}/dwFrameInterval
}

syslink_function()
{
        ln -s ${USB_FUNCTIONS_DIR}/$1 ${USB_CONFIGS_DIR}/f${USB_FUNCTIONS_CNT}
        let USB_FUNCTIONS_CNT=USB_FUNCTIONS_CNT+1
}

bind_functions()
{
        USB_FUNCTIONS_CNT=1

        test $UAC1_EN = on && syslink_function uac1.gs0
        test $UAC2_EN = on && syslink_function uac2.gs0

        if [ $UVC_EN = on ];then
                #echo 3072 > ${UVC_DIR}/streaming_maxpacket
                #echo 1 > ${UVC_DIR}/streaming_bulk

                mkdir ${UVC_CONTROL_DIR}/header/h
                ln -s ${UVC_CONTROL_DIR}/header/h ${UVC_CONTROL_DIR}/class/fs/h
                ln -s ${UVC_CONTROL_DIR}/header/h ${UVC_CONTROL_DIR}/class/ss/h

                ##YUYV support config
                mkdir ${UVC_U_DIR}
                configure_uvc_resolution_yuyv 640 480
                configure_uvc_resolution_yuyv 1280 720

                ##mjpeg support config
                mkdir ${UVC_M_DIR}
                configure_uvc_resolution_mjpeg 640 480
                configure_uvc_resolution_mjpeg 1280 720
                configure_uvc_resolution_mjpeg 1920 1080
                configure_uvc_resolution_mjpeg 2560 1440
                configure_uvc_resolution_mjpeg 2592 1944

                ## h.264 support config
                mkdir ${UVC_F_DIR}
                configure_uvc_resolution_h264 640 480
                configure_uvc_resolution_h264 1280 720
                configure_uvc_resolution_h264 1920 1080

                mkdir ${UVC_STREAMING_DIR}/header/h
                ln -s ${UVC_U_DIR} ${UVC_STREAMING_DIR}/header/h/u
                ln -s ${UVC_M_DIR} ${UVC_STREAMING_DIR}/header/h/m
                ln -s ${UVC_F_DIR} ${UVC_STREAMING_DIR}/header/h/f
                ln -s ${UVC_STREAMING_DIR}/header/h ${UVC_STREAMING_DIR}/class/fs/h
                ln -s ${UVC_STREAMING_DIR}/header/h ${UVC_STREAMING_DIR}/class/hs/h
                ln -s ${UVC_STREAMING_DIR}/header/h ${UVC_STREAMING_DIR}/class/ss/h

                syslink_function uvc.gs6
        fi

        test $RNDIS_EN = on && syslink_function rndis.gs0
        test $MTP_EN = on && syslink_function mtp.gs0
        test $NTB_EN = on && syslink_function ffs.ntb
        test $ADB_EN = on && syslink_function ffs.adb
        test $ACM_EN = on && syslink_function acm.gs6

        if [ $HID_EN = on ]; then
                echo 1 > /sys/kernel/config/usb_gadget/rockchip/functions/hid.usb0/protocol
                echo 1 > /sys/kernel/config/usb_gadget/rockchip/functions/hid.usb0/subclass
                echo 8 > /sys/kernel/config/usb_gadget/rockchip/functions/hid.usb0/report_length
                echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > /sys/kernel/config/usb_gadget/rockchip/functions/hid.usb0/report_desc
                syslink_function hid.usb0
        fi

        if [ $UMS_EN = on ];then
                echo ${UMS_RO} > ${USB_FUNCTIONS_DIR}/mass_storage.0/lun.0/ro
                if [ "$UMS_BLOCK_SIZE" != "0" -a ! -e ${UMS_BLOCK} ]; then
                        dd if=/dev/zero of=${UMS_BLOCK} bs=1M count=${UMS_BLOCK_SIZE}
                        mkfs.${UMS_BLOCK_TYPE} ${UMS_BLOCK}
                        test $? && echo "Warning: failed to mkfs.${UMS_BLOCK_TYPE} ${UMS_BLOCK}"
                fi
                mkdir /mnt/ums -p
                if [ $UMS_BLOCK_AUTO_MOUNT = on ];then
                        mount ${UMS_BLOCK} /mnt/ums
                else
                        echo ${UMS_BLOCK} > ${USB_FUNCTIONS_DIR}/mass_storage.0/lun.0/file
                fi
                syslink_function mass_storage.0
        fi

        echo ${CONFIG_STRING} > ${USB_CONFIGS_DIR}/strings/${USB_ATTRIBUTE}/configuration
}

run_binary()
{
        if [ $MTP_EN = on ];then
                start-stop-daemon --start --quiet --background --exec /usr/bin/mtp-server
        fi
        if [ $RNDIS_EN = on ];then

        sleep .5
        ifconfig usb0 172.32.0.70
        ifconfig usb0 up
        fi

}

program_kill()
{
        P_PID=`ps | grep $1 | grep -v grep | awk '{print $1}'`
        test -z ${P_PID} || kill -9 ${P_PID}
}

usb_device_stop()
{
        echo "none" > ${USB_CONFIGFS_DIR}/UDC
        program_kill adbd
        program_kill mtp-server
        ls ${USB_CONFIGS_DIR} | grep f[0-9] | xargs -I {} rm ${USB_CONFIGS_DIR}/{}
}

case "$1" in
start)
        ifconfig lo up
#       if [ ! -e "/tmp/.usb_config" ]; then
#               echo "$0: Cannot find .usb_config"
#               # exit 0
#               USB_CONFIG_FILE=/tmp/.usb_config
#               echo "usb_adb_en" >> $USB_CONFIG_FILE
#       fi

#       if [ -e /tmp/.usb_config ]; then
#               USB_CONFIG_FILE=/tmp/.usb_config
#       fi

        parameter_init
#       if [ -z $CONFIG_STRING ]; then
#               echo "$0: no function be selected"
#               exit 0
#       fi
        test -d ${USB_CONFIGFS_DIR} || configfs_init
        use_os_desc
        echo $PID > ${USB_CONFIGFS_DIR}/idProduct
        bind_functions
        pre_run_binary
        sleep 1
        UDC=`ls /sys/class/udc/| awk '{print $1}'`
        echo $UDC > ${USB_CONFIGFS_DIR}/UDC
        run_binary
        ;;
stop)
        usb_device_stop
        ;;
restart|reload)
        # Do restart usb by udev
        echo "USB_FORCE_CHANGED" >> /tmp/.usb_config
        usb_device_stop
        sleep 1
        $0 start
        # Don't forget to clear "USB_FORCE_CHANGED"
        sed -i "/USB_FORCE_CHANGED/d" /tmp/.usb_config
        ;;
*)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit 0

S60micinit

#!/bin/sh
#使能环境变量
[ -f /etc/profile.d/RkEnv.sh ] && source /etc/profile.d/RkEnv.sh
#音频播放设置
case $1 in
        start)
                if command -v amixer >/dev/null 2>&1; then
                        amixer set 'ADC ALC Left' 26 > /dev/null 2>&1
                        amixer set 'ADC ALC Right' 26 > /dev/null 2>&1
                        amixer set 'ADC MIC Left Gain' 3 > /dev/null 2>&1
                        amixer set 'ADC MIC Right Gain' 3 > /dev/null 2>&1
                        amixer set 'ADC MICBIAS Voltage' 'VREFx0_975' > /dev/null 2>&1
                        amixer set 'ADC Mode' 'SingadcL' > /dev/null 2>&1
                fi
                ;;
        *)
                exit 1
                ;;
esac

S91smb

启动samba服务

#!/bin/sh

[ -f /etc/samba/smb.conf ] || exit 0

mkdir -p /var/log/samba

start() {
        printf "Starting SMB services: "
        smbd -D
        [ $? = 0 ] && echo "OK" || echo "FAIL"

        printf "Starting NMB services: "
        nmbd -D
        [ $? = 0 ] && echo "OK" || echo "FAIL"
}

stop() {
        printf "Shutting down SMB services: "
        kill -9 `pidof smbd`
        [ $? = 0 ] && echo "OK" || echo "FAIL"

        printf "Shutting down NMB services: "
        kill -9 `pidof nmbd`
        [ $? = 0 ] && echo "OK" || echo "FAIL"
}

restart() {
        stop
        start
}

reload() {
        printf "Reloading smb.conf file: "
        kill -HUP `pidof smbd`
        [ $? = 0 ] && echo "OK" || echo "FAIL"
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        restart
        ;;
  reload)
        reload
        ;;
  *)
        echo "Usage: $0 {start|stop|restart|reload}"
        exit 1
esac

exit $?

S99_auto_reboot

配置自动重启脚本

#!/bin/sh

case "$1" in
        start)
                if [ -e "/oem/rockchip_test/auto_reboot.sh" ]; then
                        echo "start recovery auto-reboot"
                        mkdir -p /data/cfg/rockchip_test
                        cp /oem/rockchip_test/auto_reboot.sh /data/cfg/rockchip_test/
                fi

                if [ -e "/data/cfg/rockchip_test/power_lost_test.sh" ]; then
                        echo "start test flash power lost"
                        source /data/cfg/rockchip_test/power_lost_test.sh &
                fi
                if [ -e "/data/cfg/rockchip_test/auto_reboot.sh" ]; then
                        echo "start auto-reboot"
                        source /data/cfg/rockchip_test/auto_reboot.sh `cat /data/cfg/rockchip_test/reboot_total_cnt`&
                fi

                ;;
        stop)
                echo "stop auto-reboot finished"
                ;;
        restart|reload)
                $0 stop
                $0 start
                ;;
        *)
                echo "Usage: $0 {start|stop|restart}"
                exit 1
esac

exit 0

S99hciinit

音频相关的初始化

#!/bin/sh

check_hciconfig() {
        if command -v hciattach &> /dev/null; then
                if lsmod | grep -q "aic8800_fdrv"; then
                        hciattach -s 1500000 /dev/ttyS1 any 1500000 flow nosleep&
                        sleep 2
                        if hciconfig -a | grep -q "hci0"; then
                                hciconfig hci0 up&
                        else
                                echo "hci0 not found or not available."
                        fi
      ifconfig wlan0 up && udhcpc -i wlan0 > /dev/null 2>&1
                else
                        echo "aic8800_fdrv not found."
                fi
        fi
}

case $1 in
        start)
                check_hciconfig &
                ;;
        *)
                exit 1
                ;;
esac

S99luckfoxconfigload

开发板配置相关

#!/bin/sh

load_luckfoxconfig() {
        if [ -f /usr/bin/luckfox-config ]; then
                luckfox-config load
        fi
        if [ "$(cat /proc/device-tree/model)" == "Luckfox Pico Ultra" ] ||
                [ "$(cat /proc/device-tree/model)" == "Luckfox Pico Ultra W" ]; then
                if [ -f /usr/bin/luckfox_switch_rgb_resolution ]; then
                        luckfox_switch_rgb_resolution &
                fi
        fi
}

case $1 in
start)
        load_luckfoxconfig
        ;;
*)
        exit 1
        ;;
esac

S99luckfoxcustomoverlay TODO

#!/bin/bash
LUCKFOX_FDT_DTB=/tmp/.fdt.dtb
LUCKFOX_FDT_HDR_DTB=/tmp/.fdt_header.dtb
LUCKFOX_FDT_HDR_OVERLAY_DTS=/tmp/.fdt_header_overlay.dts
LUCKFOX_FDT_HDR_OVERLAY_DTBO=/tmp/.fdt_header_overlay.dtbo

LUCKFOX_FDT_DUMP_TXT=/tmp/.fdt_dump.txt
LF_CUSTOM_DTS_PATH="/mnt/cfg"
SYS_OVERLAYS_PATH="/sys/kernel/config/device-tree/overlays"
LUCKFOX_CHIP_MEDIA_CLASS="emmc"
LUCKFOX_CHIP_MEDIA="/dev/mmcblk0p4"

function luckfox_tools_check() {
        if ! command -v dialog &>/dev/null; then
                echo "The dialog is not installed "
                exit
        fi

        if ! command -v dtc &>/dev/null; then
                echo "The dtc is not installed"
                exit
        fi

        # get media class dev
        if [[ -e /dev/mmcblk0p4 ]]; then
                LUCKFOX_CHIP_MEDIA_CLASS="emmc"
                LUCKFOX_CHIP_MEDIA=/dev/mmcblk0p4
        elif [[ -e /dev/mmcblk1p4 ]]; then
                LUCKFOX_CHIP_MEDIA_CLASS="sdmmc"
                LUCKFOX_CHIP_MEDIA=/dev/mmcblk1p4
                luckfox_set_pin_parameter "SDMMC" 1
        elif [[ -e /dev/mtdblock3 ]]; then
                LUCKFOX_CHIP_MEDIA_CLASS="spi_nand"
                LUCKFOX_CHIP_MEDIA=/dev/mtdblock3
        else
                LUCKFOX_CHIP_MEDIA_CLASS="unknown"
                echo "Do not know the storage medium of Luckfox!"
                exit
        fi

}

# -- Static Overlay --
function luckfox_sha256_convert() {
        local sha256_hash=$1
        local formatted_hash=""

        for ((i = 0; i < ${#sha256_hash}; i += 8)); do
                formatted_hash+="0x${sha256_hash:$i:8} "
        done

        echo "$formatted_hash"
}

function luckfox_update_fdt() {
        # get fdt_header
        local origin_fdt_size_hex origin_fdt_size
        dd if=$LUCKFOX_CHIP_MEDIA of=$LUCKFOX_FDT_HDR_DTB bs=1 skip=0 count=2048 >/dev/null 2>&1

        # get size
        if [ ! -f $LUCKFOX_FDT_HDR_DTB ]; then
                echo "$LUCKFOX_FDT_HDR_DTB can't be found!"
                return
        fi
        origin_fdt_size_hex=$(fdtdump $LUCKFOX_FDT_HDR_DTB | grep -A 5 "fdt {" | grep "data-size" | awk '{print $3}' | tr -d ';<>')
        origin_fdt_size=$(printf "%d\n" "$origin_fdt_size_hex")

        # get fdt dtb
        dd if=$LUCKFOX_CHIP_MEDIA of=$LUCKFOX_FDT_DTB bs=1 skip=2048 count="$origin_fdt_size" >/dev/null 2>&1

        # create fdt dump
        if [ ! -f $LUCKFOX_FDT_DTB ]; then
                echo "$LUCKFOX_FDT_DTB can't be found!"
                return
        fi
        fdtdump $LUCKFOX_FDT_DTB >$LUCKFOX_FDT_DUMP_TXT
}

function luckfox_fdt_overlay() {
        #region
        local fdt_overlay_dtbo="$1"
        local fdt_dtb_size fdt_size fdt_size_hex fdt_hash_data

        fdtoverlay -i $LUCKFOX_FDT_DTB -o $LUCKFOX_FDT_DTB "$fdt_overlay_dtbo" >/dev/null 2>&1
        fdt_dtb_size=$(ls -la $LUCKFOX_FDT_DTB | awk '{print $5}')

        kernel_offset=$(fdtdump $LUCKFOX_FDT_HDR_DTB | grep -A 2 "kernel {" | grep "data-position" | sed -n 's/.*<\(0x[0-9a-fA-F]*\)>.*/\1/p')
        fdt_offset=$(fdtdump $LUCKFOX_FDT_HDR_DTB | grep -A 2 "fdt {" | grep "data-position" | sed -n 's/.*<\(0x[0-9a-fA-F]*\)>.*/\1/p')

        kernel_offset_dec=$((kernel_offset))
        fdt_offset_dec=$((fdt_offset))
        result_dec=$((kernel_offset_dec - fdt_offset_dec))

        if [ $result_dec -lt "$fdt_dtb_size" ]; then
                echo "Kernel will be affected !"
        fi

        dd if=$LUCKFOX_FDT_DTB of=$LUCKFOX_CHIP_MEDIA bs=1 seek=2048 count="$fdt_dtb_size" >/dev/null 2>&1

        # fdt header
        if [ ! -f $LUCKFOX_FDT_DTB ]; then
                echo "$LUCKFOX_FDT_DTB can't be found!"
                return
        fi
        fdt_size=$(ls -la $LUCKFOX_FDT_DTB | awk '{print $5}')
        fdt_size_hex=$(printf "%x\n" "$fdt_size")
        fdt_hash_data=$(luckfox_sha256_convert "$(sha256sum $LUCKFOX_FDT_DTB | awk '{print $1}')")
        fdt_header_content="
/dts-v1/;
/plugin/;

&{/images/fdt}{
    data-size=<0x$fdt_size_hex>;
    hash{
        value=<$fdt_hash_data>;
    };
};
"
        echo "$fdt_header_content" >$LUCKFOX_FDT_HDR_OVERLAY_DTS
        dtc -I dts -O dtb $LUCKFOX_FDT_HDR_OVERLAY_DTS -o $LUCKFOX_FDT_HDR_OVERLAY_DTBO
        if [ ! -f $LUCKFOX_FDT_HDR_OVERLAY_DTBO ]; then
                echo "$LUCKFOX_FDT_HDR_OVERLAY_DTBO can't found!"
                return
        fi
        fdtoverlay -i $LUCKFOX_FDT_HDR_DTB -o $LUCKFOX_FDT_HDR_DTB $LUCKFOX_FDT_HDR_OVERLAY_DTBO >/dev/null 2>&1
        dd if=$LUCKFOX_FDT_HDR_DTB of=$LUCKFOX_CHIP_MEDIA bs=1 seek=0 count=2048 >/dev/null 2>&1
        #endregion
}

# Load the device tree dynamically
function luckfox_load_dynamic_dts() {
        local dtbo_node_name

        if [ ! -d ${LF_CUSTOM_DTS_PATH}/dtbo/ ]; then
                exit 1
                #echo "Can't find ${LF_CUSTOM_DTS_PATH}/dtbo dir !"
        fi

        for dts_file in ${LF_CUSTOM_DTS_PATH}/dtbo/*.dts; do
                #Get DTBO name
                dtbo_node_name="$(basename "$dts_file" .dts)"
                #Check DTBO path
                if [ -d "${SYS_OVERLAYS_PATH}/${dtbo_node_name}" ]; then
                        echo "Node is exist"
                        continue
                fi

                #DTS->DTBO
                dtc -I dts -O dtb ${LF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dts -o \
                        ${LF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dtbo

                if [ ! -f "${LF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dtbo" ]; then
                        echo "${dtbo_node_name}.dts to dtbo error!"
                        continue
                else
                        mkdir -p ${SYS_OVERLAYS_PATH}/${dtbo_node_name}
                fi
                #Load and enable DTBO
                cat ${LF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dtbo > \
                        ${SYS_OVERLAYS_PATH}/${dtbo_node_name}/dtbo
                echo 1 >${SYS_OVERLAYS_PATH}/${dtbo_node_name}/status

                rm ${LLF_CUSTOM_DTS_PATH}/dtbo/${dtbo_node_name}.dtbo
        done
}

#Overwrite the disk device tree (requires restart)
function luckfox_load_static_dts() {
        local dtbo_node_name
        if [ ! -d ${LF_CUSTOM_DTS_PATH}/fdt_overlay/ ]; then
                echo "Can't find ${LF_CUSTOM_DTS_PATH}/fdt_overlay dir!"
        fi

        for dts_file in ${LF_CUSTOM_DTS_PATH}/fdt_overlay/*.dts; do
                #Get DTBO name
                dtbo_node_name="$(basename "$dts_file" .dts)"

                #DTS->DTBO
                dtc -I dts -O dtb ${LF_CUSTOM_DTS_PATH}/fdt_overlay/${dtbo_node_name}.dts -o \
                        ${LF_CUSTOM_DTS_PATH}/fdt_overlay/${dtbo_node_name}.dtbo

                if [ ! -f "${LF_CUSTOM_DTS_PATH}/fdt_overlay/${dtbo_node_name}.dtbo" ]; then
                        echo "${dtbo_node_name}.dts to dtbo error!"
                        continue
                fi

                # load to disk
                luckfox_update_fdt
                luckfox_fdt_overlay ${LF_CUSTOM_DTS_PATH}/fdt_overlay/${dtbo_node_name}.dtbo
                rm ${LUCKFOX_FDT_OVERLAY_DTBO}

        done
}

case $1 in
start)
        luckfox_load_dynamic_dts
        ;;
stop)
        luckfox_tools_check
        luckfox_load_static_dts
        ;;
*)
        exit 1
        ;;
esac

S99python

运行python脚本

#!/bin/sh
#
# python        Starts python code.
#

# Make sure the python progam exists
[ -f /usr/bin/python ] || exit 0

umask 077

main_path="/root/main.py"
boot_path="/root/boot.py"

start() {
        # Run python progam
    if [ -f $main_path ]; then
            echo "running $main_path..."
        python $main_path
    else
        if [ -f $boot_path ]; then
            echo "running $boot_path..."
            python $boot_path
        else
            echo "$main_path and $boot_path not exist ,pass..."
        fi
    fi
    echo "OK"
}
stop() {
        printf "Stopping python: "
        killall python
        echo "OK"
}
restart() {
        stop
        start
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart|reload)
        restart
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

exit $?

S99rtcinit

RTC时间校准

#!/bin/sh

case $1 in
start)
        if [ "$(hwclock | grep "1969")" ]; then
                echo "RTC time calibration"
                date -s 2024-01-01
                hwclock -w
        else
                echo "RTC does not require time calibration"
        fi
        ;;
*)
        exit 1
        ;;
esac

S99usb0config

USB相关配置,配置IP等等

#!/bin/sh

TARGET_IP="172.32.0.93"

USB_KEYWORD="android_work: sent uevent USB_STATE="
USB_MODE_PATH="/proc/device-tree/usbdrd/usb@ffb00000/dr_mode"

MAX_RETRIES=10
retries=0

usb0_config() {
        if [ "$(cat /proc/device-tree/usbdrd/usb@ffb00000/dr_mode)" == "peripheral" ]; then
                current_ip=$(ifconfig usb0 | grep -o 'inet addr:[^ ]*' | awk -F ':' '{print $2}')
                echo "current_ip = $current_ip"
                echo "TARGET_IP = $TARGET_IP"

                while [[ "$current_ip" != "$TARGET_IP" && $retries -lt $MAX_RETRIES ]]; do
                        sleep .5
                        echo "luckfox : set usb0 ip"
                        ifconfig usb0 "$TARGET_IP"
                        current_ip=$(ifconfig usb0 | grep -o 'inet addr:[^ ]*' | awk -F ':' '{print $2}')
                        echo $current_ip
                        retries=$((retries + 1))
                done

                if [[ "$current_ip" != "$TARGET_IP" ]]; then
                        echo "usb0 config error"
                else
                        echo "usb0 config success"
                fi
        else
                echo "usb0 is using host mode"
        fi
}

usb_reset() {
        while true; do
                last_line=$(dmesg | grep "$USB_KEYWORD" | tail -n 1)

                if [[ "$last_line" == *"DISCONNECTED"* ]]; then
                        echo "Detected USB DISCONNECTED."
                        /etc/init.d/S50usbdevice restart
                        usb0_config
                #elif [[ "$last_line" == *"CONFIGURED"* ]]; then
                #    echo "Detected CONFIGURED. No action required."
                #else
                #    echo "No relevant USB_STATE found."
                fi

                sleep 5
        done
}

case $1 in
start)
        # check peripheral
        usb_mode="$(cat $USB_MODE_PATH)"
        if [ "$usb_mode" = "peripheral" ]; then
                usb0_config
                usb_reset &
        fi
        ;;
stop) ;;
*)
        exit 1
        ;;
esac

自定义启动流程

#!/bin/sh


network_init() {
   #提取HWaddr 地址
        ethaddr1=$(ifconfig -a | grep "eth.*HWaddr" | awk '{print $5}')

        #如果文件存在则比对mac地址是否一样,不一样则重新设置
        if [ -f /data/ethaddr.txt ]; then
                        ethaddr2=$(cat /data/ethaddr.txt)
                        if [ $ethaddr1 == $ethaddr2 ]; then
                                        echo "eth HWaddr cfg ok"
                        else
                                        ifconfig eth0 down
                                        ifconfig eth0 hw ether $ethaddr2
                        fi
        #文件不存在则将获取到的mac地址写入到文件中
        else
                        echo $ethaddr1 >/data/ethaddr.txt
        fi
        #启动网络并固定IP地址
        ifconfig eth0 up

        ifconfig eth0 192.168.3.24 netmask 255.255.252.0
        route add default gw 192.168.3.1
        echo "nameserver 114.114.114.114" > /etc/resolv.conf
}

insert_ko() {
 # if ko exist, install ko first
        default_ko_dir=/ko
        #加载驱动
        if [ -f "/oem/usr/ko/insmod_ko.sh" ]; then
                default_ko_dir=/oem/usr/ko
        fi
        if [ -f "$default_ko_dir/insmod_ko.sh" ]; then
                cd $default_ko_dir && sh insmod_ko.sh && cd -
        fi
}

/etc/init.d/S01seedrng start
/etc/init.d/S01syslogd start
/etc/init.d/S02klogd start
/etc/init.d/S02sysctl start
/etc/init.d/S10udev start
/etc/init.d/S20linkmount start
/etc/init.d/S20urandom start

#加载驱动
insert_ko &

#初始化网络
network_init &

/etc/init.d/S40network

/etc/init.d/S50sshd start

/etc/init.d/S91smb start

幸狐SDK学习

luckfox_pico_rkmpi_example

编译

#设置环境变量
# uclibc
export LUCKFOX_SDK_PATH=<luckfox-pico SDK path>
# glibc
export GLIBC_COMPILER=<gcc bin path>/arm-linux-gnueabihf-

执行./build.sh

专业名词解释

图像采集