思路:
一. 移植前准备:u-boot源码,编译工具与开发平台等,阅读必要资料等
二. 着手移植:
1.精简代码.
2.建立自己的开发板文件
3.增加对S3C2440的支持
4.配置NOR Flash
5.添加对NAND Flash的支持
6.添加网卡DM9000的支持
7.添加NAND Flash启动
8.内核引导.
9.支持烧写Yaffs文件系统
约定:
(1)PC 的命令表示方法:在 PC 的终端使用的命令,均在其前面加 “ # ” 号。
比如:解压源码: # tar -jxvf u-boot-1.1.6.tar.bz2 -C /opt/Zac/
(2)开发板的命令表示方法:在开发板的终端(也就是 PC 的超级终端或别的串口软件)上面运行的基于开发板的命令,均在其前面加 “ $ ” 号。
比如: $ tftp 0x32000000 u-boot.bin 或
$ nfs 0x32000000 192.168.0.110:/opt/Zac/nfs_download/u-boot.bin
(3) 关于参考本手册输入命令时出错的问题的处理:请注意命令和参数间的空格,不要漏掉了。原因:在 Linux使用命令和参数之间是使用空格隔开的, 1 个空格和多个空格是等效的,在本手册中为了保持页面的整洁,对命令和参数之间使用了 1 个空格,可能因为空格的字体类型导致空格和非空格之间区别不是很明显,敬请谅解。
(4)内核及各种文件路径(Linux上):/opt/Zac/
如内核2.6.30.4的路径为:/opt/Zac/linux-2.6.30.4/
nfs共享文件夹路径为:/opt/Zac/nfs_download/
(5)主机Linux(虚拟机上)的IP:192.168.0.110
开发板IP:202.38.214.111
u-boot-1.1.6移植(1)精简与在SDRAM运行—Zac
摘要:
对源码进行精简,删除不必要的代码,增加对S3C2440的支持,并下载到SDRAM调试
移植u-boot-1.1.6到TQ2440
系统:fedora10
开发板:TQ2440
交叉编译工具:EABI-3.4.5
三. 移植前准备
1. 获取源码(ftp://ftp.denx.de/pub/u-boot/)
2. 阅读文档:
参考文档1:ARM79出品-u-boot移植手册.pdf
(http://wenku.baidu.com/view/ad133f687e21af45b307a851.html)
参考文档2:移植u-boot-1.1.6到TQ2440档.pdf
(http://wenku.baidu.com/view/1496efea172ded630b1cb656.html)
博客:
(http://blog.chinaunix.net/space.php?uid=20543672&do=serial&id=310)
3. 开发板已经有移植好的uboot(非自己制作的,主要用于调试的,等自己的u-boot移植完毕后就用自己的uboot代替)
四. 着手移植
1. 精简代码.完成移植前准备工作后,对uboot有了一定了解,首先删除不必要的文件和目录
(1)根目录(指u-boot的顶层目录)(注意下面说的是删除目录还是文件)
xxx_config.mk:留下arm_config.mk,其他删除
lib_xxx:留下lib_arm,lib_generic,其他删除
disk:移植uboot,不需对磁盘的支持,删除
ddt:不知什么用处,删除
nand_spl:不知有什么用处,可以删除?
doc:可以用来阅读了解uboot,实际移植时没用,可以保留
(2)board目录:存放和开发板有关的文件.(注意下面说的是删除目录还是文件)
因为TQ2440使用的是SAMSUNG的S3C2440芯片(ARM920T),留下smdk2410文件夹,其他删除
(3)cpu目录:存放CPU架构的文件.(注意下面说的是删除目录还是文件)
留下arm920t目录,其他目录删除
(4)cpu/arm920t目录:留下s3c24x0目录,其他文件留下,目录删除.(注意下面说的是删除目录还是文件)
(5) 删除 include/目录下 asm-XXX 的目录,只留下 asm-arm目录,其他文件保留
(6)删除 include/configs 目录下除 smdk2410.h 以外的所有其它配置头文件
(7)drivers目录.(注意下面说的是删除目录还是文件)
由于TQ板上有nand,LCD(新增目录),dm9000网卡,且开机要用到,因此除目录nand,nand_legacy,文件dm9000x.h,dm9000x.c及Makefile外,其他删除
2. 建立自己的开发板文件(我用ZacV1作为自己的开发板代号)(注意:下文中的行数不一定准确,请以实际为准)
(1) 建立板文件
复制board/smkd2410为:board/ZacV1
复制board/smdk2410/smdk2410.c为:board/ZacV1/ZacV1.c
对应的修改zac_v1目录下的:Makefile的28行: COBJS := ZacV1.o flash.o
建立配置文件:#cp include/configs/smdk2410.h include/configs/ZacV1.h
(2) 修改顶层目录下的Makefile:
根据1879行在其下方增加:
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
ZacV1_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t ZacV1 NULL s3c24x0
配置交叉编译器:修改128行
CROSS_COMPILE = arm-linux-
===>
CROSS_COMPILE = /opt/EmbedSky/crosstools_3.4.5_softfloat/gcc-3.4.5-glibc-2.3.6/arm-linux/bin/arm-linux-
(你的用于编译u-boot的交叉编译工具, 也可以选择自己的默认交叉编译器,此时路径不用修改。)
(3) 调试的时候,还想得到u-boot 的反汇编代码,修改顶层目录Makefile的239行:
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
===>
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(obj)u-boot.dis $(U_BOOT_NAND)
对应的修改2285行:
-o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \
===>
-o -name '*.srec' -o -name '*.bin' -o -name u-boot.dis -o -name u-boot.img \) \
(4)接下来可以重复通过命令:
#make mrproper //(或#make distclean修改顶层Makefile 等相关文件必须执行此步骤)
#make ZacV1_config
#make all 2> make_log (make_log为错误输出文件,通过它查找错误)
配置过一次后,可以使用下面
#make clean
#make all 2> make_log
边调试边查错修正,直到没错误.如果没有错误,则会生成u-boot.bin文件
调试纠错的实验结果见下:
*前面删除了目录disk,dtt,drivers/sk98lin等,因此根目录下Makefile的203,205,209行的注释掉(红色部分,蓝色部分操作看下一步):
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
LIBS += net/libnet.a
#LIBS += disk/libdisk.a
LIBS += rtc/librtc.a
#LIBS += dtt/libdtt.a
LIBS += drivers/libdrivers.a
LIBS += drivers/nand/libnand.a
LIBS += drivers/nand_legacy/libnand_legacy.a
#LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/cpu/libcpu.a
*如果你的u-boot不需要支持这么多种文件系统和post,可以修改上面蓝色部分为
LIBS += fs/cramfs/libcramfs.a fs/jffs2/libjffs2.a
#LIBS += post/libpost.a post/cpu/libcpu.a
*302-314行:(灰色部分要删除)
tags ctags:
ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) include \
lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
fs/cramfs fs/fat fs/fdos fs/jffs2 \
net disk rtc dtt drivers drivers/sk98lin common \
\( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
etags:
etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) include \
lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
fs/cramfs fs/fat fs/fdos fs/jffs2 \
net disk rtc dtt drivers drivers/sk98lin common \
\( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
灰色部分删除之后的代码:
tags ctags:
ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) include \
lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
fs/cramfs fs/jffs2 \
net rtc drivers common \
\( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
etags:
etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) include \
lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
fs/cramfs fs/jffs2 \
net rtc drivers common \
\( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
*由于1(7)删除了很多文件,因此其下的drivers/Makefile的第30行修改为:
COBJS = dm9000x.o
*同样的includes/configs/ZacV1.h的53-58行网卡要配置为(这个文件是开发板配置文件,此处为了DM9000,关于网卡的配置,后面有更详细的说明:第6点)
#define CONFIG_DRIVER_CS8900 1
#define CS8900_BASE 0x19000300
#define CS8900_BUS16 1
===>
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x20000300
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
#define CONFIG_DM9000_USE_16BIT
94-97行:(根据实际进行设置)
至此编译无错误.
3. 增加对S3C2440的支持
修改cpu/arm920t/start.S
(1)cpu/arm920t/start.S的124,131行和
#elif defined(CONFIG_S3C2410)和#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
===>
#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)和#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
和126行和147行增加
126行增加(S3C2440含有):
# define pWTCON 0x53000000
# define INTMOD 0X4A000004
# define INTMSK 0x4A000008
147行增加:
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
# elif defined(CONFIG_S3C2440)
ldr r1, =0x7fff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
(2)时钟设置: S3c2440 的时钟计算公式和 s3c2410 不一样,对于 s3c2440 开发板,将 PCLK 设为400Mhz,分频比为FCLK:HCLK:PCLK=1:4:8。
首先屏蔽原来s3c2410的时钟设置,修改cpu/arm920t/目录下start.S文件153行如
下:
#if 0
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif
(3)修改SDRAM配置: bl cpu_init_crit调用子程序 lowlevel_init,在board\ZacV1\lowlevel_init.S,下面的修改要根据实际硬件电路和SDRAM芯片参数设置,仅供参考:
从图上可以看出SDRAM(我的TQ板选择的是64M)的有两块HY57Vxxx组成的宽度为32数据线宽度,4Bank(BA0,BA1)组成,.因此修改:
#define B1_BWSCON (DW16) //(DW32) (IDE)
#define B2_BWSCON (DW16) // (IDE)
#define B3_BWSCON (DW16 + WAIT + UBLB) //CS8900
#define B4_BWSCON (DW16) //DM9000
#define B5_BWSCON (DW8) //(DW16)
#define B6_BWSCON (DW32) //SDRAM 宽度:32
#define B7_BWSCON (DW32)
#define B6_MT 0x3
#define B6_Trcd 0x1
#define B6_SCAN 0x1
#define B7_MT 0x3
#define B7_Trcd 0x1
#define B7_SCAN 0x1
#define REFEN 0x1
#define TREFMD 0x0
#define Trp 0x0
#define Trc 0x3
#define Tchr 0x2
#define REFCNT 0x4F4
(4) cpu/arm920t/start.S将 190-197行的stack_setup 子程序搬到 relocate 子程序之前(170行这步别忘了,这样调换的原因应该是:所调用的clock_init函数为C函数,需要先设定好堆栈),并在stack_setup 子程序后加一条跳转指令调用到clock_init 子函数,进行时钟初始化:(修改部分为红色)
#if 0
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif
//后面搬运
stack_setup:
ldr r0, _TEXT_BASE
sub r0, r0, #CFG_MALLOC_LEN
sub r0, r0, #CFG_GBL_DATA_SIZE
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12
bl clock_init //增加跳转到子函数clock_init,新函数
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:
adr r0, _start
ldr r1, _TEXT_BASE
cmp r0, r1
beq clear_bss //此处原来为beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2
add r2, r0, r2
(5)编写clock_init, 在board/ZacV1目录下建立一个名为boot_init.c的文件(因为时钟初始化函数为新函数),编写colck_init函数(如何编写可以参考board/smdk2410/smdk2410.c的board_init函数),同时加上一些声明和延时子函数,如下:
#include <common.h>
#include <s3c2410.h>
static inline void delay (unsigned long loops)
{
__asm__ volatile ("1:\n"
"subs %0, %1, #1\n"
"bne 1b":"=r" (loops):"0" (loops));
}
#define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01)) //Zac:m=100=92+8,p=3=1+2,s=1,400MHz
#define S3C2440_MPLL_405MHZ ((0x7f<<12)|(0x02<<4)|(0x01)) //Zac:m=135=127+8,p=4=2+2,s=1,405MHz
#define S3C2440_MPLL_440MHZ ((0x66<<12)|(0x01<<4)|(0x01)) //Zac:m=110,p=3,s=1, 440MHz
#define S3C2440_MPLL_480MHZ ((0x98<<12)|(0x02<<4)|(0x01)) //Zac:m=160,p=4,s=1, 480MHz
#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02)) //Zac:m=100,p=3,s=2, 200MHz
#define S3C2440_MPLL_100MHZ ((0x5c<<12)|(0x01<<4)|(0x03)) //Zac:m=100,p=3,s=3, 100MHz
#define S3C2440_UPLL_48MHZ ((0x38<<12)|(0x02<<4)|(0x02)) //Zac:m=64,p=4,s=2, 48MHz
#define S3C2440_CLKDIV 0x05 //400:100:50MHz
#define S3C2440_CLKDIV136 0x07 //400:133:66.6MHz
#define S3C2440_CLKDIV188 0x04
#define S3C2440_CAMDIVN188 ((0<<8)|(1<<9))
#define S3C2440_MPLL_399MHZ ((0x6e<<12)|(0x03<<4)|(0x01))
#define S3C2440_UPLL_48MHZ_Fin16MHZ ((60<<12)|(4<<4)|(2))
#define S3C2410_MPLL_200MHZ ((0x5C<<12)|(0x04<<4)|(0x00))
#define S3C2410_UPll_48MHZ ((0x28<<12)|(0x01<<4)|(0x02))
#define S3C2410_CLKDIV 0x03
void clock_init(void)
{
S3C24X0_CLOCK_POWER *clk_power = (S3C24X0_CLOCK_POWER *)0x4C000000
if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002)) {
clk_power->CLKDDIVN = S3C2410_CLKDIV;
__asm__("mrc p15, 0, r1, c1, c0, 0\n"
"orr r1, r1, #0xc0000000\n"
"mcr p15, 0, r1, c1, c0, 0\n"
:::"r1"
);
clk_power->LOCKTIME = 0x00FFFFFF;
clk_power->UPLLCON = S3C2410_UPLL_48MHZ; //fin=12.000MHz
delay (4000);
clk_power->MPLLCON = S3C2410_MPLL_400MHZ; //fin=12.000MHz
delay (8000);
}else {
clk_power->CLKDDIVN = S3C2440_CLKDIV;
/*异步总线模式*/
__asm__("mrc p15, 0, r1, c1, c0, 0\n"
"orr r1, r1, #0xc0000000\n"
:::"r1"
);
clk_power->LOCKTIME = 0x00FFFFFF;
clk_power->UPLLCON = S3C2440_UPLL_48MHZ; //fin=12.000MHz
delay (4000);
clk_power->MPLLCON = S3C2440_MPLL_400MHZ; //fin=12.000MHz
delay (8000);
}
}
(6)修改board/ZacV1/ZacV1.c.上面(5)完成了时钟的初始化,因而此处关于时钟的设置均可屏蔽,下面为部分修改后的代码
#include <common.h>
#include <s3c2410.h>
#define GSTATUS1 (*(volatile unsigned int *)0x560000B0) //芯片序列号 2440是0x32440001
DECLARE_GLOBAL_DATA_PTR;
int board_init (void)
{
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
gpio->GPACON = 0x007FFFFF;
gpio->GPBCON = 0x00055555; //0x00044555; //Zac modify
gpio->GPBUP = 0x000007FF;
gpio->GPCCON = 0xAAAAAAAA;
gpio->GPCUP = 0x0000FFFF;
gpio->GPDCON = 0xAAAAAAAA;
gpio->GPDUP = 0x0000FFFF;
gpio->GPECON = 0xAAAAAAAA;
gpio->GPEUP = 0x0000FFFF;
gpio->GPFCON = 0x000055AA;
gpio->GPFUP = 0x000000FF;
gpio->GPGCON = 0xFF94FFBA; //0xFF95FFBA; //Zac modify
gpio->GPGUP = 0x0000FFEF; //0x0000FFFF; //Zac modify
gpio->GPHCON = 0x002AFAAA;
gpio->GPHUP = 0x000007FF;
/*Zac:支持S3C2410和S3C2440*/
if ((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002)) {
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
} else {
gpio->GPJCON = 0x02AAAAAA;
gpio->GPJUP = 0x000007FF;
gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
}
gd->bd->bi_boot_params = 0x30000100; //启动内核时参数存放位置,在构造标记列表时用到
icache_enable();
dcache_enable();
return 0;
}
int dram_init (void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
return 0;
}
(7)修改board/ZacV1/Makefile,因为增加了boot_init.c文件,第28行
COBJS := dong2440.o flash.o boot_init.o
并在board/ZacV1/u-boot.lds文件中35行添加如下内容:
.text :
{
cpu/arm920t/start.o (.text)
board/ZacV1/boot_init.o (.text)
*(.text)
}
以增加对boot_init.o的连接
(8) 获取系统时钟的函数需要针对s3c2410、s3c2440的不同进行修改。 在后面设置串口波特率时需要获得系统时钟, 就是在 U-Boot 的第二阶段,lib_arm/board.c 中 start_armboot 函数调用 serial_init 函数初始化串口时,会调用 get_PCLK 函数。它在 cpu/arm920t/s3c24x0/speed.c 中定义,与它相关的还有get_HCLK、get_PLLCLK 等函数。 前面的 board_init 函数在识别出 S3C2410 或 S3C2440 后,设置了机器类型
ID:gd-> bd-> bi_arch_number,后面的函数可以通过它来分辨是 S3C2410 还是 S3C2440。
在 cpu/arm920t/s3c24x0/speed.c 中修改:
在程序开头41行增加一行:
DECLARE_GLOBAL_DATA_PTR;//这样才可以使用 gd 变量
修改get_PLLCLK
static ulong get_PLLCLK(int pllreg)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
ulong r, m, p, s;
if (pllreg == MPLL)
r = clk_power->MPLLCON;
else if (pllreg == UPLL)
r = clk_power->UPLLCON;
else
hang();
m = ((r & 0xFF000) >> 12) + 8;
p = ((r & 0x003F0) >> 4) + 2;
s = r & 0x3;
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
else
return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));
}
由于分频系数的设置方法也不一样,get_HCLK、get_PCLK也需要修改。对于s3c2410,沿用原来的计算方法,else分支中是s3c2440的代码,如下所示:
修改get_HCLK、get_PCLK:
#define S3C2440_CLKDIVN_PDIVN (1<<0)
#define S3C2440_CLKDIVN_HDIVN_MASK (3<<1)
#define S3C2440_CLKDIVN_HDIVN_1 (0<<1)
#define S3C2440_CLKDIVN_HDIVN_2 (1<<1)
#define S3C2440_CLKDIVN_HDIVN_4_8 (2<<1)
#define S3C2440_CLKDIVN_HDIVN_3_6 (3<<1)
#define S3C2440_CLKDIVN_UCLK (1<<3)
#define S3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0)
#define S3C2440_CAMDIVN_CAMCLK_SEL (1<<4)
#define S3C2440_CAMDIVN_HCLK3_HALF (1<<8)
#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9)
#define S3C2440_CAMDIVN_DVSEN (1<<12)
ulong get_HCLK(void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
unsigned long clkdiv;
unsigned long camdiv;
int hdiv = 1;
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
else
{
clkdiv = clk_power->CLKDIVN;
camdiv = clk_power->CAMDIVN;
switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
case S3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
case S3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
return get_FCLK() / hdiv;
}
}
ulong get_PCLK(void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
unsigned long clkdiv;
unsigned long camdiv;
int hdiv = 1;
8
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
else
{
clkdiv = clk_power->CLKDIVN;
camdiv = clk_power->CAMDIVN;
switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
case S3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
case S3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
return get_FCLK() / hdiv / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
}
}
(9)修改includes/s3c24x0.h.因为boot_init.c的S3C24X0_CLK_POWER()在 include/s3c24x0.h 中,而S3C2410与S3C2440不一样include/s3c24x0.h 中,S3C24X0_CLOCK_POWER 结构体中增加:(129 行,关于该文件对于2440来说可以用,但是有很多资源没有设置到,这个地方以后在讨论)
S3C24X0_REG32 CAMDIVN;
在455行增加定义GPJ口的定义
S3C24X0_REG32 res9[4];
S3C24X0_REG32 GPJCON;
S3C24X0_REG32 GPJDAT;
S3C24X0_REG32 GPJUP;
至此,对s3c2440的支持(时钟配置部分)就算做好了,为了方便调试,可以利用开发板自带的u-boot文件烧写到内存中运行,此时还要修改一些配置:
修改cpu/arm920t/start.S文件的162行如下:
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
@bl cpu_init_crit
#endif
修改board/dong2440/config.mk文件如下:
TEXT_BASE = 0x33000000
#TEXT_BASE = 0x33F80000
修改/include/configs/ZacV1.h
#define CFG_PROMPT "[ZacV1]$ "
则u-boot中的提示符“ SMDK2410 #” 将改成[ZacV1]$
底层初始化,底层初始化会将内存清空一次的,所以不应该让它执行,所以在代码中直接注释掉这一行代码.
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
@bl cpu_init_crit
#endif
(10)编译测试
最后make一下,没有错误,
#make clean
#make all 2> make_log
通过开发板自带的uboot加载自己的uboot到内存中运行.移植好u-boot的网卡后,就可以不用在使用开发板自带的u-boot进行下载了,我们可以直接通过tftp或nfs下载,前提是主机打开了tftp或nfs服务,网卡正常运作,网络正常.有了网卡的支持对我们的开发是有很大帮助的,以后会慢慢看到它的作用.
我的运行结果如下:
##### Boot for Nand Flash Main Menu #####
##### EmbedSky USB download mode #####
[1] Download u-boot or STEPLDR.nb1 or other bootloader to Nand Flash
[2] Download Eboot (eboot.nb0) to Nand Flash
[3] Download Linux Kernel (zImage.bin) to Nand Flash
[5] Download CRAMFS image to Nand Flash
[6] Download YAFFS image (root.bin) to Nand Flash
[7] Download Program (uCOS-II or TQ2440_Test) to SDRAM and Run it
[8] Boot the system
[9] Format the Nand Flash
[0] Set the boot parameters
[a] Download User Program (eg: uCOS-II or TQ2440_Test)
[b] Download LOGO Picture (.bin) to Nand Flash
[l] Set LCD Parameters
[n] Enter TFTP download mode menu
[r] Reboot u-boot
[t] Test Linux Image (zImage)
[q] quit from menu
Enter your selection: 7
USB host is connected. Waiting a download.
Now, Downloading [ADDRESS:30000000h,TOTAL:95346]
RECEIVED FILE SIZE: 95346 (93KB/S, 1S)
## Starting application at 0x30000000 ...
U-Boot 1.1.6 (Oct 20 2011 - 16:01:53)
DRAM: 64 MB
Flash: 512 kB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
[ZacV1]$