最近在看uboot的源码,做些笔记。
lowlevel_init.S (board\samsung\smdk6410)这个文件主要是与板级配置相关的代码,看他在那个目录就知道了。不多说了,开始看源码。
1、
#include
#include
#include
#include "smdk6410_val.h"
_TEXT_BASE:
.word TEXT_BASE
.globl lowlevel_init
lowlevel_init:
mov r12, lr 保存PC的值
ldr r0, =ELFIN_GPIO_BASE
ldr r1, =0x55555555
str r1, [r0, #GPKCON0_OFFSET]
ldr r1, =0x55555555
str r1, [r0, #GPKCON1_OFFSET]
ldr r1, =0x22222666
str r1, [r0, #GPLCON0_OFFSET]
ldr r1, =0x04000000
str r1, [r0, #GPFCON_OFFSET]
ldr r1, =0x2000
str r1, [r0, #GPFDAT_OFFSET]
上面这一段,是根据具体的开发板添加的,如飞凌的就与外设扩展的接口键盘和WIFI接口有关。
/* LED on only #8 */ 对驱动LED的GPIO进行一定的初始化
ldr r0, =ELFIN_GPIO_BASE
ldr r1, =0x00111111
str r1, [r0, #GPMCON_OFFSET]
ldr r1, =0x00000555
str r1, [r0, #GPMPUD_OFFSET]
ldr r1, =0x002a
str r1, [r0, #GPMDAT_OFFSET]
下面这个这个和MEM1DRVCON寄存器有关,Memory Port 1 Drive strength Control Register,主要是关于Memory port 1驱动电流的选择。
ldr r1, =0 /*0x55555555 phantom*/
str r1, [r0, #MEM1DRVCON_OFFSET]
看下面这个图:


/* Disable Watchdog */
ldr r0, =0x7e000000@0x7e004000
orr r0, r0, #0x4000
mov r1, #0
str r1, [r0]
上面这一段是关闭看门狗,如果你仔细看start.s的源码,会发现同样有一段代码说是关闭看门狗,但那个就看不懂了,我也列出来做个对比,如果你知道,可以告诉我。
start.S (cpu\s3c64xx)
#if defined(CONFIG_S3C6410) || defined(CONFIG_S3C6430)
orr r0, r0, #300@ disable watchdog
mov r1, #1
str r1, [r0]
@ External interrupt pending clear 外部中断挂起寄存器清零,先读出寄存器的值,如后回写就可以了。因为这个寄存器是写1,清零,看下这个寄存器NOTES,就可知道。 NOTES: 1. Each bit is cleared by writing "1"
ldrr0, =(ELFIN_GPIO_BASE+EINTPEND_OFFSET)/*EINTPEND*/
ldrr1, [r0]
strr1, [r0]
ldrr0, =ELFIN_VIC0_BASE_ADDR @0x71200000
ldrr1, =ELFIN_VIC1_BASE_ADDR @0x71300000
Base address of VIC0 is 0x7120_0000
Base address of VIC1 is 0x7130_0000
Address of control register = base address + offset
@ Disable all interrupts (VIC0 and VIC1)
mvnr3, #0x0 这里说下这个mvn指令,它与mov的不同之处在于,先把源操作寄存器的内容取反,再送到目的寄存器
strr3, [r0, #oINTMSK]
strr3, [r1, #oINTMSK]
@ Set all interrupts as IRQ
movr3, #0x0
strr3, [r0, #oINTMOD]
strr3, [r1, #oINTMOD]
@ Pending Interrupt Clear
movr3, #0x0
strr3, [r0, #oVECTADDR]
strr3, [r1, #oVECTADDR]
2、
/* init system clock */
bl system_clock_init
去看system_clock_init的源码,在同一个文件中,如下所示:
s3c6410手册中,与时钟有关的部分主要在 第三章 SYSTEM CONTROLLER中,摘自文中的一段话:
The System Clock Control logic in 6410 generates the required system clock signals, ARMCLK for CPU, HCLK for AXI/AHB-bus peripherals, and PCLK for the APB bus peripherals. There are three PLLs in 6410. One is for ARMCLK only. Second is for HCLK and PCLK. The third thing is for peripheral, especially for audio related clocks.The clock control logic generates slow-rate clock-signals for ARMCLK, HCLK and PCLK by bypassing externally supplied clock sources. The clock signal to each peripheral block can be enabled or disabled by software control to reduce the power consumption.
/*
* system_clock_init: Initialize core clock and bus clock.
* void system_clock_init(void)
*/
system_clock_init:
ldr r0, =ELFIN_CLOCK_POWER_BASE @0x7e00f000
这个地址是APLL_LOCK寄存器的地址,作为基地址
下面这段代码都是和时钟有关,在此之前先来说下ASYNC MODE和SYNC MODE的去别,看下面:
S3C6410 has APLL and MPLL, so you can use that MPLL is source for HCLK, PCLK, etc.(ASYNC mode).
In default configuration setting is SYNC mode APLL support main clock for FCLK, HCLK, PCLK, etc. If
you want to use ASYNC mode, you have to disabling definition for SMDK6410 SYNC mode selection
in “include/configs/smdk6410.h”
#define CONFIG_SYNC_MODE
应该大致明白了吧,同时在Smdk6410.h (include\configs)文件中,有如下定义,
#if defined(CONFIG_CLK_666_