我在移植过程主要参考以下文章,在此对其作者表示感谢。
u-boot移植44b0的详细步骤
U-Boot移植到S3C44B0X开发板的过程
解决你的U-boot+ RTL8019AS 驱动问题总结
《u-boot移植44b0的详细步骤》刚好符合我开发板的情况,但是在flash里设置不是很详细,而《U-Boot移植到S3C44B0X开发板的过程》正好补充。《解决你的U-boot+ RTL8019AS 驱动问题总结》使我对RTL8019接线及配置有深的认识。
开发板情况
BANK0:flash=SST39VF1601,2M,sector size=32k,sector count=64
BANK3:ETHERNET=RTL8019AS,BASEADDR=0X06000000
BANK6:SDRAM,8M
ETHERNET的接线情况:
1)
上的SA0~ SA4分别与CPU 的ADDR0~ADDR4连接,IOCS16B悬空。RTL8019
2)
拉高的BD1悬空SA8,SA9
3)
的INT0接CPU的INT1RTL8019
4)
接CPU的nGCS3,即基址为0x06000000AEN
对这几个脚最好自已测一下,有时说明书上的并不对(我的就这样);以上的接线说明我的RTL8019只能工作在8bit模式。
开发工具
1 交叉编译工具
我是在uClinux官网下载的工具包。
http://www.uclinux.org/pub/uClinux/arm-tools/RPMS/
arm-elf-binutils-2.12.1-5.i386.rpm //二进制转换工具
arm-elf-gcc-2.95.3-5.i386.rpm //编译工具
arm-elf-gdb-5.2-0.i386.rpm //调试工具
arm-elf-uClibc-0.9.20-2.i386.rpm //开发库
安装命令:rpm –ivh arm-elf-xxx.rpm
Rpm 使用:
Rpm –qd 软件名查询软件安装路径
Rpm –e 软件名删除软件
交叉编译工具如果使用工具链安装,在某些系统可能出现安装出错:
Tail:cannot open ‘43+’ for reading:no such file or dierectory
正确安装方法:
在该文件所在目录下,键入:
问题1:
tail: cannot open `+43' for reading: No such file or directory
解决方法: 在Linux下(注:不要在Win下) 重新下载一个arm-elf-tools-20030314.sh
建议用VIM(注:不要在Win下)
将第39行的代码:
tail +${SKIP} ${SCRIPT} | gunzip | tar xvf -
改成如下:
tail -n +${SKIP} ${SCRIPT} | gunzip | tar xvf -
问题2:
gunzip: stdin: unexpected end of file
解决方法: 要在arm-elf-tools-20030314.sh 最后一行加入一空行(注,不要在Win下修改,建议用VIM)
在该文件所在目录下,键入:
$ su
# ls –l arm-elf-tools-20030314.sh
该命令显示文件的各种属性,如果该脚本文件属性的不是可执行的,则还需要输入命令:# chmod 755 arm-elf-tools-20030314.sh
以将其属性改为可执行属性,然后通过键入命令(一定要用这个命令,否则可能会出问题):
#sh ./arm-elf-tools-20030314.sh
问题1:
tail: cannot open `+43' for reading: No such file or directory
解决方法: 在Linux下(注:不要在Win下) 重新下载一个arm-elf-tools-20030314.sh
建议用VIM(注:不要在Win下)
将第39行的代码:
tail +${SKIP} ${SCRIPT} | gunzip | tar xvf -
改成如下:
tail -n +${SKIP} ${SCRIPT} | gunzip | tar xvf -
问题2:
gunzip: stdin: unexpected end of file
解决方法: 要在arm-elf-tools-20030314.sh 最后一行加入一空行(注,不要在Win下修改,建议用VIM)
2 u-boot
我刚开始下载u-boot-1.1.6,以为最新的应该是最完善的,兼容性最好的,但是我用其中一个编译出错,据说需要gcc v3以上,这倒没去试,只知道u-boot-1.1.5,u-boot-1.1.6用arm-elf-gcc-2.95.编译都会出错;然后我选择u-boot-1.1.4,编译通过,针对我的开发板配置后,串口能输出数据,但是网络部分不能用。后来看网上移植成功的是1.1.1的,我也下载1.1.1的进行移植,网络部分才正常工作,这时才发现在用u-boot-1.1.4时没有使能nGCS3(对应AEN),因而网络部分用不了,我在跟踪网络部分时,发现u-boot-1.1.4没有相应的rtl8019初始化函数,但是后来用1.1.1同样没有却能用,因为启动u-boot没有初始化网络,即没有PC机ping板的功能,在ping PC机时进行初始化网络的,这也是我在用bdinf命令时没查到网络设备的缘故。在此再次感谢xxc对我网络模块调试的帮助。
u-boot-1.1.1 的下载地址
u-boot-1.1.4 的下载地址
移植过程
我的CPU是S3C44B0,所以用/board/dave/B2作为修改对象
1 安装交叉编译工具
# rpm –ivh
arm-elf-binutils-2.12.1-5.i386.rpm
# rpm –ivh
arm-elf-gcc-2.95.3-5.i386.rpm
# rpm –ivh
arm-elf-gdb-5.2-0.i386.rpm
# rpm –ivh
arm-elf-uClibc-0.9.20-2.i386.rpm
安装完毕,会在当前目录生成uClinux 文件夹,以上4个安装包的东东都在uClinux里。
Rpm 的用法:
查询安装位置 rpm –ql arm-elf-gcc
查询rpm包是否安装 rpm –initdb
综合查询 rpm –qil
安装 rpm –ivh xx.rpm
升级 rpm –uvh xx.rpm
删除 rpm –e arm-elf-gcc
2 解压u-boot
# bunzip2 u-boot-1.1.1.tar.bz2
生成u-boot-1.1.1.tar
# tar –xvf u-boot-1.1.1.tar
生成u-boot-1.1.1文件夹
3 测试
先对B2是否可用进行测试
1)
修改 /Makefile
将
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
Endif
改为
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-elf-
Endif
2) 编译
# make distclean //
清除原先的所有配置
# make B2_config //
只对
B2
进行编译
# make
对1.1.4,编译过程会出现以下错误:
invalid option `
abi
=apcs-gnu'
修改
/cpu/s3c44b0/config.mk
将
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
改为
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,$(call cc-option,-mabi=apcs-gnu))
PLATFORM_RELFLAGS+=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
编译成功后会在u-boot-1.1.1下生成三个文件
u-boot
u-boot.bin
u-boot.srec //可以直接用
flashrpm烧写
4 针对开发板的修改
将对/board/dave/B2进行修改,使他符合的开发板情况。
涉及到的文件夹和文件
/board/dave
/cpu/s3c44b0
/include/configs/B2.h
1)
修改/include/configs/B2.h
B2.h是开发板的配置头文件,配置如串口波特率,IP,基址,sdram和flash的大小等
修改
#define CONFIG_S3C44B0_CLOCK_SPEED 75 /* we have a 75Mhz S3C44B0*/
改为
#define CONFIG_S3C44B0_CLOCK_SPEED 66 /* we have a 66Mhz S3C44B0*/
在/cpu/s3c44b0/start.S 和/cpu/s3c44b0/serial.中可看到时钟频率只有75,66两种,而我的开发板最大好像只支持72Mhz
/**********************************************
/cpu/s3c44b0/start.S
#if CONFIG_S3C44B0_CLOCK_SPEED==66
ldr r0, =0x34031 /* 66MHz (Quartz=11MHz) */
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
ldr r0, =0x610c1 /*B2: Xtal=20mhz Fclk=75MHz */
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif
***********************************************/
修改
#define CONFIG_DRIVER_LAN91C96
#define CONFIG_LAN91C96_BASE 0x04000300 /*base address*/
改为
#define CONFIG_DRIVER_RTL8019
#define RTL8019_BASE 0x06000000 /* base address*/
#define CONFIG_BAUDRAT 115200 //为终端调试时的
//串口通信波特率115200,无需修改
修改
#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | /
CFG_CMD_DATE | /
CFG_CMD_ELF | /
CFG_CMD_EEPROM | /
CFG_CMD_I2C )
改为
#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | /
CFG_CMD_DATE | /
CFG_CMD_ELF | /
CFG_CMD_NET | /
CFG_CMD_PING | /
CFG_CMD_ENV | /
CFG_CMD_FLASH)
修改
#define CFG_LOAD_ADDR 0x0c700000 /* default load address */
改为
#define CFG_LOAD_ADDR 0x0c800000 /* default load address */
将uClinux内核下载到sdram后运行的地址
修改
/*-----------------------------------------------------------------------
* Physical Memory Map
*/
#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 banks of DRAM */
#define PHYS_SDRAM_1 0xc0000000 /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE 0x01000000 /* 16 MB */
#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
#define PHYS_FLASH_SIZE 0x00400000 /* 4 MB */
#define CFG_FLASH_BASE PHYS_FLASH_1
改为
/*-----------------------------------------------------------------------
* Physical Memory Map
*/
#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 banks of DRAM */
#define PHYS_SDRAM_1 0x0c000000 /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE 0x00800000 /* 8 MB */
#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
#define PHYS_FLASH_SIZE 0x00200000 /* 2 MB */
#define CFG_FLASH_BASE PHYS_FLASH_1
修改
/*-----------------------------------------------------------------------
* Environment Variable setup
*/
#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
#define CFG_ENV_OFFSET 0x0 /* environment starts at the beginning of the EEPROM */
改为
/*-----------------------------------------------------------------------
* Environment Variable setup
*/
#define CFG_ENV_IS_IN_FLASH 1 /* use EEPROM for environment vars */
#undef CFG_ENV_IS_NOWHERE
#define CFG_ENV_ADDR (CFG_FLASH_BASE+0x20000) /*environment start*/
#define CFG_ENV_SECT_SIZE 0x10000 /*total size of environment sector*/
1)
修改/board/dave/common/flash.c
先在/include/flash.h 增加对sst 39xF1601的定义
/*****************************
/include/flash.h
#define SST_ID_xF1601 0x234B234B /*FLASH
的一些信息
*/
#define FLASH_SST1601 0x00BF /*ID (8M)*/
*****************************/
修改/board/dave/common/flash.c
在flash_get_offsts()函数中:
/* set up sector start address table */
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
for (i = 0; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00010000);
改为
info->start[i] = base + (i * 0x00008000);
在 flash_print_info()函数中:
添加
case FLASH_SST1601: printf ("SST39LF/VF1601 ");
break;
在 flash_get_size()函数中添加:
value = addr2[CFG_FLASH_READ1]; /* device ID */
switch (value) {
…
case (CFG_FLASH_WORD_SIZE)SST_ID_xF1601:
info->flash_id += FLASH_SST1601;
info->sector_count=64;
info->size=0x00200000;
break;
向下找有:
/* set up sector start address table */
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
for (i = 0; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00010000);
改为
info->start[i] = base + (i * 0x00008000);
2)
修改/board/dave/B2/lowlevel_init.S
u-boot-1.1.4里的文件是/board/dave/B2/lowlevel_init.S
u-boot-1.1.1里的文件是/board/dave/B2/memsetup.S
内存配置如下:
MEMORY_CONFIG:
.long 0x11010102
.long 0x600
.long 0x7ffc
.long 0x7ffc
.long 0x7ffc
.long 0x7ffc
.long 0x2610
.long 0x18000
.long 0x18000
.long 0x960459
.long 0x10
.long 0x20
.long 0x20
内存配置非常重要,终端串口调试时没数据输出一般是内存配置不当引起的。这一部分的具体意义不是很清楚,
BWSCON
的头四字节
1101
要是配置错的话,串口就没反应,第四个字节为
0
表示网络使用
8
位。
/*********************************************************
如44b0手册里的
Programming Memory Controller
All thirteen memory control registers have to be written using the STMIA instruction as shown in the following
example;
ldr r0, =SMRDATA
ldmia r0, {r1-r13}
ldr r0, =0x01c80000 ; BWSCON Address
stmia r0, {r1-r13}
SMRDATA DATA
DCD 0x22221210 ; BWSCON
DCD 0x00000600 ; GCS0
DCD 0x00000700 ; GCS1
DCD 0x00000700 ; GCS2
DCD 0x00000700 ; GCS3
DCD 0x00000700 ; GCS4
DCD 0x00000700 ; GCS5
DCD 0x0001002a ; GCS6, EDO DRAM(Trcd=3, Tcas=2, Tcp=1, CAN=10bit)
DCD 0x0001002a ; GCS7, EDO DRAM
DCD 0x00960000 + 953 ; Refresh(REFEN=1, TREFMD=0, Trp=3, Trc=5, Tchr=3)
DCD 0x0 ; Bank Size, 32MB/32MB
DCD 0x20 ; MRSR 6(CL=2)
DCD 0x20 ; MRSR 7(CL=2)
*************************************************************/
1)
修改/cpu/s3c44b0/start.S
修改
add pc,pc,#0x0c000000
add pc,pc,#0x0c000000
add pc,pc,#0x0c000000
add pc,pc,#0x0c000000
add pc,pc,#0x0c000000
add pc,pc,#0x0c000000
add pc,pc,#0x0c000000
改为
LDR PC,Undefined_Addr
LDR PC,SWI_Addr
LDR PC,Prefetch_Addr
LDR PC,Abort_Addr
LDR PC,RESERVE_Addr
LDR PC,IRQ_Addr
LDR PC,FIQ_Addr
Undefined_Addr:
.word 0x0c000004
SWI_Addr:
.word 0x0c000008
Prefetch_Addr:
.word 0x0c00000c
Abort_Addr:
.word 0x0c000010
RESERVE_Addr:
.word 0x0c000014
IRQ_Addr:
.word 0x0c000018
FIQ_Addr:
.word 0x0c00001c
5) 修改/drivers/rtl8019.h
主要是修改偏移地址,如果rtl8019的sa0-sa4不是对应CPU的ADDR0-ADDR4则需要修改偏移量,否则偏移量为0
#define ETH_ADDR_SFT (0) //0为
#define EI_SHIFT(x) ((x)<<ETH_ADDR_SFT) //左移
0位
#define RTL8019_REG_00 (RTL8019_BASE+EI_SHIFT(0x00);
#define RTL8019_REG_01 (RTL8019_BASE+EI_SHIFT(0x01);
#define RTL8019_REG_02
…
1)
修改/board/dave/B2/B2.c
开网络中断
PCONB=0x7ff; /*
使用
nGCS3
一定要使能,否则可能出现
the packet is too big
的错误
*/
/* Port G */
PUPG = 0xffff;
PCONG = 0x0; /*PG0= EINT1= ETH_INT prepared for linux kernel*/
// INTMSK = 0x03fffeff;
// INTCON = 0x05;
/*
Configure chip ethernet interrupt as High level
Port G EINT 0-7 EINT0 -> CHIP ETHERNET
*/
temp = EXTINT;
temp &= ~(0x7<<4);
temp |= (0x4<<4); /*LEVEL_HIGH*/
EXTINT = temp;
5 烧写程序