ok6410 u-boot-2012.04.01移植二修改源码支持单板

2024-05-09 04:48

本文主要是介绍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
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等都在bl lowlevel_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 */
//ldr r0, =ELFIN_MEM_SYS_CFG
/* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */
//mov r1, #S3C64XX_MEM_SYS_CFG_NAND
//str r1, [r0]
//bl mem_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]
bic r1, r1, #0xfffffff7
cmp r1, #0x8
beq wakeup_reset
1:
mov lr, r12
mov pc, 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
mov lr, r12
mov pc, lr
nop
nop
接着在arch\arm\cpu\arm1176\start.S中增加对NAND、DDR等支持

在225:bl lowlevel_init后增加如下代码

ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)/*sp=0x0c00if80 ISRAM*/
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */

bl    ddr_init_ll
bl    nand_init_ll
bl dm9000aep_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 MEMCCMD	0x7e001004
#define P1REFRESH	0x7e001010
#define P1CASLAT	0x7e001014
#define MEM_SYS_CFG	0x7e00f120
#define P1MEMCFG	0x7e00100c
#define P1T_DQSS	0x7e001018
#define P1T_MRD		0x7e00101c
#define P1T_RAS		0x7e001020
#define P1T_RC		0x7e001024
#define P1T_RCD		0x7e001028
#define P1T_RFC		0x7e00102c
#define P1T_RP		0x7e001030
#define P1T_RRD		0x7e001034
#define P1T_WR		0x7e001038
#define P1T_WTR		0x7e00103c
#define P1T_XP		0x7e001040
#define P1T_XSR		0x7e001044
#define P1T_ESR		0x7e001048
#define P1MEMCFG2	0X7e00104c
#define P1_chip_0_cfg	0x7e001200
#define P1MEMSTAT	0x7e001000
#define P1MEMCCMD	0x7e001004
#define P1DIRECTCMD	0x7e001008
	
#define HCLK	133000000
#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:
ldr r0,=0x00000000
bl board_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
进入bl board_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);
void board_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移植二修改源码支持单板的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972428

相关文章

公共筛选组件(二次封装antd)支持代码提示

如果项目是基于antd组件库为基础搭建,可使用此公共筛选组件 使用到的库 npm i antdnpm i lodash-esnpm i @types/lodash-es -D /components/CommonSearch index.tsx import React from 'react';import { Button, Card, Form } from 'antd'

(超详细)YOLOV7改进-Soft-NMS(支持多种IoU变种选择)

1.在until/general.py文件最后加上下面代码 2.在general.py里面找到这代码,修改这两个地方 3.之后直接运行即可

C++入门01

1、.h和.cpp 源文件 (.cpp)源文件是C++程序的实际实现代码文件,其中包含了具体的函数和类的定义、实现以及其他相关的代码。主要特点如下:实现代码: 源文件中包含了函数、类的具体实现代码,用于实现程序的功能。编译单元: 源文件通常是一个编译单元,即单独编译的基本单位。每个源文件都会经过编译器的处理,生成对应的目标文件。包含头文件: 源文件可以通过#include指令引入头文件,以使

springboot家政服务管理平台 LW +PPT+源码+讲解

3系统的可行性研究及需求分析 3.1可行性研究 3.1.1技术可行性分析 经过大学四年的学习,已经掌握了JAVA、Mysql数据库等方面的编程技巧和方法,对于这些技术该有的软硬件配置也是齐全的,能够满足开发的需要。 本家政服务管理平台采用的是Mysql作为数据库,可以绝对地保证用户数据的安全;可以与Mysql数据库进行无缝连接。 所以,家政服务管理平台在技术上是可以实施的。 3.1

高仿精仿愤怒的小鸟android版游戏源码

这是一款很完美的高仿精仿愤怒的小鸟android版游戏源码,大家可以研究一下吧、 为了报复偷走鸟蛋的肥猪们,鸟儿以自己的身体为武器,仿佛炮弹一样去攻击肥猪们的堡垒。游戏是十分卡通的2D画面,看着愤怒的红色小鸟,奋不顾身的往绿色的肥猪的堡垒砸去,那种奇妙的感觉还真是令人感到很欢乐。而游戏的配乐同样充满了欢乐的感觉,轻松的节奏,欢快的风格。 源码下载

基于Java医院药品交易系统详细设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W+,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码+数据库🌟 感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人  Java精品实战案例《600套》 2023-2025年最值得选择的Java毕业设计选题大全:1000个热

开启青龙 Ninja 扫码功能失效后修改成手动填写CK功能【修正Ninja拉库地址】

国内:进入容器docker exec -it qinglong bash #获取ninjagit clone -b main https://ghproxy.com/https://github.com/wjx0428/ninja.git /ql/ninja#安装cd /ql/ninja/backend && pnpm install cp .env.example .env

vscode-创建vue3项目-修改暗黑主题-常见错误-element插件标签-用法涉及问题

文章目录 1.vscode创建运行编译vue3项目2.添加项目资源3.添加element-plus元素4.修改为暗黑主题4.1.在main.js主文件中引入暗黑样式4.2.添加自定义样式文件4.3.html页面html标签添加样式 5.常见错误5.1.未使用变量5.2.关闭typescript检查5.3.调试器支持5.4.允许未到达代码和未定义代码 6.element常用标签6.1.下拉列表

美容美发店营销版微信小程序源码

打造线上生意新篇章 一、引言:微信小程序,开启美容美发行业新纪元 在数字化时代,微信小程序以其便捷、高效的特点,成为了美容美发行业营销的新宠。本文将带您深入了解美容美发营销微信小程序,探讨其独特优势及如何助力商家实现业务增长。 二、微信小程序:美容美发行业的得力助手 拓宽客源渠道:微信小程序基于微信社交平台,轻松实现线上线下融合,帮助商家快速吸引潜在客户,拓宽客源渠道。 提升用户体验:

风水研究会官网源码系统-可展示自己的领域内容-商品售卖等

一款用于展示风水行业,周易测算行业,玄学行业的系统,并支持售卖自己的商品。 整洁大气,非常漂亮,前端内容均可通过后台修改。 大致功能: 支持前端内容通过后端自定义支持开启关闭会员功能,会员等级设置支持对接官方支付支持添加商品类支持添加虚拟下载类支持自定义其他类型字段支持生成虚拟激活卡支持采集其他站点文章支持对接收益广告支持文章评论支持积分功能支持推广功能更多功能,搭建完成自行体验吧! 原文