uboot----getenv_IPaddr代码解析
来源:互联网 发布:java多线程socket队列 编辑:程序博客网 时间:2024/06/11 11:26
这几天看uboot,感觉getenv函数里嵌套了很多其他函数,一直没搞清是怎么实现get的。今天终于领会了,把它记下来,供大家一起学习。
我研究的是IPaddr的环境变量如何get的,其实就是 gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");该如何分析。先找到getenv_IPaddr函数:
typedef ulong IPaddr_t;
IPaddr_t getenv_IPaddr (char *var){ return (string_to_ip(getenv(var)));
getenv_IPaddr函数使用字符串"ipaddr"做为参数,返回一个ulong型整数。再看getenv函数:
char *getenv (char *name){int i, nxt;WATCHDOG_RESET();for (i=0; env_get_char(i) != '\0'; i=nxt+1) {int val;for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {if (nxt >= CFG_ENV_SIZE) {return (NULL);}}if ((val=envmatch((uchar *)name, i)) < 0)continue;return ((char *)env_get_addr(val));}return (NULL);}
getenv 是一个指针函数,返回字符型指针。为什么会返回字符型指针?后面再说。getenv 函数的参数是字符指针变量name,实参就是“ipaddr"。从这里开始出现了一大堆莫名其妙的函数env_get_char,envmatch,env_get_addr。在分析getenv 之前,还得先把这些其他的函数搞清楚。首先看env_get_char:
uchar (*env_get_char)(int) = env_get_char_init;
static uchar env_get_char_init (int index){uchar c;/* if crc was bad, use the default environment */if (gd->env_valid){c = env_get_char_spec(index);} else {c = default_environment[index]; //返回default_environment指定位置的字符}return (c);}
env_get_char和env_get_char_init等效,参数为int,返回default_environment指定位置的字符。default_environment是定义了一系列缺省的环境变量值。以IP地址为例
#ifdefCONFIG_IPADDR"ipaddr="MK_STR(CONFIG_IPADDR)"\0"#endif
#define CONFIG_IPADDR192.168.1.230
结果是 "ipaddr=192.168.1.230”+"\0"
再看envmatch:
static intenvmatch (uchar *s1, int i2){while (*s1 == env_get_char(i2++))if (*s1++ == '=')return(i2);if (*s1 == '\0' && env_get_char(i2-1) == '=')return(i2);return(-1);}
我开始一直搞不清envmatch 是如何比较的。现在搞清楚了,它是在比较“ipaddr"和"ipaddr=192.168.1.230”。while (*s1 == env_get_char(i2++)) 就是从default_environment字符串的指定位置开始比较,指定位置由env_get_char返回值所定,比较不一致时函数返回-1。当比较到default_environment字符串的IPaddr时,开始有相同的字符出现了,这时while值为1,依次比较i,p,a,d,d,r字符,因为每比较一次,S1(“ipaddr")和i2的值都加1,即指向下一个字符。当比较完"r"后,指针指向了下一个字符即"=", "="之后的字符串正是我们需要的,所以return(i2),i2是赋给val的,下一步就是env_get_addr(val)。
uchar *env_get_addr (int index){if (gd->env_valid) {return ( ((uchar *)(gd->env_addr + index)) );} else {return (&default_environment[index]);}}
找到了val的值,也就是ipaddr在default_environment中所处的位置,即可以返回ipaddr字符串的地址。前面说为什么会返回字符型指针?这里给出了答案。注意:这里返回的是指针,是192.168.1.230的地址,确切地说是"1"的指针地址。
我们再返回char *getenv (char *name) 函数,其返回值也就是192.168.1.230的地址, 这个地址是string_to_ip函数的地址。
IPaddr_t string_to_ip(char *s){IPaddr_t addr;char *e;int i;if (s == NULL)return(0);for (addr=0, i=0; i<4; ++i) {ulong val = s ? simple_strtoul(s, &e, 10) : 0;addr <<= 8;addr |= (val & 0xFF);if (s) {s = (*e) ? e+1 : e;}}return (htonl(addr));}
string_to_ip函数将字符串192.168.1.230转化成整数,关键的地方是for (addr=0, i=0; i<4; ++i),这里可以看出进行了四次转化,分别是四个段。但是函数simple_strtoul是如何区分"."而分成四个段? 这是靠simple_strtoul中的while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) ? toupper(*cp) : *cp)-'A'+10) < base)实现的,因为当while遇到"."时,判定条件即为0,就不再判定而往下走了。四个段都操作完成,就出现了addr = (((((192 << 8) | 168) << 8) | 1) << 8 ) | 230,
- uboot----getenv_IPaddr代码解析
- uboot代码解析
- ARM Uboot经历——Uboot初始化代码解析
- ARM Uboot经历——Uboot初始化代码解析
- uboot解析
- uboot中的命令解析
- uboot lowlevel_init.S解析
- Uboot详细解析2
- Uboot详细解析1
- uboot解析(一)
- uboot环境变量解析
- uboot命令解析
- uboot arp地址解析
- uboot 入口解析
- uboot 编译解析
- uboot源码解析
- uboot编译脚本解析
- uboot移植:uboot下的mkconfig解析
- leetcode Interleaving String
- oracle导入导出文件补充
- 教你如何把excel中的数据导入到Mysql中
- 编写一个登陆界面不连接数据库验证用户
- ViewController 的 loadView, viewDidLoad, viewDidUnload 分别是在什么时候调用的?
- uboot----getenv_IPaddr代码解析
- POJ1741Tree(树上点分治)
- JavaScript入门-第2章 请和我互动(常用互动方法)
- CSS选择器
- Spring声明式事务配置管理方法
- 提高 Linux 上 socket 性能(精辟,转载)
- linux服务器模型
- Spring MVC ModelAndView
- 编程之美 2.20程序理解和时间分析