對於1.3.1和1.2.0的差別,我初看了一下,(對於ARM920T內核)應該是增加了對ATMEL公司的AT91RM9200系列處理器的支持。至於S3C24X0系列的芯片,原理上並沒有什麼大的變化。
一、在U-Boot中建立自己的開發板類型,並測試編譯。
我爲開發板取名叫: tekkaman2440
[tekkamanninja@ARM9-Host working]$ tar -xjvf u-boot-1.3.1.tar.bz2
1 進入U-Boot目錄,修改Makefile (我在fedora 8 下,比較喜歡使用KWrite)
[tekkamanninja@ARM9-Host working]$ cd u-boot-1.3.1
[tekkamanninja@ARM9-Host u-boot-1.3.1]$ kwrite Makefile
@$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0
@$(MKCONFIG) $(@:_config=) arm arm920t tekkaman2440 tekkaman s3c24x0
各項的意思如下:
arm: CPU的架構(ARCH)
arm920t: CPU的類型(CPU),其對應於cpu/arm920t子目錄。
tekkaman2440: 開發板的型號(BOARD),對應於board/tekkaman/tekkaman2440目錄。
tekkaman: 開發者/或經銷商(vender)。
s3c24x0: 片上系統(SOC)。
2 在/board子目錄中建立自己的開發板tekkaman2440目錄
[tekkamanninja@ARM9-Host board]$ mkdir tekkaman tekkaman/tekkaman2440
[tekkamanninja@ARM9-Host board]$ cp -arf sbc2410x/* tekkaman/tekkaman2440/
[tekkamanninja@ARM9-Host board]$ cd tekkaman/tekkaman2440/
[tekkamanninja@ARM9-Host tekkaman2440]$ mv sbc2410x.c tekkaman2440.c
[tekkamanninja@ARM9-Host tekkaman2440]$ kwrite Makefile
COBJS := tekkaman2440.o flash.o
[tekkamanninja@ARM9-Host tekkaman2440]$ cd ../../..
[tekkamanninja@ARM9-Host u-boot-1.3.1]$ cp include/configs/sbc2410x.h include/configs/tekkaman2440.h
1、配置
[tekkamanninja@ARM9-Host u-boot-1.3.1]$ make tekkaman2440_config
Configuring for tekkaman2440 board...
(1) 如果出現:
$ make tekkaman2440_config
Makefile:1927: *** 遺漏分隔符 。 停止。
請在U-boot的根目錄下的Makefile的
@$(MKCONFIG) $(@:_config=) arm arm920t tekkaman2440 tekkaman)
前加上“Tab”鍵
2、測試編譯
[tekkamanninja@ARM9-Host u-boot-1.3.1]$make
測試通過後進行下一步
|
(0)修改寄存器地址定義
#
if
defined(
CONFIG_S3C2400)
|
|
defined(
CONFIG_S3C2410)
|
|
defined(
CONFIG_S3C2440)
/* 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 /* tekkaman */
#
define
MDIV_405 0x7f <
<
12 /* tekkaman */
#
define
PSDIV_405 0x21 /* tekkaman */
#
define
MDIV_200 0xa1 <
<
12 /* tekkaman */
#
define
PSDIV_200 0x31 /* tekkaman */
.
.
.
.
.
.
(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)
/* 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 tekkaman*/
orr r1,
r1,
#
0xc0000000 /*Asynchronous tekkaman*/
mcr p15,
0,
r1,
c1,
c0,
0 /*write ctrl register tekkaman*/
/*now, CPU clock is 405.00 Mhz tekkaman*/
mov r1,
#
CLK_CTL_BASE /* tekkaman*/
mov r2,
#
MDIV_405 /* mpll_405mhz tekkaman*/
add r2,
r2,
#
PSDIV_405 /* mpll_405mhz tekkaman*/
str r2,
[
r1,
#
0x04]
/* MPLLCON tekkaman */
#
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 tekkaman*/
orr r1,
r1,
#
0xc0000000 /*Asynchronous tekkaman*/
mcr p15,
0,
r1,
c1,
c0,
0 /*write ctrl register tekkaman*/
/*now, CPU clock is 202.8 Mhz tekkaman*/
mov r1,
#
CLK_CTL_BASE /* tekkaman*/
mov r2,
#
MDIV_200 /* mpll_200mhz tekkaman*/
add r2,
r2,
#
PSDIV_200 /* mpll_200mhz tekkaman*/
str r2,
[
r1,
#
0x04]
#
endif
#
endif
/* CONFIG_S3C2400 || CONFIG_S3C2410|| CONFIG_S3C2440 */
紅色部分是我添加的,利用vivi的代碼。
(3)將從Flash啓動改成從NAND Flash啓動。
在以下U-Boot的重定向語句段:
|
的後面添加上:
|
在“ldr pc, _start_armboot”之前加入:
|
修改目的:如果看到只有LED1亮了,說明U-Boot的第一階段已完成!(針對友善之臂SBC2440V4,不是這塊開發板的,必須修改或不添加)
在 “ _start_armboot: .word start_armboot ” 後加入:
.
align
2
DW_STACK_START:
.
word
STACK_BASE+
STACK_SIZE-
4
2 在board/tekkaman/tekkaman2440加入NAND Flash讀函數文件,拷貝vivi中的nand_read.c文件到此文件夾即可:
|
3 修改board/tekkaman/tekkaman2440/Makefile文件
|
4 修改include/configs/tekkaman2440.h文件,添加如下內容:
|
5 修改board/tekkaman/tekkaman2440/lowlevel_init.S文件
依照開發板的內存區的配置情況, 修改board/tekkaman/tekkaman2440/lowlevel_init.S文件,我利用友善之臂提供的vivi源碼裏的信息做了如下更改:
|
6 修改/board/tekkaman/tekkaman2440/tekkaman2440.c
修改其對GPIO和PLL的配置(請參閱開發板的硬件說明和芯片手冊):
.
.
.
.
.
.
#
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_tekkaman2440_LED)
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_tekkaman2440_LED)
gpio-
>
GPBDAT =
0x180;
//tekkamanninja
//int board_init (void)設置完成後,LED1和LED2會亮起!
#
endif
return
0;
}
7 爲了實現NAND Flash的讀寫,再次修改/include/configs/tekkaman2440.h
(請格外注意:如果編譯時報錯,在Linux下用KWrite等有高亮顯示的文本編輯器看看文件的註釋是不是爲註釋應有的顏色(KWrite中爲灰色),如果不是,則將註釋刪除。因爲#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_tekkaman2440) ”, 使得原來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。
.
.
.
.
.
.
#
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_tekkaman2440_LED)
S3C24X0_GPIO *
const
gpio =
S3C24X0_GetBase_GPIO(
)
;
gpio-
>
GPBDAT =
0x100;
//tekkamanninja
//在串口初始化和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_tekkaman2440_LED)
S3C24X0_GPIO *
const
gpio =
S3C24X0_GetBase_GPIO(
)
;
#
endif
.
.
.
.
.
.
#
if
defined(
CONFIG_tekkaman2440_LED)
gpio-
>
GPBDAT =
0x0;
//tekkamanninja
//在進入命令提示符之前,四個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/tekkaman/tekkaman2440/tekkaman2440.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/tekkaman/tekkaman2440/tekkaman2440.c中的nand_init()函數。這裏我選擇第二種方式。
|
三、交叉編譯U-Boot。
在U-Boot的根目錄下
$make
一陣English飄過~~~~~~~~~~~~~~~~~~~~~~~
這篇文章的移植使用CS8900網卡。tftp功能是可用的.