请教 u-boot 里面的环境变量的设置 的问题。
2014-04-18 02:00
537 查看
转自: http://www.unixresources.net/linux/clf/driver/archive/00/00/66/83/668357.html 请教 u-boot 里面的环境变量的设置 的问题。 我现在已经把 nor flash的驱动加进去了, 自己写了一小段测试代码, 确实是把一段字符串写进入到nor flash里面去了。 但是saveenv却不行, 仔细一查, 原来好像是 env_relocate()有问题。 首先初始化gd: 我是上仿真器的, 我有4个SRAM , SRAM0(0x30000000) , SRAM1(0x30010000) ,SRAM2(0x30020000) , SRAM3(0x30030000) 我的nor flash的起始地址是 0x10000000 , 大小是 16M , 127个sector(normal:128k) + 4个parameter sector(每个是32k) , 我的环境打算放在 第1个快(即 0x10020000) , 我把TEXT_BASE 设置成了 , SRAM1(0x30010000) , SRAM0 (64k)专门放置gd什么的。 /* Pointer is writable since we allocated a register for it */ gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t)); /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); // reset_cpu(0); bob only testing watchdog if works well memset ((void*)gd, 0, sizeof (gd_t)); gd->bd = (bd_t*)((char*)gd - sizeof(bd_t)); memset (gd->bd, 0, sizeof (bd_t)); int env_init(void) { if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) { gd->env_addr = (ulong)&(env_ptr->data); printf("env_addr=%#08lx ",gd->env_addr); gd->env_valid = 1; return(0); } gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 0; return (0); } 而这里 env_ptr 默认是 就是 static env_t *flash_addr = (env_t *)CFG_ENV_ADDR; 即:0x10020000 ++++++++++++++++++++++++++++ 关键就是 env_relocate()这个函数, 我觉得有问题啊: env_ptr = (env_t *)malloc (CFG_ENV_SIZE); 输出是这样的: env_relocate[204] offset = 0x0 , no modify : env_ptr addr=10020000 env_relocate[222] malloced ENV at 00000000 怎么malloc返回的就是 0 呢? void env_relocate (void) { DEBUGF ("%s[%d] offset = 0x%lx , no modify : env_ptr addr=%p ", __FUNCTION__,__LINE__,gd->reloc_off,env_ptr); /* * We must allocate a buffer for the environment */ env_ptr = (env_t *)malloc (CFG_ENV_SIZE); DEBUGF ("%s[%d] malloced ENV at %p ", __FUNCTION__,__LINE__,env_ptr); /* * After relocation to RAM, we can always use the "memory" functions */ env_get_char = env_get_char_memory; if (gd->env_valid == 0) { #if defined(CONFIG_GTH) || defined(CFG_ENV_IS_NOWHERE) /* Environment not changable */ puts ("Using default environment "); #else puts ("*** Warning - bad CRC, using default environment "); SHOW_BOOT_PROGRESS (-1); #endif if (sizeof(default_environment) > ENV_SIZE) { puts ("*** Error - default environment is too large "); return; } memset (env_ptr, 0, sizeof(env_t)); memcpy (env_ptr->data, default_environment, sizeof(default_environment)); #ifdef CFG_REDUNDAND_ENVIRONMENT env_ptr->flags = 0xFF; #endif env_crc_update (); gd->env_valid = 1; } else { env_relocate_spec (); } gd->env_addr = (ulong)&(env_ptr->data); | ||
---- http://KernelChina.cublog.cn | ||
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: bob2004 Posted: 2007-12-19 22:06 Length:408 byte(s) |
[Original][Print] [Top] |
其实, 我要问的核心问题就是: 当初始化了 SRAM后, 我要malloc的时候, 返回的地址应该 SRAM的地址才对啊, 假如TEXT_BASE 定义的SDRAM的地址, 那么返回的地址应该就是SDRAM的地址范围才对啊。 返回如果是0 ,肯定就是在nor flash地址范围了, 肯定是错的啊。 不知道大家在移植u-boot的时候 有没有碰到过类似的问题。 |
---- http://KernelChina.cublog.cn |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: bob2004 Posted: 2007-12-20 10:19 Length:1,100 byte(s) |
[Original][Print] [Top] |
继续看代码: 在 start_armboot() 函数中 ,调用了: /* armboot_start is defined in the board-specific linker script */ mem_malloc_init (_armboot_start - CFG_MALLOC_LEN); //30006044 /* * Begin and End of memory area for malloc(), and current "brk" */ 所以这样看起来, 一旦以后调用malloc 应该获得地址空间就应该是 SRAM的地址啊, 可是我的malloc返回的是 0 , 奇怪了。 static ulong mem_malloc_start = 0; static ulong mem_malloc_end = 0; static ulong mem_malloc_brk = 0; static void mem_malloc_init (ulong dest_addr) { mem_malloc_start = dest_addr; mem_malloc_end = dest_addr + CFG_MALLOC_LEN; mem_malloc_brk = mem_malloc_start; memset ((void *) mem_malloc_start, 0, mem_malloc_end - mem_malloc_start); } |
---- http://KernelChina.cublog.cn |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: bob2004 Posted: 2007-12-20 14:26 Length:581 byte(s) |
[Original][Print] [Top] |
通过用multi-ICE + realview 调试发现一个奇怪的问题 , 明明c 语言里面是malloc 一次, 结果查看汇编的时候, 就变成了 3次malloc , 如图: 点击左边的DSM 按钮, 就可以看到汇编: 所以我就疯掉了, 我的内存是有限的, 这么连续三次malloc , 相当于两次leak 啊, 估计后面device_init() 就是因此挂掉了。 |
---- http://KernelChina.cublog.cn |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: tpu Posted: 2007-12-20 16:21 Length:82 byte(s) |
[Original][Print] [Top] |
但汇编里面BL malloc只有一次啊,说明只调用了一次。C语言的显示混乱是否跟优化有关呢? |
---- 精益求精! |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: bob2004 Posted: 2007-12-20 17:56 Length:1,753 byte(s) |
[Original][Print] [Top] |
你说得有道理, 看来malloc确实被调用了一次, 接着查一些资料, 查到几篇比较的资料, 比如这个: href=http://www.cublog.cn/u/26710/showart_402757.html>http://www.cublog.cn/u/26710/sho wart_402757.html 说得比较好 , 还有:http://safelab.nku.cn:8080/cgi-bin/topic.cgi?forum=26&topic=64&replynum= last#bottom (分析很有深度,让我对u-boot启动后的内存规划比较了解了。 最好的还是下面这个图,太一幕了然了, 以前总是脑子里面没有形成图啊。 : 我想请问的是, 正常的情况(从nor flash启动, SDRAM ok) , malloc返回的地址应该是上面图的哪个区域呢? 从 u-boot代码的注释来看:应该是 CFG_MALLOC_LEN 这个区域啊。 /* 大家觉得呢? 我不明白的是, mem_malloc_init () 仅仅是做了上面的动作, malloc怎么就返回 CFG_MALLOC_LEN 地址范围的地址呢? 有详尽分析过 malloc实现的兄弟指点一下啊, 我也仔细再分析一下,分析明白了, 又够一篇经典文章的了。 |
---- http://KernelChina.cublog.cn |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: bob2004 Posted: 2007-12-20 23:54 Length:240 byte(s) |
[Original][Print] [Top] |
找到一篇 env_relocate()实现的文章 , 正在分析: http://blog.chinaunix.net/u1/47239/showart_375478.html |
---- http://KernelChina.cublog.cn |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: bob2004 Posted: 2007-12-21 10:38 Length:2,827 byte(s) | ||
[Original][Print] [Top] | ||
接着读 env_relocate() 函数: 有两个地方有疑问, 还望研究过的大侠指教: 下面的代码,我删掉了一些无关的部分, 下面的envsize 都是 128k (0x20000) 我的疑问是 1》对于 最开始一句:gd->reloc_off,env_ptr); 这个 gd->reloc 是在哪里赋值的呢? 我用source insight 就没有搜索到arm 平台, 它赋值的情况。 2》从下面的代码看: env_ptr = (env_t *)malloc (CFG_ENV_SIZE); 就算 malloc成功了, 那就分配了 128k内存 而后面直接就这样了: memset (env_ptr, 0, sizeof(env_t)); memcpy (env_ptr->data,default_environment,sizeof(default_environment)); 我觉得从c语言角度就不对啊, 因为我们并没有对 env_ptr->data 进行malloc分配空间啊。 仅仅给env_ptr分配了128k空间, 就用env_ptr->data 这能行吗? void env_relocate (void) { DEBUGF ("%s[%d] offset = 0x%lx , no modify : env_ptr addr=%p ", __FUNCTION__,__LINE__, gd->reloc_off,env_ptr); /* * We must allocate a buffer for the environment */ env_ptr = (env_t *)malloc (CFG_ENV_SIZE); DEBUGF ("%s[%d] malloced ENV at %p ", __FUNCTION__,__LINE__,env_ptr); /* * After relocation to RAM, we can always use the "memory" functions */ env_get_char = env_get_char_memory; if (gd->env_valid == 0) { #if defined(CONFIG_GTH) || defined(CFG_ENV_IS_NOWHERE) /* Environment not changable */ puts ("Using default environment "); #else puts ("*** Warning - bad CRC, using default environment "); SHOW_BOOT_PROGRESS (-1); #endif if (sizeof(default_environment) > ENV_SIZE) { puts ("*** Error - default environment is too large "); return; } memset (env_ptr, 0, sizeof(env_t)); memcpy (env_ptr->data, default_environment, sizeof(default_environment)); #ifdef CFG_REDUNDAND_ENVIRONMENT env_ptr->flags = 0xFF; #endif env_crc_update (); gd->env_valid = 1; } else { env_relocate_spec (); } gd->env_addr = (ulong)&(env_ptr->data); #ifdef CONFIG_AMIGAONEG3SE disable_nvram(); #endif } | ||
---- http://KernelChina.cublog.cn | ||
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: kernelworld Posted: 2007-12-24 00:39 Length:552 byte(s) |
[Original][Print] [Top] |
出现这种奇怪的现象,首先看看你的地址配置怎么样,因为这已经涉及到操作内存了, 上次的我出现的问题更怪printf()稍微打印内容多一点CPU就复位了,最后问题就是配置 的地址不正确的。 PS:感觉现在的2.0的U-BOOT.好像是很有问题,上次改了几个BUG,一个就是环境变量的取值问题, 一个就是网卡的PING包问题,不知怎么回事,这还是明显的错误,你的U-BOOT来的门道来得正宗了, 这个要注意了,我下的U-BOOT的明显还一个内地的补丁,我当时记得也是到一个比较正式的网站下的。 刚忙完U-BOOT的移植,好久没有来祭坛了。。。欢迎共同讨论问题 |
---- 诗圣曰:语不惊人死不休 我亦曰:技不动人死不休 |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: bob2004 Posted: 2007-12-24 09:59 Length:2,244 byte(s) | |
[Original][Print] [Top] | |
谢谢你的分享 , 确实是地址设定的问题 , 问题已经解决了, malloc 返回 0 , 就是 内存太小了, 导致无法分配更多的内存。 我的memory是这样的: 0x3000 0000 SRAM0 (64k) 0x3001 0000 SRAM1 (64k) 0x3002 0000 SRAM2 (64k) 0x3003 0000 SRAM3 (64k) ..... 0x6000 0000 SDRAM(16MB) ------------------ 从上面看的话, SRAM总共才256KB , SDRAM 16MB 而我们是上仿真器的, 因为一开始 代码要下到一个memory 执行, 而此时SDRAM肯定还没有初始化, 因此 ,只好选 SRAM1的地址作为下载地址, SRAM0 存放其他的内容,比如 CFG_MALLOC_LEN , gd ,还有 各种模式的堆栈等。 而在代码中: void env_relocate (void) { DEBUGF ("%s[%d] offset = 0x%lx , no modify : env_ptr addr=%p ", __FUNCTION__,__LINE__, gd->reloc_off,env_ptr); env_ptr = (env_t *)malloc (CFG_ENV_SIZE); DEBUGF ("%s[%d] malloced ENV at %p ", __FUNCTION__,__LINE__,env_ptr); 而这里 CFG_ENV_SIZE 我定义的是 128k ,( 因为 nor flash的 扇区大小刚好是 128k) , 而CFG_MALLOC_LEN 我又恰好根据SRAM 大小调整了 , include/configs/xx.h /*------------------------------ * Size of malloc() pool *-----------------------------*/ #define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024) //use for SDRAM(64M) //#define CFG_MALLOC_LEN 0xa000 //temp modify to fit for SRAM --bob 这样的话, malloc 就有可能失败了, 因为SRAM实在太少了。 ] 当以上配置都采用正常值的时候, 直接把 u-boot 烧写到 nor 里面去 执行 , config.mk 里面配置的 TEXT_BASE也改为 SDRAM的相应地址(我是 0x63f80000) , malloc就正常了。 ------------- 我总结了一条经验, 仿真器是个好东西, 但是有的时候, 仿真器毕竟不能模仿真实的一切, 所以还要自己调整。 | |
---- http://KernelChina.cublog.cn | |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: bob2004 Posted: 2007-12-24 20:33 Length:2,136 byte(s) | |
[Original][Print] [Top] | |
针对上面的图片, 可以从代码中得到验证: stack_setup: ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ 128byte #ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ 这就和上面的 CFG_MALLOC_LEN 和 GLOBAL_DATA_SIZE 和 irq,FIQ 区域, 第二阶段的代码,做了初始化工作: /* Pointer is writable since we allocated a register for it */ gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t)); /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); //内存屏障 memset ((void*)gd, 0, sizeof (gd_t)); gd->bd = (bd_t*)((char*)gd - sizeof(bd_t)); memset (gd->bd, 0, sizeof (bd_t)); //汇编里面分配的 GLOBAL_DATA_SIZE应该是包含 gd和bd的,有128个字节。 monitor_flash_len = _bss_start - _armboot_start; 1, 可是上面图上的 “用户栈区” , 到底是在哪里分配并初始化的呢?在u-boot代码并没有看到啊? 2, 另外: /* Pointer is writable since we allocated a register for it */ gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t)); /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); 上面的 /* Pointer is writable since we allocated a register for it */ 什么意思呢?没看明白啊。 (不要翻译哦) 谢谢了。 | |
---- http://KernelChina.cublog.cn | |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: bob2004 Posted: 2007-12-24 21:26 Length:2,027 byte(s) | |
[Original][Print] [Top] | |
对下面这段经典的relocate的代码, 从细节上(汇编语言角度),我还是有点疑问, 假设 BOARD/SMDK2410/config.mk 里面的 TEXT_BASE 0x63f80000 我们就讨论, u-boot 从nor flash启动的情况: 0,问个汇编的问题, 关于 .word 查了一下, 可是还是没太明白,为什么一定要用word 呢? 比如: .globl _bss_start _bss_start: .word __bss_start ldr r2, _armboot_start ldr r3, _bss_start 那么 写成这样行吗? ldr r3, __bss_start (这个就是定义在System.map) 1, relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ beq stack_setup adr 是怎么做到 当从 nor flash启动的时候, 就是 0 , 而debug得时候, 就是0x63f80000 的呢? 2, ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 <- size of armboot */ add r2, r0, r2 /* r2 <- source end address */ 当 u-boot已经烧写道nor flash里面的时候, _start的值是多少呢? 从System.map 来看 _start 是 0x63f80000 , 而这里又 .globl _start _start: b 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 从这里来看, 从 nor flash 启动的时候, _start的地址应该就是 0 啊, 谁来解释一下啊? 谢谢了。 | |
---- http://KernelChina.cublog.cn | |
[Original][Print] [Top] |
Subject:Re: 请教 u-boot 里面的环境变量的设置 的问题。 Author: freebsdxjj Posted: 2007-12-26 17:14 Length:750 byte(s) |
[Original][Print] [Top] |
我来回答start的问题 System.map 的中的地址有可能是中间过程的地址 start的地址可能是在ld.script中 下面是我的一个ld.script OUTPUT_ARCH(mips) ENTRY(entry) SECTIONS { . = 0x80300000; .text : { *(.text.entry) *(.text) *(.rodata) } .data : { *(.data) } .bss : { *(.bss) } workspace = .; } 我的第一个指令位于 entry,从cpu来看的地址是 0x80300000 |
相关文章推荐
- 关于Qt移植后环境变量的设置 qt移植到arm中文显示问题解决 实现pc与tiny210 arm开发板 udp通信
- 从DOS切换到mysql时mysql环境变量设置的问题
- u-boot环境变量的设置与使用
- DevKit8000 U-boot环境设置问题
- “SET 命令设置的环境变量在 FOR 循环中始终为空”问题的原因与解决方法
- java环境变量设置即一些问题的解决
- linux环境变量设置空格问题
- 在uboot里面添加环境变量使用run来执行
- Java中包的概念;环境变量的设置问题;javac 与java,javap的应用
- Linux下java环境变量设置的问题
- u-boot环境变量的设置与使用
- 在linux系统中通过fw_printenv查看和设置u-boot中的环境变量
- Python环境变量设置问题
- busybox里环境变量设置的问题
- Win7中设置环境变量的注意问题
- Tomcat无法启动问题 -- 之环境变量JAVA_HOME未设置
- u-boot环境变量的设置与使用
- uboot环境变量设置好后烧写启动内核,文件系统出现的问题
- android环境变量的设置及注意问题
- 关于Ubuntu的环境变量设置问题