遇到一个经典问题:UBOOT中malloc函数返回值不对

来源:互联网 发布:linux多线程理解 编辑:程序博客网 时间:2024/05/16 15:01

遇到一个经典问题:UBOOT中malloc函数返回值不对

原来以为会一帆风顺,今天调试中断的时候才发现这个问题,中断向量表不时地会被环境变量冲掉。在网上查了一下,是UBOOT中malloc函数返回值造成的,排除中...

shixq 发表于 2008-7-30 11:04

找到一个临时解决办法:
修改./common/dlmalloc.c:
static unsigned long top_pad          = 1024;//DEFAULT_TOP_PAD;
即将top_pad的初值由0改为1024.

结果是env_ptr的值由0x8,改到了0x306DFC08,这貌似是一个正常的heap地址。
为什么会这样还不知道,可能需要读UBOOT关于内存管理的代码。标记一下,这可能是一个隐患...

shixq 发表于 2008-7-30 11:16

继续查找原因,终于找到最深层的原因

原作者:
[url]http://miaofng.eetop.cn[/url],笑含风~~
问题应该不会出现在代码的逻辑或硬件,很可能又是编译器相关。

上网瞎搜索了一下看到一个N人的BLOG,很有收获。见如下,其中有global变量与bss段的描述

[url]http://blog.jollen.org/mt-tb.cgi/346[/url]

[url]http://www.jollen.org/blog/2007/01/[/url]

当初解决malloc问题的时候仅仅将全局变量 top_pad赋初值改为一个不为0的值即可,感觉很奇怪。原来当复制为0时变量会被连接在bss段中,

见如下:

