UBOOT-1.1.6在S3C2410上的移植(基于GEC2410)

时间:2022-12-30 06:36:07

之前做过u-boot-1.1.6在AT91RM9200的移植,虽然2410和9200这两款ARM9芯片都是ARM920T核的,但还是有不少区别的,特别是启动方式(当然前者是工业级后者是民用级不必说)。at91rm9200内部本身有128k的片内rom,其固化了一个bootloader和uploader, 用来支持程序的下载和引导,而且其内部固化的程序提供了很多内部服务接口(Internel Service)供我们来使用,例如Xmodem;而S3C2410启动是把nandflash的前4K代码自动搬到Steppintstone中去运行,而Steppingstone使用的物理地是从0号位置开始的。(当然如果是Nor Flash启动,两者是相同的)
1.开发环境
宿主机:FC11 
交叉编译器: 
之前编译的arm-linux-gcc-3.4.5-softfloat,请参见:
http://blog.csdn.net/shevsten/archive/2007/07/14/1691197.aspx
开发板: GEC2410 NAND Flash:64M K9F1208, NOR Flash:2M SST39VF1601 SDRAM 64M, CS8900A

2.下载u-boot-1.1.6源码
u-boot的源码可以从以下网址下载:
ftp://ftp.denx.de/pub/u-boot/

解压放到指定目录:
# tar -xvjf u-boot-1.1.6.tar.bz2

3.建立自己GEC2410开发板的配置
复制smdk2410的开发板配置,然后在做相应修改,由于Uboot1.1.6对SMDK2410板的NAND Flash初始化部分没有写,主要移植内容为Nand Flash部分.
复制smdk2410目录及对应头文件,并改名为gec2410:
1)# cp –r board/smdk2410 board/gec2410   
2)# cp include/configs/smdk2410.h include/configs/gec2410.h

4.修改顶层Makefile
(1)增加gec2410配置
找到Line 1879:
smdk2410_config    :    unconfig
    @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
在其后面添加:
gec2410_config    :    unconfig
    @$(MKCONFIG) $(@:_config=) arm arm920t gec2410 NULL s3c24x0
各项的意思如下:
arm:        CPU的架构(ARCH)
arm920t:    CPU的类型(CPU),其对应于cpu/arm920t子目录。
fs2410:    开发板的型号(BOARD),对应于board/fs2410目录。
NULL:       开发者/或经销商(vender)。
s3c24x0:    片上系统(SOC)。

这样在执行make gec2410_config命令后就把环境变量设置好了
(2)设置编译器路径(Line 127)
ifeq ($(ARCH),arm)
CROSS_COMPILE = /home/GEC2410/toolchain/arm-softfloat-linux-gnu/bin/arm-softfloat-linux-gnu-

5.修改u-boot的命令行提示符
include/configs/gec2410.h第111行:
修改:
# define   CFG_PROMPT     "SMDK2410 #"
为:
# define   CFG_PROMPT     "GEC2410 #"
这是u-boot的命令行提示符。

6.修改board/gec2410/Makefile
将:
COBJS    := smdk2410.o flash.o
改为:
COBJS     := gec2410.o flash.o
gec2410下的smdk2410.c改成gec2410.c;

7.修改board/gec2410/lowlevel_init.S文件
参考GEC2410开发板自带BIOS里的配置参数,主要是SDRAM时序参数的配置.

这时候可以测试下编译是否成功
#make gec2410_config
#make
u-boot-bin目录下会出现u-boot.bin

8.board/fs2410加入NAND Flash读函数,建立nand_read.c(从开发板提供的u-boot-1.1.4中复制board/gec2410/nand_read.c,实际上就是从vivi中拷贝过来的)代码比较简单,实际上就一个读NAND的函数,代码如下:
具体对NAND的操作可参考CE下NAND驱动分析:
http://blog.csdn.net/shevsten/archive/2010/04/27/5533400.aspx

接着修改board/gec2410/makefile,增加对nand_read.c的编译
第28行:
COBJS     := gec2410.o flash.o nand_read.o

