打印
[应用相关]

u-boot网络固件还原功能

[复制链接]
楼主: xiaoqizi
手机看帖
扫描二维码
随时随地手机跟帖
21
xiaoqizi|  楼主 | 2019-7-9 10:51 | 只看该作者 回帖奖励 |倒序浏览
/***************************************************/

U_BOOT_CMD(
        query,        3,        1,        do_query,
        "Whether there is server alive and get inifile form server",
        "query [filetype]"
       
);

使用特权

评论回复
22
xiaoqizi|  楼主 | 2019-7-9 10:52 | 只看该作者
2、udp接收到的包交给net/udp.c处理:


#include <common.h>
#include <command.h>
#include <net.h>
#include <environment.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <netdev.h>
#include "tftp.h"
#include "bootp.h"
#include "udp.h"

#define TIMEOUT                 20000UL                /* Seconds to timeout for a lost pkt        */
#ifndef        CONFIG_NET_RETRY_COUNT
# define TIMEOUT_COUNT        10                /* # of timeouts before giving up  */
#else
# define TIMEOUT_COUNT  (CONFIG_NET_RETRY_COUNT * 2)
#endif

static ulong UdpTimeoutMSecs = TIMEOUT;
static int UdpTimeoutCountMax = TIMEOUT_COUNT;

#define MAX_LINE 200
#define MAX_SECTION 100
#define MAX_NAME 100

static IPaddr_t UdpServerIP;
static int        UdpServerPort;                /* The UDP port at their end                */
static int        UdpOurPort;                /* The UDP port at our end                */
static int        UdpTimeoutCount;               

static void UdpSend (void);
static void UdpTimeout (void);

/**********************************************************************/

使用特权

评论回复
23
xiaoqizi|  楼主 | 2019-7-9 10:52 | 只看该作者
static void
UdpSend (void)
{
        volatile uchar *        pkt;
        int                        len = 0;
       
        /*
         *        We will always be sending some sort of packet, so
         *        cobble together the packet headers now.
         */
        pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;
        len = strlen(pkt_data);
        memcpy(pkt, pkt_data, len);
        NetSendUDPPacket(NetServerEther, UdpServerIP, UdpServerPort, UdpOurPort, len);
}

使用特权

评论回复
24
xiaoqizi|  楼主 | 2019-7-9 10:53 | 只看该作者

static int inifile_handler(void *user, char *section, char *name, char *value)
{
       
        char *requested_section = (char *)user;
        int i;

         if ( *name == 's' || *name == 'b' || *name == 't') {
                 if ( *name == 't' ){
                        if(run_command(value, 0) == -1){
                                return 0;
                        }
                        return 1;
                }
                for(i=0; i<10; i++){
                        if(run_command(value, 0) == -1){       
                                if ( *name == 'b' ) {
                                        printf("bootm kernel and rootfs failure!\n");
                                        return 1;
                                }
                                printf("error, try again After 1 seconds\n");
                                udelay(1000000);
                                if ((i==9) || ctrlc()) {
                                        puts ("\nAbort\n");
                                        return 0;
                                }
                                continue;
                        }
                        break;
                }
               
        }
        else{
                setenv(name, value);
        }
        /* success */
        return 1;
}

使用特权

