zoukankan      html  css  js  c++  java
  • uboot中的命令解析

    最近有点空了,就看了点开发板的UBOOT源码(主要是去分析如何解析命令)。

    uboot最开始执行的代码是汇编,在标签 _start处开始,后面有了个中断向量表(主要是为个让这点代码被放有地址0x0处),用汇编程序是它可以保证这点代码就在0X0处。

    .globl _start

    _start: b reset  //上电后执行的第一行,跳到reset处。

      ldr pc, _undefined_instruction  //未定义中断

      ldr pc, _software_interrupt  //软中断

      ldr pc, _prefetch_abort  

      ldr pc, _data_abort  

      ldr pc, _not_used  

      ldr pc, _irq  

      ldr pc, _fiq

    进入到后,

    之后设置,CPU工作在SVC32 模式,

    对设备要完成很多的设置,这里不详讲。

    在汇编的最后

    ldr pc, _start_armboot  //PC指针指向start_armboot函数,在/lib_arm/board.c中

    在这个函数里做了很多数据的初始化工作,

    start_armboot在最后用了一个for(;;)死循环,之后调用了main_loop();在/common/main.c中。在这里用死循环的主要原因是防止main_loop的调用没有成功执行。

    1 在main_loop的前面部分记录并限制开机的次数。

    2 初始化modem

    3 set version

    4 启动延迟功能,需要等待用户从串口/网络接口输入等。

    完成设置后main_loop函数又用了一个for(;;)循环,之后就在这个死循环里面不断的读命令并执行命令,命令的解析开始~~~

    parse_file_outer();也是一种命令 解析,可是没有用,我本也想去看一下是如何用行命令解析的,可是看了半天,由于水平太差了。没有看明白,它的命令解析主要是用的Hush.c中实现。

    今天讲的是后面的这一种。

     readline (CFG_PROMPT);用来获得用户输入的命令,CFG_PROMPT就如同root@bt  # 的东西。

    在readline(CFG_PROMPT)中用getc()获得用户的输入,并存放在console_buffer数组当中。后面用了一个switch语句对输入的值进行检测,若是一些特别的ASCII码值(如:^H)则进行不同的处理(在这里实现了输入的一个比较复杂的操作就是删除操作)。

    在readline中的前面定义了一些变量,之后打印了一些东西就不多讲了。后面会有一些打印之类的函数调用也同样不多讲了。

    clear_ctrlc();//这个函数太简单了,我就不说了,

    if (strlen(cmd) >= CFG_CBSIZE) {   //这里的strlen是测试的cmd这个指针指向的命令的字符长度,长度不能超过CFG_CBSIZE。

      puts ("## Command too long!\n");   

      return -1;

    }

    strcpy (cmdbuf, cmd);//把cmd里面的内容拷到cmdbuf中去。

    while (*str) {   //这里的这个while函数 的注释说是分离“;“   但我真没看出来哪里有分离,(本人水平真的很有限)

      ........

    }

    token = str;  

     if (*sep) {       //把*sep清空,

       str = sep + 1; 

      *sep = '\0';   

    }

    后面用了一个函数process_macros的作用我也不是很清楚,但看起来也不是太重要了。

    parse_line(finaltoken, argv)是对参数进行获得,

    find_cmd(argv[0])再用这个函数在一个对命令与命令库中的命令进行比较,在这个函数里面用来比较是用的strncmp(cmd, cmdtp->name, len) == 0)。而放这些命令 的就是一个结构体cmd_tbl_s,

    struct cmd_tbl_s {

      char  *name;     //命令的名字,进行命令的解析就是用的名字。

      int  maxargs;   //最大行参数

      int  repeatable; //允许自动覆盖。   

      int  (*cmd)(struct cmd_tbl_s *, int, int, char *[]);     //命令实现用的指针

      char  *usage;  /* Usage message (short) */

    #ifdef CFG_LONGHELP

       char  *help; //命令的帮助

    #endif

    #ifdef CONFIG_AUTO_COMPLETE  

      int  (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[])

     #endif

    };

    在strncmp中比较用的是对指针中的值进行相减,如果每一位相减都为0,则这命令找到了,返回该命令的指针。此时就已经得到了命令,后面要做的事当然就是实现用户的命令了。

    if (cmdtp->cmd == do_bootd) 下面这一句,是防止bootd的递归。

    if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) //这里就是调用的cmd_tbl_s结构体当中的一个函数指针,

    {                           //cmd指针指向命令的实现函数。

       rc = -1;   

    }

    run_command函数结束,由于这是在一个for(;;)死循环当中,程序又回到了readline (CFG_PROMPT);获取用户输入的命令,

  • 相关阅读:
    【Python入门自学笔记专辑】——面向对象编程-实例方法11.3.6
    最简单的轮播广告(原生JS)
    (转)JavaScript一:为什么学习JavaScript?
    JAVASCRIPT中经典面试题
    使用AngularJS实现简单:全选和取消全选功能
    canvas绘制经典折线图(一)
    前端总结
    PHP如何连接MySQL数据库
    PHP预定义变量
    PHP语法
  • 原文地址:https://www.cnblogs.com/xueyang/p/2376302.html
Copyright © 2011-2022 走看看