Chinaunix首页 | 论坛 | 博客
  • 博客访问: 633495
  • 博文数量: 75
  • 博客积分: 7001
  • 博客等级: 少将
  • 技术积分: 1465
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-11 17:39
文章分类

全部博文(75)

文章存档

2010年(1)

2009年(25)

2008年(49)

我的朋友

分类: LINUX

2008-07-03 23:36:18

What is the struct map_desc?
 author:edwin @

Struct map_desc provided by kernel is used to describe information of board-level(machine)IO mapping.
 --- quoted from Jollen's "struct map_desc 與抽象化程式碼小談" at http://www.jollen.org/blog/2007/05/struct_map_desc.html
call procedure:
start_kernel()->void __init setup_arch(char **cmdline_p)->paging_init(&meminfo, mdesc);
->devicemaps_init(mdesc);-->/* Ask the machine support to map in the statically
                             * mapped devices.*/
                          if (mdesc->map_io)
                              mdesc->map_io();
----------------------------------------------------------------------------------------------------
Let's look at the definition of struct mdesc:
struct machine_desc {
 /*
  * Note! The first four elements are used
  * by assembler code in head-armv.S
  */
 unsigned int  nr;  /* architecture number */
 unsigned int  phys_io; /* start of physical io */
 unsigned int  io_pg_offst; /* byte offset for io
       * page tabe entry */
 const char  *name;  /* architecture name */
 unsigned long  boot_params; /* tagged list  */
 unsigned int  video_start; /* start of video RAM */
 unsigned int  video_end; /* end of video RAM */
 unsigned int  reserve_lp0 :1; /* never has lp0 */
 unsigned int  reserve_lp1 :1; /* never has lp1 */
 unsigned int  reserve_lp2 :1; /* never has lp2 */
 unsigned int  soft_reboot :1; /* soft reboot  */
 void   (*fixup)(struct machine_desc *,
      struct tag *, char **,
      struct meminfo *);
 void   (*map_io)(void);/* IO mapping function */  -----------> here is the staff of map_io(), then where is the struct mdesc initialized?
 void   (*init_irq)(void);
 struct sys_timer *timer;  /* system tick timer */
 void   (*init_machine)(void);
};
----------------------------------------------------------------------------------------------------

Where is the struct mdesc initialized?
 
From the stat above, the assignment of struct mdesc is obtained by executing setup_arch() function.
Let's peek over setup_arch() function:
void __init setup_arch(char **cmdline_p)
{
 struct tag *tags = (struct tag *)&init_tags;
 struct machine_desc *mdesc;
 char *from = default_command_line;
 init_tags.mem.start = PHYS_OFFSET;
 setup_processor();
 mdesc = setup_machine(machine_arch_type);-------------------> here, we arrive the assignment of variable mdesc!!!
 machine_name = mdesc->name;
 ................................
 ................................
}
 
 
What does setup_machine() function do?
 
 
Let delve into how mdesc is obtained.
static struct machine_desc * __init setup_machine(unsigned int nr)
{
 struct machine_desc *list;
 /*
  * locate machine in the list of supported machines.
  */
 list = lookup_machine_type(nr);
 if (!list) {
  printk("Machine configuration botched (nr %d), unable "
         "to continue.\n", nr);
  while (1);
 }
 printk("Machine: %s\n", list->name);
 return list;
}
 
 
lookup_machine_type() funciton defined in head_common.S is invoked by setup_machine(), which will look up space between
__arch_info_begin and __arch_info_end defined in arch/arm/kernel/vmlinux.lds to match corresponding machine in terms of machine ID
and  return mdesc struct.
The how is the machine related data stored in this space?
From arch/arm/kernel/vmlinux.lds,
  __arch_info_begin = .;
   *(.arch.info.init)
  __arch_info_end = .;
we can know that compiled code with atrribution of (.arch.info.init) will be loaded to this space.
 
 
/*
 * Set of macros to define architecture features.  This is built into
 * a table by the linker.
 */
#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    \
};

The macro MACHINE_START is used to define struct machine_desc, and make it with attribution of (.arch.info.init).
Under the arch/arm/mach-evb3504 directory, macro MACHINE_START is called in the following style:
MACHINE_START(EVB3504, "ARM EVB3504")
 .phys_io = 0x40000000,
 .boot_params = 0x60000100,
 .map_io  = evb3504_map_io,
 .init_irq = evb3504_init_irq,
 .timer  = &evb3504_timer,
 .init_machine = evb3504_init,
MACHINE_END
which can be unwraped as follows:
static const struct machine_desc __mach_desc_EVB3504 \
 __attribute_used__     \
 __attribute__((__section__(".arch.info.init"))) = { \
 .nr  = MACH_TYPE_EVB3504,  \
 .name  = "ARM EVB3504"),
 .phys_io = 0x40000000,
 .boot_params = 0x60000100,
 .map_io  = evb3504_map_io,  ------------------> Eventually, we find out it is evb3504_map_io() function assigned to mdesc->map_io !!!
 .init_irq = evb3504_init_irq,
 .timer  = &evb3504_timer,
 .init_machine = evb3504_init,
    \
};
 
 
 
What does evb3504_map_io() function do ?
To be continued.
 
 

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