您的位置:首页 > 其它

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

2014-04-18 02:11 531 查看

遇到一个经典问题: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

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

原作者:

http://miaofng.eetop.cn,笑含风~~

问题应该不会出现在代码的逻辑或硬件,很可能又是编译器相关。

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

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

http://www.jollen.org/blog/2007/01/

当初解决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也变成零了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: