AM335X的应用程序自启动流程以及U盘更新应用程序记录

发布时间:2024-08-19  

在AM335X的SD卡更新系统学习记录中最后更新完系统后,以后运行应用程序都会从EMMC中取出Linux系统运行。接着介绍Linux系统是怎么自己启动我们编写的应用程序的。


1、在AM335X的SD卡更新系统学习记录中已经详细介绍了整个系统的启动流程,这里在复述一下。AM335X上电后,根据Boot Sequence启动配置(LCD0-LCD15引脚,具体可参考TI官方的335X参考手册),从相应的存储设备启动,这里配置的是从SPI启动。内部的ROM从SPI的flash中拷贝镜像到RAM中运行。然后启动u-boot,u-boot启动后会从MMC的/sys分区的/boot目录下取出uImage镜像再到RAM中运行。Linux启动后,会接着挂接EMMC的/sys分区,启动BusyBox里的Init进程。init进程首先主要对/etc/inittab文件进行解析,然后按照它的指示创建各种子进程。inittab文件的内容主要以下几部分。其中系统运行后最先执行的是/etc/rc.d/rcS进程,并且它只执行一次,所以应用程序的启动是在这里运行的。


::sysinit:/etc/rc.d/rcS

::respawn:/sbin/getty 9600 tty1

::ctrlaltdel:/sbin/reboot

::shutdown:/etc/rc.d/rcS stop

::restart:/sbin/init

 

2、接着分析/etc/rc.d/rcS文件,这是一个脚本文件。这个文件的分析在AM335X的SD卡更新系统学习记录已经分析过了这里不再重复。直接看到这个脚本运行的另一个脚本/etc/rc.d/rc.local start。下面是它的内容,可以看到它的工作主要是启动daemon守护进程,应用程序由它启动,并且守护,所谓守护进程,就是不依赖于控制台会话的进程,它可以在应用程序意外退出时重新启动应用程序。如果把daemon换成应用程序,这样应用程序就能自启动了。


#!/bin/sh

mode=${1:-start}

if [ $mode = 'start' ]

then


#set sgtl5000 volume 0~127

amixer cset numid=5 65


#set power led light

echo 1 > /sys/class/leds/user_led0/brightness


#start daemon

daemon                               # 启动守护进程


fi


3、接着分析daemon程序,它的配置文件存放在/opt/Daemon/config/daemon.xml中。主要配置的是需要启动的程序路径与名称。并且可以添加多条,其中/opt/App为目录,xxx.out为可执行文件名。并且可以设置多个路径与文件。


 


4、分析到这里。可以知道一下几点。


a、存在在一个名为/opt的分区


b、其中应用程序存放在/opt/App中


c、其中daemon程序的配置文件存放在/opt/Daemon/config/daemon.xml中


d、daemon程序被放在/usr/sbin中


插上U盘后,会出现PID为13673的进程,进而出现13675、13683的进程。从这一现象可以发现./Daemon.out的另外一个作用,检测有无U盘插入,若有U盘插入的话运行/shell/udisk脚本。接下来跟着这个脚本慢慢分析。


  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND

13577     1 root     S    28776  3.7   0  0.0 ./Daemon.out

13673 13577 root     S     2936  0.3   0  0.0 sh -c ./shell/udisk mount /dev/sda1

13675 13673 root     S     2936  0.3   0  0.0 {udisk} /bin/sh ./shell/udisk mount /dev/sda1

13683 13675 root     S     2936  0.3   0  0.0 {update} /bin/sh ./shell/update ./download/xxx.bin

 

5、开始分析以下脚本,其中$1=mount;$2=/dev/sda1。可以看到其中有一句./shell/update ./download/xxx.bin。这个脚本将在接下来分析


sh -c ./shell/udisk mount /dev/sda1

          $0        $1       $2


#!/bin/sh


