day9-操作系统初始化函数init-2

1.内核如何进行多平台的适配,在内核中是如何认识这些板子的?结构体 machine_desc

2.内核启动的整体流程

3.认识一种高效的编程结构

链接脚本:vmlinux.lds.S

    .init.arch.info : {
        __arch_info_begin = .;
        *(.arch.info.init)         //代码段
        __arch_info_end = .;
    }

ARCH.H 宏定义

#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             \

};

各种板子的BSP文件中出现的宏定义调用

MACHINE_START(SMDK4212, "SMDK4212")

    /* Maintainer: Kukjin Kim */

    .atag_offset    = 0x100,

    .init_irq   = exynos4_init_irq,

    .map_io     = smdk4x12_map_io,

    .handle_irq = gic_handle_irq,

    .init_machine   = smdk4x12_machine_init,

    .timer      = &exynos4_timer,

    .restart    = exynos4_restart,

MACHINE_END

  宏展开: 


#define MACHINE_START(SMDK4212, "SMDK4212")

static const struct machine_desc __mach_desc_SMDK4212    \

 __used                         \

 __attribute__((__section__(".arch.info.init"))) = {    \

    .nr     = MACH_TYPE_SMDK4212,        \

    .name       = "SMDK4212",

    .atag_offset    = 0x100,

    .init_irq   = exynos4_init_irq,

    .map_io     = smdk4x12_map_io,

    .handle_irq = gic_handle_irq,

    .init_machine   = smdk4x12_machine_init,

    .timer      = &exynos4_timer,

    .restart    = exynos4_restart,

};

总结 machine_desc结构体,用于Linux做设备的识别结构体,这些结构体被限定在了内存的某一片区域

并且通过UBOOT传过来的参数进行该结构体的配置(通过检索taglist的方式来设置)

并且在移植Linux的时候 也要对结构体的变量进行赋值

并且在之后的启动或其他函数中 对该结构体的变量进行调用

    mrc    p15, 0, r9, c0, c0        @ get processor id
    bl    __lookup_processor_type        @ r5=procinfo r9=cpuid

__lookup_processor_type:
    adr    r3, __lookup_processor_type_data

__lookup_processor_type_data:
    .long    .
    .long    __proc_info_begin
    .long    __proc_info_end

    .size    __lookup_processor_type_data, . - __lookup_processor_type_data

    VMLINUX_SYMBOL(__proc_info_begin) = .;                \
    *(.proc.info.init)                        \
    VMLINUX_SYMBOL(__proc_info_end) = .;

__mmap_switched       将旧的地址转化为虚拟地址 代码重定义

start_kernel:

setup_arch(&command_line)

        setup_processor()

                struct proc_info_list *list;//创建一个CPU指令集描述结构体

                list = lookup_processor_type(read_cpuid_id());//从指定的内存中获取到该描述结构体

                cpu_name = list->cpu_name;//将获取到的CPU名字赋值给一个全局变量

        setup_machine_fdt(__atags_pointer);//找到一个移植Linux时写的最合适的machine_desc结构体 并且返回

                    for_each_machine_desc(mdesc) {

                        score = of_flat_dt_match(dt_root, mdesc->dt_compat);

                        if (score > 0 && score < mdesc_score) {

                            mdesc_best = mdesc;

                            mdesc_score = score;

                        }

                    }

                

                

你可能感兴趣的:(linux内核,linux,运维,服务器)