评论回复
25
xiaoqizi|  楼主 | 2019-7-9 10:53 | 只看该作者
static void
UdpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
{
        ushort proto;
        char line[MAX_LINE];
        char section[MAX_SECTION] = "";
        char prev_name[MAX_NAME] = "";
        char *start;
        char *end;
        char *name;
        char *value;
        int i, linelen;
        int newline = 1;
        int lineno = 0;
        int error = 0;
        int flag = 1;
        char *udpkt;
        char *udppkt;
       
        udpkt=(char *)malloc(1000*sizeof(char));
        udppkt = strcpy(udpkt,(char *)pkt);
        printf("receive udp packet\n");
        while(flag){
                end = memchr(udppkt, '\n', (size_t)len);
                if( *end != '\n')
                        end = memchr(udppkt, '\r', (size_t)len);
                if (end == NULL) {
                        if (len == 0)
                                return;
                        end = udppkt + len;
                        newline = 0;
                }
                linelen = min((end - udppkt) + newline, MAX_LINE);
                memcpy(line, udppkt, linelen);
                if (linelen < MAX_LINE)
                        line[linelen] = '\0';
                /* prepare the mem vars for the next call */
                len -= (end - udppkt) + newline;
                udppkt += (end - udppkt) + newline;
               
                lineno++;
                start = lskip(rstrip(line));       
loop:       
            if (*start && *start != ':' && *start != '[' && *start != '#') {
                /* Not a comment, must be a name[=:]value pair */
                        end = find_char_or_comment(start, '=');
                        if (*end != '=')
                                end = find_char_or_comment(start, ':');
                        if (*end == '=' || *end == ':') {
                                *end = '\0';
                                name = rstrip(start);
                                value = lskip(end + 1);
                                end = find_char_or_comment(value, ';');
                                if(*end == ';'){                                                                //batch cmd
                                        *end = '\0';
                                        end = find_char_or_comment(value, '\0');
                                        rstrip(value);
                                        /* Strip double-quotes */
                                        if (value[0] == '"' &&
                                                   value[strlen(value)-1] == '"') {
                                                value[strlen(value)-1] = '\0';
                                                        value += 1;
                                        }
                                        /*
                                         * Valid name[=:]value pair found, call handler
                                         */
                                        strncpy0(prev_name, name, sizeof(prev_name));
                                        printf("start %d line:%s %s\n",lineno, name, value);
                                        if (inifile_handler(section, section, name, value) &&
                                             !error){               
                                                start = ++end;
                                                goto loop;
                                        }
                                        else
                                                error = lineno;
                                }
                                else{
                                        end = find_char_or_comment(value, '\0');
                                        rstrip(value);
                                        /* Strip double-quotes */
                                        if (value[0] == '"' &&
                                                   value[strlen(value)-1] == '"') {
                                                value[strlen(value)-1] = '\0';
                                                        value += 1;
                                        }
                                        /*
                                         * Valid name[=:]value pair found, call handler
                                         */
                                        strncpy0(prev_name, name, sizeof(prev_name));
                                        printf("start %d line:%s\n",lineno, value);
                                        if (!inifile_handler(section, section, name, value) &&
                                             !error)
                                                        error = lineno;
                                               
                                }
                        }
                        else if (!error){
                                /* No '=' or ':' found on name[=:]value line */
                                error = lineno;
                        }
                }
                else if ((*start == ':' && start[1] == ':') || *start == '#') {
                        /*
                         * Per Python ConfigParser, allow '#' comments at start
                         * of line
                         */
                }
#if CONFIG_INI_ALLOW_MULTILINE
                else if (*prev_name && *start && start > line) {
                        /*
                         * Non-blank line with leading whitespace, treat as
                         * continuation of previous name's value (as per Python
                         * ConfigParser).
                         */
                    
                        if (!inifile_handler(section, section, prev_name, start) && !error)
                                error = lineno;
                }
#endif
                else if (*start == '[') {
                        /* A "[section]" line */
                        end = find_char_or_comment(start + 1, ']');
                        if (*end == ']') {
                                *end = '\0';
                                strncpy0(section, start + 1, sizeof(section));
                                *prev_name = '\0';
                        } else if (!error) {
                                /* No ']' found on section line */
                                error = lineno;
                        }
                }
                if(error){
                        printf("error= %d\n", error);
                        break;
                }
                printf("%d line done\n", lineno);
        }
       
        free(udpkt);
        udpkt = NULL;
       
        if ( error ){       
                Upgrade_flag = UPGRADE_FAILED;
                TftpNetReStartCount = 10;
        }
        else{
                Upgrade_flag = UPGRADE_SUCCESS;
                TftpNetReStartCount = 11;
        }       
}

使用特权

