主题 : uboot 链接顺序的问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 10162
精华: 0
发帖: 47
金钱: 365 两
威望: 151 点
贡献值: 0 点
综合积分: 94 分
注册时间: 2009-10-26
最后登录: 2013-09-07
楼主  发表于: 2009-12-01 13:23

 uboot 链接顺序的问题

管理提醒: 本帖被 qq2440 从 Linux技术交流专区 移动到本区(2010-02-08)
移植uboot 发现程序死在lowlevel_init.S程序,没有返回,总线对了一遍又一遍,经过半天的受伤郁闷之后,发现lowlevel_init.o链接之后代码段居然跑到一万开外,找到原因,就好办了。直接在lds里面强制把其放在start.o后面。

不清楚我的代码为什么不是按执行顺序排放,上网查,有人说:u-boot代码里面,原创作者写的链接文件,应该非常合理。而且通过验证的。

uboot移植参考:
http://hi.baidu.com/rat_linux/blog/item/988ea5631f7555dae7113af2.html                            (1)
http://www.aiothome.net/read.php?tid-3539.html                                                                (2)

当然直接用(1)编译的uboot是不能在mini2440 128M上跑的,因为那是64M的,需要修改,但是反汇编其编译出来的uboot(或者直接看uboot.map)可以看出确实是在start.o 后面跟了nand_read_ll()和lowlevel_init(),以确保其在4K之内,查看board下的lds链接脚本,也没有强制其跟在start.o后面。

又下了全新的u-boot-2008.10.tar.bz2和u-boot-2009.08.tar.bz2直接编译smdk2410的,反汇编发现其lowlevel_init()还是在4K之外。

不知道是不是我的编译器出问题了,还是linux系统出问题了,或者说,除了强制放在start.o脚本后面,需要修改些什么才能达到(1)中根据调用函数执行顺序自动优化代码排放顺序。请高人点拨!
级别: 新手上路
UID: 8849
精华: 0
发帖: 9
金钱: 100 两
威望: 50 点
贡献值: 0 点
综合积分: 18 分
注册时间: 2009-09-08
最后登录: 2010-12-18
1楼  发表于: 2009-12-01 14:11

 回 楼主(azfa) 的帖子

我也是128M rom.也是mini2440那个。可以跑的,64M这个问题基本上原作者已经写好了,改改宏就可以用到128M
原来的

#if defined(CONFIG_S3C2410) || defined(CONFIG_MINI2440)
/* configuration for 2410 with 512byte sized flash */
#define NAND_PAGE_SIZE        512
#define BAD_BLOCK_OFFSET    5
#define NAND_BLOCK_MASK        (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE        0x4000
#else
/* configuration for 2440 with 2048byte sized flash */
#define NAND_5_ADDR_CYCLE
#define NAND_PAGE_SIZE        2048
#define BAD_BLOCK_OFFSET    NAND_PAGE_SIZE
#define    NAND_BLOCK_MASK        (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE        (NAND_PAGE_SIZE * 64)
#endif
修改后
//#if defined(CONFIG_S3C2410) || defined(CONFIG_MINI2440)
#if defined(CONFIG_S3C2410)
/* configuration for 2410 with 512byte sized flash */
#define NAND_PAGE_SIZE        512
#define BAD_BLOCK_OFFSET    5
#define NAND_BLOCK_MASK        (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE        0x4000
#elif defined(CONFIG_MINI2440)
/* configuration for 2440 with 2048byte sized flash */
#define NAND_5_ADDR_CYCLE
#define NAND_PAGE_SIZE        2048
#define BAD_BLOCK_OFFSET    NAND_PAGE_SIZE
#define    NAND_BLOCK_MASK        (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE        (NAND_PAGE_SIZE * 64)
#endif

就可以跑拉。
级别: 新手上路
UID: 8849
精华: 0
发帖: 9
金钱: 100 两
威望: 50 点
贡献值: 0 点
综合积分: 18 分
注册时间: 2009-09-08
最后登录: 2010-12-18
2楼  发表于: 2009-12-01 14:18

 回 1楼(shangxiaole) 的帖子