case '$1' in

    mount)                        #挂载U盘

        if [ ! -b $2 ]            #是否存在/dev/sda1块设备装置

        then

            echo '$2 not exist!'  #如果不存在打印出不存在,然后退出

            exit 0

        fi

        

                #cd /opt/Daemon

                echo 'Current Path ' $(pwd) '...'        #当前路径已经在Daemon中切换到/opt/Daemon中了

        echo 'mount $2 to /mnt/udisk...'

        echo 1 > /sys/class/leds/user_buzzer/brightness  #打开蜂鸣器

        mkdir /mnt/udisk                                 #创建/mnt/udisk目录

        mount -t vfat $2 /mnt/udisk                      #以fat文件系统格式挂接/dev/sda1到/mnt/udisk

        

        echo 0 > /sys/class/leds/user_buzzer/brightness  #关闭蜂鸣器?


        if [ -x /mnt/udisk/xxx.bin ]                     #如果U盘里的xxx.bin文件可执行

        then

            echo 'exist firmware file[xxx.bin], auto update self...'

                        - rm /log/x.log

            cp -a /mnt/udisk/xxx.bin ./download/xxx.bin  #以递归、保留符号链接的方式拷贝文件到/opt/Daemon/download中

            chmod +x ./download/xxx.bin                  #加上可执行权限

            ./shell/update ./download/xxx.bin            #解压出xxx.bin文件到相应的目录下

            ./shell/hmkill 1                             #运行/shell/hmkill 1脚本,用于杀掉现在运行的进程

            ./daemon.sh                                  #运行新更新的守护进程

        fi


        ;;

    umount)                                 #卸载U盘

        if [ -d /mnt/udisk ]                #如果/mnt/udisk存在

        then

            echo 'umount /mnt/udisk...'

            umount /mnt/udisk                #卸载/mnt/udisk

            rm -rf /mnt/udisk                #删除/mnt/udisk

        fi

        ;;

    *)

        echo 'Usage: /shell/udisk {mount|umount}'    #其它

        echo 

        exit 1

        ;;

esac                            #case语句结束


exit 0


对以上脚本功能做一个总结:


a、挂载U盘到/mnt/udisk


b、读出U盘的MD5文件xxx.bin。并且解压出xxx.bin文件到相应的目录下。


c、杀掉现在运行的现在运行的daemon进程、app进程


d、运行新的daemon进程,这个进程会运行新的app进程


 


6、分析./shell/update ./download/xxx.bin。主要作用是读出U盘的MD5文件xxx.bin。并且解压出xxx.bin文件到相应的目录下,分析如下:


#!/bin/sh

#


if [ ! -f $1 ]                             #检测文件是否存在

then

    echo '$1 not exist!'

    exit 0

fi


echo 1 > /sys/class/leds/user_buzzer/brightness  #打开蜂鸣器


chmod +x $1                               #加可执行权限


dd if=$1 of=env.sh bs=1 count=128             #从xxx.bin读入文件放入env.sh中,每次读1字节,一共读128字节


. env.sh                                 #执行env.sh脚本


# 生成原始打包文件

dd if=$1 of=$NAME bs=1 count=$SIZE skip=128     #从xxx.bin读入文件放入NAME中,每次读1字节,一共读SIZE字节,跳过前128个字节

# 执行脚本

MD5=`md5sum $NAME | awk '{print $1}'`          #MD5校验

if [ '$SIGN' = '$MD5' ]                      #如果校验成功

then

    tar -zxvf $NAME -C /                    #解压

    chmod +x /opt/Daemon/Daemon.out             #加上可执行权限

    chmod +x /opt/Daemon/shell/x               #加上可执行权限

    chmod +x /opt/App/x.out                     #加上可执行权限

    sync                                 #同步,立刻写入磁盘

fi


rm env.sh                    #删除之前生成的文件

rm $NAME                     #删除之前生成的文件

rm $1                        #删除之前生成的文件


echo 0 > /sys/class/leds/user_buzzer/brightness #关闭蜂鸣器


exit 0                                     #退出


7、制作xxx.bin的MD5文件,其中opt里存放的是App目录与Daemon目录,pack.sh是一个脚本文件,用于打包成加密的MD5格式。这个三步之后生成xxx.bin文件。放入FAT32格式的U盘,将这个U盘插入到335X的USB口即可实现更新。


a、sudo tar -czvf ./xxx.tar.gz ./opt


b、sudo chmod 755 ./xxx.tar.gz


c、sudo ./pack.sh ./xxx.tar.gz


8、分析pack.sh脚本,这个脚本的前面128字节为其他数据。与/shell/update脚本对应,/shell/update脚本会先取出前128字节。然后取出MD5签名,然后解密文件。


 1 # !/bin/sh

 2 #

 3 

 4 [ $# != '1' ] && echo 'Usage: $0 tarfile' && exit 0   #参数个数是否为1

 5 

 6 FILE='reader.bin'                                     #加密后的文件名

 7 NAME='$1'                                             #待加密的文件名

 8 SIZE=`wc -c $1 | awk '{print $1}'`                    #以字节方式计算出待加密文件大小

 9 SIGN=`md5sum $1 | awk '{print $1}'`                   #加密,MD5签名生成  awk处理输入的整行数据的某个字段(以空格分开)、sed处理输入的整行数据

10 

11 echo 'NAME=$NAME' >> $FILE                          # 被打包文件名称

12 

13 echo 'SIZE=$SIZE' >> $FILE                          # 被打包文件大小

14 

15 echo 'SIGN=$SIGN' >> $FILE                          # 被打包文件MD5签名

16 

17 chmod +x $FILE                                      # 加上可执行权限

18 

19 dd if=$1 of=$FILE bs=1 count=$SIZE seek=128         # 在被打包文件前面加上$FILE内容,共计128字节


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>