url : git@github.com:lisider/u-boot.git
branch : ok6410a
commit id : e63a4077ad3aea53107495b0b68b95e720fe6033
config : ok6410a_mini_defconfig
reset arch/arm/cpu/arm1176/start.S 39
lowlevel_init(108) board/samsung/ok6410a/lowlevel_init.S 72
_main(110) arch/arm/lib/crt0.S 91
board_init_f(117) board/samsung/ok6410a/ok6410a.c 266
debug_uart_init(271) include/debug_uart.h 193
_debug_uart_init(196) drivers/serial/s3c64xx_serial.c 315
board_init_r(177) common/spl/spl.c 589
spl_board_init(641) board/samsung/ok6410a/ok6410a.c 255
spl_boot_mmc(258) board/samsung/ok6410a/bl2_mmc_copy.c 18
mmc_bl2_copy(23) board/samsung/ok6410a/bl2_mmc_copy.c 7
CopyMovitoMem(HSMMC_CHANNEL, MOVI_BL2_POS, MOVI_BL2_BLKCNT, bl2_base, MOVI_INIT_REQUIRED)(13) arch/arm/mach-s3c64xx/include/mach/movi.h 25
bl2base(24)
reset
save_boot_params
mrs r0, cpsr
bic r0, r0, #0x3f
orr r0, r0, #0xd3
msr cpsr, r0
lowlevel_init
spl_config_uart_baudrate
ulong val = spl_uart_getclk(is_mpll) / 115200;
_UBRDIV = val / 16 - 1;
_UDIVSLOT = udivslot[val % 16];
mem_ctrl_asm_init
_main
board_init_f_alloc_reserve
board_init_f_init_reserve
board_init_f
debug_uart_init
board_debug_uart_init
_debug_uart_init
struct s3c64xx_uart *uart = (struct s3c64xx_uart *)0x7F005000;
s3c64xx_serial_init(uart);
uart->UFCON = 0;
uart->UMCON = 0;
uart->ULCON = 3;
uart->UCON =0xa45;
s3c64xx_serial_baud(uart, get_uart_clk(0), 115200);
val = (uclk / baudrate) % 16;
uart->UBRDIV = uclk / baudrate / 16 - 1;
uart->UDIVSLOT = udivslot[val];
for (val = 0; val < 100; val++)
__asm__ __volatile__("": : :"memory");
CLEAR_BSS
ldr r0, =__bss_start
ldr r3, =__bss_end
mov r1, #0x00000000
subs r2, r3, r0
bl memset
spl_relocate_stack_gd
board_init_r
spl_set_bd
spl_init
timer_init
spl_board_init
spl_boot_mmc
ulong bl2base=0x5FB00000;
mmc_bl2_copy
writel(readl(HM_CONTROL4) | (0x3 << 16), HM_CONTROL4);
ret = CopyMovitoMem(HSMMC_CHANNEL, MOVI_BL2_POS, MOVI_BL2_BLKCNT, bl2_base, MOVI_INIT_REQUIRED);
bl2base
可以看出来 spl 的流程
1. 上电
2. 设置 cpsr
3. 调用 lowlevel_init 初始化clock和uart和ddr和中断和gpio
4. 调用_main
4.1 整理ddr的内存布局
.code .bss .data .rodata 在iram
.heap .stack 在 ddr
4.2 重新初始化uart
4.3 清BSS (与4.1为一体)
4.4 填充gd
为填充板子数据做准备
为malloc做准备
初始化timer,为delay做准备
4.5 直接 调用 i-tcm 的函数拷贝 u-boot 到 ddr , 并跳转到 u-boot
A. 初始化但是没有用到的东西
uart 与 timer 与 中断 与 gpio
.heap
gd与已经初始化的gd成员
mov r12, lr
ldr r0, =0x7f008000
ldr r1, =0x55555555
str r1, [r0, #0x800]
ldr r1, =0x55555555
str r1, [r0, #0x804]
ldr r1, =0x22222666
str r1, [r0, #0x810]
mov r0, #0
bl lcd_backlight_switch
ldr r0, =0x7f008000
ldr r1, =0x00111111
str r1, [r0, #0x820]
ldr r1, =0x00000555
str r1, [r0, #0x828]
ldr r1, =0x002a
str r1, [r0, #0x824]
ldr r1, =0
str r1, [r0, #0x1D4]
ldr r0, =0x7e000000 @0x7e004000
orr r0, r0, #0x4000
mov r1, #0
str r1, [r0]
ldr r0, =(0x7f008000 +0x924)
ldr r1, [r0]
str r1, [r0]
ldr r0, =(0x71200000) @0x71200000
ldr r1, =(0x71300000) @0x71300000
mvn r3, #0x0
str r3, [r0, #(0x14)]
str r3, [r1, #(0x14)]
mov r3, #0x0
str r3, [r0, #(0x0C)]
str r3, [r1, #(0x0C)]
mov r3, #0x0
str r3, [r0, #(0xF00)]
str r3, [r1, #(0xF00)]
# 141 "../board/samsung/ok6410a/lowlevel_init.S"
ldr r0, =0x7e00f000
ldr r1, [r0, #0x1C]
orr r1, r1, #0x2000
str r1, [r0, #0x1C]
mov r0, # 1
bl spl_config_uart_baudrate
bl uart_asm_init
mov r0, #0x4F @'O'
bl asm_putc
mov r0, #0x4B @'K'
bl asm_putc
# 184 "../board/samsung/ok6410a/lowlevel_init.S"
mov r0, #0x2B @'+'
bl asm_putc
ldr r0, =0x7e00f120
mov r1, #0x0D
str r1, [r0]
mov r0, #0x2B @'+'
bl asm_putc
bl mem_ctrl_asm_init
mov r0, #0x2D @'-'
bl asm_putc
mov r0, #0x2D @'-'
bl asm_putc
ldr r0, =(0x7e00f000 + 0x904)
ldr r1, [r0]
bic r1, r1, #0xfffffff7
cmp r1, #0x8
beq wakeup_reset
1:
mov lr, r12
mov pc, lr
.globl mem_ctrl_asm_init
mem_ctrl_asm_init:
ldr r0, =0x7e001000
ldr r1, =0x4
str r1, [r0, #(0x04)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 7800) - 1) / 1000000)
str r1, [r0, #(0x10)]
ldr r1, =(3<<1)
str r1, [r0, #(0x14)]
ldr r1, =1
str r1, [r0, #(0x18)]
ldr r1, =2
str r1, [r0, #(0x1C)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 45) - 1) / 1000000 + 1)
str r1, [r0, #(0x20)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 68) - 1) / 1000000 + 1)
str r1, [r0, #(0x24)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 23) - 1) / 1000000 + 1)
ldr r2, =(((((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 23) - 1) / 1000000 + 1) - 3) << 3)
orr r1, r1, r2
str r1, [r0, #(0x28)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 80) - 1) / 1000000 + 1)
ldr r2, =(((((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 80) - 1) / 1000000 + 1) - 3) << 5)
orr r1, r1, r2
str r1, [r0, #(0x2C)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 23) - 1) / 1000000 + 1)
ldr r2, =(((((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 23) - 1) / 1000000 + 1) - 3) << 3)
orr r1, r1, r2
str r1, [r0, #(0x30)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 15) - 1) / 1000000 + 1)
str r1, [r0, #(0x34)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 15) - 1) / 1000000 + 1)
str r1, [r0, #(0x38)]
ldr r1, =2
str r1, [r0, #(0x3C)]
ldr r1, =2
str r1, [r0, #(0x40)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 120) - 1) / 1000000 + 1)
str r1, [r0, #(0x44)]
ldr r1, =(((((12000000/(3<<1)*266)/(1 +1)/(1 +1)) / 1000 * 120) - 1) / 1000000 + 1)
str r1, [r0, #(0x48)]
ldr r1, =0x0001001a
str r1, [r0, #(0x0C)]
ldr r1, =0xB45
str r1, [r0, #(0x4C)]
ldr r1, =0x150F0
str r1, [r0, #(0x200)]
ldr r1, =0x0
str r1, [r0, #(0x304)]
ldr r1, =0x0c0000
str r1, [r0, #(0x08)]
ldr r1, =0x000000
str r1, [r0, #(0x08)]
ldr r1, =0x040000
str r1, [r0, #(0x08)]
str r1, [r0, #(0x08)]
ldr r1, =0x0a0000
str r1, [r0, #(0x08)]
ldr r1, =0x080032
str r1, [r0, #(0x08)]
mov r1, #0x0
str r1, [r0, #(0x04)]
check_dmc1_ready:
ldr r1, [r0, #(0x00)]
mov r2, #0x3
and r1, r1, r2
cmp r1, #0x1
bne check_dmc1_ready
nop
mov pc, lr
gd_t
arch
lastinc
timer_reset_value
timer_rate_hz
struct bd_info *bd;
unsigned long flags;
unsigned int baudrate;
unsigned long cpu_clk;
unsigned long bus_clk;
unsigned long pci_clk;
unsigned long mem_clk;
unsigned long fb_base;
unsigned long malloc_limit;
unsigned long malloc_ptr;
typedef struct {
S3C64XX_REG32 TCFG0;
S3C64XX_REG32 TCFG1;
S3C64XX_REG32 TCON;
S3C64XX_TIMER ch[4];
S3C64XX_REG32 TCNTB4;
S3C64XX_REG32 TCNTO4;
} S3C64XX_TIMERS;
lib/time.c 中 有 __weak 声明的
函数(get_ticks get_timer timer_init)
arm/mach-s3c64xx/timer.c
实现(get_ticks get_timer timer_init 和 get_tbclk)
提供给lib/time.c 如下函数 : get_tbclk get_ticks
提供给common/spl/spl.c 如下函数 : timer_init
目的是在 spl/lib/time.c 中 提供 delay/udelay 函数
使用者
命令中的 reset
drivers/serial/serial.c 中的 U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
用于 assert fail 和 panic