原创 uboot源码分析4-init_sequence函数

2013-9-6 22:22 1384 22 22 分类: MCU/ 嵌入式 文集: uboot

/*在board.c里面循环执行了一些函数,现在分析如下 有问题还望指正*/

int cpu_init (void)
{
    /*
     * 设置中断,快速中断在内存中的起始地址
     */
#ifdef CONFIG_USE_IRQ
    IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4;
    FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
#endif
    return 0;
}



int board_init (void)
{
/*
S3C24X0_CLOCK_POWER 是一个定义在include/s3c24x0.h的结构体 里面是2410 power&clock寄存器 顺序必须完全一样
typedef struct {
    S3C24X0_REG32    LOCKTIME;
    S3C24X0_REG32    MPLLCON;
    S3C24X0_REG32    UPLLCON;
    S3C24X0_REG32    CLKCON;
    S3C24X0_REG32    CLKSLOW;
    S3C24X0_REG32    CLKDIVN;
}  S3C24X0_CLOCK_POWER;
下面定义一个指针,最终这个指针的值在include/s3c24x0.h中定义,
#define S3C24X0_CLOCK_POWER_BASE    0x4C000000  根据datasheet可知这个值就是寄存器的地址   gpio等等其他都类似。
*/
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

    /* to reduce PLL lock time, adjust the LOCKTIME register */
    clk_power->LOCKTIME = 0xFFFFFF;

    /* configure MPLL */
    clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

    /* some delay between MPLL and UPLL */
    delay (4000);

    /* configure UPLL */
    clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

    /* some delay between MPLL and UPLL */
    delay (8000);

    /* set up the I/O ports */
    gpio->GPACON = 0x007FFFFF;
    gpio->GPBCON = 0x00044555;
    gpio->GPBUP = 0x000007FF;
    gpio->GPCCON = 0xAAAAAAAA;
    gpio->GPCUP = 0x0000FFFF;
    gpio->GPDCON = 0xAAAAAAAA;
    gpio->GPDUP = 0x0000FFFF;
    gpio->GPECON = 0xAAAAAAAA;
    gpio->GPEUP = 0x0000FFFF;
    gpio->GPFCON = 0x000055AA;
    gpio->GPFUP = 0x000000FF;
    gpio->GPGCON = 0xFF95FFBA;
    gpio->GPGUP = 0x0000FFFF;
    gpio->GPHCON = 0x002AFAAA;
    gpio->GPHUP = 0x000007FF;

    /* arch number of SMDK2410-Board这个ID最后通过寄存器被传递给内核 */
    gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;//这个宏在include/asm-arm/mach-type.h中定义 板子的ID

    /* adress of boot parameters 这个地址是tag结构体的起始地址,最后传递给内核*/
    gd->bd->bi_boot_params = 0x30000100;

    icache_enable();
    dcache_enable();
/*icache_enable函数是用来初始化S3C2410的缓冲区,并且启用CPU缓冲区。因为CPU在加电之后,它的初始化值是不启用内部的缓冲区的,
必须由程序进行设置。而dcache_enable则是用来使能高速缓存的,在默认情况下,如果没有进行程序配置使能的话,高速缓存无法运行,是没有意义的。*/
    return 0;
}

//就是设置寄存器 用到再具体看吧
int interrupt_init (void)
{
    S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();

    /*还是设置寄存器 和board——init一样 use PWM Timer 4 because it has no output */
    /* prescaler for Timer 4 is 16 */
    timers->TCFG0 = 0x0f00;
    if (timer_load_val == 0)
    {
        /*
         * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
         * (default) and prescaler = 16. Should be 10390
         * @33.25MHz and 15625 @ 50 MHz
         */
        timer_load_val = get_PCLK()/(2 * 16 * 100);
    }
    /* load value for 10 ms timeout */
    lastdec = timers->TCNTB4 = timer_load_val;
    /* auto load, manual update of Timer 4 */
    timers->TCON = (timers->TCON & ~0x0700000) | 0x600000;
    /* auto load, start Timer 4 */
    timers->TCON = (timers->TCON & ~0x0700000) | 0x500000;
    timestamp = 0;

    return (0);
}

//有好多个env-init  应该是这个吧  就是把环境变量的结构体存储空间的首地址给env-addr
int  env_init(void)
{
    gd->env_addr  = (ulong)&default_environment[0];
    gd->env_valid = 0;

    return (0);
}

static int init_baudrate (void)
{
    char tmp[64];    /* long enough for environment variables 之所以定义这么大一个数组 就是为了兼容性 满足比较大的环境变量调用getenv-r的时候  */
    int i = getenv_r ("baudrate", tmp, sizeof (tmp));
    gd->bd->bi_baudrate = gd->baudrate = (i > 0)//两个结构体的波特率是一样的 ,如果环境变量有波特率就使用,没有就使用CONFIG_BAUDRATE,一般在include/s3c2410.h中
            ? (int) simple_strtoul (tmp, NULL, 10)
            : CONFIG_BAUDRATE;

    return (0);
}

int serial_init (void)
{
    serial_setbrg ();//函数如下:

    return (0);
}

//串口寄存器赋值,
void serial_setbrg (void)
{
    S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);
    int i;
    unsigned int reg = 0;

    /* value is calculated so : (int)(PCLK/16./baudrate) -1 */
    reg = get_PCLK() / (16 * gd->baudrate) - 1;

    /* FIFO enable, Tx/Rx FIFO clear */
    uart->UFCON = 0x07;
    uart->UMCON = 0x0;
    /* Normal,No parity,1 stop,8 bit */
    uart->ULCON = 0x3;
    /*
     * tx=level,rx=edge,disable timeout int.,enable rx error int.,
     * normal,interrupt or polling
     */
    uart->UCON = 0x245;
    uart->UBRDIV = reg;

#ifdef CONFIG_HWFLOW
    uart->UMCON = 0x1; /* RTS up */
#endif
    for (i = 0; i < 100; i++);
}
//??????????????????????????
int console_init_f (void)
{
    gd->have_console = 1;

#ifdef CONFIG_SILENT_CONSOLE
    if (getenv("silent") != NULL)
        gd->flags |= GD_FIG_SILENT;
#endif

    return (0);
}

//输出一些东东
static int display_banner (void)
{
    printf ("\n\n%s\n\n", version_string);
    debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
           _armboot_start, _bss_start, _bss_end);
#ifdef CONFIG_MODEM_SUPPORT
    debug ("Modem Support enabled\n");
#endif
#ifdef CONFIG_USE_IRQ
    debug ("IRQ Stack: %08lx\n", IRQ_STACK_START);
    debug ("FIQ Stack: %08lx\n", FIQ_STACK_START);
#endif

    return (0);
}

int dram_init (void)
{
    gd->bd->bi_dram[0].start = PHYS_SDRAM_1;//dram首地址
    gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;//dram大小

    return 0;
}
//输出dram的地址 大小等信息
static int display_dram_config (void)
{
    int i;

#ifdef DEBUG
    puts ("RAM Configuration:\n");

    for(i=0; i         printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram.start);
        print_size (gd->bd->bi_dram.size, "\n");
    }
#else
    ulong size = 0;

    for (i=0; i         size += gd->bd->bi_dram.size;
    }
    puts("DRAM:  ");
    print_size(size, "\n");
#endif

    return (0);
};>;>

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
22
关闭 站长推荐上一条 /3 下一条