最近学习uboot,然后自己动手移植2010.09版的始终不成功。。。
最后参考启动流程自己写了个,启动了开发板。
。功能就初始化硬件,然后加载内核到内存指定位置。
.text
.global _start
# define pWTCON 0x53000000
# define INTMOD 0X4A000004
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
# define INTSUBMSK 0x4A00001C
#define TEXT_BASE 0x33F80000
_start:
//关闭看门狗和各自中断
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
//重新配置clock Fin=12Mhz
/*S3C2440: Mpll = (2*m * Fin) / (p * 2^s),
UPLL = (m * Fin) / (p * 2^s)
m = M (the value for divider M)+ 8,
p = P (the value for divider P) + 2
*/
/*clock register*/
#define CLK_CTL_BASE 0x4C000000
#define CLKDIVN 0x4C000014 /* clock divisor register */
#define S3C2440_CLKDIV 0x05
//#define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01))
#define MDIV_400 0x5c<<12
#define PDIV_400 0x01<<4
#define SDIV_400 0x01
//#define S3C2440_UPLL_48MHZ ((0x38<<12)|(0x02<<4)|(0x02))
#define MDIV_48 0x38<<12
#define PDIV_48 0x02<<4
#define SDIV_48 0x02
/*初始化clock分频比例*/
/* FCLK:HCLK:PCLK = 1:4:8, UCLK = UPLL/2 */
ldr r0, =CLKDIVN
mov r1, #S3C2440_CLKDIV
str r1, [r0]
/* change to asynchronous bus mod 见手册说明*/
mrc p15, 0, r1, c1, c0, 0 /* read ctrl register */
orr r1, r1, #0xc0000000 /* Asynchronous */
mcr p15, 0, r1, c1, c0, 0 /* write ctrl register */
mov r1,#CLK_CTL_BASE
mov r2,#MDIV_48
add r2,r2,#PDIV_48
add r2,r2,#SDIV_48
str r2,[r1,#0x08]
nop
nop
nop
nop
nop
nop
nop
mov r2,#MDIV_400
add r2,r2,#PDIV_400
add r2,r2,#SDIV_400
str r2,[r1,#0x04]
//关闭MMU,CACHE
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
//mem control config
bl ramctrl_config
//stack setup
ldr sp, =TEXT_BASE
sub sp,sp,#332*1024
#define GPACON 0x56000000
#define GPADAT 0x56000004
#define GPAUP 0x56000008
#define GPBCON 0x56000010
#define GPBDAT 0x56000014
#define GPBUP 0x56000018
#define GPCCON 0x56000020
#define GPCDAT 0x56000024
#define GPCUP 0x56000028
#define GPDCON 0x56000030
#define GPDDAT 0x56000034
#define GPDUP 0x56000038
#define GPECON 0x56000040
#define GPEDAT 0x56000044
#define GPEUP 0x56000048
#define GPFCON 0x56000050
#define GPFDAT 0x56000054
#define GPFUP 0x56000058
#define GPGCON 0x56000060
#define GPGDAT 0x56000064
#define GPGUP 0x56000068
#define GPHCON 0x56000070
#define GPHDAT 0x56000074
#define GPHUP 0x56000078
#define GPJCON 0x560000d0
#define GPJDAT 0x560000d4
#define GPJUP 0x560000d8
#define GPB5_out 1<<10
#define GPB6_out 1<<12
#define GPB7_out 1<<14
#define GPB8_out 1<<16
#define CODE_ADDR 0x00240000
#define linux_addr 0x30008000
#define CODE_SIZE 0x00200000
//copy code
//turn on all led
ldr r0,=GPBCON
ldr r1,=(GPB5_out|GPB6_out|GPB7_out|GPB8_out)
str r1,[r0]
ldr r0,=GPBDAT
ldr r1,=(~(0xf<<5))
str r1,[r0]
ldr r0,=CODE_ADDR
ldr r1,=linux_addr
ldr r2,=CODE_SIZE
bl copycode2ram
cmp r0,#0x0
beq call_linux
halt:
b halt
halt2:
#if 0
//failed to setup boot params , turn off all led
ldr r0,=GPBCON
ldr r1,=(GPB5_out|GPB6_out|GPB7_out|GPB8_out)
str r1,[r0]
ldr r0,=GPBDAT
ldr r1,=(~(0x0<<6))
str r1,[r0]
#endif
b halt2
#define MACH_TYPE 168 /*r1*/
#define PARAMS_ADDR 0x30000100 /*r2*/
call_linux:
gpio_setup:
ldr r0,=GPACON
ldr r1,=0x007FFFFF
str r1,[r0]
ldr r0,=GPBCON
ldr r1,=0x00055554
str r1,[r0]
ldr r0,=GPBUP
ldr r1,=0x000007FF
str r1,[r0]
ldr r0,=GPCCON
ldr r1,=0xAAAAAAAA
str r1,[r0]
ldr r0,=GPCUP
ldr r1,=0x0000FFFF
str r1,[r0]
ldr r0,=GPDCON
ldr r1,=0xAAAAAAAA
str r1,[r0]
ldr r0,=GPDUP
ldr r1,=0x0000FFFF
str r1,[r0]
ldr r0,=GPECON
ldr r1,=0xAAAAAAAA
str r1,[r0]
ldr r0,=GPEUP
ldr r1,=0x0000FFFF
str r1,[r0]
ldr r0,=GPFCON
ldr r1,=0x000055AA
str r1,[r0]
ldr r0,=GPFUP
ldr r1,=0x000000FF
str r1,[r0]
ldr r0,=GPGCON
ldr r1,=0xFF94FFBA
str r1,[r0]
ldr r0,=GPGUP
ldr r1,=0x0000FFFF
ldr r1,[r0]
ldr r0,=GPHCON
ldr r1,=0x002AFAAA
str r1,[r0]
ldr r0,=GPHUP
ldr r1,=0x000007FF
str r1,[r0]
ldr r0,=GPJCON
ldr r1,=0x02aaaaaa
str r1,[r0]
ldr r0,=GPJUP
ldr r1,=0x00001fff
str r1,[r0]
//lcd poweren
#define LCDCON1 0x4d000000
#define LCDCON5 0x4d000010
ldr r0,=GPGDAT
ldr r1,[r0]
orr r1,r1,#1<<4
str r1,[r0]
ldr r0,=LCDCON5
ldr r1,[r0]
orr r1,r1,#1<<3 //poweren
and r1,r1,#~(1<<5) //invpoweren
str r1,[r0]
//初始化串口
bl init_serial
//初始化标记列表
//ldr r0,=PARAMS_ADDR
bl setup_tags
//b halt2 /*failed to setup boot params*/
// turn on led 5 8
ldr r0,=GPBCON
ldr r1,=(GPB5_out|GPB8_out)
str r1,[r0]
ldr r0,=GPBDAT
ldr r1,=(~(0x9<<5))
str r1,[r0]
//envid 现在打开LCD
ldr r0,=LCDCON1
ldr r1,[r0]
orr r1,r1,#0x1
str r1,[r0]
//设置启动参数
ldr r0,=0x0
ldr r1,=MACH_TYPE
ldr r2,=PARAMS_ADDR
//everything is fine
ldr pc,=linux_addr
//serial setup
#define UART_BASE 0x50000000
#define ULCON0 0x50000000
//#define ULCON1 0x50004000
//#define ULCON2 0x50008000
#define UCON0 0x50000004
//#define UCON1 0x50004004
//#define UCON2 0x50008004
#define UFCON0 0x50000008
//#define UFON1 0x50004008
//#define UFON2 0x50008008
#define UMCON0 0x5000000c
//#define UMON1 0x5000400c
#define UTRSTAT0 0x50000010
#define UERSTAT0 0x50000014
#define UFSTAT0 0x50000018
#define UMSTAT0 0x5000001c
#define UTXH0 0x50000020
#define UBRDIV0 0x50000028
#define PCLK 50000000
#define UART_CLK PCLK
#define UART_BAUD_RATE 115200
#define UART_BRD ((UART_CLK/(UART_BAUD_RATE*16))-1)
init_serial:
ldr r0,=ULCON0
ldr r1,=0x3
str r1,[r0]
ldr r0,=UCON0
ldr r1,=0x245
str r1,[r0]
ldr r0,=UFCON0
ldr r1,=0x07
str r1,[r0]
ldr r0,=UMCON0
ldr r1,=0x0
str r1,[r0]
ldr r0,=UBRDIV0
ldr r1,=UART_BRD
str r1,[r0]
put_hello:
wait_tx_fifo:
ldr r0,=UTRSTAT0
ldr r1,[r0]
and r1,r1,#0x2
cmp r1,#0x2
bne wait_tx_fifo
wait_cts:
ldr r0,=UMSTAT0
ldr r1,[r0]
and r1,r1,#0x1
cmp r1,#0x1
bne wait_cts
ldr r0,=UTXH0
ldr r1,='H'
str r1,[r0]
//ldr r0,=UTXH0
ldr r1,='e'
str r1,[r0]
//ldr r0,=UTXH0
ldr r1,='l'
str r1,[r0]
//ldr r0,=UTXH0
ldr r1,='l'
str r1,[r0]
//ldr r0,=UTXH0
ldr r1,='o'
str r1,[r0]
ldr r1,='\n'
str r1,[r0]
mov pc,lr
setup_tags:
ldr r0,=PARAMS_ADDR
ldr r1,=TAG_PARAMS
add r2,r1,#28*4
copy_tagsval:
ldr r3,[r1],#4
str r3,[r0],#4
cmp r1,r2
bne copy_tagsval
mov pc,lr
/*内存初始化*/
#define BWSCON 0x48000000
/* BWSCON */
#define DW8 (0x0)
#define DW16 (0x1)
#define DW32 (0x2)
#define WAIT (0x1<<2)
#define UBLB (0x1<<3)
#define B1_BWSCON (DW16)
#define B2_BWSCON (DW16)
#define B3_BWSCON (DW16 + WAIT + UBLB)
#define B4_BWSCON (DW16)
#define B5_BWSCON (DW8)
#define B6_BWSCON (DW32)
#define B7_BWSCON (DW32)
/* BANK0CON */
#define B0_Tacs 0x0 /* 0clk */
#define B0_Tcos 0x0 /* 0clk */
#define B0_Tacc 0x7 /* 14clk */
#define B0_Tcoh 0x0 /* 0clk */
#define B0_Tah 0x0 /* 0clk */
#define B0_Tacp 0x0
#define B0_PMC 0x0 /* normal */
/* BANK1CON */
#define B1_Tacs 0x0 /* 0clk */
#define B1_Tcos 0x0 /* 0clk */
#define B1_Tacc 0x7 /* 14clk */
#define B1_Tcoh 0x0 /* 0clk */
#define B1_Tah 0x0 /* 0clk */
#define B1_Tacp 0x0
#define B1_PMC 0x0
#define B2_Tacs 0x0
#define B2_Tcos 0x0
#define B2_Tacc 0x7
#define B2_Tcoh 0x0
#define B2_Tah 0x0
#define B2_Tacp 0x0
#define B2_PMC 0x0
#define B3_Tacs 0x0 /* 0clk */
#define B3_Tcos 0x3 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x1 /* 1clk */
#define B3_Tah 0x0 /* 0clk */
#define B3_Tacp 0x3 /* 6clk */
#define B3_PMC 0x0 /* normal */
#define B4_Tacs 0x0 /* 0clk */
#define B4_Tcos 0x0 /* 0clk */
#define B4_Tacc 0x7 /* 14clk */
#define B4_Tcoh 0x0 /* 0clk */
#define B4_Tah 0x0 /* 0clk */
#define B4_Tacp 0x0
#define B4_PMC 0x0 /* normal */
#define B5_Tacs 0x0 /* 0clk */
#define B5_Tcos 0x0 /* 0clk */
#define B5_Tacc 0x7 /* 14clk */
#define B5_Tcoh 0x0 /* 0clk */
#define B5_Tah 0x0 /* 0clk */
#define B5_Tacp 0x0
#define B5_PMC 0x0 /* normal */
#define B6_MT 0x3 /* SDRAM */
/*#define B6_Trcd 0x1 *//* 3clk */
/*#define B6_SCAN 0x1 *//* 9bit */
/*#define B6_Trcd 0x0 *//* 2clk */
/*#define B6_SCAN 0x2 *//* 10bit */
#define B6_Trcd 0x1
#define B6_SCAN 0x1
#define B7_MT 0x3 /* SDRAM */
/*#define B7_Trcd 0x1 *//* 3clk */
/*#define B7_SCAN 0x1 *//* 9bit */
/*#define B7_Trcd 0x0 *//* 2clk */
/*#define B7_SCAN 0x2 *//* 10bit */
#define B7_Trcd 0x1
#define B7_SCAN 0x1
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
/*#define Trp 0x0 *//* 2clk */
/*#define Trc 0x3 *//* 7clk */
/*#define Tchr 0x2 *//* 3clk */
/*#define REFCNT 0x4f4 *//* period=7.8125us, HCLK=100Mhz, (2048+1-7.8125*100) */
#define Trp 0x0
#define Trc 0x3
#define Tchr 0x2
#define REFCNT 0x4f4
/**************************************/
ramctrl_config:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
ldr r0, =SMRDATA
ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #13*4
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32
.word 0x30
.word 0x30
#define ATAG_NONE 0x00000000
#define ATAG_CORE 0x54410001
#define ATAG_MEM 0x54410002
#define ATAG_CMDLINE 0x54410009
#define SIZEOF_CORE 5
#define SIZEOF_MEM 4
#define SIZEOF_CMDLINE 17
#define SIZEOF_NONE 0
TAG_PARAMS:
.word SIZEOF_CORE
.word ATAG_CORE
.word 0
.word 0
.word 0
.word SIZEOF_MEM
.word ATAG_MEM
.word 0x04000000
.word 0x30000000
.word SIZEOF_CMDLINE
.word ATAG_CMDLINE
//cmdline="noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0"
.word 0x6e696f6e
.word 0x64727469
.word 0x6f6f7220
.word 0x642f3d74
.word 0x6d2f7665
.word 0x6c626474
.word 0x326b636f
.word 0x696e6920
.word 0x6c2f3d74
.word 0x78756e69
.word 0x63206372
.word 0x6f736e6f
.word 0x743d656c
.word 0x41537974
.word 0x20203043
#if 0
.word SIZEOF_CMDLINE
.word ATAG_CMDLINE
.word 'n''o''i''n'
.word 'i''t''r''d'
.word ' ''r''o''o'
.word 't''=''/''d'
.word 'e''v''/''m'
.word 't''d''b''l'
.word 'o''c''k''2'
.word ' ''i''n''i'
.word 't''=''/''l'
.word 'i''n''u''x'
.word 'r''c'' ''c'
.word 'o''n''s''o'
.word 'l''e''=''t'
.word 't''y''S''A'
.word 'C''0'' '' '
#endif
.word SIZEOF_NONE
.word ATAG_NONE