终于可以编译成功了。
交叉编译u-boot -- 目标开发板SBC-2410X
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交叉编译器,即可成功编译
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)