What is the struct map_desc?
author:edwin @
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.
阅读(2056) | 评论(0) | 转发(0) |