原创 linux内核两个重要的结构体

2013-9-8 16:30 1863 16 16 分类: MCU/ 嵌入式 文集: linux

linux从协处理器P15的C0寄存器读出CPU ID 给r9,然后在proc_info_list这个段中查找(proc_info_list这个结构体在arch/arm/include/asm/procinfo.h中定义),看是否有对应的CPUid,这个段里面包含了所有支持的cpu的proc_info结构体。比如s3c2410对应的结构体在arch/arm/mm/proc_arm920.s,这个文件定义了一个__arm920_proc_info。结构体第一个数据位cpu_val,第二个为cpu_mask,如果cpu_val=cpu_mask&r9,则说明支持这个cpu。

struct proc_info_list {
    unsigned int        cpu_val;
    unsigned int        cpu_mask;
    unsigned long        __cpu_mm_mmu_flags;    /* used by head.S */
    unsigned long        __cpu_io_mmu_flags;    /* used by head.S */
    unsigned long        __cpu_flush;        /* used by head.S */
    const char        *arch_name;
    const char        *elf_name;
    unsigned int        elf_hwcap;
    const char        *cpu_name;
    struct processor    *proc;
    struct cpu_tlb_fns    *tlb;
    struct cpu_user_fns    *user;
    struct cpu_cache_fns    *cache;
};

每个cpu也会定义一个和他一样的结构体,并且给他赋值。这些结构体都被存放在proc_info_list这个段,比如在arch/arm/mm/proc_arm920.s里面有如下结构体:
__arm920_proc_info:
    .long    0x41009200
    .long    0xff00fff0
    .long   PMD_TYPE_SECT | \
        PMD_SECT_BUFFERABLE | \
        PMD_SECT_CACHEABLE | \
        PMD_BIT4 | \
        PMD_SECT_AP_WRITE | \
        PMD_SECT_AP_READ
    .long   PMD_TYPE_SECT | \
        PMD_BIT4 | \
        PMD_SECT_AP_WRITE | \
        PMD_SECT_AP_READ
    b    __arm920_setup
    .long    cpu_arch_name
    .long    cpu_elf_name
    .long    HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
    .long    cpu_arm920_name
    .long    arm920_processor_functions
    .long    v4wbi_tlb_fns
    .long    v4wb_user_fns

cpu_arch_name这些东西在同一个文件里有如下定义,就是他们的初值。

cpu_arch_name:
    .asciz    "armv4t"//初值
    .size    cpu_arch_name, . - cpu_arch_name//还不知道size的用法???

    .type    cpu_elf_name, #object//说明这是一个对象
cpu_elf_name:
    .asciz    "v4"
    .size    cpu_elf_name, . - cpu_elf_name

    .type    cpu_arm920_name, #object
cpu_arm920_name:
    .asciz    "ARM920T"
    .size    cpu_arm920_name, . - cpu_arm920_name

    .align

    .section ".proc.info.init", #alloc, #execinstr

    .type    __arm920_proc_info,#object

/***********************************************************************************/
在arch/arm/include/asm/mach/arch.h下有machine_desc结构体,这个结构体保存了board的一些信息,linux程序会从这个段中查找对应的板子ID,
struct machine_desc {
    unsigned int        nr;        /* architecture number    */
    const char        *name;        /* architecture name    */
    unsigned long        boot_params;    /* tagged list        */
    const char        **dt_compat;    /* array of device tree
                         * 'compatible' strings    */

    unsigned int        nr_irqs;    /* number of IRQs */

    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            (*reserve)(void);/* reserve mem blocks    */
    void            (*map_io)(void);/* IO mapping function    */
    void            (*init_early)(void);
    void            (*init_irq)(void);
    struct sys_timer    *timer;        /* system tick timer    */
    void            (*init_machine)(void);
#ifdef CONFIG_MULTI_IRQ_HANDLER
    void            (*handle_irq)(struct pt_regs *);
#endif
};

在arch/arm/mach-s3c64XX中定义了一个结构体:
MACHINE_START(SMDK6410, "SMDK6410")
    /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
    //.phys_io    = S3C_PA_UART & 0xfff00000,
    //.io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
    .boot_params    = S3C64XX_PA_SDRAM + 0x100,

    .init_irq    = s3c6410_init_irq,
    .map_io        = smdk6410_map_io,
    .init_machine    = smdk6410_machine_init,
    .timer        = &s3c24xx_timer,
MACHINE_END

然后在arch/arm/include/asm/mach/arch.h中有machine_start的宏定义,
#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_desc类型的变量mach_desc_smdk6410,并且赋值。最后指定这个结构体添加到.arch.info.init中去(大体上就是这个样子)。下面这些是移植linux很重要的东西,它指定了linux到板子的映射函数。根据具体的情况,可能要修改函数里面一些信息。
machine_desc  mach_desc_smdk6410{

    .nr        = MACH_TYPE_SMDK6410,//板子ID号,这个宏在其他地方定义
    .name        = _name,//板子名字
    //.phys_io    = S3C_PA_UART & 0xfff00000,
    //.io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
    .boot_params    = S3C64XX_PA_SDRAM + 0x100,

    .init_irq    = s3c6410_init_irq,
    .map_io        = smdk6410_map_io,
    .init_machine    = smdk6410_machine_init,
    .timer        = &s3c24xx_timer,
}

 

文章评论0条评论)

登录后参与讨论
我要评论
0
16
关闭 站长推荐上一条 /2 下一条