LINUX内核静态映射表的建立过程

一. machine_desc结构体

    1.1. 内核提供了一个重要的结构体struct machine_desc ,这个结构体在内核移植中起到相当重要的作用,内核通过machine_desc结构体来控制系统体系架构相关部分的初始化

    2.1. 静态映射表与machine_desc关系。

        2.1.1. kernel/arch/arm/mach-s5pv210/mach-smdkc110.c 这个文件是由三星在移植内核时提供的一个很重要的文件,这个文件中的函数都是与硬件相关的。mach-smdkc110.c文件中的smdkc110_map_io函数就是静态映射表建立过程调用的一个函数开机时调用映射表建立函数:

/*
 * 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    \
 __used                            \
 __attribute__((__section__(".arch.info.init"))) = {    \
    .nr        = MACH_TYPE_##_type,        \
    .name        = _name,

#define MACHINE_END                \
};

MACHINE_START(SMDKV210, "SMDKV210")
    /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
    .phys_io    = S3C_PA_UART & 0xfff00000,
    .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
    .boot_params    = S5P_PA_SDRAM + 0x100,
    .init_irq    = s5pv210_init_irq,
    .map_io        = smdkv210_map_io,
    .init_machine    = smdkv210_machine_init,
#ifdef CONFIG_S5P_HIGH_RES_TIMERS
    .timer        = &s5p_systimer,
#else
    .timer        = &s3c24xx_timer,
#endif
View Code

    2.3. 开机时(kernel启动时)smdkc110_map_io怎么被调用的

        2.3.1. 

        start_kernel

            setup_arch

                paging_init

                    devicemaps_init

                    {

                          if (mdesc->map_io)

                               mdesc->map_io();       //   这个map_io指向的就是smdkc110_map_io函数,这个之前在讲内核的启动过程的时候就分析过了       

                    }

二. 映射表建立相关函数

    2.1. smdkc110_map_io            

static void __init smdkv210_map_io(void)
{
    s5p_init_io(NULL, 0, S5P_VA_CHIPID);
    s3c24xx_init_clocks(24000000);
    s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
}
View Code

    2.2. s5p_init_io

/* read cpu identification code */

void __init s5p_init_io(struct map_desc *mach_desc,
            int size, void __iomem *cpuid_addr)
{
    unsigned long idcode;

    /* initialize the io descriptors we need for initialization */
    iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
    if (mach_desc)
        iotable_init(mach_desc, size);

    idcode = __raw_readl(cpuid_addr);
    s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
}
View Code

    2.3. iotable_init

/*
 * 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);
}
View Code

    2.4. 通过分析上述调用过程。最终通过iotable_init函数来实现静态映射表。这里有一个重要的结构体struct map_desc。由于描述映射关系的。内核中定义了该结构体如下:

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,
    },
};
View Code

        2.4.1. 当开发者需要增加新映射表时,只需要在此结构体数组添加即可。

 

索引文献:https://www.cnblogs.com/deng-tao/p/6366901.html

转载于:https://www.cnblogs.com/linux-37ge/p/10215149.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值