评论回复
26
xiaoqizi|  楼主 | 2019-7-9 10:53 | 只看该作者
/**
* restart the current transfer due to an error
*
* @param msg        Message to print for user
*/
static void restart(const char *msg)
{
        printf("\n%s; Net starting again\n", msg);
#ifdef CONFIG_MCAST_TFTP
        mcast_cleanup();
#endif
        NetStartAgain();
}

使用特权

评论回复
27
xiaoqizi|  楼主 | 2019-7-9 10:53 | 只看该作者
static void
ICMPHandler (unsigned type, unsigned code, unsigned dport,
                 unsigned sport, unsigned len)
{
       
                if (type == ICMP_NOT_REACH && code == ICMP_NOT_REACH_PORT) {
                        UdpTimeoutMSecs = 5000UL;
                        NetSetTimeout (UdpTimeoutMSecs, UdpTimeout);
        }
       
}

使用特权

评论回复
28
xiaoqizi|  楼主 | 2019-7-9 10:54 | 只看该作者
static void
UdpTimeout (void)
{
        if (++UdpTimeoutCount > UdpTimeoutCountMax) {
                if ( ++TftpNetReStartCount > TftpNetReStartCountMax ){
                        return;
                }
                switch(UdpTimeoutMSecs){
                        case 5000:  
                                buzzer_notify(200, 1);
                                restart("UDP server died");
                                break;
                        case 20000:  
                                buzzer_notify(200, 2);
                                restart("GetPacke Retry count exceeded");
                                break;
                        default:
                                buzzer_notify(200, 3);
                                restart("Retry count exceeded");
                                break;
                }
               
        } else {
                puts ("T ");
                NetSetTimeout (UdpTimeoutMSecs, UdpTimeout);
                UdpSend ();
        }
}

使用特权

评论回复
29
xiaoqizi|  楼主 | 2019-7-9 10:54 | 只看该作者
void
UdpStart (void)
{
        char *ep;             /* Environment pointer */

        /*
         * Allow the user to choose UDP blocksize and timeout.
         * UDP protocol has a minimal timeout of 1 second.
         */

        if ((ep = getenv("udptimeout")) != NULL){
                printf("udptimeout = %d\n", UdpTimeoutMSecs);
                UdpTimeoutMSecs = simple_strtol(ep, NULL, 10);
        }
        if (UdpTimeoutMSecs < 20000) {
                printf("UDP timeout (%ld ms) too low, "
                        "set minimum = 20000 ms\n",
                        UdpTimeoutMSecs);
                UdpTimeoutMSecs = 20000;
        }
        UdpServerIP = NetServerIP;
       
#if defined(CONFIG_NET_MULTI)
        printf ("Using %s device\n", eth_get_name());
#endif               
        UdpTimeoutCountMax = 5;
        UdpTimeoutCount = 0;
       
        NetSetTimeout (UdpTimeoutMSecs, UdpTimeout);
        NetSetHandler (UdpHandler);
        NetSetIcmpHandler(ICMPHandler);  //NO server
       
        UdpServerPort = 75;
        UdpOurPort = getenv("ourport");
       
        /* zero out server ether in case the server ip has changed */
        memset(NetServerEther, 0, 6);
        UdpSend ();

}

使用特权

评论回复
30
xiaoqizi|  楼主 | 2019-7-9 10:54 | 只看该作者
3、tftp.c的完善:
 1)增加了服务器不在的处理

static void
IcmpHandler (unsigned type, unsigned code, unsigned dport,
                 unsigned sport, unsigned len)
{
       
                if (type == ICMP_NOT_REACH && code == ICMP_NOT_REACH_PORT) {
                        TftpTimeoutMSecs = 3500UL;
                        NetSetTimeout (TftpTimeoutMSecs, TftpTimeout);
        }
       
}

使用特权

评论回复
31
xiaoqizi|  楼主 | 2019-7-9 10:55 | 只看该作者
 2)限制了NetStartAgain()的次数,超过次数终止接收数据报

在net.c中定义int TftpNetReStartCount = 0;  int TftpNetReStartCountMax  = 3;
在net.h中定义extern int TftpNetReStartCount;         extern int TftpNetReStartCountMax;

