天天看點

Linux核心---34.smdk6410平台的初始化(未完成)

1. 結構體machine_desc的定義

在arch/arm/mach-s3c64xx/mach-smdk6410.c中定義了6410的machine_desc

  1. MACHINE_START(SMDK6410, "SMDK6410")
  2.     .boot_params    = S3C64XX_PA_SDRAM + 0x100,
  3.     .init_irq    = s3c6410_init_irq,
  4.     .map_io        = smdk6410_map_io,
  5.     .init_machine    = smdk6410_machine_init,
  6.     .timer        = &s3c24xx_timer,
  7. MACHINE_END
  8. 宏MACHINE_START定義如下:
  9. #define MACHINE_START(_type,_name)            \
  10. static const struct machine_desc __mach_desc_##_type    \
  11.  __used                            \
  12.  __attribute__((__section__(".arch.info.init"))) = {    \
  13.     .nr        = MACH_TYPE_##_type,        \
  14.     .name        = _name,
  15. #define MACHINE_END                \
  16. };
  17. 把宏展開後:
  18. static const struct machine_desc __mach_desc_SMDK6410    
  19.  __used __attribute__((__section__(".arch.info.init"))) = {    
  20.     .nr        = MACH_TYPE_SMDK6410,                            //比對的nr
  21.     .name        = SMDK6410,
  22.     .boot_params    = S3C64XX_PA_SDRAM + 0x100,
  23.     .init_irq    = s3c6410_init_irq,
  24.     .map_io        = smdk6410_map_io,
  25.     .init_machine    = smdk6410_machine_init,
  26.     .timer        = &s3c24xx_timer,
  27. };
  28. 這不就是一個完整的結構體定義嘛,放在了section (arch.info.init)中

2. 尋找 結構體 machine_desc

在arch.info.init的section中定義了結構體machine_desc,那麼核心在初始化中是如何找到這個結構體的呢?

通過搜尋arch.info.init 這個section

start_kernel

    --> setup_arch(&command_line);

arch/arm/kernel/setup.c

  1. void __init setup_arch(char **cmdline_p)
  2. {    
  3.     mdesc = setup_machine_tags(machine_arch_type);            //尋找平台結構體的指針
  4.     machine_desc = mdesc;
  5.     machine_name = mdesc->name;
  6. }

start_kernel

    --> setup_arch(&command_line);

        -->  setup_machine_tags

arch/arm/kernel/setup.c

  1. static struct machine_desc * __init setup_machine_tags(unsigned int nr)
  2. {
  3.     struct machine_desc *mdesc = NULL, *p;
  4.     for_each_machine_desc(p)             //搜尋section arch.info.init
  5.         if (nr == p->nr) {               //如果nr相同說明尋找到了
  6.             mdesc = p;
  7.             break;
  8.         }
  9.      ....... 
  10.     //省略了uboot與kernel參數傳遞部分
  11.     return mdesc;    
  12. }
  13. #define for_each_machine_desc(p) \
  14.     for (p = __arch_info_begin; p < __arch_info_end; p++)

3. 第一個函數 map_io

  1. start_kernel
  2.     --> setup_arch(char **cmdline_p)
  3.         --> paging_init arch/arm/mm/mmu.c
  4. arch/arm/mm/mmu.c
  5. static void __init devicemaps_init(struct machine_desc *mdesc)
  6. {
  7.     if (mdesc->map_io)
  8.         mdesc->map_io();
  9. }

下面是一系列的調用過程

  1. arch/arm/kernel/setup.c:setup_arch[890]: next setup_machine_tags
  2. arch/arm/kernel/setup.c:setup_machine_tags[810]: Machine: SMDK6410
  3. arch/arm/mm/mmu.c:devicemaps_init[984]: next mdesc->map_io
  4. arch/arm/mach-s3c64xx/mach-smdk6410.c:smdk6410_map_io[1019]: next s3c64xx_init_io
  5. arch/arm/mach-s3c64xx/cpu.c:s3c64xx_init_io[157]: next s3c_init_cpu
  6. arch/arm/plat-samsung/init.c:s3c_init_cpu[62]: next cpu->map_io
  7. arch/arm/mach-s3c64xx/s3c6410.c:s3c6410_map_io[49]: 
  8. arch/arm/mach-s3c64xx/mach-smdk6410.c:smdk6410_map_io[1022]: next s3c24xx_init_clocks
  9. arch/arm/plat-samsung/init.c:s3c24xx_init_clocks[79]: 
  10. arch/arm/plat-samsung/init.c:s3c24xx_init_clocks[87]: 
  11. arch/arm/mach-s3c64xx/s3c6410.c:s3c6410_init_clocks[67]: next s3c64xx_register_clocks
  12. S3C24XX Clocks, Copyright 2004 Simtec Electronics
  13. camera: no parent clock specified
  14. arch/arm/mach-s3c64xx/s3c6410.c:s3c6410_init_clocks[69]: next s3c6400_setup_clocks

繼續閱讀