U-BOOT移植问题小结

U-BOOT编译中的软浮点soft-float问题(R_ARM_PLT32 __div0)
使用arm-linux-gcc-3.4.1和arm-linux-2.95.3交叉编译工具编译U-BOOT-1.1.6时,总是提示如下类似错误信息。
/lib_arm/_udivsi3.S:67: relocation truncated to fit: R_ARM_PLT32 __div0
lib_arm/_umodsi3.S:79: relocation truncated to fit: R_ARM_PLT32 __div0
上网搜索了一下,发现出现这个问题的还不少。网友给出的解决方法是:
1)去除编译选项soft-float
2) 重新制作交叉编译工具
试了一下,发现去除soft-float后,还是不能解决这个问题。按照网友vxworks尔雅的方法,重新制作了cross tools,步骤如下:
1)root登陆
2)创建目录/opt/crosstool/并修改并修改其owner。是因为此crosstool不能以root安装,而须以username安装,安装过程会读写此目录,故需要修改属主。
3)以用户username登陆
4) 创建目录/home/username/downloads这个目录将来用于自动从网上下载gcc, binutilty,glibc等。如果自己已经下载了这些软件包,也放在这个目录下,这样就不用程序自动从网上下载了。
5) 从http://kegel.com/crosstool/下载crosstool-0.43.tar.gz到目录/opt/crosstool
6) cd /opt/crosstool tar xzvf crosstool-0.43.tar.gz
7) 进入crosstool-0.43目录,执行sh demo-arm-softfloat.sh
经过漫长的等待,最后生成新的cross tool chains。修改U-BOOT的Makefile文件,指定cross tool。
make sbc2410x_config
make all

终于可以编译成功了。


交叉编译u-boot -- 目标开发板SBC-2410X

2007年09月13日 星期四 17:37

1. 下载u-boot源码包:
--------------------------------------
    http://sourceforge.net/project/showfiles.php?group_id=65938&package_id=63695
    # wget -c ftp://ftp.denx.de/pub/u-boot/u-boot-1.1.5.tar.bz2


2. u-boot的编译
--------------------------------------
    注: 交叉编译器选择3.3.2
    # cd u-boot-1.1.5
2.1 修改u-boot源码使其支持nand flash启动
2.2
u-boot向内核传递machine ID(修改cmd_boot.c)
2.4 修改Bug 2 (1.1.6不需要关注这里)

    # make sbc2410x_config
    # make

    编译完成后,可以得到u-boot各种格式的映像文件和符号表
    # ls -lh u-boot*
    u-boot.bin    118K    u-boot映像原始的二进制格式
    u-boot        448K    u-boot映像的ELF格式
    u-boot.srec   354K    u-boot映像的S-Record格式
    u-boot.map    52K     u-boot映像的符号表

    u-boot的3种映像格式都可以烧写到Flash中,但需要看加载器能否识别这些格式。一般u-boot.bin最为常用,直接按照二进制格式下载,并且按照绝对地址烧写到Flash中就可以了。u-boot和u-boot.srec格式映像都自带定位信息。

3. -
用Jflash烧写u-boot到nand flash


Bug 1
cc1: error: invalid option `abi=apcs-gnu'
------------------------------------------------------------------
    1)改用GCC为arm-linux-gcc-3.4.1.tar.bz2即可. 或者:
    2)出错的文件是/cpu/arm920t/下的config.mk:
    将
    PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
    改成:
    PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,$(call cc-option,-mabi=apcs-gnu),)


Bug 2
make[1]: *** 没有规则可以创建“all”需要的目标“hello_world.srec”。 停止。
------------------------------------------------------------------
    make[1]: Leaving directory `/home/a-ki/at91rm9200/u-boot-1.1.4/examples'
    make: *** [examples] 错误 2

    在网上查了查,有人说是make 3.81的一个BUG!
    http://blackfin.uclinux.org/gf/project/u-boot/tracker/?action =TrackerItemEdit&tracker_item_id=1324
    可以简单的改一个目录examples下的Makefile来解决:
    vi examples/Makefile
    #SREC   = hello_world.srec
    #BIN    = hello_world.bin hello_world
    SREC    = hello_world.o
    BIN     = hello_world.o hello_world