sorry.搞错了,还以为你用的是那个google code那个。 另外,如果是nand启动跟flash启动应该是不一样的,flash可以直接执行代码。nand必须要先load,因为像你说的必须要在4k內。
我修改过google code那个来用,功能相当丰富。很多命令都不知道是什么用法
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
3楼  发表于: 2009-12-01 14:37

 回 楼主(azfa) 的帖子

不管是64M还是128M  NAND Flash, 要用S3C2440A的NAND Boot方式启动, 就必须把bootloader的第一阶段(包括初始化CPU, SDRAM, NAND Flash controller等等为把第二阶段bootloader从NAND Flash里读取到SDRAM中所做的准备工作)所有代码链接在bootloader的前4K中.
而在U-boot中,实现这一功能唯一的方式就是把对应的.o写在链接脚本lds文件的相应位置. 官方发布的u-boot 2008.10和2009.8都没有支持NAND启动,因此链接顺序没有这一限制.你的做法是对的, 也是唯一可行的办法.
事实上,你可以看到所有支持NAND启动的u-boot都这样修改过lds文件.

如果不在lds文件中指定链接的顺序, 则默认的.o或者.a文件链接顺序按照编译时链接生成u-boot的传递给ld的顺序决定.
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 10162
精华: 0
发帖: 47
金钱: 365 两
威望: 151 点
贡献值: 0 点
综合积分: 94 分
注册时间: 2009-10-26
最后登录: 2013-09-07
4楼  发表于: 2009-12-01 14:54
谢谢Kasim的指导!
版主的意思我明白了,我参考的(1),我确信其没有强制放置在start.o后面,但是他编译出来的就是放在start.o后面的。那肯定有什么地方改过,而我没改。

按我的理解,start里cpu初始化调用lowlevel_init(),以及下面调用nand_read_llb() ,按默认不就是应该先链接lowlevelini.o,再链接nand_read.o?
“则默认的.o或者.a文件链接顺序按照编译时链接生成u-boot的传递给ld的顺序决定”,这个我应该查看uboot下什么文件得到相关信息?
[ 此帖被azfa在2009-12-01 15:00重新编辑 ]
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
5楼  发表于: 2009-12-01 15:49

 回 4楼(azfa) 的帖子

"传递给ld的顺序"指的就是ld命令行上的顺序, 比如

                cd /home/alex/project3/qq2440/uboot/mini2440 && /usr/local/arm/4.3.2/bin/arm-none-linux-gnueabi-ld -Bstatic -T /home
/alex/project3/qq2440/uboot/mini2440/board/mini2440/u-boot.lds  --defsym raise=hang -Ttext 0x33F40000 $UNDEF_SYM cpu/arm920t/start.o
\
                        --start-group lib_generic/libgeneric.a board/mini2440/libmini2440.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c
24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiser
fs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a drivers/bios_emulator/libatibiosemu.a drivers/block/libblock.a drivers/dma/libd
ma.a drivers/hwmon/libhwmon.a drivers/i2c/libi2c.a drivers/input/libinput.a drivers/misc/libmisc.a drivers/mtd/libmtd.a drivers/mtd/
nand/libnand.a drivers/mtd/nand_legacy/libnand_legacy.a drivers/mtd/onenand/libonenand.a drivers/net/libnet.a drivers/net/sk98lin/li
bsk98lin.a drivers/pci/libpci.a drivers/pcmcia/libpcmcia.a drivers/spi/libspi.a drivers/rtc/librtc.a drivers/serial/libserial.a driv
ers/usb/libusb.a drivers/video/libvideo.a post/libpost.a post/drivers/libpostdrivers.a common/libcommon.a libfdt/libfdt.a api/libapi
.a --end-group -L /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t -lgcc \
                        -Map u-boot.map -o u-boot

可以看到--start-group之后各个.a的顺序基本上就是最终可执行档里各个.a中符号链接的顺序. 像lowlevel_init.S中的符号属于board/mini2440/libmini2440.a的, 基本上就紧接着cpu/arm920t/start.o了
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 10162
精华: 0
发帖: 47
金钱: 365 两
威望: 151 点
贡献值: 0 点
综合积分: 94 分
注册时间: 2009-10-26
最后登录: 2013-09-07
6楼  发表于: 2009-12-01 15:55
再次感谢版主的无私指导!