使用特权

评论回复
32
xiaoqizi|  楼主 | 2019-7-9 10:55 | 只看该作者
3)超时处理函数的修改

static void restart(const char *msg)
{
        printf("\n%s; Net starting again\n", msg);
#ifdef CONFIG_MCAST_TFTP
        mcast_cleanup();
#endif
        NetStartAgain();
}

使用特权

评论回复
33
xiaoqizi|  楼主 | 2019-7-9 10:55 | 只看该作者
static void TftpTimeout (void)
{
        if (++TftpTimeoutCount > TftpTimeoutCountMax) {
                if ( ++TftpNetReStartCount > TftpNetReStartCountMax ){
                        return;
                }
                switch(TftpTimeoutMSecs){
                        case 3500:  
                                buzzer_notify(200, 1);
                                restart("TFTP server died");
                                break;
                        case 3000:  
                                buzzer_notify(200, 2);
                                restart("GetPacke Retry count exceeded");
                                break;
                        default:
                                buzzer_notify(200, 3);
                                restart("Retry count exceeded");
                                break;
                }
               
        } else {
                puts ("T ");
                NetSetTimeout (TftpTimeoutMSecs, TftpTimeout);
                TftpSend ();
        }
}

使用特权

评论回复
34
xiaoqizi|  楼主 | 2019-7-9 10:56 | 只看该作者
4、对一开始就没插网线情况的处理:
在u-boot-2010.06\drivers\net\hisfv300的net-drv.c中的int eth_init(bd_t * bd)函数中修改。

在u-boot-2010.06\drivers\net\higmacv300的higmac.c中的int eth_init(bd_t * bd)函数中修改。


使用特权

评论回复
35
xiaoqizi|  楼主 | 2019-7-9 10:56 | 只看该作者
5、在各个平台指定环境变量的地址和大小

1)hi3520dv300、hi3521a、hi3531a:

#define CONFIG_ENV_OFFSET        0x50000      /* environment starts here */
#define CONFIG_ENV_SIZE                0x10000    /*include ENV_HEADER_SIZE */

使用特权

评论回复
36
xiaoqizi|  楼主 | 2019-7-9 10:56 | 只看该作者
2)除了hi3520dv300、hi3521a、hi3531a之外其他的可以在u-boot-2010.06\include\configs中各自的.h中修改:

#define CONFIG_ENV_OFFSET          0x80000      /* environment starts here */
#define CONFIG_ENV_SIZE            0x40000    /*include ENV_HEADER_SIZE */

使用特权

评论回复
37
xiaoqizi|  楼主 | 2019-7-9 10:56 | 只看该作者
六、编译uboot

1、在u-boot-2010.06\arch\arm\comfig.mk中修改交叉编译器路径

2、make clean

3、make ARCH=arm hi3520d_config

4、make

使用特权

评论回复
38
xiaoqizi|  楼主 | 2019-7-9 10:57 | 只看该作者
如果需要压缩uboot的话加上这5、6步

5、cd arch/arm/cpu/hi3520d/compressed

6、make     //第4步和这步生成压缩之后的u-boot.bin(这时uboot还没有对寄存器的初始化,烧写到板子是跑不起来的),不过可以tftp到板子然后用go命令跑

7、cp u-boot.bin ../u-boot.tools

8、sh make.sh   //生成20D.bin(这时的uboot可以烧写进flash了),hi3520d用fastBoot烧录,hi3521a、hi3531a和hi3510dv300(烧录时选21A芯片)用HiTool工具烧录

使用特权

评论回复
39
wangjiahao88| | 2019-7-9 14:50 | 只看该作者
U-boot 是利用网络做数据的更新吗?flash更新吗?

使用特权

评论回复
40
xiaoqizi|  楼主 | 2019-8-6 12:47 | 只看该作者
wangjiahao88 发表于 2019-7-9 14:50
U-boot 是利用网络做数据的更新吗?flash更新吗?

不好意思 我也不是很清楚这个问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则