Bug 3
软浮点soft-float问题(R_ARM_PLT32 __div0)
------------------------------------------------------------------
    lib_arm/_udivsi3.S:67: relocation truncated to fit: R_ARM_PLT32 __div0
    lib_arm/_umodsi3.S:79: relocation truncated to fit: R_ARM_PLT32 __div0
    使用3.3.2交叉编译器,即可成功编译




用Jflash烧写u-boot到Nand Flash
2007年09月13日 星期四 15:23

SBC2410/Linux/sbc2410v6_linux-2.4.18_sdk.tgz(友善之臂的开发光盘)
安装烧写工具: Jflash-s3c2410
# tar zxvf sbc2410v6_linux-2.4.18_sdk.tgz
# cd opt/FriendlyARM/SBC2410/Jflash/
# cp Jflash-s3c2410 /usr/bin

或者直接从G宝盘下载
Jflash-s3c2410下载后注意修改Jflash-s3c2410的执行权限

# cd u-boot-1.1.6/
# ls -l u-boot.bin
-rwxr-xr-x 1 root root 112644 2007-09-22 15:02 u-boot.bin
# Jflash-s3c2410 u-boot.bin /t=5

+------------------------------------+
|     SEC JTAG FLASH(SJF) v 0.11     +
|     modified by MIZI 2002.7.13     +
+------------------------------------+
> flashType=5
> S3C2410X(ID=0x0032409d) is detected.
> K9S1208 is detected. ID=0xec76

K9S1208 NAND Flash JTAG Programmer Ver 0.0
0:K9S1208 Program      1:K9S1208 Pr BlkPage   2: Exit               

Select the function to test :
0

[SMC(K9S1208) NAND Flash Writing Program]

Source size: 0x1b803            <==> 112643 byte

Available target block number: 0~4095
Input target block number:
0
STATUS:Epppppppppppppppppppppppppppppppp
Epppppppppppppppppppppppppppppppp
Epppppppppppppppppppppppppppppppp
Epppppppppppppppppppppppppppppppp
Epppppppppppppppppppppppppppppppp
Epppppppppppppppppppppppppppppppp
Epppppppppppppppppppppppppppppppp
Epppppppppppppppppppppppppppppppp

K9S1208 NAND Flash JTAG Programmer Ver 0.0
0:K9S1208 Program      1:K9S1208 Pr BlkPage   2: Exit               

Select the function to test :
2

注:
(1) 将u-boot.bin烧写到Nand Flash的前111K
(2) 从u-boot源码获知"环境变量"的存放位置及其大小
vi u-boot-1.1.6/include/configs/smdk2410.h
---------------------------------------------

#define CFG_ENV_OFFSET      0x0F0000
#define CFG_ENV_SIZE        0x010000
    环境变量的存放位置:960KB;大小:64KB(Nand Flash第1M的最后64KB中存放环境变量)。这样uImage就应该存放于0x100000 <==> 1MB(从这个位置开始存放内核)




    新开发的电路板没有任何程序可以执行,也就不能启动,需要先将u-boot烧写到Flash中。如果主板上的EPROM或者Flash能够取下来,就可以通过编程器烧写。例如:计算机BIOS就存储在一块256KB的Flash上,通过插座与主板连接。但是多数嵌入式单板使用贴片的Flash,不能取下来烧写。这种情况可以通过处理器的调试接口,直接对板上的Flash编程。处理器调试接口是为处理器芯片设计的标准调试接口,包含BDM、JTAG和 EJTAG3种接口标准。BDM(Background Debug Mode)主要应用在PowerPC8xx系列处理器上;EJTAG主要应用在MIPS处理器上。这3种硬件接口标准定义有所不同,但是功能基本相同,下面都统称为JTAG接口。
    最简单方式就是通过JTAG电缆,转接到计算机并口连接。这需要在主机端开发烧写程序,还需要有并口设备驱动程序。开发板上电或者复位的时候,烧写程序探测到处理器并且开始通信,然后把Bootloader下载并烧写到Flash中。这种方式速率很慢,可是价格非常便宜。一般来说,平均每秒钟可以烧写 100~200个字节。
    烧写完成后,复位实验板,串口终端应该显示u-boot的启动信息。



