分类:
2012-07-19 17:04:51
原文地址:u-boot-1.3.2移植记录(一) 作者:I-linux
最近拿到一块LIYUTAI的44B0X的板子,所以打算自己做个BOOTLOADER,上,发现原来已经有人做得比较完善了。不用想那么多了,移植过来再说!
U-BOOT-
ELDK:
(本来是用2.95的arm-elf-gcc来编译的,但是出现的问题太多,软浮点,-MQ选项不支持等等,网上说的我全部都遇到了。看来自己的运气还是不错啊)
U-BOOT-
tar –jxf u-boot-
ELDK则需要通过虚拟光驱来安装。我是用VM来运行LINUX,所以直接用虚拟光驱load就可以了。进入光驱目录,输入
./install –d /opt/eldk/
不到五分钟就可以安装完成了。记得在/etc/profile里面加入搜索路径。
板的数据。
分析之后发现原来B2板跟ARMSYS 44B0的板最接近,就从它开始着手吧。
[root@localhost u-boot-
[root@localhost u-boot-
[root@localhost u-boot-
[root@localhost u-boot-
[root@localhost u-boot-
,增加44B0选项
打开u-boot-
44B0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s
(记着需要用用TAB代替空格!)
的配置
现在需要修改44B0的配置了。U-BOOT-
A. 修改start.s文件(参照LIYUTAI的BOOTLOADER)
#include
#include
//**********OPTIONS*******************************
//_RAM_STARTADDRESS EQU 0xc000000
#define _ISR_STARTADDRESS 0xc7ff000 //GCS6:8MB SDRAM
#define _IRQ_BASEADDRESS 0xc000000 //GCS6:8MB SDRAM
//GBLA PLLCLK
#define PLLCLK 64000000
//系统主频计算公式如下:
//Fout = (8+ M_DIV)*Fin/[(2+P_DIV)*2]
#define M_DIV 56 //Fin=8MHz Fout = ((56+8)/8)*8 =64MHz
#define P_DIV 2
#define S_DIV 1
/*
* Jump vector table
*/
.globl _start
_start:
b reset // Reset
ldr pc, =(_IRQ_BASEADDRESS + 0x04) // HandlerUndef
ldr pc, =(_IRQ_BASEADDRESS + 0x08) // HandlerSWI
ldr pc, =(_IRQ_BASEADDRESS + 0x
ldr pc, =(_IRQ_BASEADDRESS + 0x10) // HandlerDAbort
ldr pc, =(_IRQ_BASEADDRESS + 0x14) // HandlerReserved
ldr pc, =(_IRQ_BASEADDRESS + 0x18) // HandlerIRQ
ldr pc, =(_IRQ_BASEADDRESS + 0x
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* relocate u-boot to ram
* setup stack
* jump to second stage
*
*************************************************************************
*/
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
/*
* the actual reset code
*/
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x
orr r0,r0,#0x13
msr cpsr,r0
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
bl lowlevel_init
#endif
/**
* test the memory befor relocate
*/
#ifdef CONFIG_MEM_TEST
#define PDATE 0x1d
ldr r0, =PHYS_SDRAM_1 //地址指针
ldr r1, =PHYS_SDRAM_1_SIZE //地址边界
add r1,r0,r1 //r1 is the bound
ldr r3,=0xAA55AA44
loop:
str r3,[r0] //保存数据到内存
ldr r4,[r0] //重新读取数据
cmp r4,r3 //比较数据
bne error
add r0,r0,#4 //指向下一个指针
cmp r0,r1 //判断是否到达边界
beq mem_test_ok
bne loop
error:
ldr r0,=PDATE //PDATE=PDATE&0x
ldr r1,[r0]
ldr r2,=0x
and r1,r1,r2
str r1,[r0]
bl delay //Beep
ldr r1,[r0] //PDATE=PDATE|0x8;
mov r2,#0x8
orr r1,r1,r2
str r1,[r0]
bl delay //stop Beep
end:
b end //stop
delay:
ldr r3,=0xFFFF
e_loop1:
sub r3,r3,#1
cmp r3,#0
beq loop_end
ldr r4,=0xFF
e_loop2:
sub r4,r4,#1
cmp r4,#0
bne e_loop2
b e_loop1
loop_end:
mov pc,lr
mem_test_ok:
#endif
#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
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
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
/*
now copy to sram the interrupt vector
*/
adr r0, real_vectors
add r2, r0, #1024
ldr r1, =0x
add r1, r1, #0x08
vector_copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble vector_copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
ldr r0, _bss_start /* BSS段的起始地址 */
ldr r1, _bss_end /* BSS段的结束地址 */
mov r2, #0x00000000 /* BSS段置0 */
clbss_l:
str r2, [r0] /* 循环清除BSS段 */
add r0, r0, #4
cmp r0, r1
ble clbss_l
ldr pc, _start_armboot
_start_armboot: .word start_armboot
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
#define INTCON (0x
#define INTMSK (0x
#define LOCKTIME (0x
#define PLLCON (0x
#define CLKCON (0x
#define WTCON (0x
cpu_init_crit:
/* disable watch dog */
ldr r0, =WTCON
ldr r1, =0x0
str r1, [r0]
/*
* mask all IRQs by clearing all bits in the INTMRs
*/
ldr r1,=INTMSK
ldr r0, =0x07fffeff
str r0, [r1]
ldr r1, =INTCON
ldr r0, =0x05
str r0, [r1]
/* Set Clock Control Register */
ldr r0,=LOCKTIME
ldr r1,=0xfff
str r1,[r0]
ldr r1, =PLLCON
#if CONFIG_S
ldr r0, =0x34031 /* 66MHz (Quartz=11MHz) */
#elif CONFIG_S
ldr r0, =0x
#elif CONFIG_S
ldr r0, =0x38021 //Fin=8MHz,Fout=64MHz
#else
# error CONFIG_S
#endif
str r0, [r1]
ldr r1,=CLKCON
ldr r0, =0x7ff8
str r0, [r1]
mov pc, lr
/*************************************************/
/* interrupt vectors */
/*************************************************/
real_vectors:
b reset
b undefined_instruction
b software_interrupt
b prefetch_abort
b data_abort
b not_used
b irq
b fiq
/*************************************************/
undefined_instruction:
mov r6, #3
b reset
software_interrupt:
mov r6, #4
b reset
prefetch_abort:
mov r6, #5
b reset
data_abort:
mov r6, #6
b reset
not_used:
/* we *should* never reach this */
mov r6, #7
b reset
irq:
mov r6, #8
b reset
fiq:
mov r6, #9
b reset
B. 修改serial.c,修改serial_setbrg。函数由于板上的波特率使用64MHz,所以需要增加相应的波特率配置
void serial_setbrg (void)
{
u32 divisor = 0;
/* get correct divisor */
switch(gd->baudrate) {
case 1200:
#if CONFIG_S
divisor = 3124;
#elif CONFIG_S
divisor = 3905;
#elif CONFIG_S
divisor = 3124;
#else
# error CONFIG_S
#endif
break;
case 9600:
#if CONFIG_S
divisor = 390;
#elif CONFIG_S
divisor = 487;
#elif CONFIG_S
divisor = 390;
#else
# error CONFIG_S
#endif
break;
case 19200:
#if CONFIG_S
divisor = 194;
#elif CONFIG_S
divisor = 243;
#elif CONFIG_S
divisor = 194;
#else
# error CONFIG_S
#endif
break;
case 38400:
#if CONFIG_S
divisor = 97;
#elif CONFIG_S
divisor = 121;
#elif CONFIG_S
divisor = 97;
#else
# error CONFIG_S
#endif /* break; */
case 57600:
#if CONFIG_S
divisor = 64;
#elif CONFIG_S
divisor = 80;
#elif CONFIG_S
divisor = 68;
#else
# error CONFIG_S
#endif /* break; */
case 115200:
#if CONFIG_S
divisor = 32;
#elif CONFIG_S
divisor = 40;
#elif CONFIG_S
divisor = 34;
#else
# error CONFIG_S
#endif /* break; */
}
serial_flush_output();
serial_flush_input();
UFCON0 = 0x0;
ULCON0 = 0x03;
UCON0 = 0x245;
UBRDIV0 = divisor;
UFCON1 = 0x0;
ULCON1 = 0x03;
UCON1 = 0x245;
UBRDIV1 = divisor;
for(divisor=0; divisor<100; divisor++) {
/* NOP */
}
}
至此,CPU配置完成。下一步,修改电路板配置。