ok6410 u-boot-2012.04.01移植二修改源码支持单板
继ok6410 u-boot-2012.04.01移植一后修改代码,对ok6410单板初始化,主要包括时钟、串口、NAND、DDR等初始化。这些工作在以前的裸板程序都写了,直接拿来用。我觉得先写裸板程序对移植u-boot还是很有帮助的,以前写的裸板代码不管是在u-boot移植还是后面的驱动开发,都用得着。
开发环境:
系统:ubuntu 10.04.4
单板:ok6410
NAND FLASH:K9GAG08U0D 2048MB
NOR Flash:EN29LV160AB 2MB
DDR:K4X1G163PCX2 256MB
NET:DM9000AEP
编译器:arm-linux-gcc-4.3.2
搭建开发环境详见ubuntu 10.04.4开发环境配置。
目标:
1.板级初始化,支持单板ok6410
2.增加菜单update功能
3.修改u-boot,支持NAND启动
4.增加MLC NAND支持
5.支持DM9000,网卡下载程序
6.修改环境变量以及mtdpart分区
7.u-boot裁剪及制作补丁
一、修改时钟配置
查看代码,从start.S开始,发现时钟、内存、NAND等都在bllowlevel_init完成,进入board\samsung\smdk6410\lowlevel_init.S:修改95: bl system_clock_init,将时钟初始化换成如下代码(以前写的裸板代码):
board\samsung\smdk6410\lowlevel_init.S 151:system_clock_init:
system_clock_init:
//ldr r0, =ELFIN_CLOCK_POWER_BASE /* 0x7e00f000 */
/* 1.设置LOCK_TIME */
ldr r0, =0x7E00F000 /* APLL_LOCK */
ldr r1, =0x0000FFFF
str r1, [r0] str r1, [r0, #4] /* MPLL_LOCK */
str r1, [r0, #8] /* EPLL_LOCK */ #define OTHERS 0x7e00f900
@ set async mode /* 当CPU时钟 != HCLK时,要设为异瞈u0153模蔦u0153 */
ldr r0, =OTHERS
ldr r1, [r0]
bic r1, r1, #0xc0 /* 1100,0000 */
str r1, [r0]
loop1: /* 等\u017d钡\u0153CPU\u0153胍觳\u0153模蔦u0153 */
ldr r0, =OTHERS
ldr r1, [r0]
and r1, r1, #0xf00
cmp r1, #0
bne loop1
/* SYNC667 */
/* MISC_CON[19] = 0 */
#define ARM_RATIO 0 /* ARMCLK = DOUTAPLL / (ARM_RATIO + 1) */
#define HCLKX2_RATIO 1 /* HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) */
#define HCLK_RATIO 1 /* HCLK = HCLKX2 / (HCLK_RATIO + 1) */
#define PCLK_RATIO 3 /* PCLK = HCLKX2 / (PCLK_RATIO + 1) */
#define MPLL_RATIO 0 /* DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1) */
ldr r0, =0x7E00F020 /* CLK_DIV0 */
ldr r1, =(ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12)
str r1, [r0] /* 2.配置时钟 */
/* 2.1 配置APLL */
/* 2.1.1 设置APLL
* 2.1.2 MUXAPLL
* 2.1.3 SYNC667
* 2.1.4 DIVAPLL
*/
#define APLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F00C
ldr r1, =APLL_CON_VAL
str r1, [r0] /* APLL_CON, FOUTAPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz */ /* 2.2 配置MPLL */
/* 2.2.1 设置MPLL
* 2.2.2 MUXMPLL
* 2.2.3 SYNCMUX
* 2.2.4 SYNC667
* 2.2.5 HCLKX2_RATIO
* 2.2.6 PCLK_RATIO
*/
#define MPLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F010
ldr r1, =MPLL_CON_VAL
str r1, [r0] /* MPLL_CON, FOUTMPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz */ /* 3.选择PLL的输出作为时钟診u017d */
ldr r0, =0x7E00F01C
ldr r1, =0x03
str r1, [r0] mov pc, lr
二、修改串口初始化
board\samsung\smdk6410\lowlevel_init.S 226:uart_asm_init:换成如下代码
uart_asm_init:
/* set GPIO to enable UART */
ldr r0, =ELFIN_GPIO_BASE
ldr r1, =0x220022
str r1, [r0, #GPACON_OFFSET] ldr r0, =0x7F005000/*ULCON0 = 0x3;*/
ldr r1, =0x3
str r1, [r0] ldr r0, =0x7F005004/*UCON0 = 0x5;*/
ldr r1, =0x5
str r1, [r0] ldr r0, =0x7F005008/*UFCON0 = 0x07; FIFO enable */
ldr r1, =0x07
str r1, [r0] ldr r0, =0x7F00500C/*UMCON0 = 0;*/
ldr r1, =0x00
str r1, [r0] ldr r0, =0x7F005028/*UBRDIV0 = 35;*/
ldr r1, =0x23
str r1, [r0] ldr r0, =0x7F00502C/*UDIVSLOT0 = 0x1;*/
ldr r1, =0x01
str r1, [r0] mov pc, lr
三、修改NAND、DDR初始化代码
把board\samsung\smdk6410\lowlevel_init.S关于NAND、DDR初始化部分代码去掉,我们换成C语言代码在start.S实现
104://bl nand_asm_init
107:/* Memory subsystem address 0x7e00f120 */
//ldrr0, =ELFIN_MEM_SYS_CFG
/* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */
//movr1, #S3C64XX_MEM_SYS_CFG_NAND
//strr1, [r0]
//blmem_ctrl_asm_init
/* Wakeup support. Don't know if it's going to be used, untested. */
//ldr r0, =(ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET)/*RST_STAT*/
/*ldr r1, [r0]
bicr1, r1, #0xfffffff7
cmpr1, #0x8
beqwakeup_reset
1:
movlr, r12
movpc, lr
wakeup_reset:
*/
/* Clear wakeup status register */
//ldr r0, =(ELFIN_CLOCK_POWER_BASE + WAKEUP_STAT_OFFSET)/*WAKEUP_STAT*/
//ldr r1, [r0]
//str r1, [r0]
/* LED test */
//ldr r0, =ELFIN_GPIO_BASE
//ldr r1, =0x9
//str r1, [r0, #GPMDAT_OFFSET]
/* Load return address and jump to kernel */
//ldr r0, =(ELFIN_CLOCK_POWER_BASE + INF_REG0_OFFSET)/*INFORM0*/
/* r1 = physical address of s3c6400_cpu_resume function */
//ldr r1, [r0]
/* Jump to kernel (sleep-s3c6400.S) */
//mov pc, r1
movlr, r12
mov pc, lr
nop
nop
接着在arch\arm\cpu\arm1176\start.S中增加对NAND、DDR等支持
在225:bllowlevel_init后增加如下代码
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)/*sp=0x0c00if80 ISRAM*/
bicsp, sp, #7 /* 8-byte alignment for ABI compliance */
bl ddr_init_ll
bl nand_init_ll
bldm9000aep_init
mov r0, #0
ldr r1, _TEXT_BASE
ldr r2, _bss_start_ofs
bl copy_code_to_sdram
bl clear_bss
ldr pc, =call_board_init_f/*from ISRAM jump to SDRAM*/
上面函数的实现,直接拷贝以前的update裸板代码。直接在board\samsung\smdk6410增加sdram.c、init.c两个文件。代码如下
文件sdram.c:
//#include <common.h> #define MEMCCMD0x7e001004
#define P1REFRESH0x7e001010
#define P1CASLAT0x7e001014
#define MEM_SYS_CFG0x7e00f120
#define P1MEMCFG0x7e00100c
#define P1T_DQSS0x7e001018
#define P1T_MRD0x7e00101c
#define P1T_RAS0x7e001020
#define P1T_RC0x7e001024
#define P1T_RCD0x7e001028
#define P1T_RFC0x7e00102c
#define P1T_RP0x7e001030
#define P1T_RRD0x7e001034
#define P1T_WR0x7e001038
#define P1T_WTR0x7e00103c
#define P1T_XP0x7e001040
#define P1T_XSR0x7e001044
#define P1T_ESR0x7e001048
#define P1MEMCFG20X7e00104c
#define P1_chip_0_cfg0x7e001200 #define P1MEMSTAT0x7e001000
#define P1MEMCCMD0x7e001004
#define P1DIRECTCMD0x7e001008 #define HCLK133000000 #define nstoclk(ns)(ns/( 1000000000/HCLK)+1) #define vi *( volatile unsigned int * ) #define set_zero( addr, bit ) ( (vi addr) &= ( ~ ( 1 << (bit) ) ) )
#define set_one( addr, bit ) ( (vi addr) |= ( 1 << ( bit ) ) ) #define set_bit( addr, bit, val ) ( (vi addr) = (( vi addr)&=(~(1<<(bit))) ) | ( (val)<<(bit) ) ) #define set_2bit( addr, bit, val ) ( (vi addr) = (( vi addr)&(~(3<<(bit))) ) | ( (val)<<(bit) ) )
#define set_nbit( addr, bit, len, val ) \
( (vi addr) = ((( vi addr)&(~(( ((1<<(len))-1) )<<(bit)))) | ( (val)<<(bit) ) )) #define get_bit( addr, bit ) ( (( vi addr ) & ( 1 << (bit) )) > 0 ) #define get_val( addr, val ) ( (val) = vi addr )
#define read_val( addr ) ( vi ( addr ) )
#define set_val( addr, val ) ( (vi addr) = (val) )
#define or_val( addr, val ) ( (vi addr) |= (val) ) void ddr_init_ll( void )
{
// tell dramc to configure
set_val( MEMCCMD, 0x4 ); // set refresh period
set_val( P1REFRESH, nstoclk(7800) ); // set timing para
set_val( P1CASLAT, ( 3 << 1 ) );
set_val( P1T_DQSS, 0x1 );// 0.75 - 1.25
set_val( P1T_MRD, 0x2 );
set_val( P1T_RAS, nstoclk(45) );
set_val( P1T_RC, nstoclk(68) ); unsigned int trcd = nstoclk( 23 );
set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );
unsigned int trfc = nstoclk( 80 );
set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );
unsigned int trp = nstoclk( 23 );
set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) );
set_val( P1T_RRD, nstoclk(15) );
set_val( P1T_WR, nstoclk(15) );
set_val( P1T_WTR, 0x7 );
set_val( P1T_XP, 0x2 );
set_val( P1T_XSR, nstoclk(120) );
set_val( P1T_ESR, nstoclk(120) ); // set mem cfg
set_nbit( P1MEMCFG, 0, 3, 0x2 ); /* 10 column address */ /* set_nbit: 把从第bit位开始的一共len位消零,然后把这几位设为val */ set_nbit( P1MEMCFG, 3, 3, 0x2 ); /* 13 row address */
set_zero( P1MEMCFG, 6 ); /* A10/AP */
set_nbit( P1MEMCFG, 15, 3, 0x2 ); /* Burst 4 */ set_nbit( P1MEMCFG2, 0, 4, 0x5 );
set_2bit( P1MEMCFG2, 6, 0x1 );/* 32 bit */
set_nbit( P1MEMCFG2, 8, 3, 0x3 );/* Mobile DDR SDRAM */
set_2bit( P1MEMCFG2, 11, 0x1 ); set_one( P1_chip_0_cfg, 16 );/* Bank-Row-Column organization */ // memory init
set_val( P1DIRECTCMD, 0xc0000 ); // NOP
set_val( P1DIRECTCMD, 0x000 );// precharge
set_val( P1DIRECTCMD, 0x40000 );// auto refresh
set_val( P1DIRECTCMD, 0x40000 );// auto refresh
set_val( P1DIRECTCMD, 0xa0000 ); // EMRS
set_val( P1DIRECTCMD, 0x80032 ); // MRS set_val( MEM_SYS_CFG, 0x0 ); // set dramc to "go" status
set_val( P1MEMCCMD, 0x000 ); // wait ready
while( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));
}
文件init.c:
#define MEM_SYS_CFG (*((volatile unsigned long *)0x7E00F120))
#define NFCONF (*((volatile unsigned long *)0x70200000))
#define NFCONT (*((volatile unsigned long *)0x70200004))
#define NFCMMD (*((volatile unsigned long *)0x70200008))
#define NFADDR (*((volatile unsigned long *)0x7020000C))
#define NFDATA (*((volatile unsigned char *)0x70200010))
#define NFSTAT (*((volatile unsigned long *)0x70200028)) void nand_read_ll(unsigned int nand_start, unsigned int ddr_start, unsigned int len); int isBootFromNorFlash(void)
{
volatile int *p = (volatile int *)0;
int val; val = *p;
*p = 0x12345678;
if (*p == 0x12345678)
{
/*鍐欐垚鍔燂紝鏄痭and鍚姩*/
*p = val;
return 0;
}
else
{
/*Nor涓嶈兘鍍忓唴瀛樹竴鏍峰啓*/
return 1;
}
} void copy_code_to_sdram(unsigned int src, unsigned int dest, unsigned int len)
{
int i = 0;
/*濡傛灉鏄疦or鍚姩*/
unsigned char *src_start = (unsigned char *)src;
unsigned char *dest_start = (unsigned char *)dest;
if(isBootFromNorFlash())
{
while (i < len)
{
dest_start[i] = src_start[i];
i++;
}
}
else
{
//nand_init();
//nand_resd(src, dest, len)
nand_read_ll(src, dest, len);
}
} static void nand_select(void)
{
NFCONT &= ~(1<<1);
} static void nand_deselect(void)
{
NFCONT |= (1<<1);
} static void nand_cmd(unsigned char cmd)
{
NFCMMD = cmd;
} static void nand_addr(unsigned char addr)
{
NFADDR = addr;
} static unsigned char nand_get_data(void)
{
return NFDATA;
} static void nand_send_data(unsigned char data)
{
NFDATA = data;
} static void wait_ready(void)
{
while ((NFSTAT & 0x1) == 0);
} static void nand_reset(void)
{
/* 閫変腑 */
nand_select(); /* 鍙戝嚭0xff鍛戒护 */
nand_cmd(0xff); /* 绛夊緟灏辩华 */
wait_ready(); /* 鍙栨秷閫変腑 */
nand_deselect();
} void clear_bss(void)
{
extern int __bss_start, __bss_end__;
int *p = &__bss_start; for (; p < &__bss_end__; p++)
*p = 0;
} void nand_init_ll(void)
{
/* 璁﹛m0csn2鐢ㄤ綔nand flash cs0 鐗囬€夊紩鑴?*/
MEM_SYS_CFG &= ~(1<<1); /* 璁剧疆鏃堕棿鍙傛暟 */
#define TACLS 0
#define TWRPH0 2
#define TWRPH1 1
NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4)); /* 浣胯兘nand flash controller */
NFCONT |= 1;
NFCONT &= ~(1<<16); /* 妫soft lock */ nand_reset();
} static void nand_send_addr(unsigned int addr)
{
#if 1
unsigned int page = addr / 4096;
unsigned int colunm = addr & (4096 - 1); /* 杩欎袱涓湴鍧€琛ㄧず浠庨〉鍐呭摢閲屽紑濮?*/
nand_addr(colunm & 0xff);
nand_addr((colunm >> 8) & 0xff); /* 涓嬮潰涓変釜鍦板潃琛ㄧず鍝竴椤?*/
nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);
#else
nand_addr(addr & 0xff); /* a0~a7 */
nand_addr((addr >> 8) & 0x1f); /* 绋嬪簭鐨勮搴? a8~a12 */ nand_addr((addr >> 13) & 0xff); /* 绋嬪簭鐨勮搴? a13~a20 */
nand_addr((addr >> 21) & 0xff); /* 绋嬪簭鐨勮搴? a21~a28 */
nand_addr((addr >> 29) & 0x7); /* 绋嬪簭鐨勮搴? a29 ~ */ #endif
} void nand_read_ll(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
unsigned int addr = nand_start;
int i = nand_start % 4096;
int left = i;
int count = 0;
unsigned char *dest = (unsigned char *)ddr_start;
unsigned char data = 0; /* 閫変腑鑺墖 */
nand_select(); while (count < len)
{
/* 鍙戝嚭鍛戒护0x00 */
nand_cmd(0x00); /* 鍙戝嚭鍦板潃 */
nand_send_addr(addr); /* 鍙戝嚭鍛戒护0x30 */
nand_cmd(0x30); /* 绛夊緟灏辩华 */
wait_ready(); /* 璇绘暟鎹?*/
for (; i < (4096-left) && count < len; i++)//浠庢煇椤电殑i澶勫紑濮嬭
{
data = nand_get_data();
if(addr<16384)//鍓?椤垫瘡娆″彧鑳藉啓2K
{
if(i<(2048-left))
{
dest[count++] = data;
}
}
else
{
dest[count++] = data;
}
//dest[count++] = nand_get_data();
addr++;
} i = 0;
left = i;
} /* 鍙栨秷鐗囬€?*/
nand_deselect();
// return 0;
} void nand_erase_block_ll(unsigned long addr)
{
int page = addr / 4096; nand_select();
nand_cmd(0x60); nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff); nand_cmd(0xd0);
wait_ready(); nand_deselect();
} void nand_write_ll(unsigned int nand_start, unsigned char * buf, unsigned int len)
{
unsigned long count = 0;
unsigned long addr = nand_start;
int i = nand_start % 4096;
int left = i; nand_select();
while (count < len)
{
nand_cmd(0x80);
nand_send_addr(addr);
for (; i < (4096-left) && count < len; i++)
{
if(addr<16384)//鍐欏墠2K
{
if(i<(2048-left))//鍓?椤垫瘡椤靛彧鑳藉啓2K
{
nand_send_data(buf[count++]);
}
}
else
{
nand_send_data(buf[count++]);
}
//nand_send_data(buf[count++]);
addr++;
} nand_cmd(0x10);
wait_ready();
i = 0;
left = i;
} nand_deselect(); } #define ULCON0 (*((volatile unsigned long *)0x7F005000))
#define UCON0 (*((volatile unsigned long *)0x7F005004))
#define UFCON0 (*((volatile unsigned long *)0x7F005008))
#define UMCON0 (*((volatile unsigned long *)0x7F00500C))
#define UTRSTAT0 (*((volatile unsigned long *)0x7F005010))
#define UFSTAT0 (*((volatile unsigned long *)0x7F005018))
#define UTXH0 (*((volatile unsigned char *)0x7F005020))
#define URXH0 (*((volatile unsigned char *)0x7F005024))
#define UBRDIV0 (*((volatile unsigned short *)0x7F005028))
#define UDIVSLOT0 (*((volatile unsigned short *)0x7F00502C)) #define GPACON (*((volatile unsigned long *)0x7F008000)) #define ENABLE_FIFO int getc_nowait(unsigned char *pChar)
{
#ifdef ENABLE_FIFO
if ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)
#else
if ((UTRSTAT0 & (1<<0)) == 0)
#endif
{
return -1;
}
else
{
*pChar = URXH0;
return 0;
}
}
#define SROM_BW (*((volatile unsigned long *)0x70000000))
void dm9000aep_init(void)
{
SROM_BW |= (0XFF<<4);
}
增加文件还要修改board\samsung\smdk6410下的Makefile:修改37行
COBJS-y:= smdk6410.o sdram.o init.o
上面的代码都是我直接从以前的裸板update程序拷贝过来的,实现了NAND、DDR初始化以及拷贝代码到内存。分析u-boot-2012.04.01的重定位写的很复杂,这里还是沿用以前那种简单的重定位,有兴趣的可以分析它的重定位代码,下面继续修改
241:修改call_board_init_f成如下:
call_board_init_f:
ldrr0,=0x00000000
blboard_init_f
/*r0=(unsigned int)id */
ldr r1, _TEXT_BASE/*link address*/
ldr sp, base_sp //add*** you must add sp, otherwise,Saving Environment to NAND...
/*jump to second step code*/
bl board_init_r
这里新用到变量base_sp ,需要定义134:增加
.globl base_sp//add***
base_sp:
.long 0
同时去掉u-boot自带的重定位代码,下面这部分代码可以全部去掉,这里没有用
/*------------------------------------------------------------------------------*/ /*
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
*/
.globl relocate_code
relocate_code:
mov r4, r0 /* save addr_sp */
mov r5, r1 /* save addr of gd */
mov r6, r2 /* save addr of destination */ /* Set up the stack */
stack_setup:
mov sp, r4 adr r0, _start
cmp r0, r6
beq clear_bss /* skip relocation */
mov r1, r6 /* r1 <- scratch for copy_loop */
ldr r3, _bss_start_ofs
add r2, r0, r3 /* r2 <- source end address */ copy_loop:
ldmia r0!, {r9-r10} /* copy from source address [r0] */
stmia r1!, {r9-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
blo copy_loop #ifndef CONFIG_SPL_BUILD
/*
* fix .rel.dyn relocations
*/
ldr r0, _TEXT_BASE /* r0 <- Text base */
sub r9, r6, r0 /* r9 <- relocation offset */
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
add r10, r10, r0 /* r10 <- sym table in FLASH */
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
fixloop:
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
add r0, r0, r9 /* r0 <- location to fix up in RAM */
ldr r1, [r2, #4]
and r7, r1, #0xff
cmp r7, #23 /* relative fixup? */
beq fixrel
cmp r7, #2 /* absolute fixup? */
beq fixabs
/* ignore unknown type of fixup */
b fixnext
fixabs:
/* absolute fix: set location to (offset) symbol value */
mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
add r1, r10, r1 /* r1 <- address of symbol in table */
ldr r1, [r1, #4] /* r1 <- symbol value */
add r1, r1, r9 /* r1 <- relocated sym addr */
b fixnext
fixrel:
/* relative fix: increase location by offset */
ldr r1, [r0]
add r1, r1, r9
fixnext:
str r1, [r0]
add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
cmp r2, r3
blo fixloop
#endif #ifdef CONFIG_ENABLE_MMU
enable_mmu:
/* enable domain access */
ldr r5, =0x0000ffff
mcr p15, 0, r5, c3, c0, 0 /* load domain access register */ /* Set the TTB register */
ldr r0, _mmu_table_base
ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE
ldr r2, =0xfff00000
bic r0, r0, r2
orr r1, r0, r1
mcr p15, 0, r1, c2, c0, 0 /* Enable the MMU */
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #1 /* Set CR_M to enable MMU */ /* Prepare to enable the MMU */
adr r1, skip_hw_init
and r1, r1, #0x3fc
ldr r2, _TEXT_BASE
ldr r3, =0xfff00000
and r2, r2, r3
orr r2, r2, r1
b mmu_enable .align 5
/* Run in a single cache-line */
mmu_enable: mcr p15, 0, r0, c1, c0, 0
nop
nop
mov pc, r2
skip_hw_init:
#endif clear_bss:
#ifndef CONFIG_SPL_BUILD
ldr r0, _bss_start_ofs
ldr r1, _bss_end_ofs
mov r4, r6 /* reloc addr */
add r0, r0, r4
add r1, r1, r4
mov r2, #0x00000000 /* clear */ clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l #ifndef CONFIG_NAND_SPL
bl coloured_LED_init
bl red_led_on
#endif
#endif
进入blboard_init_f 还要修改arch\arm\lib\board.c
在265:声明前面start.S定义的变量
extern ulong base_sp;//**add
在373行修改如下:
//addr -= gd->mon_len;
//addr &= ~(4096 - 1);
addr = _TEXT_BASE;//0x57e0000
在439行修改如下去掉重定位,返回堆栈
base_sp = addr_sp;//**add
//relocate_code(addr_sp, id, addr);
return (unsigned int)id;
既然return (unsigned int)id;那么还要修改函数类型
259:void board_init_f(ulong bootflag)改为unsigned int board_init_f(ulong bootflag)
继续修改arch\arm\config.mk 75:
#LDFLAGS_u-boot += -pie
u-boot运行后,不管是NNAD还是NOR Flash启动,都会进行重定位,即把代码拷到内存运行,就像PC机一样程序都是在内存运行的。那么支持NAND启动的u-boot,重定位之前代码必须小于4KB,才能跑起来。分析现在较新的u-boot源码(以后在另外文章分析),代码连接时加-pie选项,重定位成位置无关代码,搞的很高级,不利于像S3C2440这样片内SRAM十分有限的SOC跑。这里修改重定位代码,支持NAND启动。故去掉-pie
在board\samsung\smdk6410/u-boot-nand.lds:38增加
board/samsung/smdk6410/libsmdk6410.o (.text)
这样做是为了保证重定位前的代码放在最前面4K以内。
上面修改了很多地方,先编译,有问题再修改
change@change:/si/OK6410/u-boot-2012.04.01$ make
board.c:259: error: conflicting types for 'board_init_f'
/si/OK6410/u-boot-2012.04.01/include/common.h:276: error: previous declaration of 'board_init_f' was here
make[1]: *** [board.o] Error 1
make[1]: Leaving directory `/si/OK6410/u-boot-2012.04.01/arch/arm/lib'
make: *** [arch/arm/lib/libarm.o] Error 2
change@change:/si/OK6410/u-boot-2012.04.01$
出错了,跟着提示include/common.h:276: error: previous declaration of 'board_init_f' was here去include/common.h:276看看
果然有问题,去掉noreturn,修改函数类型如下:
unsigned int board_init_f (ulong);
voidboard_init_r (gd_t *, ulong);
再编译change@change:/si/OK6410/u-boot-2012.04.01$ make
编译通过了,现在的程序串口应该能正常输出了
四、烧写测试
现在的u-boot肯定还是不能用,如果你想烧进去看看现象,这里介绍一种好方法烧写程序。先用飞淩提供的一键烧写工具,写mmc.bin到sd卡,再把上面编译生成的u-boot.bin拷到sd卡,接着把单板拨到sd卡启动。我的OK6410在NAND启动的情况下直接把6、7拨到on就变成SD启动了。单板SD卡启动上电,串口(115200 8 n 1)输出如下:
U-Boot 1.1.6 (Dec 15 2010 - 09:02:39) for SMDK6410
****************************************
** u-boot 1.1.6 **
** Updated for TE6410 Board **
** Version 1.0 (10-01-15) **
** OEM: Forlinx Embedded **
** Web: http://www.witech.com.cn **
****************************************
CPU: S3C6410 @532MHz
Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)
Board: SMDK6410
DRAM: 128 MB
Flash: 0 kB
NAND: tmp = 29
select s3c_nand_oob_mlc_128
2048 MB
SD/MMC: 1904 MB
*** Warning - bad CRC or moviNAND, using default environment
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
NAND erase: device 0 whole chip
Skipping bad block at 0x00800000
Skipping bad block at 0x0e400000
Skipping bad block at 0x0e780000
Skipping bad block at 0x13b80000
Skipping bad block at 0x27a80000
Skipping bad block at 0x7e280000
Erasing at 0x7ff80000 -- 100% complete.
OK
reading u-boot.bin
error found: 0010
很不幸遇到error,再网上看了很多贴找到了解决方法。
在这里http://www.pc6.com/softview/SoftView_66768.html下载Aomei Partition Assistant Professional Edition 4.0,用该分区根据将以前分区删除,然后新建分区就行了,记住只选择你的SD卡盘,不要把自己系统盘给删了,那就亏大了。还是简单说明哈操作,解压进入运行PartAssist.exe,在看到最下面的sd卡盘,选择你的sd卡盘,单击左侧Delete All Partitions,再单击上面的Aplly.完成后同样的操作新建分区即可。不清楚可以问我,要是系统盘给自己格了,别怪我。重新分区后的SD卡启动如下
K
U-Boot 1.1.6 (Dec 15 2010 - 09:02:39) for SMDK6410
****************************************
** u-boot 1.1.6 **
** Updated for TE6410 Board **
** Version 1.0 (10-01-15) **
** OEM: Forlinx Embedded **
** Web: http://www.witech.com.cn **
****************************************
CPU: S3C6410 @532MHz
Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)
Board: SMDK6410
DRAM: 128 MB
Flash: 0 kB
NAND: tmp = 29
select s3c_nand_oob_mlc_128
2048 MB
SD/MMC: 1904 MB
*** Warning - bad CRC or moviNAND, using default environment
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
NAND erase: device 0 whole chip
Skipping bad block at 0x00800000
Skipping bad block at 0x0e400000
Skipping bad block at 0x0e780000
Skipping bad block at 0x13b80000
Skipping bad block at 0x27a80000
Skipping bad block at 0x7e280000
Erasing at 0x7ff80000 -- 100% complete.
OK
reading u-boot.bin
242792 bytes read
NAND write: device 0 offset 0x0, size 0x100000
1032192 bytes written: OK
reading zImage
** Unable to read "zImage" from mmc 0:1 **
就说明u-boot.bin烧写完毕了,没有放zImage当然Unable to read "zImage"。没关系,断电将ok6410拨码开关6、7拨到off就变成NAND启动了。启动输出如下:
U-Boot 2012.04.01 (Jun 24 2013 - 23:27:16) for SMDK6400
CPU: S3C6400@532MHz
Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: SMDK6400
DRAM: 128 MiB
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###
还有很多问题,串口基本正常输出了。根据u-boot输出的Flash: *** failed ***,根据以往经验应该是没有检测到板子的NOR FLASH就卡住了,问题不大,好吧继续修改
进入arch/arm/lib/board.c 530修改如下
//puts(failed);
//hang();
puts("0 KB\n\r");
没有检测到就hang();,屏蔽让它输出OKB,修改后继续编译,编译OK按照上面的方法烧到单板,NAND启动输出如下:
U-Boot 2012.04.01 (Jun 24 2013 - 23:35:21) for SMDK6400
CPU: S3C6400@532MHz
Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: SMDK6400
DRAM: 128 MiB
WARNING: Caches not enabled
Flash: 0 KB
NAND: No oob scheme defined for oobsize 218
2048 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: CS8900-0
Hit any key to stop autoboot: 0
SMDK6400 #
基本OK了,这篇修改的代码有点多,先写到这吧。
ok6410 u-boot-2012.04.01移植二修改源码支持单板的更多相关文章
- ok6410 u-boot-2012.04.01移植六完善MLC NAND支持
继ok6410 u-boot-2012.04.01移植四.五后,开发板基本已支持MLC NAND,支持DM9000.但是通过NAND命令更新u-boot到NAND,还存在问题,需要根据u-boot的n ...
- ok6410 u-boot-2012.04.01移植五支持DM9000
继ok6410 u-boot-2012.04.01移植四后,开发板基本已支持MLC NAND,但还有一些细节地方修改,这节增加DM9000支持,通过网卡tftp程序到内存,接着通过NAND命令写到NA ...
- ok6410 u-boot-2012.04.01移植七完善u-boot移植(u-boot移植结束)
继ok6410 u-boot-2012.04.01移植六后,开发板已支持MLC NAND.DM9000等.但还需要完善比如环境变量.mtdpart分区.裁剪.制作补丁等.下面的工作就是完善移植的u-b ...
- 移植u-boot.2012.04.01
/*************************************************** *u-boot版本:u-boot2012.04.01 *gcc版本:arm-linux-gcc ...
- Spring Boot REST(二)源码分析
Spring Boot REST(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) SpringBoot RE ...
- 在Ubuntu Server14.04上编译Android6.0源码
此前编译过Android4.4的源码,但是现在Android都到了7.0的版本,不禁让我感叹Google的步伐真心难跟上,趁这周周末时间比较充裕,于是在过去的24小时里,毅然花了9个小时编译了一把An ...
- Alink漫谈(二十二) :源码分析之聚类评估
Alink漫谈(二十二) :源码分析之聚类评估 目录 Alink漫谈(二十二) :源码分析之聚类评估 0x00 摘要 0x01 背景概念 1.1 什么是聚类 1.2 聚类分析的方法 1.3 聚类评估 ...
- 34 网络相关函数(二)——live555源码阅读(四)网络
34 网络相关函数(二)——live555源码阅读(四)网络 34 网络相关函数(二)——live555源码阅读(四)网络 2)socketErr 套接口错误 3)groupsockPriv函数 4) ...
- Ubuntu12.04编译Android4.0.1源码全过程-----附wubi安装ubuntu编译android源码硬盘空间不够的问题解决
昨晚在编译源码,make一段时间之后报错如下: # A fatal error has been detected by the Java Runtime Environment: # # SIGSE ...
随机推荐
- Android注入事件的三种方法比较
方法1:使用内部APIs 该方法和其他所有内部没有向外正式公布的APIs一样存在它自己的风险.原理是通过获得WindowManager的一个实例来访问injectKeyEvent/injectPoin ...
- 4. SQL Server数据库状态监控 - 作业状态
原文:4. SQL Server数据库状态监控 - 作业状态 有很多地方可以设置定时任务,比如:Windows的计划任务,Linux下的crontab,各种开发工具里的timer组件.SQL Serv ...
- canvas绘制自定义的曲线,以椭圆为例,通俗易懂,童叟无欺
本篇文章,将讲述如何通过自定义的曲线函数,使用canvas的方式进行曲线的绘制. 为了通俗易懂,将以大家熟悉的椭圆曲线为例,进行椭圆的绘制.至于其他比较复杂的曲线,用户只需通过数学方式建立起曲线函数, ...
- Math.random引发的骗术,绝对是用随机数骗前端妹纸的最佳方法
我觉得今天我运气特好,今天我们来赌一赌,我们来搞个随机数,Math.floor(Math.random() * 10),如果这个数等于0到7,这个月的饭,我全请了,如果是8或9,你就请一个礼拜成不?于 ...
- JS复选框选中
Web前端之复选框选中属性 熟悉web前端开发的人都知道,判断复选框是否选中是经常做的事情,判断的方法很多,但是开发过程中常常忽略了这些方法的兼容性,而是实现效果就好了.博主之前用户不少方法,经常 ...
- 从PHP官网被攻击,到熟悉SSL(安全链路层)
近日,php官网php.net网站受到恶意攻击,攻击者至少破坏了2个服务器.PHP工作组不得不重置用户密码. PHP工作组在随后的调查发现,攻击者成功的对网站注入了恶意的JavaScript代码,这个 ...
- SQLServer通过链接服务器远程删除数据性能问题解决
原文:SQLServer通过链接服务器远程删除数据性能问题解决 在上一遍文章中介绍了SQLServer通过链接服务器访问Oracle性能问题的解决方法,本文介绍链接服务器下远程删除SQLServer数 ...
- 网页启动Windows服务
如何在网页启动Windows服务 由于公司有许多windows服务进行业务的处理,所谓对服务的维护也是一个比较头痛的问题,因为自己也不知道服务什么时候自动停了,而且更主要的原因是服务都是由运维部门 ...
- Tomcat7 Cluster 集群
Tomcat7 自带的集群功能是通过session复制完成的,现有两个复制方式: DeltaManager: 将session复制到所有tomcat节点中,不管是否有相应的应用(it will rep ...
- 快速创建InfoPath表单
快速创建InfoPath表单 2010年已经过去了一半了,这时候再说初识InfoPath可能会被很多人笑话,但是又有多少人真正认识InfoPath呢?无论你是刚刚 听说这个东西还是它的老相好都请同我一 ...