对uboot移植的点滴记录

命令使用:
烧写Uboot:protect off 1:0
                     erase 1:0
                      tftp 30008000 u-boot.bin
                      cp.b 30008000 0 20000
对于Uboot下一步的工作是增加一个fl命令,应该比这个erase好用些,因为erase察出要知道那几个扇区或者是那两块地址之间
烧写BMP图片:tftp 30008000 logo.bmp
                            cp.b 300080000 00fa0000 $filesize
                             setenv splashimage 00fa0000
                             saveenv
                             bmp info $splashimage
把JPG转换成BMP(在Linux下使用PBM工具):
#jpegtopnm Bergkirchen.jpg | /
> ppmquant 256 | /
> ppmtobmp -bpp 8 >Bergkirchen-8bit.bmp
jpegtopnm: WRITING PPM FILE
ppmquant: making histogram...
ppmquant: too many colors!
ppmquant: scaling colors from maxval=255 to maxval=127 to improve clustering...
ppmquant: making histogram...
ppmquant: too many colors!
ppmquant: scaling colors from maxval=127 to maxval=63 to improve clustering...
ppmquant: making histogram...
ppmquant: 9760 colors found
ppmquant: choosing 256 colors...
ppmquant: mapping image to new colors...
ppmtobmp: analyzing colors...
ppmtobmp: 231 colors found
ppmtobmp: Writing 8 bits per pixel with a color pallette

制作uImage:
./mkimage -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -n  'linux-2.4.18'   -d zImage Image
-A 设置那种类型的CPU
-O 设置那种类型的OS
-T  设置映像image类型
-C  是否压缩
-a  设置装载点
-e 设置进入点(内核的入口地址,信息头的大小是0X40,在制作uImage时,加的一个头,在使用bootm时会判别这个头)
-n 设置image名称

把信息传入linux核心的TAG定义:
#define CONFIG_SETUP_MEMORY_TAGS   //如果没有定义这个参数,则uboot参数必须加入men=内存大小
#define CONFIG_INITRD_TAG
#define CONFIG_CMDLINE_TAG  //设置bootargs出入内核必须

#define CFG_LOAD_ADDR  0x33000000 //把0X33000000改为0X30008000

设置NFS启动:
set bootargs root=/dev/nfs nfsroot=192.168.0.5:/home/zouzheng/HHARM/rootbox rw noinitrd init=/linuxrc ip=192.168.0.240:192.168.0.5:192.168.0.5:255.255.255.0:hharm:eth0:off console=ttyS0,115200
设置RAMDISK启动:
set bootargs  initrd=0x30800000,0x440000 mem=64M  root=/dev/ram init=/linuxrc console=ttyS0

 内核启动参数

/////////////关于根文件系统的位置:
(1)initrd=0x30800000,0x440000 root=/dev/ram init=/linuxrc   (ramdisk)

(2)console=ttyS0,115200 nfsroot=10.0.0.38:/root_arm ip=10.0.0.182:10.0.0.38:10.0.0.38:255.0.0.0:arm_emb:eth0:off (网络文件系统)

(3)noinitrd root=/dev/mtdblock/3 init=/linuxrc console=ttySAC0" (在jffs2 或 cramfs)

(4)console=ttySC1,115200 root=/dev/inftla"  (在DOC)

要看你到底使用的什么文件系统,及文件系统的位置

1.调试时最便捷的搭配:(内核---server/tftpboot/zImage ; 文件系统----sever/root_arm)

#define CONFIG_BOOTCOMMAND"help;help;tftp 30008000 zImage;go 30008000"

console=ttySAC0,115200 nfsroot=10.0.0.38:/root_arm ip=10.0.0.182:10.0.0.38:10.0.0.38:255.0.0.0:arm_emb:eth0:off (网络文件系统)

