对于1.3.2和1.2.0的差别,我初看了一下,(对于ARM920T内核)应该是增加了对ATMEL公司的AT91RM9200系列处理器的支持。至 于S3C24X0系列的芯片,原理上并没有什么大的变化。
一、在U-Boot中建立自己的开发板类型,并测试编译。
我为开发板取名叫: dumu
[ddbing@ARM9-Host working]$ tar -xjvf u-boot-1.3.2.tar.bz2
1 进入U-Boot目录,修改Makefile (我在ununtu10.04 下,本人比较喜欢使用vim)
[ddbing@ARM9-Host working]$ cd u-boot-1.3.2
[ddbing@ARM9-Host u-boot-1.3.2]$ vim Makefile
2408 @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
2409
2410 #add dudebing
2411 dumu244_c0onfig : unconfig
2412 @$(MKCONFIG) $(@:_config=) arm arm920t dmu2440 dumu s3c24x0
2413 #end
各项的意思如下:
arm: CPU的架构(ARCH)
arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录。
dumu2440: 开发板的型号(BOARD),对应于board/dumu/dumu2440目录。
dumu: 开发者/或经销商(vender)。
s3c24x0: 片上系统(SOC)。
144 #CROSS_COMPILE = arm-linux-
145 CROSS_COMPILE = /opt/arm/usr/local/arm/4.3.2/bin/arm-none-linux-gnueabi-
146 endif
2 在/board子目录中建立自己的开发板dumu2440目录
[ddbing@ARM9-Host board]$ mkdir dumu dumu/dumu2440
[ddbing@ARM9-Host board]$ cp -arf sbc2410x/* dumu/dumu2440/
[ddbing@ARM9-Host board]$ cd dumu/dumu2440/
[ddbing@ARM9-Host dumu2440]$ mv sbc2410x.c dumu2440.c
[ddbing@ARM9-Host dumu2440]$ vim Makefile
COBJS := dumu2440.o flash.o
最后记得make 一下,成功了,再往下执行。否则要找到错后再往下改,不要把错误堆到一起。
[ddbing@ARM9-Host dumu2440]$ cd ../../..
[ddbing@ARM9-Host u-boot-1.3.4]$ cp include/configs/sbc2410x.h include/configs/dumu2440.h
1、配置
[ddbing@ARM9-Host u-boot-1.3.4]$ make dumu2440_config
Configuring for dumu2440 board...
(1) 如果出现:
$ make dumu2440_config
Makefile:1927: *** 遗漏分隔符 。 停止。
请在U-boot的根目录下的Makefile的
@$(MKCONFIG) $(@:_config=) arm arm920t dumu2440 dumu)
前加上“Tab”键
2、测试编译
[ddbing@ARM9-Host u-boot-1.3.4]$make
测试通过后进行 下一步
|
(0)
修改寄存器地址定义
#
if
defined(
CONFIG_S3C2400)
|
|
defined(
CONFIG_S3C2410)
|
|
defined(
CONFIG_S3C2440)
dumu
/*
turn off the watchdog */
#
if
defined(
CONFIG_S3C2400)
#
define
pWTCON 0x15300000
#
define
INTMSK 0x14400008 /* Interupt-Controller base addresses */
#
define
CLKDIVN 0x14800014 /* clock divisor register */
#
else
#
define
pWTCON 0x53000000
#
define
INTMSK 0x4A000008 /* Interupt-Controller base addresses */
#
define
INTSUBMSK 0x4A00001C
#
define
CLKDIVN 0x4C000014 /* clock divisor register */
#
endif
#
define
CLK_CTL_BASE 0x4C000000 /*
*/
dumu
#
define
MDIV_405 0x7f <
<
12 /*
*/
dumu
#
define
PSDIV_405 0x21 /*
*/
dumu
#
define
MDIV_200 0xa1 <
<
12 /*
*/
dumu
#
define
PSDIV_200 0x31 /*
*/
.
.
.
.
.
.
(1)
修改中断禁止部分
#
if
defined(
CONFIG_S3C2410)
ldr r1,
=
0x7
ff
/*根据2410芯片手
册,INTSUBMSK有11位可用,
vivi也是0x7ff,U-Boot一直没改过来。*/
ldr r0,
=
INTSUBMSK
str r1,
[
r0]
#
endif
#
if
defined(
CONFIG_S3C2440)
ldr r1,
=
0x7fff /*根据2440芯片手册,INTSUBMSK有15位可用*/
ldr r0,
=
INTSUBMSK
str r1,
[
r0]
#
endif
(2)
修改时钟设置(2440的主频为405MHz。)
#
if
defined(
CONFIG_S3C2440)
dumu
/*
FCLK:HCLK:PCLK = 1:4:8 */
ldr r0,
=
CLKDIVN
mov r1,
#
5
str r1,
[
r0]
mrc p15,
0,
r1,
c1,
c0,
0 /*read
ctrl register
*/
dumu
orr r1,
r1,
#
0xc0000000 /*Asynchronous
*/
dumu
mcr p15,
0,
r1,
c1,
c0,
0 /*write
ctrl register
*/
dumu
/*now,
CPU clock is 405.00 Mhz
*/
dumu
mov r1,
#
CLK_CTL_BASE /*
*/
dumu
mov r2,
#
MDIV_405 /* mpll_405mhz
*/
dumu
add r2,
r2,
#
PSDIV_405 /* mpll_405mhz
*/
dumu
str r2,
[
r1,
#
0x04]
/*
MPLLCON
*/
dumu
#
else
/*
FCLK:HCLK:PCLK = 1:2:4 */
/*
default
FCLK is 12 MHz !
在这里U-Boot有一个错误:以为默认时钟为120MHz。其实如果没有添加以下设置FCLK的语句,芯片内部的PLL是无效的,即FCLK为
12MHz。S3C24x0的芯片手册说得很明白。我一开始没有注意到这一点,是 CalmArrow
提醒了我并和我讨论过,他也做过实验证实了这点。在这里对CalmArrow表示感谢和敬意
!*/
ldr r0,
=
CLKDIVN
mov r1,
#
3
str r1,
[
r0]
mrc
p15,
0,
r1,
c1,
c0,
0 /*read
ctrl register
*/
dumu
orr r1,
r1,
#
0xc0000000 /*Asynchronous
*/
dumu
mcr p15,
0,
r1,
c1,
c0,
0 /*write
ctrl register
*/
dumu
/*now,
CPU clock is 202.8 Mhz
*/
dumu
mov r1,
#
CLK_CTL_BASE /*
*/
dumu
mov r2,
#
MDIV_200 /* mpll_200mhz
*/
dumu
add r2,
r2,
#
PSDIV_200 /* mpll_200mhz
*/
str r2,
[
r1,
#
0x04]
#
endif
#
endif
/*
CONFIG_S3C2400 || CONFIG_S3C2410|| CONFIG_S3C2440 */
红色部分是我添加的。
(3)
将从Flash启动改成从NAND Flash启动。
在以下U-Boot的重定向语句段:
|
的后面添加上:
|
在“ldr pc, _start_armboot”之前加入:
|
修改目
的:如果看到只有LED1亮了,说明U-Boot的第一阶段已完成!
.
align
2
DW_STACK_START:
.
word
STACK_BASE+
STACK_SIZE-
4
2 在board/ dumu/ dumu2440加入NAND Flash读函数文件,拷贝vivi中的nand_read.c文件到此文件夹即可:
|
3 修改board/ dumu/ dumu2440/Makefile文件
|
4 修改include/configs/ dumu2440.h文件,添加如下内容:
|
5
修改board/
dumu/
dumu2440/lowlevel_init.S文件
依照开发板的内存区的配置情况,
修改board/dumu/dumu2440/lowlevel_init.S文件,我利用友善之臂提供的vivi源码里的信息做了如下
更改:
|
6
修改/board/dumu/dumu2440/dumu
2440.c
修改其对GPIO和PLL的配置(请参阅开发板的硬件说明和芯片手册):
.
.
.
.
.
.
dumu
#
define
FCLK_SPEED 1
#
if
FCLK_SPEED=
=
0 /* Fout = 203MHz, Fin = 12MHz for Audio */
#
define
M_MDIV 0xC3
#
define
M_PDIV 0x4
#
define
M_SDIV 0x1
#
elif
FCLK_SPEED=
=
1
#
if
defined(
CONFIG_S3C2410)
/*
Fout = 202.8MHz */
#
define
M_MDIV 0xA1
#
define
M_PDIV 0x3
#
define
M_SDIV 0x1
#
endif
#
if
defined(
CONFIG_S3C2440)
/*
Fout = 405MHz */
#
define
M_MDIV 0x7f
#
define
M_PDIV 0x2
#
define
M_SDIV 0x1
#
endif
#
define
USB_CLOCK 1
#
if
USB_CLOCK=
=
0
#
define
U_M_MDIV 0xA1
#
define
U_M_PDIV 0x3
#
define
U_M_SDIV 0x1
#
elif
USB_CLOCK=
=
1
#
if
defined(
CONFIG_S3C2410)
#
define
U_M_MDIV 0x48
#
define
U_M_PDIV 0x3
#
endif
#
if
defined(
CONFIG_S3C2440)
#
define
U_M_MDIV 0x38
#
define
U_M_PDIV 0x2
#
endif
#
define
U_M_SDIV 0x2
#
endif
.
.
.
.
.
.
/*
set up the I/O ports */
gpio-
>
GPACON =
0x007FFFFF;
#
if
defined(
CONFIG_
2440_LED)
dumu
gpio-
>
GPBCON =
0x00055556;
#
else
gpio-
>
GPBCON =
0x00044556;
#
endif
.
.
.
.
.
.
#
if
defined(
CONFIG_S3C2410)
/*
arch number of SMDK2410-Board */
gd-
>
bd-
>
bi_arch_number =
MACH_TYPE_SMDK2410;
#
endif
#
if
defined(
CONFIG_S3C2440)
/*
arch number of S3C2440 -Board */
gd-
>
bd-
>
bi_arch_number =
MACH_TYPE_S3C2440 ;
#
endif
/*
adress of boot parameters */
gd-
>
bd-
>
bi_boot_params =
0x30000100;
icache_enable(
)
;
dcache_enable(
)
;
#
if
defined(
CONFIG_
2440_LED)
gpio-
>
GPBDAT =
0x180;
//
dumu 这里可有可无,不会影响uboot的正常工作。
//int
board_init (void)设置完成后,LED1和LED2会亮起!
#
endif
return
0;
}
7 为了实现NAND
Flash的读写,再次修改/include/configs/
dumu2440.h
(请格外注意:
如果编译时报错,在Linux下用
vim等有高亮显示的文本编辑器看看文件的注释是不是为注释应有的颜色(
vim中为灰色),如果不是,则将
注释删除。因为#define后面的注释被认为是程序的一部分。建议注释和#define分行写)
|
8、在个文件中添加“CONFIG_S3C2440”, 使得原来s3c2410的代码可以编译进来。
(1)/include
/common.h文件的第474行:
#
if
defined(
CONFIG_S3C2400)
|
|
defined(
CONFIG_S3C2410)
|
|
defined(
CONFIG_LH7A40X)
|
|
defined(
CONFIG_S3C2440)
(2)/include/s3c24x0.h文件的
第85、95、99、110、148、404行:
将“#ifdef
CONFIG_S3C2410”
改为
#
if
defined(
CONFIG_S3C2410)
|
|
defined (
CONFIG_S3C2440)
顺便在其中加入2440 的NAND FLASH
寄存器定义(第160行附近)和CAMDIVN定义(第128行附近):
.
.
.
.
.
.
typedef
struct
{
S3C24X0_REG32 LOCKTIME;
S3C24X0_REG32 MPLLCON;
S3C24X0_REG32 UPLLCON;
S3C24X0_REG32 CLKCON;
S3C24X0_REG32 CLKSLOW;
S3C24X0_REG32 CLKDIVN;
#
if
defined (
CONFIG_S3C2440)
S3C24X0_REG32 CAMDIVN;
#
endif
}
/*__attribute__((__packed__))*/
S3C24X0_CLOCK_POWER;
.
.
.
.
.
.
#
if
defined(
CONFIG_S3C2410)
/*
NAND FLASH (see S3C2410 manual chapter 6) */
typedef
struct
{
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG32 NFDATA;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFECC;
}
/*__attribute__((__packed__))*/
S3C2410_NAND;
#
endif
#
if
defined (
CONFIG_S3C2440)
/*
NAND FLASH (see S3C2440 manual chapter 6) */
typedef
struct
{
S3C24X0_REG32 NFCONF;
S3C24X0_REG32 NFCONT;
S3C24X0_REG32 NFCMD;
S3C24X0_REG32 NFADDR;
S3C24X0_REG32 NFDATA;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFECC;
}
/*__attribute__((__packed__))*/
S3C2410_NAND;
#
endif
(3)/cpu
/arm920t/s3c24x0/interrupts.c文件的第33行:
#
if
defined(
CONFIG_S3C2400)
|
|
defined (
CONFIG_S3C2410)
|
|
defined (
CONFIG_TRAB)
|
|
defined (
CONFIG_S3C2440)
第38行:
|
在个文件中添加“defined(CONFIG_ dumu2440) ”, 使得原来SBC2410X的代码可以编译进来。第181行:
|
(
4)/cpu
/arm920t/s3c24x0/serial.c文件的第22行:
#
if
defined(
CONFIG_S3C2400)
|
|
defined (
CONFIG_S3C2410)
|
|
defined (
CONFIG_TRAB)
|
|
defined
(
CONFIG_S3C2440)
第26行:
|
(5)/cpu
/arm920t/s3c24x0/speed.c文件的第33行:
#
if
defined(
CONFIG_S3C2400)
|
|
defined (
CONFIG_S3C2410)
|
|
defined (
CONFIG_TRAB)
|
|
defined
(
CONFIG_S3C2440)
第37行:
|
顺便修改源代码,以匹配s3c2440:
|
(6)/cpu
/arm920t/s3c24x0/usb_ohci.c文件的第45行:
#
elif
defined(
CONFIG_S3C2410)
|
|
defined
(
CONFIG_S3C2440)
(7)drivers/rtc
/s3c24x0_rtc.c文件的第35行:
(8)/cpu/arm920t/s3c24x0/usb.c文件的第31行:
#
elif
defined(
CONFIG_S3C2410)
|
|
defined
(
CONFIG_S3C2440)
(9)/cpu/arm920t/s3c24x0/i2c.c文件的第35行:
#
elif
defined(
CONFIG_S3C2410)
|
|
defined
(
CONFIG_S3C2440)
第66、85、142、150、174行:
#
elif
defined(
CONFIG_S3C2410)
|
|
defined
(
CONFIG_S3C2440)
将“#ifdef CONFIG_S3C2410”改为
#
if
defined(
CONFIG_S3C2410)
|
|
defined
(
CONFIG_S3C2440)
(10)drivers/usb /usb_ohci.c文件的第68行附近:
|
9、在 include/linux/mtd/nand_ids.h的结构体nand_flash_ids加入
|
修改include/linux/mtd/nand.h
/*
* Constants for hardware specific CLE/ALE/NCE function
*/
#
if
0
/*
Select the chip by setting nCE to low */
#
define
NAND_CTL_SETNCE 1
/*
Deselect the chip by setting nCE to high */
#
define
NAND_CTL_CLRNCE 2
/*
Select the command latch by setting CLE to high */
#
define
NAND_CTL_SETCLE 3
/*
Deselect the command latch by setting CLE to low */
#
define
NAND_CTL_CLRCLE 4
/*
Select the address latch by setting ALE to high */
#
define
NAND_CTL_SETALE 5
/*
Deselect the address latch by setting ALE to low */
#
define
NAND_CTL_CLRALE 6
/*
Set write protection by setting WP to high. Not used! */
#
define
NAND_CTL_SETWP 7
/*
Clear write protection by setting WP to low. Not used! */
#
define
NAND_CTL_CLRWP 8
#
endif
10、修改/lib_arm中的
board.c, 实际开发可不用改这里,只是便于调试。
.
.
.
.
.
.
dumu
#
include
<
common.
h>
#
include
<
command.
h>
#
include
<
malloc
.
h>
#
include
<
devices.
h>
#
include
<
version.
h>
#
include
<
net.
h>
#
include
<
s3c2410.
h>
.
.
.
.
.
.
static
int
display_banner (
void
)
{
#
if
defined(
CONFIG_
2440_LED)
ddbing
S3C24X0_GPIO *
const
gpio =
S3C24X0_GetBase_GPIO(
)
;
gpio-
>
GPBDAT =
0x100;
//
dumu
//在串口初始化和
console初始化完成,串口输出信息之前,LED1、LED2、LED3会亮起!
#
endif
printf
(
"/n/n%s/n/n"
,
version_string)
;
debug (
"U-Boot
code: %08lX -> %08lX BSS: -> %08lX/n"
,
_armboot_start,
_bss_start,
_bss_end)
;
#
ifdef
CONFIG_MODEM_SUPPORT
debug (
"Modem
Support enabled/n"
)
;
#
endif
#
ifdef
CONFIG_USE_IRQ
debug (
"IRQ
Stack: %08lx/n"
,
IRQ_STACK_START)
;
debug (
"FIQ
Stack: %08lx/n"
,
FIQ_STACK_START)
;
#
endif
return
(
0)
;
}
.
.
.
.
.
.
void
start_armboot (
void
)
{
init_fnc_t *
*
init_fnc_ptr;
char
*
s;
#
ifndef
CFG_NO_FLASH
ulong size;
#
endif
#
if
defined(
CONFIG_VFD)
|
|
defined(
CONFIG_LCD)
unsigned
long
addr;
#
endif
#
if
defined(
CONFIG_
2440_LED)
dumu
S3C24X0_GPIO *
const
gpio =
S3C24X0_GetBase_GPIO(
)
;
#
endif
.
.
.
.
.
.
#
if
defined(
CONFIG_
2440_LED)
ddbing
gpio-
>
GPBDAT =
0x0;
//
//在进入命令提示符之
前,四个LED会同时亮起!
#
endif
/* main_loop() can return to retry autoboot, if so just run it
again. */
for
(
;
;
)
{
main_loop (
)
;
}
/* NOTREACHED - no way out of command loop except booting */
}
11、
修改common/env_nand.c
.
.
.
.
.
.
#
ifdef
CONFIG_INFERNO
#
error
CONFIG_INFERNO not
supported yet
#
endif
int
nand_legacy_rw (
struct
nand_chip*
nand,
int
cmd,
size_t
start,
size_t
len,
size_t
*
retlen,
u_char *
buf)
;
extern
struct
nand_chip nand_dev_desc[
CFG_MAX_NAND_DEVICE]
;
extern
int
nand_legacy_erase(
struct
nand_chip *
nand,
size_t
ofs,
size_t
len,
int
clean)
;
/*
info for NAND chips, defined in drivers/nand/nand.c */
extern
nand_info_t nand_info[
CFG_MAX_NAND_DEVICE]
;
.
.
.
.
.
.
#
else
/* !
CFG_ENV_OFFSET_REDUND */
int
saveenv(
void
)
{
ulong total;
int
ret =
0;
puts
(
"Erasing
Nand..."
)
;
//
if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))
if
(
nand_legacy_erase(
nand_dev_desc +
0,
CFG_ENV_OFFSET,
CFG_ENV_SIZE,
0)
)
return
1;
puts
(
"Writing
to Nand... "
)
;
total =
CFG_ENV_SIZE;
//
ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total,
(u_char*)env_ptr);
ret =
nand_legacy_rw(
nand_dev_desc +
0,
0x00 |
0x02,
CFG_ENV_OFFSET,
CFG_ENV_SIZE,
&
total,
(
u_char*
)
env_ptr)
;
if
(
ret |
|
total !
=
CFG_ENV_SIZE)
return
1;
puts
(
"done/n"
)
;
return
ret;
.
.
.
.
.
.
#
else
/* !
CFG_ENV_OFFSET_REDUND */
/*
* The legacy NAND code saved the environment in the first NAND device
i.e.,
* nand_dev_desc + 0. This is also the behaviour using the new NAND
code.
*/
void
env_relocate_spec (
void
)
{
#
if
!
defined(
ENV_IS_EMBEDDED)
ulong total;
int
ret;
total =
CFG_ENV_SIZE;
//
ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total,
(u_char*)env_ptr);
ret
=
nand_legacy_rw(
nand_dev_desc +
0,
0x01 |
0x02,
CFG_ENV_OFFSET,
CFG_ENV_SIZE,
&
total,
(
u_char*
)
env_ptr)
;
.
.
.
.
.
.
12、
在/board/
dumu/
dumu2440/
dumu2440.c文件的末尾添加对Nand Flash
的初始化函数(在后面Nand Flash的操作都要用到)
u-boot运行至
第二阶段进入start_armboot()函数。其中nand_init()函数是对nand
flash的最初初始化函数。Nand_init()函数在两个文件中实现。其调用与CFG_NAND_LEGACY宏有关,如果没有定义这个宏,系统调
用 drivers/nand/nand.c中的nand_init();
否则调用自己在board/
dumu/
tekkaman2440/
tekkaman2440.c中的nand_init()函数。这里我选择第二
种方式。
|
三、交叉编译U-Boot。
在U-Boot的根目录下
$make
这篇文章的移植使用CS8900网卡。tftp可以下载。后面把dm9000和usb下载的部分加上。
此篇主要参考http://blog.21ic.com/user1/1425/archives/2008/50775.html这篇文章,非常感谢!