Chinaunix首页 | 论坛 | 博客
  • 博客访问: 22791
  • 博文数量: 7
  • 博客积分: 350
  • 博客等级: 一等列兵
  • 技术积分: 75
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-23 12:17
文章分类

全部博文(7)

文章存档

2011年(1)

2010年(5)

2009年(1)

我的朋友
最近访客

分类: 嵌入式

2010-04-12 10:11:32

2440的初始化流程

(不知道2440中为什么会调用mach-smdk2410.c中的函数,而不调用mach-smdk2440.c中的,请知道的告知一声) 

1、在mach-smdk2410.c中通过MACHINE_STARTMACHINE_END

/*#define MACHINE_START(_type,_name)     \
static const struct machine_desc __mach_desc_##_type \
 __attribute_used__        \
 __attribute__((__section__(".arch.info.init"))) = { \
 .nr     = MACH_TYPE_##_type,     \
 .name   = _name,

#define MACHINE_END       \
};*///

定义了一个结构体。

此结构体定义了machine_desc的变量,其中注册了smdk2410_map_io(), s3c2410_init_irq(), smdk2410_init()3个回调函数. 3个回调函数会在系统起来的时候setup_arch()里面逐个调用来进行虚实地址映射, 中断初始化, clock初始化,片上设备的注册等操作.

/*向系统注册一个machine_desc的对象*/

MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch

                  * to SMDK2410 */

     MAINTAINER("Jonas Dietsche")

     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)

     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)

     MAPIO(smdk2410_map_io)

     INITIRQ(smdk2410_init_irq)

    .timer     = &s3c24xx_timer,

MACHINE_END 

2 smdk2410_map_io()   用来静态remap物理地址和虚拟地址, 初始化clockuart, 调用顺序为: arch/arm/kernel/ setup.c: Setup_arch()->paging_init()->devicemaps_init()->mdesc->map_io()->smdk2410_map_io().

static void __init smdk2410_map_io(void)

{

    s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));

//初始化了cpu id 确定了在cpu.c中是调用s3c241.c 还是s3c2440.c中定义的相关初始化函数

    s3c24xx_init_clocks(0);

    s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));

    s3c24xx_set_board(&smdk2410_board);

}

1) 首先调用s3c24xx_init_io()->s3c2410_map_io()来映射虚实地址, 最终映射好的虚实地址为 (s3c2410_iodesc[])

S3C24XX_VA_CLKPWR  --> __phys_to_pfn(S3C24XX_PA_CLKPWR), size S3C24XX_SZ_CLKPWR

S3C24XX_VA_LCD  --> __phys_to_pfn(S3C24XX_PA_LCD), size S3C24XX_SZ_LCD

S3C24XX_VA_TIMER  --> __phys_to_pfn(S3C24XX_PA_ TIMER), size S3C24XX_SZ_ TIMER

S3C24XX_VA_WATCHDOG  --> __phys_to_pfn(S3C24XX_PA_ WATCHDOG), size S3C24XX_SZ_ WATCHDOG

如果我们要加入我们自己的映射,只要在smdk2410_iodesc[]添加就行了, 以后如果某个资源没有映射也可以在相应的驱动种用ioremap()来动态映射

2) s3c24xx_init_clocks()->s3c2410_init_clocks()来初始化clock:

时钟资源添加入系统后, 每个驱动在初始化时会到这个list中去着属于自己的clock并打开它.

3) 调用s3c24xx_init_uarts()->s3c2410_init_uarts()->s3c24xx_init_uartdevs()

4) 最后调用s3c24xx_set_board(), 这个函数相对简单, 它查看smdk2410_board下有没有clock资源,有的话也添加到clocks list中去

 3 s3c2410_init_irq()   用来初始化irq,  调用顺序为: arch/arm/kernel/ setup.c  :   setup_arch():init_arch_irq = mdesc->init_irq()  -> init_IRQ()->init_arch_irq()->s3c24xx_init_irq().

4 smdk2410_init():  调用顺序为: arch/arm/kernel/ setup.c   

setup_arch():init_machine = mdesc-> init_machine () -> customize_machine() -> init_machine()->smdk_machine_init ()

void __init smdk_machine_init(void)

{

    /* Configure the LEDs (even if we have no LED support)*/

    s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);

    s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);

    s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);

    s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);

        /*设置默认的GPIO*/

    s3c2410_gpio_setpin(S3C2410_GPF4, 1);

    s3c2410_gpio_setpin(S3C2410_GPF5, 1);

    s3c2410_gpio_setpin(S3C2410_GPF6, 1);

    s3c2410_gpio_setpin(S3C2410_GPF7, 1);

     /*初始化nand设备信息, 在驱动里的probe中会用到*/

    s3c_device_nand.dev.platform_data = &smdk_nand_info; 

 /*

* 把设备添加进系统里去,这样以后相应的驱动注册后就可以匹配到相关设备, 以后我们要添加什

* 么设备也可以添加到smdk_devs 数组中, smdk_devs 下的每个设备都静态定义好了它自己的所有

* 资源,包括寄存器地址, 中断号等, 在驱动probe到后就可以使用这些资源来操作这个设备了

*/

    platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs)); 

   s3c2410_pm_init();/*电源管理方面的初始化*/

}

 

 

 

阅读(1378) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~