文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>boot loader启动c程序分析

boot loader启动c程序分析

时间:2009-08-08  来源:lixuan216

本文还是以u-boot-1.1.4为例,以make smdk2410_config命令配置源代码之后进行分析。 对于C语言部分代码的调用出现在cpu/arm920t/start.S的第223行: [code]         ldr pc, _start_armboot   _start_armboot: .word start_armboot [/code] 这里的start_armboot就是lib_arm/board.c中第207行的start_armboot()函数,由此U-Boot开始执行C语言部分的代码。 start_armboot()函数一开始首先是一个宏调用: [code] DECLARE_GLOBAL_DATA_PTR; [/code] 这个宏的定义在include/asm-arm/global_data.h文件的第64行: [code] #define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8") [/code] 大概的意思是声明一个指向gd_t结构体变量的指针gd,并固定使用寄存器r8来存放该指针。而对gd_t结构体的定义从上面的第36行开始: [code] typedef struct global_data {
    bd_t  *bd;
    unsigned long flags;
    unsigned long baudrate;
    unsigned long have_console; /* serial_init() was called */
    unsigned long reloc_off; /* Relocation Offset */
    unsigned long env_addr; /* Address  of Environment struct */
    unsigned long env_valid; /* Checksum of Environment valid? */
    unsigned long fb_base; /* base address of frame buffer */
#ifdef CONFIG_VFD
    unsigned char vfd_type; /* display type */
#endif
#if 0
    unsigned long cpu_clk; /* CPU clock in Hz!  */
    unsigned long bus_clk;
    unsigned long ram_size; /* RAM size */
    unsigned long reset_status; /* reset status register at boot */
#endif
    void  **jt;  /* jump table */
} gd_t;
[/code] 在lib_arm/board.c文件中之所以能够直接使用这个宏和gd_t结构体是因为包含了include/common.h头文件,在common.h的第115行包含了include/asm-arm/global_data.h头文件。 继续来看start_armboot()函数的执行。lib_arm/board.c第229行开始的一个for循环: [code] for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
    if ((*init_fnc_ptr)() != 0) {
        hang ();
    }
} [/code] 这里的init_sequence是定义在上面第190行处的一个指针数组: [code] init_fnc_t *init_sequence[] = {
    cpu_init,  /* basic cpu dependent setup */
    board_init,  /* basic board dependent setup */
    interrupt_init,  /* set up exceptions */
    env_init,  /* initialize environment */
    init_baudrate,  /* initialze baudrate settings */
    serial_init,  /* serial communications setup */
    console_init_f,  /* stage 1 init of console */
    display_banner,  /* say that we are here */
    dram_init,  /* configure available RAM banks */
    display_dram_config,
#if defined(CONFIG_VCMA9) || defined (CONFIG_CMC_PU2)
    checkboard,
#endif
    NULL,
};
[/code] 数组类型init_fnc_t则是一个定义在第188行的函数指针类型: [code] typedef int (init_fnc_t) (void); [/code] 由此可知,init_sequence[]数组当中的所有元素都是函数指针了,而这个for循环的作用就是遍历这个数组的所有元素,然后用“(*init_fnc_ptr)()”就依次调用了这些函数来进行初始化的工作。
我们依次来看看init_sequence[]数组当中的各个元素。   首先是cpu_init()函数,定义于lib_arm/arm920t/cpu.c第88行。   接下来的board_init()函数定义于board/smdk2410/smdk2410.c第68行:

int board_init (void)
{
    DECLARE_GLOBAL_DATA_PTR;
    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 */
    gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

    /* adress of boot parameters */
    gd->bd->bi_boot_params = 0x30000100;

    icache_enable();
    dcache_enable();

    return 0;
}

interrupt_init()函数定义于cpu/arm920t/s3c24x0/interrupts.c第55行:

int interrupt_init (void)
{
    S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();

    /* 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);
}

排行榜 更多 +
动物大战僵尸I

动物大战僵尸I

飞行射击 下载
龙兽争霸无限零件图纸

龙兽争霸无限零件图纸

飞行射击 下载
金属战士2最新版

金属战士2最新版

飞行射击 下载