0c6199d8 A armboot_end_data
0c6199d8 A __bss_start--------------------------------------bss start----------
0c6199d8 A __u_boot_cmd_end
0c6199d8 B monitor_flash_len
0c6199dc b mem_malloc_brk
0c6199e0 b mem_malloc_end
0c6199e4 b mem_malloc_start
0c6199e8 B NetTxPacket
0c6199ec B NetEtherNullAddr
0c6199f2 B NetServerEther
0c6199f8 B NetBootFileSize
0c6199fa B NetOurRootPath
0c619a3a B NetOurHostName
0c619a5a B NetOurNISDomain
0c619a7c B NetOurDNSIP
0c619a80 B NetOurGatewayIP
0c619a84 B NetOurSubnetMask
0c619a88 B NetArpWaitTry
0c619a8c B NetArpWaitTimerStart
0c619a90 B NetArpWaitPacketBuf
0c61a0b0 B NetArpWaitTxPacketSize
0c61a0b4 B NetArpWaitTxPacket
0c61a0b8 B NetArpWaitPacketMAC
0c61a0bc B NetArpWaitReplyIP
0c61a0c0 B NetArpWaitPacketIP
0c61a0c4 B PktBuf
0c61bee4 B NetPingIP
0c61bee8 B BootFile
0c61bf68 B NetState
0c61bf6c B NetIPID
0c61bf70 B NetRxPktLen
0c61bf74 B NetRxPkt
0c61bf78 B NetRxPackets
0c61bf88 B NetServerIP
0c61bf8c B NetOurIP
0c61bf90 B NetOurEther
0c61bf98 B NetBootFileXferSize
0c61bf9c b mac.2511
0c61bfa2 b PingSeqNo
0c61bfa4 b timeDelta
0c61bfa8 b timeStart
0c61bfac b timeHandler
0c61bfb0 b packetHandler
0c61bfb4 b tftp_filename
0c61bfb8 b default_filename
0c61bfc8 b TftpState
0c61bfcc b TftpBlockWrapOffset
0c61bfd0 b TftpBlockWrap
0c61bfd4 b TftpLastBlock
0c61bfd8 b TftpBlock
0c61bfdc b TftpTimeoutCount
0c61bfe0 b TftpOurPort
0c61bfe4 b TftpServerPort
0c61bfe8 B BootpTry
0c61bfec B BootpID
0c61bff0 B RarpTry
0c61bff4 b rpc_id
0c61bff8 b fs_mounted
0c61bffc b nfs_path_buff
0c61c7fc b nfs_path
0c61c800 b nfs_filename
0c61c804 b default_filename
0c61c844 b NfsState
0c61c848 b NfsTimeoutCount
0c61c84c b NfsOurPort
0c61c850 b NfsSrvNfsPort
0c61c854 b NfsSrvMountPort
0c61c858 b NfsServerIP
0c61c85c b NfsDownloadState
0c61c860 b filefh
0c61c880 b dirfh
0c61c8a0 b nfs_len
0c61c8a4 B console_buffer
0c61c9a4 b lastcommand.1849
0c61caa4 B header
0c61cae4 b i2c_mm_last_alen
0c61cae8 b i2c_mm_last_addr
0c61caec b i2c_mm_last_chip
0c61caf0 b i2c_dp_last_alen
0c61caf4 b i2c_dp_last_addr
0c61caf8 b i2c_dp_last_chip
0c61cafc B send_ptr
0c61cb00 B send_parms
0c61cb14 B os_data_char
0c61cb18 B os_data_init
0c61cb1c B his_quote
0c61cb1d B his_pad_char
0c61cb20 B his_pad_count
0c61cb24 B his_eol
0c61cb28 B os_data_header
0c61cb48 B os_data_count
0c61cb4c b k_data_escape_saved
0c61cb50 b k_data_escape
0c61cb54 b bin_start_address
0c61cb58 b os_data_addr_saved
0c61cb5c b os_data_addr
0c61cb60 b os_data_count_saved
0c61cb64 b os_data_state_saved
0c61cb68 b os_data_state
0c61cb6c b a_b
0c61cb84 B mm_last_size
0c61cb88 B mm_last_addr
0c61cb8c B dp_last_size
0c61cb90 B dp_last_addr
0c61cb94 b base_address
0c61cb98 b tmp_buf.1933
0c61cd98 b tmp_buf
0c61ce98 b ctrlc_was_pressed
0c61ce9c b ctrlc_disabled
0c61cea0 B stdio_devices
0c61ceac B devlist
0c61ceb0 b n_mmaps_max
0c61ceb4 b top_pad----------------------------malloc 返回0的真凶---------------------
0c61ceb8 b current_mallinfo
0c61cee0 b max_total_mem
0c61cee4 b mmapped_mem
0c61cee8 b max_sbrked_mem
0c61ceec b xyz
0c61d328 B ___strtok
0c61d32c b fixed_built
0c61d330 b fixed_lock
0c61d334 b fixed_td
0c61d338 b fixed_tl
0c61d33c b fixed_bd
0c61d340 b fixed_bl
0c61d344 b fixed_mem
0c61e3d4 B flash_info
0c61e8e0 b lastdec
0c61e8e4 b timestamp
0c61e8e8 b params
0c61e8ec A _end----------------------------------------bss end--------------------------------

而bss段的初始化由C在调用main程序前将其初始化。但是对于U-BOOT而言,这些只能由它自己去完成。

而s3c44b0 start.s中没有做这部分工作。结果便会导致所以依赖于bss段赋初值为0的函数发生问题。

比如前面的malloc函数,他的top_pad为一个随机数,如几个M/Gbytes,咱们系统中总共才那么点SDRAM,

哪够你这么挥霍的, 其结果必然是malloc分配堆失败,程序挂掉了;

同理,今天晚上的tftp问题也由此原因造成。

最根本的solution为:

//cpu/s3c44b0/start.s

...

vector_copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble vector_copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

////////////////////////////////////////////{

/*miaofng--- to init the bss segment*/
ldr r0, = 0
ldr r1, _bss_start
ldr r2, _bss_end
bss_init:
str r0, [r1]
add r1,r1,#4
cmp r1,r2
blt bss_init
////////////////////////////////////////}
/* Set up the stack          */
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                        */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

shixq 发表于 2008-7-30 11:22

使用了根本的solution后,内存分配搞定!
吼吼,虽然不是自己解决的,还是比较开心的!

shixq 发表于 2008-7-30 11:27

不知道这个问题是否和编译器相关,是不是有的编译器对变量有不同的链接方式,或者会清空BSS段。
从这个事件中也要吸取教训,最好在代码中显式地将BSS段清空,以避免不可预料的错误。

shixq 发表于 2008-7-30 13:18

联想起前两天遇到的base是随机值的问题,应该是同一问题,果然今天将BSS清空后base也变成零了。
0 0
原创粉丝点击