Linux内核启动之 __lookup_machine_type

来源:互联网 发布:股票投资 知乎 编辑:程序博客网 时间:2024/06/07 02:37

tansuohao注:针对大部分情况,都是买的芯片和SDK,但是自己要开发不同电路板。linux里面叫machine type,就是uboot里面传进来的机器ID r1。

在 include/generated/mach-types.h 文件能看到

#define MACH_TYPE_S3C2440 362

#define MACH_TYPE_MINI2440 1999


以下是转载原文,转载链接为 http://blog.sina.com.cn/s/blog_63ac1cef0100vco1.html

 __lookup_machine_type函数

   

 1.  内核中对于每种支持的开发板都会使用宏MACHINE_START、MACHINE_END来定义一个machine_desc结构,它定义开发板相关的一些属性及函数,比如机器类型ID、起始I/O物理地址、Bootloader传入的参数的地址、中断初始化函数、I/O映射函数等,比如对于SMDK2440开发板,在arch/arm/mach-s3c2440/mach-smdk2440.c中定义如下:

(3)Linux内核启动之 <wbr> <wbr>__lookup_machine_type

2.   在331、341中定义的MACHINE_START、MACHINE_END在“arch/arm/include/asm/mach/arch.h”中定义如下:

 (3)Linux内核启动之 <wbr> <wbr>__lookup_machine_type

3.   machine_desc结构体在“arch/arm/include/asm/mach/arch.h”中定义,其如下所示:

 (3)Linux内核启动之 <wbr> <wbr>__lookup_machine_type

      所有machine_desc结构体都处于“.arch.info.init”段中,在连接内核时,它们被组织在一起,开始地址为__arch_info_begin,结束地址为__arch_info_end,从连接脚本“arch/arm/kernel/vmlinux.lds.S”中可以看出:

           38     __arch_info_begin = .;   //machine_desc结构体的开始地址

           39         *(.arch.info.init)   //所有machine_desc都在这里面

           40     __arch_info_end = .;     //machine_desc结构体的开始地址

 

4.  不同的machine_desc结构用于不同的开发板,U-BOOT调用内核时,会在r1寄存器中给出开发板的标记(机器类型ID);对于S3C2410、S3C2440开发板,U-Boot传入的机器类型ID为MACH_TYPE_SMDK2410、MACH_TYPE_S3C2440,它们对应的machine_desc结构分别在arch/arm/mach-s3c2410/mach-smdk2410.c

arch/arm/mach-s3c2440/mach-smdk2440.c中定义

 

190  3:    .long  .                  //当前行编译链接后的虚拟地址

191        .long  __arch_info_begin  //machine_desc结构体的开始地址(虚拟地址)

192        .long  __arch_info_end    //machine_desc结构体的结束地址(虚拟地址)

 

         .........................

205  __lookup_machine_type:

206        adr r3, 3b               //r3 = 190行的物理地址

207        ldmia  r3, {r4, r5, r6}  //[r3]->r4,[r3+4]->r5,[r3+8]->r6

                                     r4 = 190行的虚拟地址

                                     r5 = __arch_info_begin (VA)

                                     r6 = __arch_info_end (VA)

208        sub r3, r3, r4          //r3=(190行的物理地址)-(190行的虚拟地址)

209        add r5, r5, r3         //r5= __arch_info_begin(物理地址)

210        add r6, r6, r3         //r6= __arch_info_end(物理地址)  

211  1:    ldr r3, [r5, #MACHINFO_TYPE]      //r5是machine_desc结构体地址

                           r3 = r5 + MACHINFO_TYPE=machine_desc结构中定义的nr成员,即机器类型ID

212        teq r3, r1            //r1是Bootloader调用内核时传入的机器类型ID

213        beq 2f               //相等则跳转到218行

214        add r5, r5, #SIZEOF_MACHINE_DESC     //否则跳转到下一个machine_desc结构体

215        cmp r5, r6          //是否已经比较完所有的machine_desc结构体

216        blo 1b              //没有则继续比较(lo:无符号小于)

217        mov r5, #0          //比较完毕,但没有匹配的machine_desc结构体,r5=0

218  2:    mov pc, lr          //返回

 

上面代码功能说明:

__lookup_machine_type函数将这个r1寄存器中的机器类型ID与machine_desc结构中的nr成员比较,如果相等则表示找到了匹配的machine_desc结构,于是返回它的地址(存于r5中),如果__arch_machine_begin和__arch_machine_end间所有machine_desc结构的nr成员都不等于r1寄存器中的值,则返回0(r5等于0)

 

在配置菜单时,选中两个开发板即可:

    System Type--->

         S3C2410 Machines--->

              [*] SMDK2410/A9M2410

         S3C2440 Machines--->

              [*] SMDK2440

 

 NB:其实,__lookup_machine_type和__lookup_processor_type两个函数非常相似,只需理解一个即可

0 0