9.修改cpu/arm920t/start.S文件
2410从Nand Flash启动时,NAND FLASH的前4KB(地址为0x00000000,OM[1:0]=0)将被装载到SDRAM中被称为Setppingstone的地址中,然后开始执行这段代码.启动以后,这4KB的空间可以做其他用途,在start.S加入搬运代码.
主要工作开始初始化NAND控制器,然后调用nand_read.c中的nand_read_ll函数来复制u-boot自身代码到RAM中,最后跳转到RAM中运行.汇编代码如下:

注意bl  copy_myself即第一个#ifdef CONFIG_S3C2410_NAND_BOOT的内容必须放在Set up the stack之前,否则会发生tftp Retry count exceeded; starting again的错误.(具体为net.c中 if (memcmp(ether, NetEtherNullAddr, 6) == 0) NetEtherNullAddr初始值为{0,0,0,0,0,0},而调试发现变成了{ff,ff,ff,ff,ff,ff},从而导致ether server的MAC地址无法获得,发送的UDP包目标机MAC地址缺失,从而无法连接,原因可能是堆栈区设置好后被uboot代码覆盖,因此,堆栈设置应该在uboot复制到ram后进行)

10.在gec2410.h中定义:
主要是NAND控制器地址,寄存器偏移量,uboot RAM地址等.
其中CONFIG_S3C2410_NAND_BOOT定义从Nand启动,如果不定义CONFIG_S3C2410_NAND_BOOT则u-boot从nor flash启动.

11.编写NAND闪存初始化函数
u-boot运行至第二阶段进入start_armboot()函数(位于Lib_arm/board.c
)。其中nand_init()函数是对nand flash 的最初初始化函数。其调用与 CFG_NAND_LEGACY 宏有关,如果没定义CFG_NAND_LEGACY 这个宏,就按照start_armboot()调用drivers/nand/nand.c 中的nand_init 函数(该函数在 1.1.6 已经被实现), 但还有个 board_nand_init()函数没实现,需自己添加。如果定义了CFG_NAND_LEGACY,就不使用默认的nand_init,而调用自己写的nand_init 函数了,这里我们选择第二种方式。
在common/cmd_nand.c最后添加:

该函数首先初始化NAND控制器,然后调用nand_probe获取NAND信息.
nand_probe实现在/src/drivers/nand_legacy/nand_legacy.c
有这样一段代码:

生成的u-boot.bin烧写后运行,NAND的信息无法得到,显示的0MB,同样不能saveenv.
检查发现上面的循环中的if并未进入,nand指针一直为NULL,就直接返回0了.原因是该文件上面定义的
struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};
而if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN) 判断时则会为否.因此在for循环之前增加:
nand_dev_desc[0].ChipID = 0x00;
使if判断成功,nand才能成功被赋值.

12. 修改include/configs/gec2410.h,在上次修改的基础上加上如下代码,定义NAND 闪存命令层的底
接口函数等:

13. 修改common/env_nand.c
make后出现/env_nand.c:206 undefined reference to 'nand_info'等等问题
原来nand flash 真正的擦除和读写函数使用的是drivers/nand_legacy/目录下面的读写、擦除函数
在env_nand.c中添加如下声明:

修改saveenv和env_relocate_spec函数:

14.U-BOOT给linux内核传递合适参数的定义
再次修改include/configs/gec2410.h:

15.修改UBOOT的2410CPU频率
smdk2410的U-BOOT原来运行频率是202.8M,而GEC2410的BIOS里面是200M,所以不修改频率可能会出点问题.
修改board/gec2410/gec2410.c文件如下:


使用H-JTAG烧写到板子上后重启,出现如下信息:
U-Boot 1.1.6 (May 12 2010 - 13:48:06)

DRAM:  64 MB
Flash: 512 kB
NAND:  nand flash :   64 MB
In:    serial
Out:   serial
Err:   serial
GEC2410#

saveenv,tftp均成功:

GEC2410#saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
GEC2410#

 

GEC2410#tftp 30008000 zImage
TFTP from server 192.168.1.15; our IP address is 192.168.1.5
Filename 'zImage'.
Load address: 0x30008000
Loading: #################################################################
         #################################################################
         #################################################################
         ##############################
done
Bytes transferred = 1147452 (11823c hex)

接下来就是移植linux内核了.