2.典型应用:(内核---flash ; 文件系统----flash)

 

#define CONFIG_BOOTCOMMAND"help  ;version  ; cp 01040000 30008000 100000; cp 01140000 30800000 400000; go 30008000 "

initrd=0x30800000,0x440000 root=/dev/ram init=/linuxrc

3.最终产品:(内核---flash ; 文件系统----DOC)

#define CONFIG_BOOTCOMMAND"help  ;version  ; cp 01040000 30008000 200000; go 30008000 "

console=ttySC0,115200 root=/dev/inftla"

Uboot编译错误记录:

1、此时会出现一个错误:cc1: error: invalid option `abi=apcs-gnu'
修改/cpu/arm920t/下的config.mk:
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
改成:PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,$(call cc-option,-mabi=apcs-gnu),)

2、编译的时候出现下面的错误:
  /usr/local/arm/3.4.1/bin/arm-linux-ld: ERROR:
  /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/libgcc.a(_divsi3.oS) uses hardware FP, whereas u-boot uses software FP
  /usr/local/arm/3.4.1/bin/arm-linux-ld: failed to merge target specific data of file /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/libgcc.a(_divsi3.oS)
  /usr/local/arm/3.4.1/bin/arm-linux-ld: ERROR:
  /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/libgcc.a(_modsi3.oS) uses hardware FP, whereas u-boot uses software FP
  /usr/local/arm/3.4.1/bin/arm-linux-ld: failed to merge target specific data of file
  /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/libgcc.a(_modsi3.oS)lib_arm/libarm.a(_udivsi3.o)(.text+0x8c):/u-boot/u-boot-1.1.4/lib_arm/_udivsi3.S:67:relocation truncated to fit: R_ARM_PLT32 __div0 lib_arm/libarm.a(_umodsi3.o)(.text+0xa:/u-boot/u-boot-1.1.4/lib_arm/_umodsi3.S:79:
relocation truncated to fit: R_ARM_PLT32 __div0
  /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/libgcc.a(_divsi3.oS)(.text+0x11c):/work/crosstool-0.27/build/arm-linux/gcc-3.4.1-glibc-2.3.2/gcc-3.4.1/gcc/config/arm/lib1funcs.asm:735:
relocation truncated to fit: R_ARM_PLT32 __div0
  /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/libgcc.a(_modsi3.oS)(.text+0xd:/work/crosstool-0.27/build/arm-linux/gcc-3.4.1-glibc-2.3.2/gcc-3.4.1/gcc/config/arm/lib1funcs.asm:795:
relocation truncated to fit: R_ARM_PLT32 __div0
make: *** [u-boot] Error 1
   出现上面的错误有人说这样修改:
   PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8
#        -msoft-float

PLATFORM_CPPFLAGS += -march=armv4
# =========================================================================
#
# Supply options according to compiler version
#
# =========================================================================
#PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,)
PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))

其实这样改是没有用的,问题是3.4.1用的是hardware FP,而u-boot uses software FP,用2.95或者3.3.2版本可解决这个问题
不过用2.95版本的时候还要修改一个链接


在Uboot里找一块使用相同Flash的板子
如:使用SST160 Flash
grep –R ‘SST160A’ ./
看到一大堆的板子,我们选用名字为dave中的flash.c,拷贝这个flash.c到smdk2410目录,
cp board/dave/common/flash.c board/smdk2410/
如:使用SST39VF160 Flash的板子
grep -nir sst39vf160 u-boot
然后把使用sst39vf160的flash拷贝
如:找44B0的板子
find . -exec grep -l 44B0 {} /;


问题:如果你在uboot保存环境变量时saveenv,出现Error: end address not on sector boundary
 解决办法:/include/configs/at91rm9200dk.h(smdk2410.h)中 #define CFG_ENV_ADDR (PHYS_FLASH_1+0X20000) #define CFG_ENV_SIZE 0X20000(将环境变量放到了0x10040000,大家也可以根据具体情况改变你的地址,即修改CFG_ENV_ADDR)

你可能感兴趣的:(嵌入式系统)