【环境】
1:Ubuntu 10.10
2:u-boot-2010.03
3:优龙FS2410
4:交叉编译器:arm-none-linux-gnueabi-gcc version 4.3.2
Step1: 创建板级源码
1) 解压
tar jxvf u-boot-2010.03.tar.bz2
2) 进入板极源码目录
tony@Ubuntu:~/win/u-boot-2010.03/board/samsung$ls
smdk2400 smdk2410 smdk6400 smdkc100
3) 拷贝一份最相似的平台代码并改名(smdk2410是s3c2410的标准板,我们在smdk2410的基础上做FS2410的移植)
tony@Ubuntu:~/win/u-boot-2010.03/board/samsung$cp smdk2410 fs2410 -a
修改文件名
tony@Ubuntu:~/win/u-boot-2010.03/board/samsung/fs2410$mv smdk2410.cfs2410.c
修改 Makefile
tony@Ubuntu:~/win/u-boot-2010.03/board/samsung/fs2410$vim Makefile
将28行的COBJS := smdk2410.o flash.o
修改为COBJS := fs2410.o flash.o
拷贝头文件并改名
tony@Ubuntu:~/win/u-boot-2010.03/include/configs$cp smdk2410.h fs2410.h
4) 修改* Makefile
tony@Ubuntu:~/win/u-boot-2010.03$vim Makefile
在 3045 和 3046 行下加入以下两句
fs2410_config : unconfig
(Tab键)@$(MKCONFIG) $(@:_config=)arm arm920t fs2410 samsung s3c24x0
修改编译器
在162、163和164行下添加(可以先找到编译器的绝对路径)
ifeq (arm,$(ARCH))
CROSS_COMPILE?=/home/tony/toolchain/bin/arm-none-linux-gnueabi-
Endif
5) 编译
tony@Ubuntu:~/win/u-boot-2010.03$make distclean
tony@Ubuntu:~/win/u-boot-2010.03$makefs2410_config
tony@Ubuntu:~/win/u-boot-2010.03$make
这个时候我们就可以得到一个u-boot.bin也就是我们的目标文件,但是这个文件通常情况下是不能够正常工作的,我们还需要对u-boot源代码进行进一步的修改。
Step2: 修改平台相关信息
1) 修改中断屏蔽位
tony@Ubuntu:~/win/u-boot-2010.03$vim cpu/arm920t/start.S
将159行的 ldr r1, =0x3ff 修改为ldr r1, =0x7ff
2) 修改 SDRAM 刷新周期
tony@Ubuntu:~/win/u-boot-2010.03$ vimboard/samsung/fs2410/lowlevel_init.S
将126行 #defineREFCNT 1113 /* period=15.6us, HCLK=60Mhz,(2048+1-15.6*60) */
修改为#define REFCNT 1268 /*period=7.8125us, HCLK=100Mhz, (2048+1-7.8152*100) */
Step3:修改配置文件include/configs/fs2410.h
1) 命令行提示符的修改:
修改:#define CONFIG_SYS_PROMPT "SMDK2410 # "
改成:#define CONFIG_SYS_PROMPT "fs2410 # "
2) 添加uImage内核启动时候的TAG参数数支持
#define CONFIG_CMDLINE_TAG 1 /*enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS1
#define CONFIG_INITRD_TAG 1
#define CONFIG_ETH_TAG 1
3) 网络参数设置
#defineCONFIG_ETHADDR 08:00:3e:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#defineCONFIG_IPADDR 开发板IP
#defineCONFIG_SERVERIP Ubuntu IP
4) 内核加载地址的修改
修改:#define CONFIG_SYS_LOAD_ADDR 0x33000000
改成:#define CONFIG_SYS_LOAD_ADDR 0x30008000
5) Nand功能添加
#defineCONFIG_CMD_NAND /*NAND support*/
#if defined(CONFIG_CMD_NAND)
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x4E000000
#define CONFIG_NAND_S3C2410
#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x8000
/* Nand Flash */
#define CONFIG_MTD_NAND_VERIFY_WRITE 1
#endif
6) 同时支持nand启动和nor启动
#if defined(CONFIG_S3C2410)
#define CONFIG_S3C2410_NAND_BOOT 1 //nand启动
#define CONFIG_S3C2410_NOR_BOOT 1 //nor启动
#endif
7) 环境变量保存位置
#ifdef CONFIG_S3C2410_NOR_BOOT
#define CONFIG_ENV_IS_IN_FLASH 1/*common/env_flash.c */
#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x30000)
#endif
#ifdef CONFIG_S3C2410_NAND_BOOT
#define CONFIG_ENV_IS_IN_NAND 1 /*common/env_nand.c */
#define CONFIG_ENV_SIZE 0x10000
#define CONFIG_ENV_OFFSET 0x30000
#define NAND_CTL_BASE 0x4E000000
/* Offset */
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFADDR 0x08
#define oNFDATA 0x0c
#define oNFSTAT 0x10
#define oNFECC 0x14
#endif
8) USB功能的添加
#defineCONFIG_CMD_FAT /*FAT support*/
#defineCONFIG_CMD_USB /*USB support*/
#if defined(CONFIG_CMD_USB)
#define CONFIG_DOS_PARTITION
#define CONFIG_USB_OHCI
#define CONFIG_USB_STORAGE
#define CONFIG_SUPPORT_VFAT
#define LITTLEENDIAN
#endif
9) Ping命令的添加
#defineCONFIG_CMD_PING /*ping support*/
10) Nor flash(sst39vf1601)及Norflash相关内容的
注释掉
#defineCONFIG_AMD_LV400 1 /*uncomment this if you have a LV400 flash */
#define CONFIG_AMD_LV800 1 /*uncomment this if you have a LV800 flash */
添加
#define CONFIG_SST_39VF1601 1
#ifdef CONFIG_SST_39VF1601
#definePHYS_FLASH_SIZE 0x00200000/* 2M*/
#defineCONFIG_SYS_MAX_FLASH_SECT (512) /*max number of sectors on one chip */
#endif
Step4:添加Nand启动功能(修改cpu/arm920t/start.S)
u-boot默认情况下是nar启动,这里我们添加nand启动的内容:
1) 添加头文件
#include <version.h>
#include <status_led.h>
2) 添加nand启动标志位
/*add for env_nand.c*/
.extern pbootflag
@pbootflag: //1:NORflash, 0:NAND flash
3) 添加BWSCON寄存器的定义
# 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 */
# define BWSCON 0x48000000
# endif
4) 添加启动模式判断Nor启动还是nand启动
ldrr0,=BWSCON
ldrr0,[r0]
andsr0,r0,#6
beqnand_boot
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif /*CONFIG_SKIP_RELOCATE_UBOOT */
bl stack_setup
5) 添加NAND启动自搬移代码(在上一步代码下添加)
nand_boot:
#ifdef CONFIG_S3C2410_NAND_BOOT
@ reset NAND
mov r1,#NAND_CTL_BASE
ldr r2, =0xf830 @ initial value
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
bic r2, r2, #0x800 @ enable chip
str r2, [r1, #oNFCONF]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait
nand1:
add r3, r3, #0x1
cmp r3, #0xa
blt nand1
nand2:
ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x1
beq nand2
ldr r2, [r1, #oNFCONF]
orr r2, r2, #0x800 @ disable chip
str r2, [r1, #oNFCONF]
@ get read to call C functions (for nand_read())
ldr sp,DW_STACK_START @ setup stack pointer
mov fp, #0 @ noprevious frame, so fp=0
@ copy U-Boot to RAM
ldr r0, =TEXT_BASE
mov r1, #0x0
mov r2, #0x30000
bl nand_read_ll
tst r0, #0x0
beq ok_nand_read
bad_nand_read:
loop2: b loop2 @ infinite loop
ok_nand_read:
ldr r0, =pbootflag
movr1, #0x0
str r1, [r0]
@ verify
mov r0, #0
ldr r1, =TEXT_BASE
mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4,[r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq stack_setup
bne go_next
notmatch:
loop3: b loop3 @ infinite loop
#endif @ CONFIG_S3C2410_NAND_BOOT
6) 在_start_armboot: .word start_armboot下添加如下代码:
.align 2
DW_STACK_START: .word STACK_BASE +STACK_SIZE – 4
Step5:添加nand_read.c为nand启动做支持
在board/samsung/fs2410下添加文件nand_read.c并在这个文件中添加如下内容:
#include <config.h>
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
# if defined(CONFIG_S3C2410)
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCMD __REGb(NF_BASE + 0x4)
#define NFADDR __REGb(NF_BASE + 0x8)
#define NFDATA __REGb(NF_BASE + 0xc)
#define NFSTAT __REGb(NF_BASE + 0x10)
#define BUSY 1
#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE – 1)
inline void wait_idle(void) {
int i;
while(!(NFSTAT& BUSY))
for(i=0;i<10; i++);
}
/* low level nand read function */
int
nand_read_ll(unsigned char *buf, unsigned long start_addr,int size)
{
int i, j;
if ((start_addr& NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
return -1; /*invalid alignment */
}
/* chip Enable */
NFCONF &=~0x800;
for(i=0; i<10;i++);
for(i=start_addr;i < (start_addr + size);) {
/* READ0 */
NFCMD = 0;
/* Write Address*/
NFADDR = i &0xff;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
wait_idle();
for(j=0; j <NAND_SECTOR_SIZE; j++, i++) {
*buf = (NFDATA &0xff);
buf++;
}
}
/* chip Disable */
NFCONF |= 0x800;/* chip disable */
return 0;
}
# endif
并修改board/Samsung/fs2410/ 下Makefile
修改:COBJS :=fs2410.o flash.o
改成:COBJS :=fs2410.o flash.o nand_read.o
Step6:修改board/samsung/fs2410/flash.c支持sst19lv1601 NOR flash芯片
修改:#define MAIN_SECT_SIZE0x10000 /*64KB*/
改成:#define MAIN_SECT_SIZE 0x1000 /*4KB forsst39lv1601*/
修改:#defineCMD_UNLOCK_BYPASS 0x00000020
改成:#defineCMD_UNLOCK_BYPASS 0x000000A0
修改:#defineMEM_FLASH_ADDR1 (*(volatileu16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))
#defineMEM_FLASH_ADDR2 (*(volatileu16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))
改成:#defineMEM_FLASH_ADDR1 (*(volatileu16 *)(CONFIG_SYS_FLASH_BASE + (0x00005555<< 1)))
#defineMEM_FLASH_ADDR2 (*(volatileu16 *)(CONFIG_SYS_FLASH_BASE + (0x00002AAA << 1)))
在
#elif defined(CONFIG_AMD_LV800)
(AMD_MANUFACT& FLASH_VENDMASK) |
(AMD_ID_LV800B& FLASH_TYPEMASK);
下添加
#elif defined(CONFIG_SST_39VF1601)
(SST_MANUFACT& FLASH_VENDMASK) |
(SST_ID_xF1601& FLASH_TYPEMASK);
修改
for (j = 0; j <flash_info[i].sector_count; j++) {
if(j <= 3) {
/*1st one is 16 KB */
if(j == 0) {
flash_info[i].start[j]= flashbase + 0;
}
/*2nd and 3rd are both 8 KB */
if((j == 1) || (j == 2)) {
flash_info[i].start[j]=
flashbase+ 0x4000 + (j -1) * 0x2000;
}
/*4th 32 KB */
if(j == 3) {
flash_info[i].start[j]=
flashbase+ 0x8000;
}
}else {
flash_info[i].start[j]=
flashbase+ (j - 3)*MAIN_SECT_SIZE;
}
}
替换为
for (j = 0; j < flash_info[i].sector_count; j++) {
flash_info[i].start[j]=
flashbase+ j*MAIN_SECT_SIZE;
}
在
case (AMD_MANUFACT &FLASH_VENDMASK):
printf("AMD: ");
break;
下添加
case (SST_MANUFACT & FLASH_VENDMASK):
printf("SST: ");
break;
在
case (AMD_ID_LV800B &FLASH_TYPEMASK):
printf("1x Amd29LV800BB (8Mbit)\n");
break;
下添加
case ( SST_ID_xF1601 & FLASH_TYPEMASK):
printf("1x 39VF1601\n");
break;
修改
if ((info->flash_id &FLASH_VENDMASK) !=
(AMD_MANUFACT & FLASH_VENDMASK)) {
returnERR_UNKNOWN_FLASH_VENDOR;
}
为
if ((info->flash_id & FLASH_VENDMASK) !=
(SST_MANUFACT& FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
注释掉下面语句
if (!chip
&& (result & 0xFFFF) &BIT_PROGRAM_ERROR)
chip= ERR;
注释掉
*addr = CMD_PROGRAM;
Step7:修改common/env_flash.c,为nor flash保存环境变量做准备
修改:char * env_name_spec ="Flash";
改成:char* nor_env_name_spec = "Flash";
修改:env_t *env_ptr = (env_t*)(&environment[0]);
改成:extern env_t *env_ptr = (env_t*)(&environment[0]);
修改:env_t*env_ptr = (env_t *)CONFIG_ENV_ADDR;
改成:externenv_t *env_ptr ;
添加:extern ucharenv_get_char_spec (int index);
并注释掉下面语句
ucharenv_get_char_spec (int index)
{
return ( *((uchar*)(gd->env_addr + index)) );
}
修改:int env_init(void)
改成:int nor_env_init(void) (2处)
修改:int saveenv(void)
改成:int nor_saveenv(void) (2处)
修改:void env_relocate_spec (void)
改成:void nor_env_relocate_spec (void)
Step8:修改common/env_nand.c添加norflash环境变量烧写功能
添加
volatile int pbootflag=1; //add by lht 1->nor 0->nand
extern int nor_env_init(void);
修改int env_init(void)函数在函数开始添加如下内容:
if(pbootflag==1)
{
env_name_spec= "NOR";
env_ptr=(env_t *)CONFIG_ENV_ADDR;
returnnor_env_init();
}
修改int saveenv(void)函数,在函数开始添加如下内容 (2处)
if(pbootflag==1)
{
env_name_spec= "NOR";
returnnor_saveenv();
}
修改voidenv_relocate_spec (void)函数,在函数开始添加如下内容 (2处)
if(pbootflag==1)
{
returnnor_env_relocate_spec();
}
Step9:链接文件的修改(cpu/arm920t/u-boot.lds)
在cpu/arm920t/start.o (.text)
下添加
board/samsung/fs2410/lowlevel_init.o (.text)
board/samsung/fs2410/nand_read.o (.text)
Step10:go命令的优化(修改common/cmd_boot.c)
int do_go (cmd_tbl_t *cmdtp,int flag, int argc, char *argv[])
{
ulong addr,rc;
int rcode = 0;
/****add 2011-10-08**************************************/
char *commandline = getenv("bootargs");
struct param_struct *tag_params=(struct param_struct *)0x30000100;
printf("setup linux parameters at 0x30000100\n");
memset(tag_params s,0,sizeof(struct param_struct));
tag_params ->u1.s.page_size=4096;
tag_params ->u1.s.nr_pages=0x4000000>>12;
memcpy(tag_params->commandline,commandline,strlen(commandline)+1);
printf("linux command line is:\"%s\"\n",commandline);
/***************************************************************/
if (argc < 2) {
cmd_usage(cmdtp);
return 1;
}
addr = simple_strtoul(argv[1],NULL, 16);
printf ("## Startingapplication at 0x%08lX ...\n", addr);
/*
* pass address parameter as argv[0] (akacommand name),
* and all remaining args
*/
/********************* add 2011-10-08 by wgx *********************/
__asm__(
"mov r1, #193\n"
"mov ip,#0\n"
"mcr p15,0, ip, c13, c0, 0\n" /*zero PID */
"mcr p15,0, ip, c7, c7, 0\n" /*invalidate I,D caches */
"mcr p15,0, ip, c7, c10, 4\n" /*drain write buffer */
"mcr p15,0, ip, c8, c7, 0\n" /*invalidate I,D TLBs */
"mrc p15,0, ip, c1, c0, 0\n" /* getcontrol register */
"bic ip,ip,#0x0001\n" /*disable MMU */
"mov pc, %0\n"
"nop\n"
:
:"r"(addr)
);
/***************************************************************/
rc = do_go_exec ((void *)addr,argc - 1, argv + 1);
if (rc != 0) rcode = 1;
printf ("## Applicationterminated, rc = 0x%lX\n", rc);
return rcode;
}
重新编译
$ make distclean
$ make fs2410_config
$ make
大功告成,现在就可以获得一个我们能够使用的u-boot了