• Linux内核分析:uboot与Linux内核机器码分析


    (注:本文参考资料:朱有鹏嵌入式课程。本文为个人学习记录,如有错误,欢迎指正。)

    1. uboot机器码

    在uboot启动的start_armboot阶段,调用board_init函数初始化机器码。

    int board_init(void)
    {
    ..............................
    
        gd->bd->bi_arch_number = MACH_TYPE_SMDKV210;
        gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
    
      return 0;
    }

    在uboot启动内核时,将机器码传参至内核。

    uboot源码中,也有一个/uboot/arch/arm/include/mach-types.h文件,该文件维护至该版本的uboot所支持的所有机器码。

    //利用寄存器向内核传参r0 = 0, r1 = machid, r2 = bi_boot_params
    theKernel (0, machid, bd->bi_boot_params);

    2. Linux机器码

    在内核源码根目录的/arch/arm目录下,每一个“mach-xxx”文件夹代表内核支持的CPU型号;在该文件夹下有多个“mach-xxx.c”文件,每个文件代表内核支持的开发板型号。在每个“mach-xxx.c”文件的末尾,都利用MACHINE_START宏定义一个机器描述符结构体,其中包含了该开发板的相关信息。

    以/kernel/arch/arm/mach-s5pv210/mach-smdkv210.c文件为例,相关代码如下:

    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
    MACHINE_END

    为分析方便,人工替换其中的宏定义,得到如下代码:

    static const struct machine_desc __mach_desc_SMDKV210
     __used
     __attribute__((__section__(".arch.info.init"))) = {
        .nr= MACH_TYPE_SMDKV210,
        .name= "SMDKV210",
        .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,
        .timer= &s5p_systimer,
    };
    • 结构体中成员“.nr = MACH_TYPE_SMDKV210”,表示该开发板的机器码。
    • 机器码值“MACH_TYPE_SMDKV210”在/kernel/include/generated/mach-types.h文件中定义,该文件在内核配置过程中自动生成。mach-types.h文件维护着该版本内核所支持的全部机器码。
    • 结构体成员“.name= "SMDKV210"”,表示该开发板的名称。
    • 结构体成员“.init_machine = smdkv210_machine_init”,定义了一个函数smdkv210_machine_init,该函数是一个硬件初始化函数,包含了内核中各种硬件的初始化信息。

    3. uboot与Linux内核机器码的联系

    在Linux内核初始化前期,会比对uboot的机器码和内核的机器码是否匹配,若不匹配,则停止启动内核。

    ENTRY(stext)
    setmodePSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
                                                                            @ and irqs disabled
    mrcp15, 0, r9, c0, c0    @ get processor id
    bl__lookup_processor_type   @ r5=procinfo r9=cpuid
    movsr10, r5    @ invalid processor (r5=0)?
    beq__error_p    @ yes, error 'p'
    bl__lookup_machine_type    @ r5=machinfo   检查机器码是否匹配
    movsr8, r5    @ invalid machine (r5=0)?
    beq__error_a    @ yes, error 'a'
    bl__vet_atags
    bl__create_page_tables
  • 相关阅读:
    课堂讨论电子版
    项目目标文档
    系统利益相关者
    实训八(游戏背景)
    实训七(项目准备与创建)
    实训六(Cocos2dx游戏分享到微信朋友圈----AppID的获取)
    实训五(Cocos2dx-3.x 打包apk再理解)
    实训四(cocos2dx sharesdk集成-1)
    实训三(cocos2dx 3.x 打包apk)
    实训二(cocos2dx 2.x 打包apk)
  • 原文地址:https://www.cnblogs.com/linfeng-learning/p/9285546.html
Copyright © 2020-2023  润新知