machine_desc结构体
内核提供了一个重要的结构体struct machine_desc ,这个结构体在内核移植和系统启动过程中起到相当重要的作用, 内核通过machine_desc结构体来控制系统体系架构相关部分的初始化。
该结构体的定义和声明在arch/arm/include/asm/mach/arch.h 目录中,如下:
struct machine_desc {
/*
* Note! The first four elements are used
* by assembler code in head.S, head-common.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 */
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
};
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__used \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
而该结构体的使用在各个平台结构下的mach-xxx.c中使用,如x210的\arch\arm\mach-s5pv210\mach-x210.c 中:
其中,.map_io成员是静态映射的关键接口。
函数分析
函数调用关系如下:
start_kernel
setup_arch
mdesc = setup_machine(machine_arch_type);
paging_init(mdesc);
devicemaps_init
mdesc->map_io();//最终调用smdkc110_map_io
smdkc110_map_io分析:
smdkc110_map_io();
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
/*
* Create the architecture specific mappings
*/
void __init iotable_init(struct map_desc *io_desc, int nr)
{
int i;
for (i = 0; i < nr; i++)
create_mapping(io_desc + i);
}
从上面的函数调用分析可知,最终调用create_mapping接口,使用map_desc 类型的一个结构体进行后续映射工作的材料。而该结构体的实体就是调用iotable_init时的传参 s5p_iodesc。
map_desc 结构体
map_desc 类型定义如下:
struct map_desc {
unsigned long virtual;//映射后的虚拟地址
unsigned long pfn;//I/O资源物理地址所在的页帧号
unsigned long length;//I/O资源长度(一个页的大小可能是4K,所以最少是4K)
unsigned int type;//I/O资源类型
};
该结构体的使用在arch\arm\plat-s5p\cpu.c中,定义如下:
static struct map_desc s5p_iodesc[] __initdata = {
{
.virtual = (unsigned long)S5P_VA_CHIPID,
.pfn = __phys_to_pfn(S5P_PA_CHIPID),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_SYS,
.pfn = __phys_to_pfn(S5P_PA_SYSCON),
.length = SZ_64K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_UART,
.pfn = __phys_to_pfn(S3C_PA_UART),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)VA_VIC0,
.pfn = __phys_to_pfn(S5P_PA_VIC0),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)VA_VIC1,
.pfn = __phys_to_pfn(S5P_PA_VIC1),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_TIMER,
.pfn = __phys_to_pfn(S5P_PA_TIMER),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_GPIO,
.pfn = __phys_to_pfn(S5P_PA_GPIO),
.length = SZ_4K,
.type = MT_DEVICE,
},
};
以上这个结构体填充了所以需要被映射的地址资源。后续可按需添加相应的映射资源。