|
自从几周前莫名其妙的搞定eldk(arm-linux-gcc) 编译 u-boot-1.3.0 malloc()返回为0的问题后一直不知道ROOTCAUSE是什么。
今天在搞TFTP的问题时候借介上两次解决问题的经验:问题应该不会出现在代码的逻辑或硬件,很可能又是编译器相关。
上网瞎搜索了一下看到一个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)
...