在阅读uboot(u-boot)代码的时候,很多人首先被.word搞晕了,为什么使用.word,其实与调用有关
大家首先好好理解汇编代码:
ldr pc, main_loop
// 换一下代码 ldr pc, =main_loop
main_loop:
.word test_code
b main_loop
test_code:
b test
在bootloader中使用的第一种,没有加=的代码。调用main_loop, 其实是让pc指向test_code的地址
调用ldr时,什么时候使用有=的代码
ldr pc, =main_loop
main_loop:
// 此注释代码千万不可以打开 .word test_code
b main_loop
此时如果取消注释,哈哈:),让程序飞吧!!
ldr, mov 命令之比较:
ldr地址相关,mov地址无关
我说一个关键点,可能大家不曾思考:
ldr r1, =0x50000000
ldr r1, =0x50000011
这两句编译生成的代码并不一样,通过arm-linux-objdump可以看到
第一句:
0: e3a00205 mov r0, #1342177280 ; 0x50000000
第二句:
0: e51f0004 ldr r0, [pc, #-4] ; 4 <.text+0x4>
4: 50000011 andpl r0, r0, r1, lsl r0
第一个值能用立即数表示,mov指令就行了
第二句不能用立即数表示,不能不使用ldr指令
其实Arm还是很聪明的嘛!第一句能节省一个指令空间,代码size减少了4字节啊!
如果非要看看第一句也使用ldr指令,大概是这样的汇编,当然不会是真的:
0: e51f0004 ldr r0, [pc, #-4] ; 4 <.text+0x4>
4: 50000000 。。。。。。
Uboot 分析(2010.09版):
拿到源代码,如果解压之后,通常执行两个步骤(假设smdk2410)
#make smdk2410_config
#make all
如果不能确定是否运行***_config,期望一个干净的环境,可以首先执行:
#make distclean
运行make ****_config?检查Makefile
%_config:: unconfig
@$(MKCONFIG) -A $(@:_config=)
.......
#还有:
galaxy5200_config: unconfig
....
MVBC_P_config: unconfig
......
不能搜索到smdk2410_config in Makefile,所以选择运行:
%_config:: unconfig
@$(MKCONFIG) -A $(@:_config=)
MKCONFIG := $(SRCTREE)/mkconfig
等同于./mkconfig -A smdk2410,其实调用当前目录下的脚本mkconfig执行。
如果板子是MVBC_P_config, 运行:make MVBC_P_config,则选择不一样了。
mkconfig中:
if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
# Automatic mode
line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || {
echo "make: *** No rule to make target \`$2_config'. Stop." >&2
exit 1
}
set ${line}
# add default board name if needed
[ $# = 3 ] && set ${line} ${1}
fi
条件为真,set ${line}, 嘿嘿,参数改变了,变为了:
./mkconfig smdk2410 arm arm920t - samsung s3c24x0
运行命令,看看结果:
echo $1
echo $2
lds的部分理解,在arch\arm\cpu\arm920t\u-boot.lds中
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
在include/command.h中
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
凡是用U_BOOT_CMD进行声明的变量,作为cmd_tbl_t类型的变量,这些变量放到.u_boot_cmd中,不放到普通的.text中。
进行代码移植的时候,通常会新建自己的板子,时间长了,忘了是什么名字。
make ***_config
可以查看boards.cfg,我们会定义自己新建的板子,找到就知道了。
如果把u-boot移动了位置,再次编译的时候会失败。
比如原来放在/root/u-boot-test,移动为/root/u-boot-new目录。
#make clean
#make all
清空*.o文件后编译会提示:
make[1]: Entering directory `/root/work/friendlyArm/code_test/bootloader/test/u-boot-2010.09redo/tools'
make[1]: *** No rule to make target `/root/u-boot-test/lib/crc32.c', needed by `crc32.o'. Stop.
因为/root/u-boot-test已经不存在了。所以还需要删除所有依赖关系:
#find . -name "*.depend" //可以看见生成的依赖关系文件
#find . -name "*.depend" -exec rm -fr {} \;
我也是新手,欢迎大家拍砖:)
共同进步!